面向对象的设计,用于Python中的投资/股票和期权组合

时间:2011-03-23 01:26:22

标签: python projects-and-solutions stocks trading

我是初学者/中级Python程序员,但我没有编写应用程序,只编写脚本。我目前没有使用很多面向对象的设计,所以我希望这个项目能够帮助我建立自己的OOD技能。问题是,我不知道从设计角度开始(我知道如何创建对象和所有东西)。对于它的价值,我也是自学成才,没有正式的CS教育。

我想尝试编写一个程序来跟踪投资组合股票/期权头寸。

我对什么会成为好的候选对象(投资组合,股票,期权等)和方法(买入,卖出,更新数据等)有一个粗略的想法。

多头头寸可买入开仓,卖出收盘,而空头头寸有买卖,买入收盘。

portfolio.PlaceOrder(type="BUY", symbol="ABC", date="01/02/2009", price=50.00, qty=100)
portfolio.PlaceOrder(type="SELL", symbol="ABC", date="12/31/2009", price=100.00, qty=25)
portfolio.PlaceOrder(type="SELLSHORT", symbol="XYZ", date="1/2/2009", price=30.00, qty=50)
portfolio.PlaceOrder(type="BUY", symbol="XYZ", date="2/1/2009", price=10.00, qty=50)

然后,一旦调用此方法,我该如何存储信息?起初我以为我会有一个Position对象,其中包含Symbol,OpenDate,OpenPrice等属性,但考虑更新位置以考虑销售变得棘手,因为购买和销售发生在不同的时间和数量。

  • 买入100股开,1次,1股。卖4种不同的时间,4种不同的价格。
  • 购买100股。每天卖1股,持续100天。
  • 购买4种不同的时间,4种不同的价格。一次性卖出全部头寸,1个价格。

一种可能的解决方案是为每股股票创建一个对象,这样每个股票就会有不同的日期和价格。这会是太多开销吗?该投资组合可能有数千或数百万个小共享对象。如果你想找出一个头寸的总市值,你需要这样的东西:

sum([trade.last_price for trade in portfolio.positions if trade.symbol == "ABC"])

如果您有位置对象,则计算很简单:

position.last * position.qty

提前感谢您的帮助。看看其他帖子显然是“帮助”不要“为你编写程序”。我觉得我只需要一些方向,指向正确的道路。

反思的其他信息 目的 该计划将跟踪所有开放和关闭的头寸;能够看到详细的盈亏。

当我想到详细的P& L时,我想看到......   - 所有开放日期(和关闭日期)   - 时间到了   - 开盘价(截止日期)   - P& L自开放以来   - 每天P& L

@Senderle

  

我想也许你的字面意思也是“对象”比喻,因此试图在某种程度上将这种看似非常像对象的共享转换为该字的编程意义上的对象。如果是这样,那就是一个错误,这就是我所认为的并列的重点。

这是我的错。考虑“对象”share对象似乎是自然的候选者。直到有数百万人认为这个想法似乎很疯狂。我本周末会有一些免费的编码时间,并会尝试创建一个有数量的对象。

5 个答案:

答案 0 :(得分:2)

在设计此类系统时,您应该记住两条基本规则:

  1. 消除数据的冗余。没有冗余可以确保完整性。
  2. 以最低级别的细节保留您回答任何查询所需的所有数据。
  3. 基于这些规则,我的建议是维护一个事务日志文件。每个交易代表某种状态的变化,以及所有相关的事实:何时,什么,买/卖,多少,多少等等。每个交易将由一个记录表示(一个名字小组在这里很有用)在一个平面文件中。一年(或甚至5年或10年)的交易应该很容易适合内存驻留列表。然后,您可以创建函数来从此列表中选择,排序和汇总所需的任何信息,并且作为内存驻留,它将非常快,比SQL数据库快得多。

    当交易日志变得太大或太慢时,您可以计算截至特定日期(如年终)的所有头寸的状态,将其用于下一期间的初始状态,并存档您的旧日志文件到光盘。

    您可能需要一些关于您的馆藏的辅助信息,例如任何特定日期的价值/价格,因此您可以为任何或所有馆藏绘制价值与时间的关系(此类信息的在线资源,雅虎财经一个。)包含有关每个馆藏的静态信息的主数据库也很有用。

    我知道这听起来不是“面向对象”,但是OO设计可以用于隐藏系统在TransLog对象中的详细工作方式以及保存/恢复光盘数据的方法(保存/打开方法),输入/更改/删除交易;以及将数据处理成有意义的信息显示的其他方法。

    首先使用命令行界面编写API。当这令您满意时,您可以根据需要继续创建GUI前端。

    祝你好运,玩得开心!

答案 1 :(得分:1)

避免使用物体。面向对象的设计是有缺陷的。将您的程序视为对数据(列表和词典)进行操作的行为的集合。然后将相关行为分组为模块中的函数。 每个功能都应具有明确的输入和输出。将数据全局存储在每个模块中。 为什么没有物体呢?因为它更接近问题空间。面向对象的编程创建了太多的间接来解决问题。不必要的间接导致软件膨胀和错误。

一种可能的解决方案是为每股股票创建一个对象,这样每个股票就会有不同的日期和价格。这会是太多开销吗?该投资组合可能有数千或数百万个小共享对象。如果您想了解某个职位的总市值,您需要以下内容:

