自动化回溯测试
原文: https://www.backtrader.com/docu/automated-bt-run/automated-bt-run/
到目前为止,所有的backtrader
示例和工作示例都从零开始创建一个主Python模块,该模块加载数据、策略、观察者,并准备现金和佣金方案。
算法交易的目标之一是交易自动化,鉴于 backtrader 是一个旨在检查交易算法的回溯测试平台(因此是一个算法交易平台),自动化使用 backtrader 是一个明显的目标。
安装时backtrader
以脚本/可执行文件的形式提供 2 个入口点,可自动执行大多数任务:
bt-run-py
使用下一项代码库的脚本
和
-
btrun
(可执行)包装过程中
setuptools
创建的入口点。可执行文件在 Windows 下具有优势,理论上不会出现关于“未找到路径/文件”的错误。
以下描述同样适用于这两种工具。
btrun
允许最终用户:
-
说明必须加载哪些数据源
-
设置加载数据的格式
-
指定数据的日期范围
-
将参数传递给大脑
- 禁用标准观察者
这是“大脑”参数实施之前的原始额外开关。因此,如果向 Cerbero 传递了一个关于标准观察者的参数,则该参数将被忽略(向 Cerbero 传递的参数
stdstats
) -
从内置观察器或 python 模块加载一个或多个观察器(例如:
DrawDown
-
为经纪人设置现金和佣金方案参数(佣金、保证金、mult)
-
启用打印,控制显示数据的图表数量和样式
-
将参数化写入器添加到系统
最后,核心竞争力应该是什么:
-
加载策略(内置策略或来自 Python 模块)
-
将参数传递给加载的策略
脚本的用法见下文。
应用用户定义的策略
让我们考虑以下策略:
-
仅加载 SimpleMovingAverage(默认时段 15)
-
打印输出
-
位于名为
mymod.py
的文件中
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import backtrader as bt
import backtrader.indicators as btind
class MyTest(bt.Strategy):
params = (('period', 15),)
def log(self, txt, dt=None):
''' Logging function fot this strategy'''
dt = dt or self.data.datetime[0]
if isinstance(dt, float):
dt = bt.num2date(dt)
print('%s, %s' % (dt.isoformat(), txt))
def __init__(self):
sma = btind.SMA(period=self.p.period)
def next(self):
ltxt = '%d, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f'
self.log(ltxt %
(len(self),
self.data.open[0], self.data.high[0],
self.data.low[0], self.data.close[0],
self.data.volume[0], self.data.openinterest[0]))
使用常规测试样本执行策略很简单:简单:
btrun --csvformat btcsv \
--data ../../datas/2006-day-001.txt \
--strategy mymod.py
图表输出
控制台输出:
2006-01-20T23:59:59+00:00, 15, 3593.16, 3612.37, 3550.80, 3550.80, 0.00, 0.00
2006-01-23T23:59:59+00:00, 16, 3550.24, 3550.24, 3515.07, 3544.31, 0.00, 0.00
2006-01-24T23:59:59+00:00, 17, 3544.78, 3553.16, 3526.37, 3532.68, 0.00, 0.00
2006-01-25T23:59:59+00:00, 18, 3532.72, 3578.00, 3532.72, 3578.00, 0.00, 0.00
...
...
2006-12-22T23:59:59+00:00, 252, 4109.86, 4109.86, 4072.62, 4073.50, 0.00, 0.00
2006-12-27T23:59:59+00:00, 253, 4079.70, 4134.86, 4079.70, 4134.86, 0.00, 0.00
2006-12-28T23:59:59+00:00, 254, 4137.44, 4142.06, 4125.14, 4130.66, 0.00, 0.00
2006-12-29T23:59:59+00:00, 255, 4130.12, 4142.01, 4119.94, 4119.94, 0.00, 0.00
同样的策略,但:
- 将参数
period
设置为 50
命令行:
btrun --csvformat btcsv \
--data ../../datas/2006-day-001.txt \
--plot \
--strategy mymod.py:period=50
图表输出。
笔记
如果没有给出.py
扩展,bt run 将添加它。
使用内置策略
backtrader
将慢慢包括样本(教科书)策略。除了bt-run.py
脚本外,还包括一个标准的简单移动平均交叉策略。姓名:
-
SMA_CrossOver
-
参数
-
快速移动平均线的
fast
(默认10
期间 -
慢速移动平均线的
slow
(默认30
期间
-
该策略在快速移动平均线与快速移动平均线交叉时买入,在快速移动平均线与慢速移动平均线交叉时卖出(仅在之前买入的情况下)。
代码
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import backtrader as bt
import backtrader.indicators as btind
class SMA_CrossOver(bt.Strategy):
params = (('fast', 10), ('slow', 30))
def __init__(self):
sma_fast = btind.SMA(period=self.p.fast)
sma_slow = btind.SMA(period=self.p.slow)
self.buysig = btind.CrossOver(sma_fast, sma_slow)
def next(self):
if self.position.size:
if self.buysig < 0:
self.sell()
elif self.buysig > 0:
self.buy()
标准执行:
btrun --csvformat btcsv \
--data ../../datas/2006-day-001.txt \
--plot \
--strategy :SMA_CrossOver
注意:
。加载策略的标准符号(见下文)为:
module:stragegy:kwargs
遵守以下规则:
-
如果模块存在并且指定了策略,则将使用该策略
-
如果模块存在但未指定策略,则返回模块中找到的 1st策略
-
如果未指定模块,则假定“策略”指的是
backtrader
包中的策略 -
如果存在模块和/或策略,如果存在 KWARG,则会将其传递给相应的策略
笔记
相同的符号和规则适用于--observer
、--analyzer
和--indicator
选项
显然,对于相应的对象类型
输出
最后一个示例是添加佣金方案、现金和更改参数:
btrun --csvformat btcsv \
--data ../../datas/2006-day-001.txt \
--plot \
--cash 20000 \
--commission 2.0 \
--mult 10 \
--margin 2000 \
--strategy :SMA_CrossOver:fast=5,slow=20
输出
我们对该策略进行了回溯测试:
-
改变移动平均周期
-
设置新的起始现金
-
为类似期货的工具制定佣金计划
查看每一条的现金连续变化,因为现金是针对期货(如工具每日变化)进行调整的
不使用策略
这是一个过分的说法。将应用一个策略,但您可以使用任何类型的策略和默认的 backtrader。策略将被添加。
分析仪、观察员和指示器将自动注入策略中。
例如:
btrun --csvformat btcsv \
--data ../../datas/2006-day-001.txt \
--cash 20000 \
--commission 2.0 \
--mult 10 \
--margin 2000 \
--nostdstats \
--observer :Broker
这没有多大作用,但可以达到以下目的:
-
默认的 backtrader。在后台添加策略
-
Cerbero 不会实例化常规观察者(经纪人、买卖、交易)
-
手动添加一个
Broker
观察者
如上所述,nostdstats
是一个遗留参数。更新版本的btrun
可以将参数直接传递给Cerebro
。等效调用为:
btrun --csvformat btcsv \
--data ../../datas/2006-day-001.txt \
--cash 20000 \
--commission 2.0 \
--mult 10 \
--margin 2000 \
--cerebro stdstats=False \
--observer :Broker
添加分析器
btrun
还支持使用与选择内部/外部分析器的策略相同的语法添加Analyzers
。
2005-2006 年SharpeRatio
分析示例:
btrun --csvformat btcsv \
--data ../../datas/2005-2006-day-001.txt \
--strategy :SMA_CrossOver \
--analyzer :SharpeRatio
控制台输出为无。
如果希望打印出Analyzer
结果,则必须指定:
-
--pranalyzer
默认调用下一个(除非分析仪覆盖了正确的方法) -
--ppranalyzer
使用pprint
模块打印结果
笔记
这两个打印选项是在writers
成为 backtrader 的一部分之前实施的。添加一个没有 csv 输出的 writer 将实现同样的效果(并且输出得到了改进)
从上面扩展示例:
btrun --csvformat btcsv \
--data ../../datas/2005-2006-day-001.txt \
--strategy :SMA_CrossOver \
--analyzer :SharpeRatio \
--plot \
--pranalyzer
====================
== Analyzers
====================
##########
sharperatio
##########
{'sharperatio': 11.647332609673256}
好策略!!!(对于实际也不承担佣金的示例,纯粹是运气)
图表(仅显示分析仪不在绘图中,因为无法绘制分析仪,它们不是直线对象)
相同的示例,但使用了一个writer
参数:
btrun --csvformat btcsv \
--data ../../datas/2005-2006-day-001.txt \
--strategy :SMA_CrossOver \
--analyzer :SharpeRatio \
--plot \
--writer
===============================================================================
Cerebro:
-----------------------------------------------------------------------------
- Datas:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- Data0:
- Name: 2005-2006-day-001
- Timeframe: Days
- Compression: 1
-----------------------------------------------------------------------------
- Strategies:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SMA_CrossOver:
*************************************************************************
- Params:
- fast: 10
- slow: 30
- _movav: SMA
*************************************************************************
- Indicators:
.......................................................................
- SMA:
- Lines: sma
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Params:
- period: 30
.......................................................................
- CrossOver:
- Lines: crossover
- Params: None
*************************************************************************
- Observers:
.......................................................................
- Broker:
- Lines: cash, value
- Params: None
.......................................................................
- BuySell:
- Lines: buy, sell
- Params: None
.......................................................................
- Trades:
- Lines: pnlplus, pnlminus
- Params: None
*************************************************************************
- Analyzers:
.......................................................................
- Value:
- Begin: 10000.0
- End: 10496.68
.......................................................................
- SharpeRatio:
- Params: None
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Analysis:
- sharperatio: 11.6473326097
增加指标和观察员
与Strategies
和Analyzers
一样,btrun 还可以添加:
Indicators
和
Observers
当添加一个Broker
观察者时,语法与上面看到的完全相同。
让我们重复这个例子,但添加一个Stochastic
、Broker
并查看绘图(我们将更改一些参数):
btrun --csvformat btcsv \
--data ../../datas/2006-day-001.txt \
--nostdstats \
--observer :Broker \
--indicator :Stochastic:period_dslow=5 \
--plot
图表
绘图控件
上述大多数示例都使用了以下选项:
--plot
已激活默认绘图的创建
在--plot
选项中添加kwargs
可以实现更多的控制
--plot style="candle"
例如,使用烛台打印,而不是使用LineOnClose
样式打印(这是打印默认设置)
调用:
btrun --csvformat btcsv \
--data ../../datas/2006-day-001.txt \
--nostdstats \
--observer :Broker \
--indicator :Stochastic:period_dslow=5 \
--plot style=\"candle\"
笔记
candle
周围的引号使用反斜杠\\
引用,因为该示例在 bash shell 中运行,在将参数传递给脚本之前,该 shell 会删除该引号。
在这种情况下,需要使用反斜杠引号来确保“bar”进入脚本,并且可以作为字符串进行计算
图表
脚本的使用
直接从脚本:
$ btrun --help
usage: btrun-script.py [-h] --data DATA [--cerebro [kwargs]] [--nostdstats]
[--format {yahoocsv_unreversed,vchart,vchartcsv,yahoo,mt4csv,ibdata,sierracsv,yahoocsv,btcsv,vcdata}]
[--fromdate FROMDATE] [--todate TODATE]
[--timeframe {microseconds,seconds,weeks,months,minutes,days,years}]
[--compression COMPRESSION]
[--resample RESAMPLE | --replay REPLAY]
[--strategy module:name:kwargs]
[--signal module:signaltype:name:kwargs]
[--observer module:name:kwargs]
[--analyzer module:name:kwargs]
[--pranalyzer | --ppranalyzer]
[--indicator module:name:kwargs] [--writer [kwargs]]
[--cash CASH] [--commission COMMISSION]
[--margin MARGIN] [--mult MULT] [--interest INTEREST]
[--interest_long] [--slip_perc SLIP_PERC]
[--slip_fixed SLIP_FIXED] [--slip_open]
[--no-slip_match] [--slip_out] [--flush]
[--plot [kwargs]]
Backtrader Run Script
optional arguments:
-h, --help show this help message and exit
--resample RESAMPLE, -rs RESAMPLE
resample with timeframe:compression values
--replay REPLAY, -rp REPLAY
replay with timeframe:compression values
--pranalyzer, -pralyzer
Automatically print analyzers
--ppranalyzer, -ppralyzer
Automatically PRETTY print analyzers
--plot [kwargs], -p [kwargs]
Plot the read data applying any kwargs passed
For example:
--plot style="candle" (to plot candlesticks)
Data options:
--data DATA, -d DATA Data files to be added to the system
Cerebro options:
--cerebro [kwargs], -cer [kwargs]
The argument can be specified with the following form:
- kwargs
Example: "preload=True" which set its to True
The passed kwargs will be passed directly to the cerebro
instance created for the execution
The available kwargs to cerebro are:
- preload (default: True)
- runonce (default: True)
- maxcpus (default: None)
- stdstats (default: True)
- live (default: False)
- exactbars (default: False)
- preload (default: True)
- writer (default False)
- oldbuysell (default False)
- tradehistory (default False)
--nostdstats Disable the standard statistics observers
--format {yahoocsv_unreversed,vchart,vchartcsv,yahoo,mt4csv,ibdata,sierracsv,yahoocsv,btcsv,vcdata}, --csvformat {yahoocsv_unreversed,vchart,vchartcsv,yahoo,mt4csv,ibdata,sierracsv,yahoocsv,btcsv,vcdata}, -c {yahoocsv_unreversed,vchart,vchartcsv,yahoo,mt4csv,ibdata,sierracsv,yahoocsv,btcsv,vcdata}
CSV Format
--fromdate FROMDATE, -f FROMDATE
Starting date in YYYY-MM-DD[THH:MM:SS] format
--todate TODATE, -t TODATE
Ending date in YYYY-MM-DD[THH:MM:SS] format
--timeframe {microseconds,seconds,weeks,months,minutes,days,years}, -tf {microseconds,seconds,weeks,months,minutes,days,years}
Ending date in YYYY-MM-DD[THH:MM:SS] format
--compression COMPRESSION, -cp COMPRESSION
Ending date in YYYY-MM-DD[THH:MM:SS] format
Strategy options:
--strategy module:name:kwargs, -st module:name:kwargs
This option can be specified multiple times.
The argument can be specified with the following form:
- module:classname:kwargs
Example: mymod:myclass:a=1,b=2
kwargs is optional
If module is omitted then class name will be sought in
the built-in strategies module. Such as in:
- :name:kwargs or :name
If name is omitted, then the 1st strategy found in the mod
will be used. Such as in:
- module or module::kwargs
Signals:
--signal module:signaltype:name:kwargs, -sig module:signaltype:name:kwargs
This option can be specified multiple times.
The argument can be specified with the following form:
- signaltype:module:signaltype:classname:kwargs
Example: longshort+mymod:myclass:a=1,b=2
signaltype may be ommited: longshort will be used
Example: mymod:myclass:a=1,b=2
kwargs is optional
signaltype will be uppercased to match the defintions
fromt the backtrader.signal module
If module is omitted then class name will be sought in
the built-in signals module. Such as in:
- LONGSHORT::name:kwargs or :name
If name is omitted, then the 1st signal found in the mod
will be used. Such as in:
- module or module:::kwargs
Observers and statistics:
--observer module:name:kwargs, -ob module:name:kwargs
This option can be specified multiple times.
The argument can be specified with the following form:
- module:classname:kwargs
Example: mymod:myclass:a=1,b=2
kwargs is optional
If module is omitted then class name will be sought in
the built-in observers module. Such as in:
- :name:kwargs or :name
If name is omitted, then the 1st observer found in the
will be used. Such as in:
- module or module::kwargs
Analyzers:
--analyzer module:name:kwargs, -an module:name:kwargs
This option can be specified multiple times.
The argument can be specified with the following form:
- module:classname:kwargs
Example: mymod:myclass:a=1,b=2
kwargs is optional
If module is omitted then class name will be sought in
the built-in analyzers module. Such as in:
- :name:kwargs or :name
If name is omitted, then the 1st analyzer found in the
will be used. Such as in:
- module or module::kwargs
Indicators:
--indicator module:name:kwargs, -ind module:name:kwargs
This option can be specified multiple times.
The argument can be specified with the following form:
- module:classname:kwargs
Example: mymod:myclass:a=1,b=2
kwargs is optional
If module is omitted then class name will be sought in
the built-in analyzers module. Such as in:
- :name:kwargs or :name
If name is omitted, then the 1st analyzer found in the
will be used. Such as in:
- module or module::kwargs
Writers:
--writer [kwargs], -wr [kwargs]
This option can be specified multiple times.
The argument can be specified with the following form:
- kwargs
Example: a=1,b=2
kwargs is optional
It creates a system wide writer which outputs run data
Please see the documentation for the available kwargs
Cash and Commission Scheme Args:
--cash CASH, -cash CASH
Cash to set to the broker
--commission COMMISSION, -comm COMMISSION
Commission value to set
--margin MARGIN, -marg MARGIN
Margin type to set
--mult MULT, -mul MULT
Multiplier to use
--interest INTEREST Credit Interest rate to apply (0.0x)
--interest_long Apply credit interest to long positions
--slip_perc SLIP_PERC
Enable slippage with a percentage value
--slip_fixed SLIP_FIXED
Enable slippage with a fixed point value
--slip_open enable slippage for when matching opening prices
--no-slip_match Disable slip_match, ie: matching capped at
high-low if slippage goes over those limits
--slip_out with slip_match enabled, match outside high-low
--flush flush the output - useful under win32 systems