如何用对象继承来减少量化策略代码量
在真格量化的API文档里我们经常遇到“bal.CashBalance”、“order.id”这类看起来非常诡异的变量写法。这都是些什么东西呢?
这得从“面向对象”(Object Oriented)的编程思想说起。
首先,”对象“可以是我们想研究的任何事物,从一个自然数到一个星系,都可以视为对象。它不仅可以是具体的事物,比如一吨大豆,还可以是更抽象的规则,比如大豆期货合约。
其次,对象具有状态和行为。我们可以用各种数值来描述对象的状态,如对于大豆期货合约,可以有合约乘数、交割日期、当前价格等等。对象也有对应的行为,或者操作,比如对于大豆期货合约,我们可以买入、卖出、开仓、平仓、交割等等。我们可以把这些状态和行为都和这个对象关联起来。
再次,对于具有相近特性、类似行为的对象,我们可以将其归为一类,比如豆粕期货合约在很多属性和行为上与大豆期货合约颇为相似。我们可以将它们都归为“期货合约”这个类别。豆粕期货合约、大豆期货合约等等合约的抽象就是期货合约这个“类”。“期货合约”这个类的具体化,可以是大豆期货或者豆粕期货这个“对象”。
最后,我们可以通过各种“方法”(比如期货合约的买卖、查询)来对对象进行操作,并且获取各种“信息”(比如合约乘数、买卖状态)。
还是以期货合约为例,我们要用Python创建一个“期货合约”的“类”:
其中init()方法是一种特殊的方法,被称为类的初始化方法,当创建了这个类的实例时就会调用该方法。
有了期货合约“Contract”这个类,我们可以在这个类里通过“初始化方法”(即输入合约名和合约乘数)创建几个对象,也就是具体的期货合约:
比如我们用以下语句创建了三个期货合约对象:
con1=Contract("M.DCE",10)
con2=Contract("IF.CFFEX",300)
con3=Contract("TA.CZCE",5)
现在我们可以调用displayContrac方法就能显示这些合约的名称和合约乘数(我们用“.”来连接对象名和其属性或方法,也就是”对象名.属性“或者”对象名.方法“):
con1.displayContract()
con2.displayContract()
con3.displayContract()
结果显示为:
Contract Name : M.DCE , multiplier: 10
Contract Name : IF.CFFEX , multiplier: 300
Contract Name : TA.CZCE , multiplier: 5
我们还可以通过Contract.ContractCount来访问“类变量”,这里是对合约数量的计数:
print "total contracts %d" % Contract.ContractCount
结果显示为:
3
因为我们一共建立了3个合约对象。
对于期货合约这个类在初始化时还没有的属性,我们也可以轻易地增加,比如我们设定合约1也就是con1的价格为2555:
con1.price=2555
然后我们可以用getattr(对象名,属性名)来访问这个属性,或者更简洁地,用”变量名.属性名“来直接访问:
print "price is %d" % getattr(con1,‘price‘)
或者
print "price is %d" % con1.price
结果都是
price is 2555
我们还可以通过GetContractValue方法来计算合约的价值(合约价格乘以合约乘数):
print con1.GetContractValue()
结果为:
25550
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。比如我们可以再定义一个“期权合约”类来作为”期货合约“类的“子类”:
子类的定义方法为:
class 子类名(父类名):
............
我们可以先创建一个期权合约对象(创建时包含合约代码、合约乘数、对应期货合约代码):
op1=Options("OM.DCE",10,"M.DCE")
然后设定其价格:
op1.price=20
然后可以直接调用GetContractValue方法来求合约价值:
op1.displayContract()
输出为:
200
也就是20×10.
虽然我们并未在期权合约类中去定义GetContractValue方法,但是期权合约类从期货合约类直接继承了GetContractValue方法,不劳我们写一行代码(这对程序员来说是绝佳的体验),可以说是非常省事了!
知道了Python面向对象的编程方法,下次您再看到“context.accounts["回测期货"].GetOrder(order.id)”该不会犯晕了吧?
原文地址:https://blog.51cto.com/14258357/2376816