多参数优化不要刻意逃避

资料上都会建议cta策略的参数越少越好,最好小于等于两个,确实,两个参数最好做优化,两个参数的组合再大能超过10k次?跑回测也不会跑过1天,再做滚动优化和蒙特卡罗模拟另算。我现在两个参数的组合也就在1k次左右,分钟线7年的数据也就3小时不到。

但是有时不是你想参数少就参数少,比如我用到了atr止损和adx/cci来判断趋势强弱,这时候atr的窗口和adx/cci的窗口用默认的14或者是其他值?经我测试,有时候用其他值会更好,这时候怎么办?假装不知道这回事儿,强制用默认值,还是把atr和adx/cci的窗口也拿过来进行组合测试优化?这时候我的建议是一起进行测试优化,别害怕过拟合,用默认值和进行优化与过拟合是没有直接关系的。当然这时候要看一下atr或者adx/cci和你的主参数有没有直接关系,如果相关性很强就没必要优化,如果相关性不强就立刻拿过来优化。

遗传算法靠谱吗?不太靠谱

我今天通过一个01背包问题的示例,简单的了解了一个遗传算法,我的总结为:不断的重组和变异,在有限的计算次数内找到近似的最优值,这时候想想:如果我有3个参数,每个参数的取值个数都有50个,这样就有505050=125000个组合需要回测,现在知道为什么建议在2个参数以下了吧,2个参数才2500次,参数的个数增长会导致回测次数指数型增长。如果遗传算法能让我们在25000次回测找到一个近似解也不错啊。那为什么不靠谱呢?

  1. 遗传算法有一个适应函数,其实就是验证这组参数是否可用,在01背包问题里面很简单,这个组合的重量大于书包的负荷了就不可用,反之可用。那cta回测呢?很难定一个具体的值,要么只能自己假想一个,sharp ratio大于1,倒也不是不行。

  2. 遗传算法的参数组合是随机的,不像我们做cta回测时是连续的,这会导致一个问题,我取的最优解不一定是在一个连续平面上。我们在tb或者文华上做回测时,会绘制一个3D图,我们从上面找一块相对较高的连续平面,当中取一点为最优解。遗传不一样了,遗传的优点就在于随机变化来尽量覆盖全集,相当于一张低像素和一张高像素,高像素是全集,低像素是遗传后的子集,但是这个子集并不是图片的某一小部分,而是整张图片的浓缩,但是不影响观察。这也就决定了遗传的离散性非常强。因为cta在实际环境中和回测环境往往会发生参数的偏移,这样要是在离散环境中选的最优值周围并不是连续的,那到生产环境可就玩不动了。

  3. 如果没有非常确定的适应函数,迭代的次数不太容易去拍出来。

也可以尝试一下

当然如果非要用,我觉得也不是不行:

  1. 计算一个迭代的次数,先从小的订起,而且把回测的结果缓存,如果需要跑新的迭代次数,则可以直接用以前跑过的结果,省去了大量时间

  2. 保留top值在列表当中,然后再针对top值去做传统的优化,也不是不行,找机会我自己去试试看。

  3. 利用连续的特性,如果某个参数的sharp特别低(可以定其他的适应函数),则周围一片的参数组合都设置为不可用,可以节省不少时间。假如a:5 b:37 c:89 sharp 才0.5则 a:5 b{35~39} c{87~91}; a{3~7} b:37 c{87~91}; a{3~7} b{35~39} c:89 不可用,每次按二维的连续排除,而且如果离limit值太远的可以排除的范围更大一些

  4. 一定要能并行计算,不然单线程能搞死人。

  5. 或者这样行不行呢?因为我们可以把所有参数都假想为n个二维平面,这样我们在设置初始参数时就先设置成每个二维平面的均匀采样,就像把图片缩小一样的算法,这样我们的初始集就能大幅增加参数覆盖的全面性,后面再遗传的工作量也会相应变小。

不过我觉得就算这样优化,跑的次数还是会很惊人。

还有就是这里我只针对cta参数回测做了些分析,其他方面,比如:投资组合什么的啊,我还未进行研究。

Bayesian 贝叶斯

2018.6.5

中间花了两个多星期的时间搞了下贝叶斯优化,确实比遗传算法还要好,和我上面的思路类似,只是用了科学的方法,遗传是纯随机的,所以有可能某片区域在0.8以下,其实这片区域都可以放弃的,但是遗传还是有可能变种到那边去,但是贝叶斯就不一样,可以把这片区域过滤掉。

为什么呢?因为bayesian要求这些变量符合高斯过程,高斯过程就是连续随机变量,有固定的期望和标准差,这里面其实连续是重点,不是这个点是-1下一个点就是1了,因为在cta回测里面严格符合高斯过程不大可能,但是连续这个特征非常符合

说说我这两个星期的感悟,现有的框架,我测试了3个,有一个没有bayesian,而是tpe但是结果不能收敛,直接放弃。

另两两个其实结果都还不错,有一个支持并发,有一个不支持,但这个不支持的有mm问题的参数调节,很实用的功能。最后测试下来,这个支持并发的很容易到局部最优,而且参数特别容易重复,而且并行的功能也支持得一般,8线程同时不大可能跑得满,所以放弃了。

而且这些框架都是连续变量来测试的,当然这也是正常的,正态分布本来就是连续的,但是有个问题就是我的计划是参数A[1,2,3,4,5] B[5,6,7,8,9],这样组合才25个,万一连续了,我计算的量就要翻个好几番,如果要缩减我的计算时间我就只能用离散量来计算,那么就会出现框架出来的参数组{A:0.8, B:5.1} 和 {A:0.91, B:5.2} 计算出来的结果是一样的{A:1, B:5},但是其实是不一样的,所以这是会影响计算结果的,so,我自己加了控制变量组的产生,只产生int也就是离散量,这样减少了回测的次数,也不至于给框架一个错误的结果

最后改造了那个支持mm参数调节的,改成并行即可,结果还可以,后续找时间再落地。


Comments

comments powered by Disqus