【PA交易】BackTrader: 讨论下分析器和评测指标

前言 

BackTrader的分析器主要使用的是analyzers模块,我们可以从Analyzers - Backtrader找到一个非常简单的示例。这个示例中使用方式很简单,其他分析器也可以通过如此简单封装方式进行装载。如果仅是复制粘贴官方教程,完全是制造互联网垃圾,更丝毫没必要写一篇博客来讨论。

但是,当我们关注微观时,我们的日线通常是通过Resample API(例如:多周期K线的Resampling)合并的,这时诸如PyFolio这样跟时序相关的分析器是否支持足够呢?同时,又有哪些框架内置的分析器?哪些分析器依赖于时序?哪些又需要哪些其他组件支持呢?如果我们定制Broker或者如前文所述基于Tick数据进行回测,那么应该如何使用框架提供的分析功能?

更进一步的,这些分析器是些个什么玩意?这些评测指标是什么?

本文将从这些问题出发,更包含了对一些框架提供的评测指标的文字解释和公式说明。阅读之前请参考官网示例实践几个分析器的挂载和使用。

Analyzer简述

要解答前面的问题,必不可少的是了解分析器内部的类关系,这是最简单但却重要的第一步。框架内部的内置分析器类层次结构如下所示:

而不同的分析器之间也存在相互依赖,比如PyFolio的结果则是另外三个分析器的汇总:

如下代码可以很简单的验证着点:

cerebro.addanalyzer(btanalyzers.Transactions, _name='mytran')
cerebro.addanalyzer(btanalyzers.PositionsValue, _name='mypos')
cerebro.addanalyzer(btanalyzers.GrossLeverage, _name='grosslv')
cerebro.addanalyzer(btanalyzers.PyFolio, _name='mypyfolio')

# ....

mytran = thestrat.analyzers.mytran.get_analysis()
series1 = ordered_dict_to_df('Transactions', mytran)
mypos = thestrat.analyzers.mypos.get_analysis()
series2 = ordered_dict_to_df('PositionsValue', mypos)
grosslv = thestrat.analyzers.grosslv.get_analysis()
series2 = ordered_dict_to_df('GrossLeverage', grosslv)
results = thestrat.analyzers.mypyfolio.get_analysis()
pyfolio_series = []
for key in results:
    series = ordered_dict_to_df(key, results[key])
    pyfolio_series.append(series)

如上代码使用Series对比:

分析器的next

上面的例子可以看到,多数分析器都会加入到策略的生命周期中,即使是直接继承自bt.Analyzer。以PositionsValue为例,在PositionsValue的实现中,分别会由框架调用start和next方法,如下调用堆栈:

start, positions.py:69
_start, analyzer.py:194
_start, strategy.py:397
runstrategies, cerebro.py:1269
run, cerebro.py:1132
<module>, MyAnalyzer.py:47

上述调用栈中,start, positions.py是PositionsValue分析器的实现,同样的也包括next方法实现。并且在方法中,调用了Broker的get_value和get_cash方法。而像杠杆率评测的GrossLeverage分析器则是直接在next方法中直接使用了data0的时间,而如果data0是tick级别考虑杠杆率这颗粒度显然太细了。

这对于本文开始的问题做出了一些解答:

  • 框架自身的一些基础分析器默认适配Tick级别数据的分析并不合适。
  • 分析器的很多实现需要调用Broker的接口方法。

虽然有一些计算器无法适配,但是前图中的bt.TimeFrameAnalyzerBase子类可以通过指定timeframe参数实现指定基于时间级别数据的分析。在TimeFrameAnalyzerBase的源码中可以看到:

class TimeFrameAnalyzerBase(with_metaclass(MetaTimeFrameAnalyzerBase,
                                           Analyzer)):
    params = (
        ('timeframe', None),
        ('compression', None),
        ('_doprenext', True),
    )

    def _start(self):
        # Override to add specific attributes
        self.timeframe = self.p.timeframe or self.data._timeframe

当然,一个成熟化的、准确的、产品级回测工具需要对这些分析指标进行充分的定制化的修改和拓展。这对于能够关注到这点的朋友来讲,从技术上解决起来是很容易的。本文不在过多赘述具体如何去定制化的细节实现。


