Cerebro#

这个类是 backtrader 的核心,因为它充当以下功能的中央点:

  1. 收集所有输入( 数据源 )、参与者( 策略)、观察者(* 观察器 )、分析器( 分析器 )和文档编写器( 编写器*), 确保节目在任何时刻都可以继续进行。

  2. 执行回测/实时数据供给/交易

  3. 返回结果

  4. 提供绘图功能

收集输入 *** ** ** ** ** ** **

  1. 首先创建一个 cerebro 实例:

    cerebro = bt.Cerebro(**kwargs)

    可以使用一些 **kwargs 来控制执行情况,详情请参见参考文档 (同样的参数也可以稍后应用于 run 方法)1. 添加 数据源

最常见的模式是 cerebro.adddata(data) , 其中 data 是一个已经实例化的 数据源 。例如:

data = bt.BacktraderCSVData(dataname='mypath.days', timeframe=bt.TimeFrame.Days)
cerebro.adddata(data)

重新取样回放 数据也可以采用相同的模式:

  data = bt.BacktraderCSVData(dataname='mypath.min', timeframe=bt.TimeFrame.Minutes)
  cerebro.resampledata(data, timeframe=bt.TimeFrame.Days)

或者::

  data = bt.BacktraderCSVData(dataname='mypath.min', timeframe=bt.TimeFrame.Minutes)
  cerebro.replaydata(data, timeframe=bt.TimeFrame.Days)

系统可以接受任意数量的数据源,包括混合常规数据与重新取样和/或回放的数据。当然,其中的一些组合肯定是没有意义的,为了能够组合数据,有一个约束: *时间对齐* 。参见
:doc:`data-multitimeframe/data-multitimeframe`,
:doc:`data-resampling/data-resampling` - 重新取样 和
:doc:`data-replay/data-replay` 部分。
  1. 添加 策略

    与已经是类实例的 数据源 不同, cerebro 直接接受 策略 类和要传递给它的参数。其背后的原理是: 在优化方案中,类将被实例化多次,并传递不同的参数 。即使没有运行任何*优化*,该模式仍然适用:

    cerebro.addstrategy(MyStrategy, myparam1=value1, myparam2=value2)

当进行 优化*时,参数必须作为可迭代对象添加。有关详细解释,请参见 优化*部分。基本模式如下:

cerebro.optstrategy(MyStrategy, myparam1=range(10, 20))

这将运行 MyStrategy 10次, myparam1 的值从10到19(请记住Python中的范围是半开区间,不会达到 20

  1. 其他元素

还可以添加一些其他元素来增强回测体验。相关方法有:

  • addwriter

  • addanalyzer

  • addobserver (或 addobservermulti )4. 更改经纪人

Cerebro会使用 backtrader 中的默认经纪人,但是可以进行覆盖:

`python broker = MyBroker() cerebro.broker = broker  # 使用getbroker/setbroker方法的属性 `

  1. 接收通知

如果 数据源 和/或 经纪人 发送通知(或创建通知的 存储提供者 ),可以通过 Cerebro.notify_store 方法接收到它们。有三种方法可以处理这些通知:

  • 通过 addnotifycallback(callback) 调用,在 cerebro 实例中添加一个*回调*。回调函数必须支持以下签名:

    `python callback(msg, *args, **kwargs) `

    实际接收到的 msg 、 `` args`` 和 ``**kwargs`` 是实现定义的(完全取决于 数据/经纪人/存储 ),但通常可以期望它们是 可打印*的,以便接收和实验。

  • 在添加到 cerebro 实例的 Strategy 子类中重写 notify_store 方法。

    签名: notify_store(self, msg, *args, **kwargs) - 子类化 Cerebro 并覆盖 notify_store (与 Strategy 中的签名相同)

    这应该是最不推荐的方法

执行回测#

有一个单独的方法可以执行,但它支持多个选项(也可以在实例化时指定)以决定如何运行:

result = cerebro.run(**kwargs)

请参考下面的参考资料以了解可用的参数。

标准观察者#

cerebro (除非另有说明)自动实例化*三个*标准 观察者

  • 一个 Broker 观察者,用于跟踪 cashvalue (投资组合)

  • 一个 Trades 观察者,应该显示每个交易的效果如何

  • 一个 Buy/Sell 观察者,应该记录操作执行的时间点

如果希望有一个更整洁的绘图,请使用 stdstats=False 禁用它们。返回结果#

cerebro 返回在回测期间创建的策略实例。这样可以分析它们做了什么,因为可以访问策略中的所有元素:

result = cerebro.run(**kwargs)

run 返回的 result 的格式会根据是否使用了 优化*(使用 ``optstrategy`` 添加了 策略*)而有所不同:

  • 所有使用 addstrategy 添加的策略

    result 将是一个在回测期间运行的实例列表

  • 使用 optstrategy 添加了 1 个或多个策略

    result 将是一个 listlist 。每个内部列表将包含每次优化运行之后的策略

注意

优化 的默认行为已更改为仅返回系统中存在的* 分析器*,以减轻计算机核心之间的消息传递负担。

如果希望返回完整的策略集合作为返回值,请将参数 optreturn 设置为 False 。提供绘图功能

*** ** ** ** ** ** ** **

如果安装了 matplotlib ,那么可以绘制策略的图表。一般的操作模式如下:

cerebro.plot()

请参阅下面的参考和 绘图 章节

回测逻辑 *** ** ** **

大致流程概述:

  1. 处理任何存储通知

  2. 请求数据源提供下一个时刻/周期的行情数据

    在 1.9.0.99 版本发生变更: 新行为 数据源通过查看下一个即将提供的 datetime 来保持同步。在新的时间段内没有交易的数据源仍会提供旧的数据点,而有新数据可用的数据源则提供这个新数据(以及指标的计算)。

旧的行为 (在 Cerebro 中使用 oldsync=True 时保留)

第一个插入系统的数据是 datamaster ,系统会等待它提供一个tick。

其他的数据源基本上是 datamaster 的从属,而且:

  • 如果下一个将被提供的tick的时间(datetime)比 datamaster 提供的tick更新,则不会进行提供。

  • 由于多种原因,可能不提供新的tick并返回。

这个逻辑的设计目的是方便同步多个数据源以及具有不同时间框架的数据源。

  1. 通知策略有关挂单、交易和资金/价值的券商通知的排队情况。

  2. 告诉券商接受排队的订单,并使用新数据执行挂起的订单。4. 调用策略的 “next” 方法,让策略评估新的数据(可能会下达经纪人排队的订单)

    根据当前阶段,可能是 “prenext” 或 “nextstart”,这取决于策略/指标的最短周期要求是否满足

    内部,策略还将触发 “observers”、”indicators”、”analyzers” 和其他激活的元素

  1. 告诉任何 “writers” 将数据写入目标位置

需要注意的重要事项:

备注

在上述的步骤1中,当 数据源 提供新的一组 K 线时,这些 K 线是 已经关闭 的。这意味着数据已经发生。

因此,在步骤4中,策略下达的 订单 不能用步骤1中的数据执行。

这意味着订单将以 “x + 1” 的概念执行。其中,”x” 是订单执行的 K 线时刻,”x + 1” 是下一个时刻,是可能执行订单的最早时间点

参考资料#

..自动类:: Cerebro

..自动方法:: addstorecb

..自动方法:: notify_store

..自动方法:: adddatacb

..自动方法:: notify_data

..自动方法:: adddata

..自动方法:: resampledata

..自动方法:: replaydata

..自动方法:: chaindata

..自动方法:: rolloverdata.. automethod:: addstrategy