2011-03-23 52 views
7

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

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

我有一个关于什么可以使良好的对象候选人(投资组合,股票,期权等)和方法(买入,卖出,更新数据等)的粗略想法。

一个多头头寸将买入开盘和卖出结束,而空头头寸有卖出开盘和买入结束。

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每天

@Senderle

我&大号想想也许你是从字面上理解了“对象”的隐喻,并且也试图从这个词的编程意义上将一个看起来很像对象的分享转化为一个对象。如果是这样,这是一个错误,这是我认为是并列的观点。

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

+1

你想为这种应用程序的数据库层。 – Santa 2011-03-23 01:34:16

+0

由于好奇心,对这个术语不太熟悉,我是否认为持有特定股票的“开放”头寸对于一个非零(正面或负面的空头头寸)是正确的? – senderle 2011-03-25 13:34:01

+0

是的,一个开放的头寸将是非零的。基本上有两种类型的头寸:多头和空头。长期投资是大多数人的想法。低买高卖。空头头寸与持续多头相反。你从你的经纪人那里借入股票并在市场上卖出,创造一个责任,你必须把股票归还给你的破产者(或者当他要求他们回来时)。这个过程是(借入股票)卖高,买低(回到他们的经纪人)。 – 2011-03-29 05:33:46

回答

1

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

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

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

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

+4

我同意'将您的数据存储在数据库中'和'不要过度设计一切';我完全不同意'面向对象的设计是有缺陷的'。有可能做得不好,但是对任何事情都是如此。 – 2011-03-23 02:48:37

+0

也许我不知道该怎么做。但我喜欢做东西。不要考虑制作它们。 – 2011-03-23 03:09:39

+0

@juxtapose:真的吗?你有没有想过你有多少个500多行的程序? – 2011-03-23 03:17:07

1

我想我会分离成

  • 控股(你目前拥有或每个符号的欠)
  • 订单(简单要求购买或在单一时间卖单符号)
  • 交易(订单的集合)

这使得它可以很容易得到的电流值,队列订单,并建立更复杂的订单,并轻松映射到数据对象在他们身后的数据库。

+0

我试图想象这将如何工作。价格历史显然应该存储在数据库中。但是股票呢?我是否还想用一个对象作为共享的想法? (只有在这种情况下,它将是一个数据库记录,而不是一个对象) – 2011-03-23 06:25:10

1

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

这就是说,我不明白为什么你需要有一个对象每股;我不明白这个策略背后的推理。即使您希望能够详细跟踪订单历史记录,您也可以只存储汇总数据,如“x股票,每股y美元,日期z”。

它会更有意义有一个position对象(或holding对象,在休的术语) - 每只股票之一,或许与.order_history属性,如果你真的需要你持有的详细历史股票。是的,一个数据库肯定会对这类事情有用。

想蜡一会儿:我想也许你是从字面上理解“对象”的隐喻,所以试图将一个看起来很像对象的分享视为一个对象在编程意义上这个词。如果是这样,这是一个错误,这是我认为是并列的观点。

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

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

**在许多编译语言中,编译模块时产生的文件称为“对象”文件。我认为这是其中“对象”隐喻实际上来自于。 (我没有任何这方面的真实证据!所以任何知道得更清楚的人,请随时纠正我。)人们看到的OOD的无处不在的玩具例子 - car.drive(mph=50); car.stop(); car.refuel(unleaded, regular) - 我认为是可能会混淆概念的回形式一点点。

+0

谢谢你的评论是有帮助的。我同意从字面上思考这个问题。 – 2011-03-25 05:18:55

2

有两种基本的戒律设计这样的系统时,你应该记住:

  1. 消除从你的数据冗余。没有冗余确保完整性。
  2. 保留所有您需要的数据以回答任何疑问,并以最低的细节水平。

根据这些规则,我的建议是维护一个事务日志文件。每笔交易代表某种形式的状态变化,以及所有相关的事实:何时,什么,买/卖,多少,多少等等。每笔交易将由一笔记录表示(这里的一个名称是有用的)在一个平面文件中。一年(或甚至5年或10年)的交易应该很容易适应记忆驻地名单。然后,您可以创建函数来从列表中选择,排序和总结您需要的任何信息,并将其作为内存驻留,这将非常快速,比SQL数据库快得多。

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

您可能需要一些有关您的持股的辅助信息,例如在任何特定日期的价值/价格,以便您可以绘制价值vs.任何或所有持股的时间(有这种信息的网上资源,雅虎财经为一。)一个主数据库包含关于你的每个持股的静态信息也将是有用的。

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

首先用命令行界面编写API。当这个工作让你满意时,如果你愿意,你可以继续创建一个GUI前端。

祝你好运,玩得开心!