优化改进
原文: https://www.backtrader.com/docu/optimization-improvements/
backtrader的1.8.12.99
版本改进了在多处理过程中如何管理数据源和结果。
笔记
这两种行为都已发生
这些选项的行为可以通过两个新的大脑参数进行控制:
-
optdatas
(默认为True
)如果
True
和优化(并且系统可以preload
和使用runonce
,则在主流程中只进行一次数据预加载,以节省时间和资源。 -
optreturn
(默认为True
)如果
True
优化结果不是完整的Strategy
对象(以及所有数据、指标、观察者…),而是具有以下属性的对象(与Strategy
相同):-
params
(或p
)执行的策略 -
analyzers
策略已经执行
在大多数情况下,只有分析器和参数是评估策略性能所需的东西。如果需要对(例如)指标的生成值进行详细分析,请关闭此选项
-
数据馈送管理
在优化场景中,这可能是大脑参数的组合:
-
preload=True
(默认)在运行任何回溯测试代码之前,将预加载数据 feeed
-
runonce=True
(默认)指标将在回路的批次模式 a 紧下计算,而不是逐步计算。
如果两个条件都是True
和optdatas=True
,则:
- 数据源将在主流程中预加载,然后再生成新的子流程(负责执行回测的子流程)
成果管理
在优化场景中,在评估每个策略运行时使用的不同参数时,两件事应该起到最重要的作用:
-
strategy.params
(或strategy.p
)用于回溯测试的实际值集
-
strategy.analyzers
负责评估策略实际执行情况的对象。例子:
SharpeRatio_A
(年化SharpeRatio)
当optreturn=True
时,不返回完整的策略实例,而是创建带有上述两个属性的占位符对象,以便进行评估。
这避免了传回大量生成的数据,例如在回测期间由指示器生成的值
如果希望使用全策略对象,只需在大脑实例化或执行cerebro.run
时设置optreturn=False
。
一些测试运行
反向交易者来源中的优化样本已经扩展,增加了对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。optdatas
和optreturn
将被禁用
optdata
和optreturn
都处于激活状态
默认行为:
$ ./optimization.py
...
...
...
==================================================
Time used: 56.5889185394
通过使用多核以及数据馈送和结果改进的总体改进意味着从184.92
秒下降到56.58
秒。
考虑到样本使用的是252
条,指示器仅生成长度为252
点的值。这只是一个例子。
真正的问题是这在多大程度上归因于新的行为。
optreturn
停用
让我们将完整的策略对象传递回调用方:
$ ./optimization.py --no-optreturn
...
...
...
==================================================
Time used: 67.056914007
执行时间已增加18.50%
(或15.62%
的加速已到位。
optdatas
停用
每个子进程都必须为数据馈送加载自己的一组值:
$ ./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%
的加速已到位。
这表明多核的使用是时间改进的主要因素。
笔记
这些执行是在一台笔记本电脑上完成的,该笔记本电脑带有一个i7-4710HQ
(4 核/8 逻辑),在 Windows 10 64 位下具有 16 GB 的 RAM。在其他条件下,里程数可能会有所不同
总结
-
优化过程中时间减少的最大因素是使用多核
-
以
optdatas
和optreturn
运行的样本显示速度分别约为22.19%
和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