当前位置:网站首页>量化框架backtrader之一文讀懂Analyzer分析器
量化框架backtrader之一文讀懂Analyzer分析器
2022-06-13 07:13:00 【諸葛說talk】

諾貝爾獎獲得者威廉夏普
簡介
策略績效評價是量化交易很重要的一環,投資不僅需要了解策略的收益率, 也需要了解策略的風險。backtrader提供多種analyzer分析器,可以輸出多種績效指標,用來分析策略回測的效果。
使用方法
cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name='AnnualReturn')
cerebro.addanalyzer(bt.analyzers.SharpeRatio, riskfreerate=0.003, annualize=True, _name='SharpeRatio')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='DrawDown')
strats = cerebro.run()
# 第一個策略
strat = strats[0]
print("--------------- AnnualReturn -----------------")
print(strat.analyzers.AnnualReturn.get_analysis())
print("--------------- SharpeRatio -----------------")
print(strat.analyzers.SharpeRatio.get_analysis())
print("--------------- DrawDown -----------------")
print(strat.analyzers.DrawDown.get_analysis())
AnnualReturn代錶年化收益率分析器, SharpeRatio代錶夏普比率分析器, DrawDown代錶回測分析器。各個分析器的結果通常以 OrderedDict 字典的形式返回,如下所示,可以通過 keys 取需要的 values, 如strat.analyzers.SharpeRatio.get_analysis()['sharperatio'] 。
--------------- AnnualReturn -----------------
OrderedDict([(2010, 0.0055023006637382466), (2011, 0.0015355496623354892), (2012, 0.004218277850025043), (2013, 0.09220659214070048), (2014, 0.05213380413050861), (2015, 0.012115724348371826), (2016, -0.017901621371985033), (2017, 0.06763449420829182), (2018, 0.01391412496311406), (2019, 0.05472002239157425), (2020, 1.8864865026259587), (2021, 0.36892175167157526), (2022, -0.2711252801992251)])
--------------- SharpeRatio -----------------
OrderedDict([('sharperatio', 0.3360518820606975)])
--------------- DrawDown -----------------
AutoOrderedDict([('len', 145), ('drawdown', 35.66222565509548), ('moneydown', 21054.40185546875), ('max', AutoOrderedDict([('len', 648), ('drawdown', 40.770090001923634), ('moneydown', 24070.00244140625)]))])
可以看出來, Analyzer分析器輸出的結果都是一些數值,並沒有繪圖。以SharpeRatio 為例,夏普比率計算後是一個數值0.3360518820606975。實際上,Analyzers 不包含lines對象,這也意味著analyzer對象對內存非常友好,不會占用很多的內存。
進一步說明:一個analyzer分析器分析的是一個策略的績效錶現而不是整個系統的錶現。 通過addanalyzer函數添加的分析器類,在
cerebro.run運行時,每個分析器實例會被鏈接到各個策略, 如果回測包含3個策略,那麼同一個分析器將有3個實例被創建,每個實例會被鏈接到不同的策略一些
Analyzer分析器對象會使用其他analyzers分析器來完成任務,比如SharpeRatio使用了TimeReturn分析器的輸出來進一步計算,但這些依賴用戶並不可見
backtrader自帶的Analyzers分析器
AnnualReturn:年化收益率
Calmar: 卡瑪比率
DrawDown:回撤
TimeDrawDown: 指定時間粒度下的回撤
GrossLeverage: 總杠杆
PositionsValue: 持倉價值
PyFolio: 生成數據兼容pyfolio
LogReturnsRolling: 滾動log收益率
PeriodStats: 給定時段下的基本統計信息
Returns: 用對數法計算總、平均、複合、年化收益率
SharpeRatio: 夏普比率
SharpeRatio_A: 年化夏普比率
SQN:系統質量數System Quality Number
TimeReturn:不同時段的收益率
TradeAnalyzer:交易統計信息,如獲勝、失敗次數等
Transactions: 每筆交易的標的、價格、數量等信息
VWR: variability weighted return,波動率加權的收益率
常用的Analyzer分析器有:AnnualReturn, DrawDown, PyFolio, SharpeRatio, TimeReturn。
新建Analyzer分析器
如果backtrader自帶的分析器無法滿足需求,可以自建Analyzer分析器。以SharpeRatio 為例,參考代碼如下。夏普比例是最常用的績效評價指標之一,其反映的是單比特波動貢獻的超額收益率,越大越好。夏普比例等於策略相對無風險收益率的超額收益率除以收益率標准差。
import backtrader as bt
from backtrader.utils.py3 import map
from backtrader.mathsupport import average, standarddev
class SharpeRatio(bt.Analyzer):
params = (
('timeframe', bt.TimeFrame.Years),
('riskfreerate', 0.01),
)
def __init__(self):
super(SharpeRatio, self).__init__()
self.anret = bt.analyzers.AnnualReturn()
# analyzer與策略一樣,都是從第0根bar開始運行
def start(self):
pass
def prenext(self):
pass
def nextstart(self):
pass
def next(self):
pass
# 一般對策略整體的評價指標是在策略結束後開始計算的
def stop(self):
retfree = [self.p.riskfreerate] * len(self.anret.rets)
retavg = average(list(map(operator.sub, self.anret.rets, retfree)))
retdev = standarddev(self.anret.rets)
self.ratio = retavg / retdev
# Analyzer類特有方法,返回包含分析結果的類dict對象
def get_analysis(self):
return dict(sharperatio=self.ratio)
# 支持與策略一樣的信息打印函數
def notify_order(self, order):
pass
def notify_trade(self, trade):
pass
def notify_cashvalue(self, cash, value):
pass
def notify_fund(self, cash, value, fundvalue, shares):
pass
從上述代碼可以看出,盡管Analyzer 對象沒有Lines對象且並不需要在lines上迭代,但它們跟策略一樣遵守相同的運行模式,當然也有get_analysis 這種特有的方法用來返回分析結果。
在backtrader中使用PyFolio
cerebro.addanalyzer(bt.analyzers.PyFolio)
strats = cerebro.run()
# retrieve the 1st strategy
strat0 = strats[0]
pyfolio = strats.analyzers.getbyname('pyfolio')
returns, positions, transactions, gross_lev = pyfoliozer.get_pf_items()
import pyfolio as pf
pf.create_full_tear_sheet(returns)
pyfolio 在Jupyter Notebook外也可以運行,但在Jupyter裏面運行支持的最好。
跟基線benchmark對比
import backtrader as bt
cerebro = bt.Cerebro()
spypd = bt.feeds.PandasData(dataname=spydata, name="spy")
cerebro.adddata(spypd)
cerebro.addanalyzer(bt.analyzers.TimeReturn, timeframe=bt.TimeFrame.Years, _name='TimeReturn')
cerebro.addanalyzer(bt.analyzers.TimeReturn, timeframe=bt.TimeFrame.Years, data=spypd, _name='BenchTimeReturn')
strats = cerebro.run()
time_return = strat.analyzers.getbyname('TimeReturn').get_analysis()
bench_time_return = strat.analyzers.getbyname('BenchTimeReturn').get_analysis()
print("--------------- TimeReturn -----------------")
print(time_return)
print("--------------- BenchTimeReturn -----------------")
print(bench_time_return)
輸出日志:
--------------- TimeReturn -----------------
OrderedDict([(datetime.date(2009, 12, 31), 0.0), (datetime.date(2010, 12, 31), 0.0055023006637382466), (datetime.date(2011, 12, 31), 0.0015355496623354892), (datetime.date(2012, 12, 31), 0.004218277850025043), (datetime.date(2013, 12, 31), 0.09220659214070048), (datetime.date(2014, 12, 31), 0.05213380413050861), (datetime.date(2015, 12, 31), 0.012115724348371826), (datetime.date(2016, 12, 31), -0.017901621371985033), (datetime.date(2017, 12, 31), 0.06763449420829182), (datetime.date(2018, 12, 31), 0.01391412496311406), (datetime.date(2019, 12, 31), 0.05472002239157425), (datetime.date(2020, 12, 31), 1.8864865026259587), (datetime.date(2021, 12, 31), 0.36892175167157526), (datetime.date(2022, 12, 31), -0.2711252801992251)])
--------------- SpyTimeReturn -----------------
OrderedDict([(datetime.date(2009, 12, 31), -0.011793865755532318), (datetime.date(2010, 12, 31), 0.12840988195524994), (datetime.date(2011, 12, 31), -0.001988071570576566), (datetime.date(2012, 12, 31), 0.134741065036728), (datetime.date(2013, 12, 31), 0.2968892471880906), (datetime.date(2014, 12, 31), 0.11289182180470925), (datetime.date(2015, 12, 31), -0.008124930541476227), (datetime.date(2016, 12, 31), 0.09643402233275422), (datetime.date(2017, 12, 31), 0.19384416771302204), (datetime.date(2018, 12, 31), -0.06347893319524989), (datetime.date(2019, 12, 31), 0.28785206349908), (datetime.date(2020, 12, 31), 0.16162313396749006), (datetime.date(2021, 12, 31), 0.2703540848726258), (datetime.date(2022, 12, 31), -0.13563244077211734)])
注意不是所有Analyzers分析器都支持Benchmark對比。
結論 & 交流
關注微信公眾號:諸葛說talk,獲取更多內容。同時還能獲取邀請加入投資交流群、量化投資研討群, 與眾多投資愛好者、量化從業者、技術大牛一起交流、切磋,快速提昇自己的投資水平。
寫文章不易,覺得本文對你有幫助的話,幫忙點個贊吧。
參考
边栏推荐
- Time field comparison time size in MySQL
- Tidb dashboard modify port
- 2022-06-12:在N*N的正方形棋盘中,有N*N个棋子,那么每个格子正好可以拥有一个棋子。 但是现在有些棋子聚集到一个格子上了,比如: 2 0 3 0 1 0 3 0 0 如上的二维数组代表,一
- mysql中时间字段 比较时间大小
- Calculate running total / running balance
- Tree list under winfrom treelist related
- Raspberry school advanced development - "writing of IO port driver code" includes bus address, physical \u virtual address and bcm2835 chip manual knowledge
- Reflection of C # Foundation
- 学习Mysql基础第一天
- How to solve the 404 problem
猜你喜欢