分析器评测指标

为了方便实现上述的处于是配合定制化目的的修改和拓展,有必要结合BackTrader的实现,对于几个经典评测指标进行一些讨论。

AnnualReturn

标准的年化收益率,在回测结束的stop阶段计算。计算公式没有太特殊的地方:

分别基于期初净值和期末净值以及年数做出计算。当数据不足一年时,参数特化为:

框架中的代码页基本实现了类似的逻辑。

DrawDown

回撤是简单直白的风险度指标,在BT中返回在回测结束时最终的:

  • 距离最高点的回撤比例和资金回撤
  • 回测过程中的最大回撤

这个计算不复杂,即使完全自主实现也难度不大。

Calmar

卡玛比率为年化收益率与最大回撤的比值,主要为了突出风险度,同时也是一个很重要的评测指标。实际上Calmar将年化使用回撤进行了单位化。高Calmar意味着以回撤为单位的年化收益率。虽然通常的算法交易CTA在5以上都是很厉害的了,但是有些大牛高频量化系统将Calmar率控制在10以上并不少见。

BackTrader中Calmar主要使用了TimeDrawDown类。框架示例代码:“calmar-test.py”展示了使用方式。在框架源码实现中,calmar的计算实现于on_dt_over中,由上层的TimeFrameAnalyzerBase在next中调用,也就是每个数据源周期中都会发生计算(但是可以通过timeframe参数指定要计算的周期)。

SharpeRatio

标准的夏普率计算,框架的夏普率的计算依赖于AnnualReturn。夏普率几乎是公认的最常用评测指标,虽然他的争议较大。夏普率计算公式为:

夏普率计算中主要是标准差的计算稍微有些难以理解,其实在源码中可以看到BT的实现方式主要是对年华收益率计算:

math.sqrt(average(variance(self.AnnualReturn.rets, \
    average([r - rate for r in returns])), \
    bessel=self.p.stddev_sample))

