开发日志丨关于回测框架搭建的一些进展,以及接下来的想法
条评论工作需要,决定自己从头搭建一个系统的回测框架。开发至今,先暂停一会,思考下这个回测框架应该如何编写。
目前开发完全使用 Python 语言,已经完成了StratPerf
类和 NetWorthMaker
类,分别可以对净值序列生成绩效数据和对持仓数据生成净值。接下来,应该就是要对因子数据生成持仓。
由于量化策略的复杂性,一个显而易见的问题是,这些类是否能用于不同类型的策略?
目前根据我的观察,策略主要分为三类:择时策略、截面策略和规则型策略。当然,可能还有什么无法归结到这三个类别的策略。这套框架开发应当尽可能适用于这三类策略。首先,StratPerf
没有问题,因为这个最少只需要输入一个净值数据,而这一点对于所有策略是通用的;NetWorthMaker
应当也没有问题,因为这个类通过持仓生成净值,而任何策略当然都可以生成一个持仓表。
那么可能存在问题的环节就是生成持仓的类的编写了。首先讨论,一个类是否能够统一择时和截面因子?一般而言,我们参考截面因子来做多因子值偏高的品种,做空因子值偏低的品种;而对于择时因子,我们做多因子值为正的品种,做空因子值为负的品种。当然,我们也完全可能做一些变化,比如对于截面因子,我们也可以做多因子值为正的品种,做空因子值为负的品种;而对于择时因子,当然没有截面的相对大小可以比较,但是我们也可以控制当因子值大于某个非零值时做多,小于某个非零值时做空……
这样的问题可以通过增加一个参数解决,比如,可以在 __init__()
函数中增加一个 mode
参数,用于指定是根据相对值来多空还是根据绝对值来多空。而对于这两种模式,我们又可以设计更多的参数,比如是否只多不空,亦或只空不多;再如截面多空是选择几只品种还是选择排名前后多少占比的品种?如果是根据绝对值来多空,那么多和空的阈值又是多少?我在考虑用一串字符串来表示以上提到的所有参数。比如根据相对值来持仓、分别多空前后 10%-30% 的品种,就可以表示为r_l:10%-30%_s:70%-90%
。嗯,看上去不错。
假设上面这个方法可以兼容择时和截面因子,那么如何兼容规则型策略呢?规则策略一般意味着达到某些条件就触发买入或者卖出的信号,看上去似乎和因子型策略形式大为不同,然而实际上,任何规则型策略都可以转换成因子型策略,只需将买卖信号作为因子,然后用绝对数值来生成持仓就可以了。基于这个思路,我们只需要在程序中根据我们的规则型策略生成买卖信号表,那么同样可以利用上述的类来生成持仓,剩下的流程就和普通因子型策略一样了。
当然,这样的方式也许有点为难使用者,因此也可以考虑再写一个类,用来根据规则来生成买卖信号。设想这个类可以接受一系列数据和一个函数,这个函数则可以根据这些数据来生成买卖信号。那么,这个类应当可以根据这个函数和这些数据来生成信号表或者因子表,不过这是后话。
除了上述考虑以外,受到舍友的启发,对于因子型的策略(其实规则型策略也一样),完全可以开发出一个标准化的开发流程,将因子编写集中到一个小小的函数中,然后利用整个系统来对这个因子进行测试、结合进入因子库。具体来说,可以实现一个人因子基类,然后令所有因子先继承这个类、指定需要读取的数据、根据数据给出生成因子值的逻辑。这样,策略的研究就可以大体上回归到对一个个因子本身的研究。也许大多数因子工厂就是这样的模式。
以上就是我目前对于回测框架的想法。