模板列表类¶
Instrument List (模板列表类)是RiskQuantLib中,任何 Instrument (模板类)的实例的一个集合,它非常类似于python自己的list,但模板列表类的每个元素都是一个模板类的实例。模板列表类与python默认list最大的差别在于,对于每一个模板类,RiskQuantLib都会创建一个对应的模板列表类。当你更改其中任何一个模板列表类的时候,其他的模板列表类不会受到影响。比如, bond 会有一个对应的,名为 bondList 的模板列表类, stock 会有一个对应的名为 stockList 的模板列表类。如果你声明了一个新的模板类 pandaBond,那么对应的,模板列表类 pandaBondList 也会被创建。
任何一个模板列表类 Instrument List 都拥有一个名为 all 的属性,这个属性用于盛放所有的模板类的实例。模板列表类还拥有众多预置函数,允许你向模板列表中添加新的实例。这样的添加函数被称为add函数族,比如 bondList 就拥有 addBond 和 addBondSeries 两个用于新增元素的函数。当你使用这两个函数的时候,你就可以向 bondList 中新增一个 bond 模板类的实例,或者新增好几个实例。
Instrument List 允许盛放两个完全相同的元素,也就是说,你可以将同一个实例添加两次。
通常情况下,Instrument List 会继承自 RiskQuantLib.Operation.operation.operation。这个名为operation的类包含了所有用于对列表元素进行操作的函数。你可以阅读 Operation Of List 来获取更多信息。
模板列表类的一些有用的默认函数包括: groupBy, filter, execFunc, apply, join, merge, sort 等。
非常有必要在这里介绍一下模板列表类的重要属性:
新增元素¶
如果 pandaBondList 是一个模板列表类,你可以使用 addPandaBondSeries 来新增几个列表元素。新增的列表元素将是 pandaBond 模板类的实例。
listA = pandaBondList()
listA.addPandaBondSeries(codeSeries,nameSeries)
你也可以只增加一个元素,只需要使用 addPandaBond::
listA = pandaBondList()
listA.addPandaBond(code,name)
注意:不同的模板列表类的add函数名称也是不一样的,如果你编译了一个名为 samuraiBond 的模板类,那么你应该使用 addSamuraiBond。
混合索引¶
对于python的默认list,如果你知道元素处于第几个,你可以很容易地索引元素,比如通过 listA[2] 这种方式你可以得到第三个元素。但在RiskQuantLib中,方括号中可以填写的不仅仅是一个表示位置的数字,也可以是某个元素的 code 属性的值,也可以是属性的名称,也可以是一个 code 属性的值的列表,或者属性的名称的列表。比如::
rqlListA = stockList()
rqlListA.addStockSeries(['A','B','C'],['TC US','HU China','JI UK'])
rqlListA.setIssuer(['A','B','C'],['Tencent','HU JI FA','JIK&'])
# This will give you the third element
theThirdElement = rqlListA[2]
# This will give you the first stock whose code is 'C'
theThirdElement = rqlListA['C']
# This will give you the last element
theThirdElement = rqlListA[-1]
# This will give you the first two element
theFirstTwoElement = rqlListA[:2]
# This will give you all the elements whose code is 'A' or 'B'
theFirstTwoElement = rqlListA[['A','B']]
# This will give you a list whose element is the value of attribute issuer
theValueListOfIssuer = rqlListA['issuer']
# This will give you an dict whose element is the value of attribute issuer and name
theValueDictOfIssuerAndName = rqlListA[['issuer','name']]
你可能会问,如果属性 code 的值碰巧和其他属性的名称相同,那么RiskQuantLib会如何处理这个索引任务呢?实际上如果这种情况出现,RiskQuantLib会认为这是一个 code 属性的值,并返回一个元素,这个元素 code 属性的值必须等于你传入的值。
Set函数族¶
Set函数族是用于为模板列表类的元素设定属性的多个函数的统一称呼。正如你在上面的例子中看见的,我们使用 rqlListA.setIssuer(['A','B','C'],['Tencent','HU JI FA','JIK&']) 来为rqlListA的元素设定 issuer 这个属性。通常,Set函数族中的函数都有两个参数需要传入,在这个例子里,是 codeSeries 和 issuerNameSeries。你应当为这两个参数分别传入一个可迭代对象,比如list。当你传入两个list后,他们的元素会建立一个一一对应的关系。 codeSeries 的第一个元素对应 issuerNameSeries 的第一个元素, codeSeries 的第二个元素对应 issuerNameSeries 的第二个元素,以此类推,所以理论上,这两个list1的长度应该是相同的。在这个例子里,股票A和Tencent对应,股票B和HU JI FA对应。需要注意的是,传入的list的长度不一定需要等于模板列表类的长度,如果你传入的 codeSeries 的列表长度比模板列表的长度短,那么那些没有出现在传入列表里的元素会被跳过,其属性会被设定为空。
模板列表的加减¶
你可以把两个模板列表相加或者相减。比如::
rqlListC = rqlListA + rqlListB
rqlListD = rqlListA - rqlListB
在这样操作之后,所有B列表的元素都会被加入A列表,或者从A列表中删除。但是,A列表的属性并不会被保留在结果C或者D中,只有元素被保留。如果你需要C保留A的属性,你应该这样使用::
rqlListC = rqlListA.copy(deep = False)
rqlListC.setAll(rqlListA.all + rqlListB.all)
遍历¶
如果 rqlListA 是一个股票列表,在 RiskQuantLib.Instrument.Security.Stock.stock 中,你这样定义了一个类函数::
class stock(base):
...
def calTradingAmount(self):
self.tradingAmount = self.tradingPrice * self.tradingShare
如果你需要遍历模板列表的元素,对每一个元素执行这个自定义函数,那么你应该使用 execFunc,像这样::
rqlListA.execFunc('calTradingAmount')
这完全相当于::
for element in rqlListA:
element.calTradingAmount()
你也可以在调用这个函数的时候传入参数,比如::
rqlListA.execFunc('calTradingAmount',tradingAmountType)
这完全相当于::
for element in rqlListA:
element.calTradingAmount(tradingAmountType)
筛选¶
如果 rqlListA 是一个股票列表,你想要选择其中name属性的值包含了HG这个字符串的元素,你可以这样使用::
selectedElements = stockListA.filter(lambda x:x.name.find('HG')!=-1)
这里,filter 函数被用于选择那些符合你条件的元素。你可以传入一个函数,这个函数接受一个参数(在这个例子里是x),这个参数代表了模板列表类的元素(在这个例子中是 stock 模板类),通过对这个元素进行运算(这个例子中是 x.name.find('HG')!=-1 ),这个函数应该返回一个bool类型的值,即 True 或者 False。filter 函数即返回所有符合 True 的元素。