当前位置:网站首页>One article of quantitative framework backtrader read analyzer

One article of quantitative framework backtrader read analyzer

2022-06-13 07:15:00 Zhuge said talk

The Nobel Prize winner William sharp

brief introduction

Strategic performance evaluation is a very important part of quantitative trading , Investing requires more than just knowing the yield of the strategy , You also need to understand the risks of the strategy .backtrader Offer a variety of analyzer analyzer , Multiple performance indicators can be output , Used to analyze the effect of strategy backtesting .

Usage method

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()

#  The first strategy 
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 Represents the annualized yield analyzer , SharpeRatio Represents sharp ratio analyzer , DrawDown Representative backtest analyzer . The results of each analyzer are usually expressed as OrderedDict The form of a dictionary returns , As shown below , Can pass keys Take what you need values, Such as 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)]))])

You can see it , Analyzer The output of the analyzer is some numerical value , No drawings . With SharpeRatio  For example , The sharp ratio is a numerical value after calculation 0.3360518820606975. actually ,Analyzers  It doesn't contain lines object , It also means that analyzer Object is very memory friendly , It won't take up a lot of memory .

  • Go further : One analyzer The analyzer analyzes the performance of a strategy rather than the performance of the whole system . adopt addanalyzer Function to add the parser class , stay cerebro.run  Runtime , Each analyzer instance is linked to each policy , If the backtest contains 3 Strategies , Then the same parser will have 3 Instances are created , Each instance will be linked to a different policy

  • some Analyzer  The parser object uses other analyzers Analyzer to complete the task , such as SharpeRatio  Used TimeReturn  The output of the analyzer to further calculate , But these dependent users are not visible

backtrader Self contained Analyzers analyzer

  • AnnualReturn: Annualized rate of return

  • Calmar:  Kama ratio

  • DrawDown: retracement

  • TimeDrawDown:  Rollback at specified time granularity

  • GrossLeverage:  Total leverage

  • PositionsValue:  Position value

  • PyFolio:  Generate data compatible pyfolio

  • LogReturnsRolling:  rolling log Yield

  • PeriodStats:  Basic statistics for a given time period

  • Returns:  Calculate the total by logarithm 、 Average 、 Reunite with 、 Annualized rate of return

  • SharpeRatio:  Sharp ratio

  • SharpeRatio_A:  Annualized Sharpe ratio

  • SQN: System mass number System Quality Number

  • TimeReturn: Yield in different periods

  • TradeAnalyzer: Transaction statistics , If you win 、 Failure times, etc

  • Transactions:  The subject matter of each transaction 、 Price 、 Quantity, etc

  • VWR: variability weighted return, Volatility weighted yield

frequently-used Analyzer Analyzer has :AnnualReturn, DrawDown, PyFolio, SharpeRatio, TimeReturn.

newly build Analyzer analyzer

If backtrader The built-in analyzer cannot meet the requirements , You can build it yourself Analyzer analyzer . With SharpeRatio  For example , The reference codes are as follows . Sharp ratio is one of the most commonly used performance evaluation indicators , It reflects the excess return contributed by unit volatility , The bigger the better . The sharp ratio is equal to the excess return of the relative risk-free return of the strategy divided by the standard deviation of the return .

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 Like strategy , It's all from the beginning 0 root bar Began to run 
    def start(self):
        pass

    def prenext(self):
        pass
    
    def nextstart(self):
        pass

    def next(self):
        pass

    #  Generally, the evaluation index of the whole strategy is calculated after the end of the strategy 
    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 Class specific methods , Return the class containing the analysis results dict object 
    def get_analysis(self):
        return dict(sharperatio=self.ratio)

    #  Support the same information printing function as policy 
    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

As can be seen from the above code , Even though Analyzer  Objects have no Lines Object and does not need to be in lines Last iteration , But they follow the same operating mode as the policy , Of course, there are get_analysis  This unique method is used to return the analysis results .

stay backtrader Use in 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  stay Jupyter Notebook It can also run , But in Jupyter It is the best one to run and support .

Follow the baseline benchmark contrast

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)

Output log :

--------------- 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)])

Note that not all Analyzers Analyzers support Benchmark contrast .

Conclusion &  communication

Pay attention to WeChat public number : Zhuge said talk, Get more . At the same time, you can also get an invitation to join the investment exchange group 、 Quantitative investment seminar group , With many investment lovers 、 Quantitative practitioners 、 Technical leaders communicate with each other 、 Compare notes , Quickly improve your investment level .

It's not easy to write , If you think this article can help you , Do me a favor .

Reference resources

原网站

版权声明
本文为[Zhuge said talk]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/164/202206130712428264.html