backtrader版本1.8.12.99
改进了在多处理过程中管理data feeds和结果的方式。
注意
两者的行为都已制定
这些选项的行为可以通过两个新的 Cerebro 参数来控制:
-
optdatas
(默认值:True
)如果
True
和优化(和系统可以preload
和使用runonce
),数据预加载将只在主进程中完成一次,以节省时间和资源。 -
optreturn
(默认值:True
)如果
True
优化结果不是完整的Strategy
对象(以及所有数据、指针、 observers ...),而是具有以下属性的对象(与 中Strategy
相同):-
params
(或p
)运行策略 -
analyzers
策略已运行
在大多数场合,只有 analyzers ,以及参数是评估策略性能所需的东西。如果需要对(例如)指针的生成值进行详细分析,请将其关闭
-
Data Feed 管理
在优化方案中,这可能是 Cerebro 参数的组合:
-
preload=True
(默认值)在运行任何回溯测试代码之前,将预加载数据费用
-
runonce=True
(默认值)指针将在批处理模式下进行计算,而不是逐步进行循环。
如果两个条件都是True
和 optdatas=True
,则:
- Data Feeds将在生成新的子进程(负责运行回溯测试的子进程)之前预加载到主进程中
成果管理
在优化场景中,在评估运行每个策略的不同参数时,两件事应该起着最重要的作用:
-
strategy.params
(或strategy.p
)用于回溯测试的实际值集
-
strategy.analyzers
负责评估「战略」实际运行情况的对象。例:
SharpeRatio_A
(年化夏普拉蒂奥)
当不是返回完整的策略实例时optreturn=True
,将创建占比特元对象,这些对象带有上述两个属性,以便进行评估。
这避免了回传大量生成的数据,例如在回溯测试期间指针生成的值
如果需要完整的策略对象,只需在cerebro实例化期间或运行 cerebro.run
时设置optreturn=False
即可。
一些测试运行
backtrader源中的优化范例已扩展为添加对optdatas
和 optreturn
的控制(实际上禁用它们)
单核运行
作为参考,当CPU数量限制为1
multiprocessing
并且不使用模块时会发生什么:
$ ./optimization.py --maxcpus 1 ================================================== ************************************************** -------------------------------------------------- OrderedDict([(u'smaperiod', 10), (u'macdperiod1', 12), (u'macdperiod2', 26), (u'macdperiod3', 9)]) ************************************************** -------------------------------------------------- OrderedDict([(u'smaperiod', 10), (u'macdperiod1', 13), (u'macdperiod2', 26), (u'macdperiod3', 9)]) ... ... OrderedDict([(u'smaperiod', 29), (u'macdperiod1', 19), (u'macdperiod2', 29), (u'macdperiod3', 14)]) ================================================== Time used: 184.922727833
多核运行
在不限制CPU数量的情况下,Pythonmultiprocessing
模块将尝试使用所有这些CPU,并将optreturn
被禁用。 optdatas
两者兼optdata
而有 optreturn
之
缺省行为:
$ ./optimization.py ... ... ... ================================================== Time used: 56.5889185394
通过多核以及 data feed 和结果改进的总体改进意味着从184.92
几秒钟开始 56.58
。
考虑到样本使用的252
是柱线,指针仅生成点长度的值 252
。这只是一个例子。
真正的问题是,这其中有多少可归因于新行为。
optreturn
关闭
让我们将完整的策略对象传递回调用方:
$ ./optimization.py --no-optreturn ... ... ... ================================================== Time used: 67.056914007
运行时间增加18.50%
(或加速 15.62%
)到位。
optdatas
关闭
每个子进程都被迫为 data feeds加载自己的一组值:
$ ./optimization.py --no-optdatas ... ... ... ================================================== Time used: 72.7238112637
运行时间增加28.52%
(或加速 22.19%
)到位。
两者都已停用
仍在使用多核,但具有旧的未改进行为:
$ ./optimization.py --no-optdatas --no-optreturn ... ... ... ================================================== Time used: 83.6246643786
运行时间增加47.79%
(或加速 32.34%
)到位。
这表明使用多个内核是时间改进的主要贡献者。
注意
运行是在Windows 10 64位下具有i7-4710HQ
16 GB RAM的笔记型电脑中完成的(4核/ 8逻辑)。在其他条件下,里程可能会有所不同
总结
-
优化期间时间减少的最大因素是使用多个内核
-
该范例运行
optdatas
并显示周围22.19%
和optreturn
15.62%
每个的加速(32.34%
两者都在测试中一起)
示例用法
$ ./optimization.py --help usage: optimization.py [-h] [--data DATA] [--fromdate FROMDATE] [--todate TODATE] [--maxcpus MAXCPUS] [--no-runonce] [--exactbars EXACTBARS] [--no-optdatas] [--no-optreturn] [--ma_low MA_LOW] [--ma_high MA_HIGH] [--m1_low M1_LOW] [--m1_high M1_HIGH] [--m2_low M2_LOW] [--m2_high M2_HIGH] [--m3_low M3_LOW] [--m3_high M3_HIGH] Optimization optional arguments: -h, --help show this help message and exit --data DATA, -d DATA data to add to the system --fromdate FROMDATE, -f FROMDATE Starting date in YYYY-MM-DD format --todate TODATE, -t TODATE Starting date in YYYY-MM-DD format --maxcpus MAXCPUS, -m MAXCPUS Number of CPUs to use in the optimization - 0 (default): use all available CPUs - 1 -> n: use as many as specified --no-runonce Run in next mode --exactbars EXACTBARS Use the specified exactbars still compatible with preload 0 No memory savings -1 Moderate memory savings -2 Less moderate memory savings --no-optdatas Do not optimize data preloading in optimization --no-optreturn Do not optimize the returned values to save time --ma_low MA_LOW SMA range low to optimize --ma_high MA_HIGH SMA range high to optimize --m1_low M1_LOW MACD Fast MA range low to optimize --m1_high M1_HIGH MACD Fast MA range high to optimize --m2_low M2_LOW MACD Slow MA range low to optimize --m2_high M2_HIGH MACD Slow MA range high to optimize --m3_low M3_LOW MACD Signal range low to optimize --m3_high M3_HIGH MACD Signal range high to optimize