脑波
本课程是backtrader
的基石,因为它是以下内容的中心点:
-
收集所有输入(数据源),演员(策略),观众(观察员),评论家(分析员)和资料员(编剧),确保该剧在任何时候都能继续进行。
-
执行回溯测试/或实时数据馈送/交易
-
返回结果
-
允许使用绘图设备
收集投入
-
首先创建一个
cerebro
:py cerebro = bt.Cerebro(**kwargs)
支持一些控制执行的
**kwargs
,请参见参考(相同的参数可以稍后应用于run
方法) -
添加数据源
最常见的模式是
cerebro.adddata(data)
,其中data
是已经实例化的数据馈送。例子:py data = bt.BacktraderCSVData(dataname='mypath.days', timeframe=bt.TimeFrame.Days) cerebro.adddata(data)
重新采样和重放数据是可能的,并且遵循相同的模式:
py data = bt.BacktraderCSVData(dataname='mypath.min', timeframe=bt.TimeFrame.Minutes) cerebro.resampledata(data, timeframe=bt.TimeFrame.Days)
或:
py data = bt.BacktraderCSVData(dataname='mypath.min', timeframe=bt.TimeFrame.Minutes) cerebro.replaydatadata(data, timeframe=bt.TimeFrame.Days)
系统可以接受任意数量的数据馈送,包括将常规数据与重新采样和/或重放的数据混合。当然,其中一些组合肯定毫无意义,为了能够组合数据,存在一个限制:时间对齐。请参阅“数据-多个时间段”、“数据重采样-重采样”和“数据-重播”部分。
-
添加
Strategies
与已经是类实例的
datas feeds
不同,cerebro
直接获取Strategy
类和要传递给它的参数。背后的基本原理:在优化场景中,类将被实例化多次,并传递不同的参数即使没有运行优化,模式仍然适用:
py cerebro.addstrategy(MyStrategy, myparam1=value1, myparam2=value2)
当优化时,必须将参数作为可比项添加。详细说明请参见优化部分。基本模式:
py cerebro.optstrategy(MyStrategy, myparam1=range(10, 20))
它将运行
MyStrategy
10 次,其中myparam1
取 10 到 19 之间的值(记住 Python 中的范围是半开的,不会达到20
) -
其他要素
还可以添加一些其他元素来增强回溯测试体验。请参见相关章节。这些方法是:
-
addwriter
-
addanalyzer
-
addobserver
(或addobservermulti
)
-
-
更换经纪人
Cerbero 将使用
backtrader
中的默认代理,但这可以被覆盖:py broker = MyBroker() cerebro.broker = broker # property using getbroker/setbroker methods
-
接收通知
如果数据源和/或代理发送通知(或创建通知的存储提供商),则将通过
Cerebro.notify_store
方法接收通知。使用这些通知有三(3)种方法- 通过
addnotifycallback(callback)
调用向cerebro
实例添加回调。回调必须支持此签名:
py callback(msg, *args, **kwargs)
实际接收的
msg
、*args
和**kwargs
是实现定义的(完全取决于数据/代理/存储),但一般情况下,人们应该期望它们是可打印的,以允许接收和实验。- 重写
Strategy
子类中添加到cerebro
实例的notify_store
方法。
签名:
notify_store(self, msg, *args, **kwargs)
- 子类
Cerebro
和覆盖notify_store
(与Strategy
中的签名相同)
这应该是最不可取的方法
- 通过
执行回溯测试
只有一个方法可以执行此操作,但它支持多个选项(在实例化时也可以指定这些选项)来决定如何运行:
result = cerebro.run(**kwargs)
请参阅下面的示例,了解哪些参数可用。
标准观察员
cerebro
(除非另有说明)自动实例化三个标准观察者
-
跟踪
cash
和value
(投资组合)的经纪人观察员 -
一个交易观察者,该观察者应显示每笔交易的有效性
-
一个买入/卖出的观察者,该观察者应记录何时执行操作
如果需要更干净的绘图,只需使用stdstats=False
禁用它们即可
返回结果
cerebro
返回在回溯测试期间创建的策略实例。这允许分析他们所做的事情,因为战略中的所有元素都是可访问的:
result = cerebro.run(**kwargs)
run
返回的result
格式会根据是否使用优化而有所不同(在策略中增加了optstrategy
:
-
所有策略都添加了
addstrategy
result
将是回溯测试期间运行的实例的list
-
使用
optstrategy
添加了 1 个或多个策略result
将是list
的list
部分。每个内部列表将包含每次优化运行后的策略
笔记
优化的默认行为已更改为仅返回系统中存在的分析器,以使通过计算机内核传递的消息更轻松。
如果希望将整套策略作为返回值,则将参数optreturn
设置为False
允许使用绘图设备
如果安装了额外的 anmatplotlib
,则可以绘制策略。通常的模式是:
cerebro.plot()
参考和剖面图见下文
回溯测试逻辑
事物流动的简要概述:
-
发送任何门店通知
-
要求数据源提供下一组刻度/条形图
版本变更:在 1.9.0.99 版本中变更:新行为
通过查看日期时间同步数据馈送,可用数据馈送将提供该日期时间。在新时期未交易的数据源仍然提供旧数据点,而有新数据可用的数据源提供此数据点(以及指标的计算)
旧行为(与大脑一起使用
oldsync=True
时保留)插入系统的 1st数据为
datamaster
,系统将等待其发出滴答声其他数据馈送或多或少是
datamaster
的从属数据,并且:``py * If the next tick to deliver is newer (datetime-wise) than the one delivered by the
datamaster` it will not be delivered- May return without delivering a new tick for a number of reasons ```
该逻辑设计用于轻松同步多个数据源和具有不同时间段的数据源
-
通知策略有关订单、交易和现金/价值的排队经纪人通知
-
告诉代理接受排队的订单,并使用新数据执行挂起的订单
-
调用 strategies'
next
方法,让策略评估新数据(并可能发出在代理中排队的订单)根据阶段的不同,在满足策略/指标的最短期限要求之前,可能是
prenext
或nextstart
在内部,这些策略也会打击
observers
、indicators
、analyzers
等积极因素 -
告诉任何
writers
将数据写入其目标
重要的是要考虑到:
笔记
在上面的步骤1
中,当数据馈送传递新的一组棒时,这些棒被关闭。这意味着数据已经发生了。
因此,步骤4
中的策略发出的指令不能使用步骤1
中的数据执行。
这意味着订单将以x + 1
的概念执行。其中,x
是执行订单的酒吧时刻,x + 1
是下一个,这是可能执行订单的最早时刻
参考
类 backtrader.Cerebro()
参数:
preload
(默认为True
)
是否为策略预加载传递给大脑的不同data feeds
runonce
(默认为True
)
以矢量化模式运行Indicators
以加速整个系统。战略和观察员将始终基于事件运行
live
(默认为False
)
如果没有数据报告自身为live(通过数据的islive
方法,但最终用户仍希望在live
模式下运行,则可将此参数设置为 true
这将同时停用preload
和runonce
。它对内存节省方案没有影响。
以矢量化模式运行Indicators
以加速整个系统。战略和观察员将始终基于事件运行
-
maxcpus
(默认值:无->所有可用内核)同时使用多少个内核进行优化
-
stdstats
(默认为True
)
如果是真的,将添加默认观察者:经纪人(现金和价值)、交易和买卖
oldbuysell
(默认为False
)
如果stdstats
为True
且观察者被自动添加,则此开关控制BuySell
观察者的主要行为
-
False
:使用现代行为,买入/卖出信号分别绘制在低/高价格下方/上方,以避免弄乱图形 -
True
:使用不推荐的行为,在该行为中,在给定时刻执行订单的平均价格为的位置绘制买入/卖出信号。这当然会在 OHLC 条的顶部或 Cloe 条上的一条线上,难以识别绘图。 -
oldtrades
(默认为False
)
如果stdstats
为True
且观察者被自动添加,则此开关控制Trades
观察者的主要行为
-
False
:使用现代行为,所有数据的交易都用不同的标记绘制 -
True
:使用旧的交易观察器,该观察器使用相同的标记绘制交易,仅当它们为正或负时进行区分 -
exactbars
(默认为False
)
使用默认值,存储在一行中的每个值都保存在内存中
可能值:
* `True` or `1`: all “lines” objects reduce memory usage to the
automatically calculated minimum period.
If a Simple Moving Average has a period of 30, the underlying data
will have always a running buffer of 30 bars to allow the
calculation of the Simple Moving Average
* This setting will deactivate `preload` and `runonce`
* Using this setting also deactivates **plotting**
* `-1`: datafreeds and indicators/operations at strategy level will
keep all data in memory.
For example: a `RSI` internally uses the indicator `UpDay` to
make calculations. This subindicator will not keep all data in
memory
* This allows to keep `plotting` and `preloading` active.
* `runonce` will be deactivated
* `-2`: data feeds and indicators kept as attributes of the
strategy will keep all points in memory.
For example: a `RSI` internally uses the indicator `UpDay` to
make calculations. This subindicator will not keep all data in
memory
If in the `__init__` something like
`a = self.data.close - self.data.high` is defined, then `a`
will not keep all data in memory
* This allows to keep `plotting` and `preloading` active.
* `runonce` will be deactivated
objcache
(默认为False
)
实验性选项,用于实现线对象缓存并减少线对象的数量。来自 Ultimate 振荡器的示例:
bp = self.data.close - TrueLow(self.data)
tr = TrueRange(self.data) # -> creates another TrueLow(self.data)
如果这是True
,则TrueRange
内的 2ndTrueLow(self.data)
与bp
计算中的签名匹配。它将被重新使用。
在角点情况下,可能会使线条对象偏离其最小周期,并打断某些内容,因此将其禁用。
writer
(默认为False
)
如果设置为True
,将创建一个默认 WriterFile,该文件将打印到标准输出。它将被添加到策略中(除了用户代码添加的任何其他编写器)
tradehistory
(默认为False
)
如果设置为True
,则会在所有策略的每笔交易中激活更新事件日志记录。这也可以通过策略方法set_tradehistory
在每个策略的基础上完成
optdatas
(默认为True
)
如果True
和优化(并且系统可以preload
和使用runonce
,则在主流程中只进行一次数据预加载,以节省时间和资源。
测试显示,从83
秒内的样本执行到66
秒,大约有20%
的加速
optreturn
(默认为True
)
如果True
优化结果不是完整的Strategy
对象(以及所有数据、指标、观察者…),而是具有以下属性的对象(与Strategy
相同):
* `params` (or `p`) the strategy had for the execution
* `analyzers` the strategy has executed
在大多数情况下,只有分析器和参数是评估策略性能所需的东西。如果需要对(例如)指标的生成值进行详细分析,请关闭此选项
测试表明执行时间有了13% - 15%
的改进。与optdatas
相结合,在优化运行中,总增益增加至32%
的总加速。
oldsync
(默认为False
)
从 1.9.0.99 版开始,多个数据(相同或不同时间段)的同步已更改为允许不同长度的数据。
如果希望使用 data0 作为系统主节点的旧行为,请将此参数设置为 true
tz
(默认为None
)
为策略添加全局时区。论点tz
可以是
* `None`: in this case the datetime displayed by strategies will be
in UTC, which has been always the standard behavior
* `pytz` instance. It will be used as such to convert UTC times to
the chosen timezone
* `string`. Instantiating a `pytz` instance will be attempted.
* `integer`. Use, for the strategy, the same timezone as the
corresponding `data` in the `self.datas` iterable (`0` would
use the timezone from `data0`)
cheat_on_open
(默认为False
)
将调用策略的next_open
方法。这种情况发生在next
之前以及经纪人有机会评估订单之前。指标尚未重新计算。这允许发布考虑到前一天指标的订单,但使用open
价格进行股权计算
对于未平仓订单执行欺诈,还需要调用cerebro.broker.set_coo(True)
或使用BackBroker(coo=True)
即时通知经纪人(其中coo代表未平仓欺诈)或将broker_coo
参数设置为True
。除非下面禁用,否则大脑将自动执行此操作。
broker_coo
(默认为True
)
这将自动调用代理的set_coo
方法和True
激活cheat_on_open
执行。仅当cheat_on_open
也是True
时才会执行此操作
quicknotify
(默认为False
)
经纪人通知在下一个价格交付之前交付。对于回溯测试,这没有任何影响,但是对于实时代理,通知可以在酒吧交付之前很久发生。当设置为True
时,将尽快发送通知(请参见实时提要中的qcheck
)
设置为False
以确保兼容性。可更改为True
addstorecb(回调)
添加回调以获取将由 notify_store 方法处理的消息
回调的签名必须支持以下内容:
callback(msg, *args, **kwargs)
实际接收的msg
、*args
和**kwargs
是实现定义的(完全取决于数据/代理/存储),但一般情况下,人们应该期望它们是可打印的,以允许接收和实验。
通知门店(消息,args,*kwargs)
在 Cerbero 中接收存储通知
此方法可以在Cerebro
子类中重写
实际接收的msg
、*args
和**kwargs
是实现定义的(完全取决于数据/代理/存储),但一般情况下,人们应该期望它们是可打印的,以允许接收和实验。
adddatacb(回调)
添加回调以获取将由 notify_data 方法处理的消息
回调的签名必须支持以下内容:
- 回调(数据、状态、args、*kwargs)
实际接收到的*args
和**kwargs
是实现定义的(完全取决于数据/代理/存储,但通常情况下,人们应该期望它们是可打印的,以允许接收和实验。
通知 _ 数据(数据、状态、args、*kwargs)
在 Cerbero 中接收数据通知
此方法可以在Cerebro
子类中重写
实际接收到的*args
和**kwargs
是实现定义的(完全取决于数据/代理/存储,但通常情况下,人们应该期望它们是可打印的,以允许接收和实验。
adddata(数据,名称=无)
向混合中添加一个Data Feed
实例。
如果name
不是无,则将其放入data._name
中,用于装饰/绘图目的。
重采样数据(dataname,name=None,**kwargs)
添加一个Data Feed
供系统重新采样
如果name
不是无,则将其放入data._name
中,用于装饰/绘图目的。
由重采样过滤器支持的任何其他 KWARG,如timeframe
、compression
、todate
将透明通过
replaydata(dataname,name=None,**kwargs)
添加一个Data Feed
供系统重播
如果name
不是无,则将其放入data._name
中,用于装饰/绘图目的。
回放过滤器支持的任何其他 KWARG,如timeframe
、compression
、todate
,都将透明地通过
链数据(args,*kwargs)
将多个数据源链接为一个
如果name
作为命名参数传递,而不是 None,它将被放入data._name
,用于装饰/绘图目的。
如果为None
,则使用 1st数据的名称
rolloverdata(args,*kwargs)
将多个数据源链接为一个
如果name
作为命名参数传递,而不是 None,它将被放入data._name
,用于装饰/绘图目的。
如果为None
,则使用 1st数据的名称
任何其他 KWARG 都将传递给滚动类
添加策略(策略,args,*kwargs)
将Strategy
类添加到单遍运行的混合中。实例化将在run
时间内发生。
args 和 kwargs 将在实例化期间传递给策略。
返回可以引用添加的其他对象(如大小调整器)的索引
选择策略(策略,args,*kwargs)
在混合中添加一个Strategy
类以进行优化。实例化将在run
时间内发生。
arg 和 kwarg 必须是保存要检查的值的 iterables。
示例:如果策略接受参数period
,出于优化目的,对optstrategy
的调用如下所示:
- 大脑选择策略(我的策略,周期=(15,25))
这将对值 15 和 25 执行优化。鉴于
- 大脑选择策略(我的策略,周期=范围(15,25))
将使用period
值 15->25 执行 MyStrategy(不包括 25,因为 Python 中的范围是半开放的)
如果传递了一个参数,但未对其进行优化,则调用如下所示:
- 大脑选择策略(我的策略,周期=(15,)
请注意,period
仍然作为一个 iterable…传递,只有 1 个元素
backtrader
无论如何都会尝试识别以下情况:
- 大脑选择策略(我的策略,周期=15)
如果可能,将创建一个内部伪 iterable
optcallback(cb)
将回调添加到回调列表中,当每个策略都已运行时,将通过优化调用该回调列表
签名:cb(战略)
附加指示器(indcls、args、*kwargs)
在混合中添加一个Indicator
类。实例化将在传递的策略中的run
时间完成
addobserver(obscls,args,*kwargs)
在混合中添加一个Observer
类。实例化将在run
时间完成
addobservermulti(obscls、args、*kwargs)
在混合中添加一个Observer
类。实例化将在run
时间完成
系统中每个“数据”将添加一次。用例是观察单个数据的买卖观察者。
一个反例是 CashValue,它观察系统范围的值
addanalyzer(ancls、args、*kwargs)
在混合中添加一个Analyzer
类。实例化将在run
时间完成
addwriter(wrtcls、args、*kwargs)
在混合中添加一个Writer
类。实例化将在大脑中的run
时间完成
运行(**kwargs)
执行回溯测试的核心方法。传递给它的任何kwargs
都将影响已使用实例化的标准参数Cerebro
的值。
如果cerebro
没有数据,该方法将立即退出。
它有不同的返回值:
-
非优化:策略类实例列表中增加
addstrategy
-
优化:一个列表列表,包含添加了
addstrategy
的策略类实例
runstop()
如果从策略内部或其他任何地方(包括其他线程)调用,执行将尽快停止。
经纪人(经纪人)
为该策略设置一个特定的broker
实例,替换从 Cerbero 继承的实例。
getbroker()
返回代理实例。
这也可以通过名称为broker
的property
来获得
绘图(绘图仪=无,numfigs=1,iplot=真,开始=无,结束=无,宽度=16,高度=9,dpi=300,紧密=真,使用=无,**kwargs)
在大脑中绘制策略
如果plotter
为 None,则创建默认Plot
实例,并在实例化过程中将kwargs
传递给该实例。
numfigs
如果需要,将绘图拆分为指定数量的图表,减少图表密度
iplot
:如果True
在notebook
中运行,则图表将在线显示
use
:将其设置为所需 matplotlib 后端的名称。它将优先于iplot
start
:策略的日期时间行数组的索引或datetime.date
、datetime.datetime
实例,表示情节的开始
end
:策略日期时间行数组的索引或datetime.date
、datetime.datetime
实例,表示情节结束
width
:已保存图形的英寸数
height
:已保存图形的英寸数
dpi
:保存图形的每英寸点数质量
tight
:只保存实际内容,不保存图框
addsizer(sizercls,args,*kwargs)
添加一个Sizer
类(和 args),这是添加到 Cerbero 的任何策略的默认大小设置
addsizer_byidx(idx,sizercls,args,*kwargs)
通过 idx 添加一个Sizer
类。此 idx 与addstrategy
返回的引用兼容。只有idx
引用的策略才会收到此大小
添加信号(sigtype、sigcls、sigargs、*sigkwargs)
向系统添加一个信号,该信号稍后将添加到SignalStrategy
信号 _ 并发(onoff)
如果向系统添加信号且concurrent
值设置为真,则允许并发订单
信号累积(开启关闭)
如果向系统添加信号且accumulate
值设置为真,则允许在已经进入市场时进入市场,以增加头寸
信号 _ 策略(stratcls、ARG、*kwargs)
添加可以接受信号的 SignalStrategy 子类
添加日历(cal)
将全球交易日历添加到系统中。单个数据源可能有单独的日历,覆盖全局日历
cal
可以是TradingCalendar
字符串的实例,也可以是pandas_market_calendars
的实例。一个字符串将被实例化为一个PandasMarketCalendar
(需要在系统中安装模块pandas_market_calendar
。
如果传递了 TradingCalendarBase 的子类(而不是实例),它将被实例化
addtz(tz)
这也可以通过参数tz
实现
为策略添加全局时区。论点tz
可以是
-
None
:在这种情况下,策略显示的日期时间将以 UTC 为单位,这一直是标准行为 -
pytz
实例。它将用于将 UTC 时间转换为所选时区 -
string
。将尝试实例化一个pytz
实例。 -
integer
。对于策略,使用与self.datas
表中对应的data
相同的时区(0
将使用data0
中的时区)
添加计时器(当,offset=datetime.timedelta(0),repeat=datetime.timedelta(0),平日=[],周载波=False,月载波=[],月载波=True,allow=None,tzdata=None,strats=False,cheat=False,args,*kwargs)
安排一个计时器来调用notify_timer
-
参数
当(-)–可以
-
datetime.time
实例(见下文tzdata
) -
bt.timer.SESSION_START
引用会话开始 -
bt.timer.SESSION_END
引用会话结束 -
offset
必须是datetime.timedelta
实例
用于偏移值
when
。它与SESSION_START
和SESSION_END
结合使用,有意义地表示在会话开始后调用15 minutes
计时器之类的事情。-
repeat
必须是datetime.timedelta
实例指示在 1st呼叫后,是否会在同一会话中以预定的
repeat
增量安排更多呼叫一旦计时器在会话结束后被重置为
when
的原始值 -
weekdays
:一个排序的iterable,带有整数,表示可以实际调用计时器的日期(iso 代码,周一是 1,周日是 7)如果未指定,计时器将在所有日期都处于活动状态
-
weekcarry
(默认为False
)。如果True
和工作日不可见(例如:交易假日),计时器将在第二天执行(即使在新的一周内) -
monthdays
:一个排序的iterable,整数表示计时器必须在月份的哪几天执行。例如,始终在当月的第15天如果未指定,计时器将在所有日期都处于活动状态
-
monthcarry
(默认为True
)。如果看不到该日(周末、交易日),计时器将在下一个可用日执行。 -
allow
(默认为None
)。接收 datetime.date实例并返回
True的回调,如果允许计时器使用该日期,则返回
False` -
tzdata
可以是None
(默认)、一个pytz
实例或一个data feed
实例。None
:when
按面值解释(这意味着即使不是 UTC,也要像对待 UTC 一样处理)pytz
实例:when
将被解释为在时区实例指定的本地时间内指定。data feed
实例:when
将被解释为数据馈送实例的tz
参数指定的本地时间。笔记
如果
when
为SESSION_START
或SESSION_END
且tzdata
为None
,则系统中的 1st数据馈送(又名self.data0
)将作为查询会话时间的参考。 -
strats
(默认值:False
)同时调用策略的notify_timer
-
cheat
(默认False
)如果True
计时器将在经纪人有机会评估订单之前调用。这样就有机会根据开盘价发出订单,例如在会议开始之前 -
*args
:任何额外参数都将传递给notify_timer
-
**kwargs
:任何额外的 KWARG 将传递给notify_timer
-
返回值:
- 创建的计时器
通知计时器(计时器,时间,args,*kwargs)
接收定时器通知,timer
为add_timer
返回的定时器,when
为呼叫时间。args
和kwargs
是传递给add_timer
的任何附加参数
实际的when
时间可以晚一点,但系统之前可能无法调用计时器。该值为计时器值,不代表系统时间。
添加订单历史记录(订单,通知=True)
添加要在代理中直接执行的订单的历史记录以进行性能评估
-
orders
:是一个 iterable(例如:list、tuple、iterator、generator),其中每个元素也将是一个 iterable(具有长度),具有以下子元素(可能有两种格式)[datetime, size, price]
或[datetime, size, price, data]
笔记
它必须按日期时间升序排序(或生成已排序的元素)
哪里:
-
datetime
是 pythondate/datetime
实例或格式为 YYYY-MM-DD[THH:MM:SS[.us]]的字符串,括号中的元素是可选的 -
size
为整数(正对买入,负对卖出) -
price
是浮点/整数 -
data
如果存在,可采用以下任一值-
无-1st数据馈送将用作目标
-
整数-将使用具有该索引的数据(在大脑中的插入顺序)
-
字符串-具有该名称的数据(例如分配有
cerebro.addata(data, name=value)
的数据)将成为目标
-
-
-
notify
(默认为真如果
True
系统中插入的 1st策略将根据orders
中每个订单的信息通知创建的人工订单
笔记
描述中隐含的是需要添加作为订单目标的数据提要。例如,这是跟踪例如返回的分析器所需要的