分析器#

无论是回测还是交易,能够分析交易系统的表现是理解是否仅获得了利润的关键,还是是否以过高的风险实现了利润,或者与参考资产(或无风险资产)相比是否真的值得付出努力。

这就是 Analyzer 对象系列发挥作用的地方:提供已经发生甚至正在发生的分析。

分析器的特点#

该接口模仿了 Lines 对象的接口,例如具有 next 方法,但有一个主要区别:

  • Analyzers 不持有行。

    这意味着它们在内存方面不会很昂贵,因为即使分析了成千上万个价格柱,它们仍然可以只在内存中存储单个结果。

生态系统中的位置#

通过 cerebro 实例将 Analyzer 对象(与 策略、* 观察者 和*数据 一样)添加到系统中:

  • addanalyzer(ancls, *args, **kwargs) 但是在 cerebro.run 操作期间,对于系统中的每个 * strategy*,将发生以下情况:

  - strategy 中的 ancls 将在 cerebro.run 期间使用 *args**kwargs 实例化

  - ancls 实例将被附加到 strategy

这意味着:

  - 如果回测运行包含例如 3 个策略 ,那么将创建 3 个 ``ancls`` 实例 ,并且每个实例将附加到不同的策略。

最重要的是: 分析器可以分析单个策略的性能 ,而不是整个系统的性能。

附加位置#

有些 Analyzer 对象实际上可能使用其他分析器来完成其工作。例如: SharpeRatio 使用 TimeReturn 的输出进行计算。

这些 子分析器 或*从属分析器*也将插入到与创建它们的策略相同的策略中。但是它们对用户来说是完全看不见的。

属性 ==========为了执行所需的工作,“Analyzer”对象提供了一些默认属性,这些属性会自动传递并在实例中设置,以便于使用:

  • self.strategy :指向策略子类的引用,分析器对象正在其上操作。任何可由 strategy 访问的内容也可以由 analyzer 访问。

  • self.datas[x] :策略中存在的数据源数组。尽管可以通过 strategy 引用访问,但这个快捷方式使工作更加舒适。

  • self.data :对 self.datas[0] 的快捷方式,提供额外的便利。

  • self.dataX :对不同的 self.datas[x] 的快捷方式。

还有一些别名可用,尽管它们可能有些多余:

  • self.dataX_Y ,其中X是对 self.datas[X] 的引用,而Y是对隐射到 self.datas[X].lines[Y] 的行的引用。

如果行有一个名称,还可以使用以下方式:

  • self.dataX_Name 解析为 self.datas[X].Name ,返回按名称而不是按索引查询的行。

对于第一个数据,可以在没有初始的“X”数字引用的情况下使用最后两个快捷方式。例如:- “self.data_2” 指的是 “self.datas[0].lines[2]”

  • “self.data_close” 指的是 “self.datas[0].close”

返回分析#

Analyzer 基类创建了一个 self.rets (类型为 collections.OrderedDict )成员属性来返回分析结果。这是在方法 create_analysis 中完成的,如果需要创建定制的分析器,则可以在子类中重写该方法。

操作方式#

尽管 Analyzer 对象不是 Lines 对象,因此不能迭代行,但它们已经被设计为遵循相同的操作模式。

  1. 在系统开始运行之前初始化(因此调用 __init__

  2. 用 “start” 标记操作的开始

  3. 在指标工作的最小时间段后,将调用 “prenext” / “nextstart” / “next” 来进行下一轮操作。 prenextnextstart 的默认行为是调用next,因为分析器可能从系统一开始就进行分析。

Lines 对象中,通常可以调用 len(self) 来检查实际的bar数量。这也适用于 Analyzers ,通过返回 self.strategy 的值来实现。

  1. 订单和交易将通过 notify_ordernotify_trade 类似于策略一样进行通知。

  2. 现金和价值也将通过 notify_cashvalue 方法进行通知,就像在策略中一样。

  3. 现金、价值、基金净值和基金份额还将通过 notify_fund 方法进行通知,就像在策略中一样。

  4. stop 将被调用以表示操作的结束。

完成常规操作周期后, 分析器 具有用于提取/输出信息的附加方法。

  • get_analysis :理想情况下(非强制性),返回包含分析结果的类似于 dict 的对象。

  • print 使用标准的 backtrader.WriterFile (除非被覆盖)来从 get_analysis 中写入分析结果。

  • pprintpretty print )使用Python的 pprint 模块打印 get_analysis 的结果。最后:

  • get_analysis 方法创建了一个成员属性 self.ret (类型为 collections.OrderedDict ),分析器将分析结果写入该属性。

