优化improvements- backtrader中文教程
优化improvements
的backtrader包括如何改善data feeds和resultsmultiprocessing.
Note
两种行为已made
这些选项的行为可以通过两种新的Cerebro控制参数:
optdatas
(默认值:True
)如果
True
和优化(并且该系统可以preload
和使用runonce
,数据预载将在主过程只需进行一次为了节省时间和resources.optreturn
(默认:True
)如果
True
优化结果不会是完整的Strategy
对象(和所有datas, indicators, observers…),但和对象具有以下属性(同Strategy
):params
(或p
)策略曾用于executionanalyzers
的策略具有executed
在大多数occassions,只有analyzers并与params是事情需要评估的策略的性能。如果对于生成的值的详细分析(例如)indicators是必要的,把这个off
数据馈送Management
In了Optimization场景这是Cerebro一个可能的组合参数:
preload=True
(默认)的数据Feeeds将运行的任何回溯测试code
runonce=True
(默认值)之前被预加载Indicators将以批处理模式紧来计算for循环,而不是一步step.
If的两个条件都为True
和optdatas=True
,则:
- 的Data Feeds将在主预加载产卵前的新工艺子过程(那些负责执行的backtesting)
结果management
In了Optimization情况下两件事情应该发挥的最重要作用评价当不同的parameters with which each *Strategy是运行:
strategy.params
(或strategy.p
)用于backtesting
strategy.analyzers
The的实际设定值的负责提供如何Strategy评价的对象已实际执行。例如:
SharpeRatio_A
的(年率SharpeRatio)
当optreturn=True
,而不是返回全strategy的情况下,占位符对象将被创建携带这两个属性的前述让评估采取place.
这避免了回传大量生成的数据的像例如值期间由指标生成的backtesting
如若full strategy objects被希望,只需设置optreturn=False
脑期间在instantiation源一直延伸到添加做时cerebro.run
.
的一些测试runs
Theoptimization样品backtrader或控制optdatas
和optreturn
(实际上禁用它们)
单核Run
As参考时会发生什么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
多个Core Runs
Without限制的CPU的数量,Python的multiprocessing
模块将尝试使用他们。optdatas
和optreturn
会disabled
Bothoptdata
和optreturn
active
The默认行为:
$ ./optimization.py ... ... ... ================================================== Time used: 56.5889185394
由具有多核的总的改进和data feed和results改进装置184.92
到56.58
seconds.
Take到的是,样品使用252
杆和指标从下降与252
点的长度仅生成值。这只是一个example.
真正的问题是多少的,这是因为新型behavior.
optreturn
deactivated
Let的传球全strategy对象返回给调用者:
$ ./optimization.py --no-optreturn ... ... ... ================================================== Time used: 67.056914007
的执行时间增加18.50%
(或15.62%
的速度时)是在place.
optdatas
deactivated
Each subproccess被强制加载自己的一套价值观的data feeds:
$ ./optimization.py --no-optdatas ... ... ... ================================================== Time used: 72.7238112637
执行时间增加了28.52%
(或的加速22.19%
)是在使用place.
Both deactivated
Still多核但与旧的非改进的性能:
$ ./optimization.py --no-optdatas --no-optreturn ... ... ... ================================================== Time used: 83.6246643786
的执行时间增加47.79%
(或一个速度 -最多的32.34%
)是在place.
This表明,多核的使用是主要贡献者时间improvement.
Note
The处决已在笔记本电脑已经完成与i7-4710HQ
(4核/ 8逻辑的)与在Windows 10的64位的RAM 16个千兆字节。里程可能会有所不同下优化过程中时间的减少等conditions
Concluding
样品Usage
$ ./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
Sample Code
from __future__ import (absolute_import, division, print_function, unicode_literals) import argparse import datetime import time from backtrader.utils.py3 import range import backtrader as bt import backtrader.indicators as btind import backtrader.feeds as btfeeds class OptimizeStrategy(bt.Strategy): params = (("smaperiod", 15), ("macdperiod1", 12), ("macdperiod2", 26), ("macdperiod3", 9), ) def __init__(self): # Add indicators to add load btind.SMA(period=self.p.smaperiod) btind.MACD(period_me1=self.p.macdperiod1, period_me2=self.p.macdperiod2, period_signal=self.p.macdperiod3) def runstrat(): args = parse_args() # Create a cerebro entity cerebro = bt.Cerebro(maxcpus=args.maxcpus, runonce=not args.no_runonce, exactbars=args.exactbars, optdatas=not args.no_optdatas, optreturn=not args.no_optreturn) # Add a strategy cerebro.optstrategy( OptimizeStrategy, smaperiod=range(args.ma_low, args.ma_high), macdperiod1=range(args.m1_low, args.m1_high), macdperiod2=range(args.m2_low, args.m2_high), macdperiod3=range(args.m3_low, args.m3_high), ) # Get the dates from the args fromdate = datetime.datetime.strptime(args.fromdate, "%Y-%m-%d") todate = datetime.datetime.strptime(args.todate, "%Y-%m-%d") # Create the 1st data data = btfeeds.BacktraderCSVData( dataname=args.data, fromdate=fromdate, todate=todate) # Add the Data Feed to Cerebro cerebro.adddata(data) # clock the start of the process tstart = time.clock() # Run over everything stratruns = cerebro.run() # clock the end of the process tend = time.clock() print("==================================================") for stratrun in stratruns: print("**************************************************") for strat in stratrun: print("--------------------------------------------------") print(strat.p._getkwargs()) print("==================================================") # print out the result print("Time used:", str(tend - tstart)) def parse_args(): parser = argparse.ArgumentParser( description="Optimization", formatter_class=argparse.RawTextHelpFormatter, ) parser.add_argument( "--data", "-d", default="../../datas/2006-day-001.txt", help="data to add to the system") parser.add_argument( "--fromdate", "-f", default="2006-01-01", help="Starting date in YYYY-MM-DD format") parser.add_argument( "--todate", "-t", default="2006-12-31", help="Starting date in YYYY-MM-DD format") parser.add_argument( "--maxcpus", "-m", type=int, required=False, default=0, help=("Number of CPUs to use in the optimization" "\n" " - 0 (default): use all available CPUs\n" " - 1 -> n: use as many as specified\n")) parser.add_argument( "--no-runonce", action="store_true", required=False, help="Run in next mode") parser.add_argument( "--exactbars", required=False, type=int, default=0, help=("Use the specified exactbars still compatible with preload\n" " 0 No memory savings\n" " -1 Moderate memory savings\n" " -2 Less moderate memory savings\n")) parser.add_argument( "--no-optdatas", action="store_true", required=False, help="Do not optimize data preloading in optimization") parser.add_argument( "--no-optreturn", action="store_true", required=False, help="Do not optimize the returned values to save time") parser.add_argument( "--ma_low", type=int, default=10, required=False, help="SMA range low to optimize") parser.add_argument( "--ma_high", type=int, default=30, required=False, help="SMA range high to optimize") parser.add_argument( "--m1_low", type=int, default=12, required=False, help="MACD Fast MA range low to optimize") parser.add_argument( "--m1_high", type=int, default=20, required=False, help="MACD Fast MA range high to optimize") parser.add_argument( "--m2_low", type=int, default=26, required=False, help="MACD Slow MA range low to optimize") parser.add_argument( "--m2_high", type=int, default=30, required=False, help="MACD Slow MA range high to optimize") parser.add_argument( "--m3_low", type=int, default=9, required=False, help="MACD Signal range low to optimize") parser.add_argument( "--m3_high", type=int, default=15, required=False, help="MACD Signal range high to optimize") return parser.parse_args() if __name__ == "__main__": runstrat()
评论被关闭。