Calculate running total / running balance

【RS-422与RS-485】RS-422与RS-485串行接口标准

玄武云科技通过上市聆讯:业绩波动明显,陈永辉等三人为控股股东

2022 - 06 - 12: dans un échiquier carré n * N, il y a n * n pièces, donc chaque pièce peut avoir exactement une pièce. Mais maintenant quelques pièces sont rassemblées sur une grille, par exemple: 2 0

Tree list under winfrom treelist related

Detailed description of drawing ridge plot, overlapping densities of overlapping kernel density estimation curve, facetgrid object and function sns Kdeplot, function facetgrid map

TiDB Lightning

Learning notes of MySQL series by database and table

通过函数seaborn.cubehelix_palette生成顺序调色板

对绘制丘岭密度图ridge plot的详细说明、重叠核密度估计曲线overlapping densities、FacetGrid对象、函数sns.kdeplot、函数FacetGrid.map
随机推荐
[Tencent Alibaba's most comprehensive collection of test questions] (four sides: three rounds of technology +1 round of HR)
Personal JS learning notes
理财产品连续几天收益都是零是怎么回事?
I always don't understand the high address and high position
Sharp weapon tcpdump
Learning notes of MySQL series by database and table
【马尔科夫链-蒙特卡罗】马尔科夫链-蒙特卡罗方法对先验分布进行抽样
SDN基本概述
同花顺可以开股票账户吗?安全吗?
Evolution in the digital age
杭州网上开户是安全的吗?
检测循环数“142857“
Word document export
What languages can be decompiled
Computer network interview questions
Upper computer development (detailed design of firmware download software)
[Markov chain Monte Carlo] Markov chain Monte Carlo method sampling prior distribution
C # Advanced Programming - Feature Section
Issues related to C # delegation and events
Implementation of fruit mall wholesale platform based on SSM