Analyzer 的子类可以重写此方法以更改此行为。

分析器模式#

backtrader 平台中开发 Analyzer 对象时,已经发现了两种不同的用法模式来生成分析结果:

  1. 在执行期间通过在 notify_xxxnext 方法中收集信息,并在 next 方法中生成当前分析信息。

    例如, TradeAnalyzer 只使用 notify_trade 方法生成统计数据。

  2. 像上面一样收集(或不收集)信息,但是在 stop 方法中一次性生成分析结果。

    SQN系统质量数 )在 notify_trade 方法中收集交易信息,但是在 stop 方法中生成统计数据。

快速示例 ===============与它看起来一样简单:

```
from __future__ import (absolute_import, division, print_function,

unicode_literals)

import datetime

import backtrader as bt import backtrader.analyzers as btanalyzers import backtrader.feeds as btfeeds import backtrader.strategies as btstrats

cerebro = bt.Cerebro()

# 数据 dataname = ‘../datas/sample/2005-2006-day-001.txt’ data = btfeeds.BacktraderCSVData(dataname=dataname)

cerebro.adddata(data)

# 策略 cerebro.addstrategy(btstrats.SMA_CrossOver)

# 分析器 cerebro.addanalyzer(btanalyzers.SharpeRatio, _name=’mysharpe’)

thestrats = cerebro.run() thestrat = thestrats[0]

``` 打印(‘夏普比率:’, thestrat.analyzers.mysharpe.get_analysis())

执行它(将其存储在 analyzer-test.py 中):

$ ./analyzer-test.py 夏普比率: {‘sharpe比率’: 11.647332609673256}

由于 SharpeRatio 在计算结束时只有一个单一值,所以没有绘图。

分析器的法医学分析#

让我们重申一下, 分析器 并不是 Lines 对象,但为了无缝地将它们整合到 backtrader 生态系统中, 遵循了几个 Lines 对象的内部API约定(实际上是它们的 混合 )。

注意

SharpeRatio 的代码已经发展,例如考虑到年化,这里的版本仅供参考。 请参阅 分析器参考

另外还有一个 SharpeRatio_A ,它以年化形式直接提供值,而不考虑寻求的时间范围。

SharpeRatio 的代码作为基础(简化版本)该代码可以分为以下部分:

  • params 声明

    虽然声明的变量没有被使用(仅作为示例),但是像大多数 backtrader 中的其他对象一样, Analyzers 也支持参数。

  • __init__ 方法

    就像 Strategies__init__ 中声明 Indicators 一样, Analyzers 也可以声明需要的支持对象。

    在这个例子中: SharpeRatio 是使用 年收益率 计算的。计算将会自动执行,并且 SharpeRatio 将会使用这个计算结果进行进一步的计算。

    备注

    实际上, SharpeRatio 的实现使用了更通用且后续开发的 TimeReturn analyzer

  • next 方法

    SharpeRatio 不需要这个方法,但是这个方法会在父策略的 next 方法调用后被调用。- start 方法

    在回测开始之前调用。可以用于额外的初始化任务。Sharpe比率不需要它。

  • stop 方法

    在回测结束后立即调用。与 SharpeRatio 一样,可用于结束/完成计算。

  • get_analysis 方法(返回一个字典)

    用于外部调用者访问生成的分析结果。

    返回值:包含分析数据的字典。

参考#