本文继续记录bt相关的概念内容。启动和运行 bt的启动和运行至少涉及3个Line对象:DatafeedStrategy(实际上是Strategy的子类)Cerebro(西班牙语中的大脑) DataFeed Datafeed提供了用于回测的数据,bt支持下列几种datafeed:读取CSV格式文件在线获取Yahoo数据获取PandasDataframe或者blaze数据InteraciveBrokers、VisualChart和Oanda的实时数据 在datafeed中,没有数据周期、压缩率等信息,而在有些场景下是需要用到这些信息的,比如想把5分钟级的数据,通过DataFeedResampling构造日线数据,这时就需要将数据名称、周期、压缩率等信息告知bt,来完成新数据的构造。 下面的例子展示读取YahooCSVDataFeed的方式:importbacktraderasbtimportbacktrader。feedsasbtfeeds。。。datapathpathtoyouryahoodata。csvdatabtfeeds。YahooFinanceCSVData(datanamedatapath,reversedTrue) 其中参数reversed被设置为True,这是由于从Yahoo下载的CSV格式的数据,默认是按时间倒序排列的,也就是最新的数据在最前面,而在回测或者实盘时,我们往往希望数据时间的先后顺序升序排列,所以这里对数据进行了反转,对A股而言,国内大部分数据数据源下载后是不需要反转的。 如果只需要部分时间范围内的数据,则可以按下面方式处理:databtfeeds。YahooFinanceCSVData(datanamedatapath,reversedTruefromdatedatetime。datetime(2014,1,1),todatedatetime。datetime(2014,12,31)) 这里使用参数fromdate和todate来约束待处理数据的时间范围。 上面提到的时间周期(timeframe),压缩率(compression),数据名称(name)也可以通过传入参数进行添加,在后续绘图时,也会用到这些信息:databtfeeds。YahooFinanceCSVData(datanamedatapath,reversedTruefromdatedatetime。datetime(2014,1,1),todatedatetime。datetime(2014,12,31)timeframebt。TimeFrame。Days,compression1,nameYahoo) Strategy 使用bt进行回测的核心逻辑都是在Strategy的子类中完成的,其中至少两个函数需要被重写:init初始化阶段,技术指标的计算和一些准备工作都在这里进行next具体的策略逻辑在这里实现,每个周期都会被调用一次,用于处理当前时刻的K线 有两类需要注意情况:如果datafeed的时间周期(timeframe)不同,比如同时使用日线和周线,next函数会按主数据(即第一个被添加的数据)的数目进行调用,因此多周期数据操作时,需要先将小周期(例如日线和周线数据中的日线数据)的数据添加到系统中。如果DataReplay功能被使用,那么会出现在同一根K线上调用多次next的情况。 一个最基础的Strategy子类示例如下:classMyStrategy(bt。Strategy):definit(self):self。smabtind。SimpleMovingAverage(self。data,period20)defnext(self):ifself。smaself。data。close:self。buy()elifself。smaself。data。close:self。sell() Strategy还提供一些其他可重写的函数,示例如下:classMyStrategy(bt。Strategy):definit(self):self。smabtind。SimpleMovingAverage(self。data,period20)defnext(self):ifself。smaself。data。close:submittedorderself。buy()elifself。smaself。data。close:submittedorderself。sell()defstart(self):print(Backtestingisabouttostart)defstop(self):print(Backtestingisfinished)defnotifyorder(self,order):print(Anordernewchangedexecutedcanceledhasbeenreceived)start回测即将开始时被调用stop回测结束时被调用notifyorder当有订单被提交、执行、取消、改变时被调用。当在Strategy中使用buysell提交订单后,会返回订单的引用;当订单状态有变化时就会通过notifyorder告知Strategy,这样就可以通过判断订单的状态来实现避免重复下单等逻辑。 Strategy中的一些其他函数功能:buysellclose使用隐含的broker和sizer提交买单或者卖单,close是平仓操作。getposition(或者使用position属性)返回当前的持仓状态setsizergetsizer(或者使用sizer属性)用于设置默认的交易数据 像其他Line对象一样,Strategy支持参数设置功能,示例如下:classMyStrategy(bt。Strategy):params((period,20),)definit(self):self。smabtind。SimpleMovingAverage(self。data,periodself。params。period)。。。 这里定义的均线周期就不是固定值20了,而使用的是参数period。 如果不想通过子类化Strategy来,也可以使用bt的signal机制,这个后面会介绍。 Cerebro Cerebro负责将Datafeed和Strategy组织起来并进行回测,实例化cerebro的代码如下:cerebrobt。Cerebro() 这里所有参数都使用默认值,实现了以下效果:创建一个默认的broker交易佣金为0Datafeed被预加载默认使用runonce系列操作,来提升计算速度。bt内置的指标都支持runonce模式,用户自定义的指标无须重新实现runonce系列函数,cerebro会进行模拟实现,但是执行速度会比实现了runonce系列函数的指标慢一些。 Cerebro创建后,就可以将Datafeed和Strategy组织在一起,就开始执行了,示例如下:cerebro。adddata(data)cerebro。addstrategy(MyStrategy,period25)cerebro。run() 在上面的代码中,一个Datafeed的实例首先被添加到cerebro中,然后一个Strategy的子类MyStrategy和与其相关联的关键词参数被添加,cerebro会用收到的参数在后台创建MyStrategy的实例。 用户可添加的Strategy和Datafeed的数目是不受限制的,不同策略间如果交互在bt中没有做增强实现或者约束。 Cerebro支持的一些其他操作:预加载和执行模式cerebrobt。Cerebro(runonceTrue,preloadTrue) 可以通过preload设置是否对数据进行预加载,但是当runonce为True时,必须将preload也设为True,这是因为只有当数据预加载后,才可能执行runconce逻辑。当然预加载的数据,可以不执行runonce逻辑。setbrokergetbroker(或者使用broker属性)支持用户设置自定义的代理(broker),也支持获取当前使用的代理。绘图。可以通过下面的代码快速实现绘图:cerebro。run()cerebro。plot() 也可以通过使用一些参数来修改绘图效果: numfigs1 如果要绘制的内容较多,可以修改numfigs来绘制多张子图。 plotterNone 用户可以通过plotter参数传输自定义的绘图器来代替默认的绘图器。 kwargs 标准的关键词参数,用于将参数传给plotter。策略优化 上面介绍到,在cerebro中添加策略时,是将策略的子类(没有直接添加策略子类的实例)和关键词参数一起添加的,在cerebro。run()执行时,针对每一个关键词参数取值,就可以实例化一个策略子类的实例。当关键词参数有多种取值或者取值组合时,cerebro就会每次取一组关键词参数生成一个策略子类实例,这样通过关键词参数不同组合的计算,实现策略的优化,也就是说,策略的优化实际是对其关键词参数的的优化,优化的示例如下所示:cerebro。optstrategy(MyStrategy,periodxrange(10,20)) optstrategy函数和addstrategy的形式相同,区别在于optstrategy的关键词参数是一个取值范围,而不是单一值,这样optstrategy就可以对参数进行优化。 在上面的例子中,period的取值是从10到19,cerebro将分别用这些值进行回测。 optstrategy也支持复杂的关键词参数组合,比如取值范围和单一值组合:cerebro。optstrategy(MyStrategy,periodxrange(10,20),factor3。5) 再比如多个取值范围参数:cerebro。optstrategy(MyStrategy,period〔5,10,20〕,period2〔20,30,60〕) 感兴趣的读者也可以关注我的CSDN博客码农甲V,里面有更多内容。 欢迎大家关注、点赞、转发、留言,感谢支持!