如何用Python的面向对象编程方法节约代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用Python的面向对象编程方法节约代码相关的知识,希望对你有一定的参考价值。

如何用对象继承来减少量化策略代码量


在真格量化的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)”该不会犯晕了吧?

技术图片

以上是关于如何用Python的面向对象编程方法节约代码的主要内容,如果未能解决你的问题,请参考以下文章

如何用面向对象的思维去封装一个小型轮播图插件

Python基础-week06 面向对象编程进阶

Python 2.7 学习笔记 面向对象的编程

面向对象Python

面向切面编程AOP是面向对象编程OOP的补充

面向对象基础二