其中贝塞尔方程可以通过参数指定(具体参考SharpeRatio - Backtrader)。除了贝塞尔以外,还要考虑配置若干参数,比如无风险利率、timeframe等。参数的不同配置可能会造成结果有较大出入,也容易产生争议(争论策略的夏普率之前最好双方Sync一下夏普率参数

关于BackTrader夏普率的讨论和介绍在CSDN有大量专题讨论,此处不再过多赘述。

GrossLeverage

当我们讨论回测的时候,毛杠杆率主要目的还是体现资金的利用率。“Gross Leverage”的原始定义为:

从源码中可以看到GrossLeverage的实现相对简单。即:

lev = (self._value - self._cash) / self._value

不过需要注意的是,杠杆率的计算是逐数据帧的,并且没有提供timeframe参数,如果想要考虑这个指标可能需要有一个最终汇总操作,给策略一个整体的杠杆率评价。否则如果在微观中逐tick的评价意义不大,并且观测难度也很大(可能画图是个办法)。

几点结论

对于前言中的一些问题:

  • 诸如PyFolio这样跟时序相关的分析器是否支持足够呢?
  • 如果我们定制Broker或者如前文所述基于Tick数据进行回测,那么应该如何使用框架提供的分析功能?

继承自TimeFrameAnalyzerBase的分析器可以支持指定timeframe,但是如果考虑定制化和细颗粒度,以及从性能优化角度,特别是针对tick源数据,这些基于timeframe的分析器尚显不足。

  • 又有哪些框架内置的分析器?哪些分析器依赖于时序?

我们列出了分析器的完整框架,同时可以看出哪些分析器支持timeframe。如果这些内置分析器,则可以根据自己回测评测的需求去定制对应的分析器。

  • 哪些又需要哪些其他组件支持呢?

首先分析器多数需要Broker支持。Broker提供了标准接口,如果是自定义Broker,实现对应接口即可。同时分析器互相之间存在大量依赖,例如文中提到过得Calmar对TimerDrawDown和AnnualReturn的依赖,以及类似于前面提到的PyFolio就是对几个分析器的汇总。

  • 这些分析器是些个什么玩意?这些评测指标是什么?

本文第二部分介绍了一些常用的评测指标是什么。处于篇幅原因,没有过度展开。实际上不少指标如果微调一些参数会有很大出入。所以如果是自己的回测系统大可以根据自己需要去定制,不必过分追求指标好看。除非为了忽悠资金或者抬杠,否则纠结这些指标意义很小。

最后,愿点赞的朋友早日打造出Calmar大于20甚至50的策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/744352.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【前后端实现】AHP权重计算

AHP权重计算&#xff1a; 需求&#xff1a;前端记录矩阵维度、上三角值&#xff0c;后端构建比较矩阵、计算权重值并将结果返回给前端 比较矩阵构建 如果你想要根据上三角&#xff08;不包括对角线&#xff09;的值来构建对称矩阵&#xff0c;那么你可以稍作修改上述的generate…

Kivy tutorial 004: Making the GUI do stuff, binding to events

Kivy tutorial 004: Making the GUI do stuff, binding to events – Kivy Blog Central themes: Events and Kivy properties 中心主题&#xff1a;事件和kivy属性 We left the last tutorial with a calculator app GUI with some nice automatic behaviour, but which doe…

嵌入式C语言中常见寄存器的控制方法

使用C语言对寄存器赋值时,常常需要用到C语言的位操作方法。 把寄存器某位清零 假设a代表寄存器,且其中本来已有值。如果要把其中某一位清零且其它位不变,代码如下。 //定义一个变量 a = 1001 1111 b (二进制数)unsigned char a = 0x9f;//对 bit2 清零a &= ~(1<<…

实现批量自动化电商数据采集|商品详情页面|店铺商品信息|订单详情数据

电商数据采集是指通过技术手段获取电商平台上的商品信息、店铺信息和订单信息等数据。这些数据可以用于市场分析、竞品分析、用户行为分析等。 商品详情页面是指电商平台上展示商品详细信息的页面&#xff0c;包括商品名称、价格、图片、描述、评价等信息。通过采集商品详情页…

springboot+vue+mybatis门窗管理系统+PPT+论文+讲解+售后

如今社会上各行各业&#xff0c;都在用属于自己专用的软件来进行工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。互联网的发展&#xff0c;离不开一些新的技术&#xff0c;而新技术的产生往往是为了解决现有问题而产生的。针对于仓库信息管理方…

[学习笔记] 禹神:一小时快速上手Electron笔记,附代码

课程地址 禹神&#xff1a;一小时快速上手Electron&#xff0c;前端Electron开发教程_哔哩哔哩_bilibili 笔记地址 https://github.com/sui5yue6/my-electron-app 进程通信 桌面软件 跨平台的桌面应用程序 chromium nodejs native api 流程模型 main主进程 .js文件 node…

攻克PS之路——Day1(A1-A8)

#暑假到了&#xff0c;作为可能是最后一个快乐的暑假&#xff0c;我打算学点技能来傍身&#xff0c;首先&#xff0c;开始PS之旅 这个帖子作为我跟着B站up主学习PS的记录吧&#xff0c;希望我可以坚持下去&#xff01; 学习的链接在这里&#xff1a;A02-PS软件安装&#xff0…

Qt | 子类化 QStyle(Qt自带图标大全)

01、简介 1、把绘制自定义部件外观的步骤大致分为三大板块,如下: ①、样式元素:即指定需要绘制的图形元素(比如焦点框、按钮,工具栏等)。样式元素使 用 QStyle 类中的一系列枚举(共有 11 个枚举)进行描述。 ②、样式选项:包含了需要绘制的图形元素的所有信息,比如包含…

【QCustomPlot实战系列】QCPGraph区域高亮

使用QCPDataSelection来设置选中的区域&#xff0c;并将QCPGraph的可选择区域设置成QCP::stMultipleDataRanges void AreaPieces::initCustomPlot(QCustomPlot *parentPlot) {QVector<double> x {0, 1, 2, 3, 4, 5, 6, 7, 8};QVector<double> y {200, 560, 750…

asp.net core反向代理

新建项目 新建空白的asp.net core web项目 安装Yarp.ReverseProxy包版本为2.2.0-preview.1.24266.1 编写代码 namespace YarpStu01;public class Program {public static void Main(string[] args){var builder WebApplication.CreateBuilder(args);builder.Services.AddRev…

昇思25天学习打卡营第01天|基本介绍

作为曾经的javaer&#xff0c;本着不断学习的初心&#xff0c;报名了昇思25天的课程&#xff0c;希望自己能学会点东西的目的。 昇思MindSpore介绍 昇思MindSpore是一个全场景深度学习框架&#xff0c;旨在实现易开发、高效执行、全场景统一部署三大目标。 其中&#xff0c;…

AI大模型日报#0625:OpenAI停止不支持国家API、大模型「考上」一本、苹果上新视觉模型4M-21

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE-4.0-8K-latest&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xff01;《AI大模型日报》今日要点&#xf…

【LeetCode】一、数组相关(双指针算法 + 置换)

文章目录 1、算法复杂度1.1 时间复杂度1.2 空间复杂度 2、数组3、leetcode485&#xff1a;最大连续1的个数4、leetcode283&#xff1a;移动05、leetcode27&#xff1a;移除元素 1、算法复杂度 1.1 时间复杂度 算法的执行时间与输入值之间的关系&#xff08;看代码实际总行数的…

MySQL 5.7.42 主从复制环境搭建

MySQL 5.7.42 主从复制环境搭建 下载MySQL二进制包操作系统环境配置安装过程搭建从库 本次安装环境&#xff1a; OS版本&#xff1a;Red Hat Enterprise Linux Server release 6.8 (Santiago) MySQL版本&#xff1a;5.7.42 架构&#xff1a;同一台机器&#xff0c;多实例安装搭…

洁净室(区)浮游菌检测标准操作规程及GB/T 16292-2010测试方法解读

洁净室(区)空气中浮游菌的检测。洁净区浮游菌检测是一种评估和控制洁净区(如实验室、生产车间等)内空气质量的方法。这种检测的目的是通过测量空气中的微生物(即浮游菌)数量&#xff0c;来评估洁净区的清洁度或污染程度。下面中邦兴业小编带大家详细看下如何进行浮游菌采样检测…

TSLANet:时间序列模型的新构思

实时了解业内动态&#xff0c;论文是最好的桥梁&#xff0c;专栏精选论文重点解读热点论文&#xff0c;围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;…

Python --- 如何修改Jupyter Notebook保存文件的路径?

如何修改Jupyter Notebook在本地保存文件的默认路径&#xff1f; 一直以来都比较喜欢jupter notebook&#xff0c;自从用了以后就爱上了。平时用的时候&#xff0c;因为大多都是临时调用&#xff0c;每次在界面里直接new一个新的file就开干。 曾经也想过我创建的这些python文件…

Android开发系列(十)Jetpack Compose之Card

Card是一种常用的UI组件&#xff0c;用于显示一个具有卡片样式的容器。Card组件通常用于显示列表项、卡片式布局或任何需要显示边框和阴影的UI元素。 使用Card组件&#xff0c;您可以轻松地创建带有卡片效果的UI元素。以下是一些Card组件的常见属性和功能&#xff1a; elevati…

微软专家分享 | AIGC开发者沙龙上海站来啦!

为了向技术开发者、业务人员、高校学生、以及个体创业人员等AI技术关注者们提供更深入的行业洞察、技术交流平台和创新思维的启发&#xff0c;AIGC开放社区联合微软Reactor特别组织了一系列城市巡回沙龙分享活动。在上海站中&#xff0c;我们有幸邀请到多位微软专家进行深入的主…

操作系统实训复习笔记(第7关:生产者消费者问题实践)

目录 第7关&#xff1a;生产者消费者问题实践 第1关&#xff1a;生产者消费者问题实践 1、在主线程中初始化锁为解锁状态 2、访问对象时的加锁操作与解锁操作 3、&#xff08;生产和消费进程操作后&#xff09;信号量操作实现进程同步 4、先等待&#xff08;生产还是消费…