是的,开销太大了。这里的解决方案是将数据存储在数据库中。除非您使用NOSQL方案,否则查找职位的总市值将在SQL中完成。

不要试图设计所有可能的未来结果。只需让你的程序以它现在需要的方式工作。

答案 2 :(得分:1)

我想我会把它分成

  • 馆藏(您目前拥有或欠每个符号的内容)
  • 订单(单次购买或出售单个符号的简单要求)
  • 交易(订单集合)

这使得获取当前值,排队顺序和构建更复杂的订单变得非常容易,并且可以轻松地映射到数据对象后面的数据库。

答案 3 :(得分:1)

回答您的问题:您似乎已经清楚了解您的数据模型。但在我看来,你需要更多地思考你希望这个程序做什么。它会跟踪股价的变化吗?下订单,或建议下单?或者它只是跟踪你所下的订单?这些用途中的每一种都可能需要不同的策略。

那就是说,我不明白为什么你需要为每个共享提供一个对象;我不明白这个策略背后的原因。即使您希望能够非常详细地跟踪订单历史记录,您也可以存储汇总数据,例如“x每股y美元的份额,z

根据Hugh的术语,有一个position对象(或holding对象更合理 - 每个库存一个,可能带有.order_history属性,如果你真的需要您在该股票中持有的详细历史记录。是的,数据库绝对可以用于此类事情。

让哲学刻薄一刻:我想也许你的字面意思是“对象”比喻,所以试图分享,这在某些方面看起来很像对象,进入编程意义上的一个对象。如果是这样,那就是一个错误,这就是我所认为的并列的重点。

我不同意他的说法,面向对象的设计是有缺陷的 - 这是一个非常大胆的声明! - 但是他的答案是正确的,因为“对象”(例如,一个类实例)几乎与模块**相同。它是链接到某个共享状态的相关函数的集合。在类实例中,状态通过selfthis共享,而在模块中,它通过全局命名空间共享。

对于大多数用途,类实例和模块之间唯一的主要区别是可以有许多类实例,每个类实例都有自己独立的状态,而只能有一个模块实例。 (当然,还有其他差异,但大多数时候它们涉及对学习OOD不太重要的技术问题。)这意味着您可以以与您对模块的思考方式类似的方式思考对象,并且这是一个有用的方法。

**在许多编译语言中,编译模块时产生的文件称为“对象”文件。我认为“对象”隐喻实际来自哪里。 (我没有任何真实的证据!所以任何知道更好的人,都可以随意纠正我。)人们看到的OOD无处不在的玩具例子 - car.drive(mph=50); car.stop(); car.refuel(unleaded, regular) - 我认为是背影可能会混淆这个概念。

答案 4 :(得分:0)

我很想听听你的想法。我大约 4 个月(兼职)创建了一个订单处理程序,虽然它大部分完成了,但我仍然有和你一样的问题,因为我希望它被正确地制作。

目前,我保存了两个文件

策略命中日志”,其中保存了来自任何策略脚本的每个买入/​​卖出信号。例如:当buy_at_yesterdays_close_price.py 策略被触发时,它将该买入请求保存在该文件中,并将该请求传递给Order Handler

一个“订单日志”,它是一个单一的 DataFrame - 该文件符合您关注的目的。

  • 来自策略的每个请求都与单个基础证券(例如 AAPL 股票)相关,并创建一个 Order,该订单在 DataFrame 中保存为一行,其中包含股票代码、策略的列产生此 Order 以及 SuborderBroker Suborder 列的名称(解释如下)。
  • 每个订单都有一个存储在 Suborder 列中的 Suborders(字典)列表。例如:如果您看好 AAPL,则子订单可能是:
[
{'security': 'equity', 'quantity':10},
{'security': 'option call', 'quantity':10}
]
  • 每个订单还有一个存储在 Broker Suborder 列中的 Broker Suborders(字典)列表。每个 Broker Suborder 是对 Broker 购买或出售证券的请求,并使用 Broker 为该请求提供的“订单 ID”进行索引。对 Broker 的每个新请求都是一个新的 Broker Suborder,并且取消该 Broker Suborder 会记录在该 dict 中。要记录对经纪商子订单的修改,您可以取消旧的经纪商子订单并发送并记录新的子订单(使用 IBKR 与佣金相同)。

改进

  1. 类列表而不是 DataFrame:我认为将每个 Order 保存为 Order_Class 的实例(而不是一行 a DataFrame),它具有 SuborderBroker_Suborder 属性,这两个属性也是 Suborder_ClassBroker_Suborder_Class 的实例。 我目前的问题是将类列表保存为我所有打开和关闭的订单的记录是pythonic还是愚蠢。

  2. 可视化注意事项:似乎订单应该以表格形式保存以便于查看,但也许最好将它们保存在这种“类实例列表”形式中并使用在查看时将它们列表化的功能?任何人的任何意见将不胜感激。我想摆脱这个并开始玩 ML,但我不想让 Order Handler 未完成。

  3. 这都是废话吗?:是否应该将每个 Broker Suborder(对经纪人的买入/卖出请求)附加到 Order(这只是一个特定的来自策略脚本的策略请求)还是应该按时间顺序记录所有 Broker Suborders 并且只引用产生 Order 的策略顺序(Broker Suborder)? Idk...但我会喜欢每个人的意见。