Un artículo sobre el backtrader del marco cuantitativo para comprender el analizador Analyzer.

Premio Nobel William Sharp

Introducción

La evaluación del desempeño de la estrategia es una parte muy importante del comercio cuantitativo. La inversión requiere no sólo comprender la tasa de rendimiento de la estrategia, sino también el riesgo de la estrategia. Backtrader proporciona una variedad de analizadores que pueden generar una variedad de indicadores de desempeño para analizar el efecto del backtesting de la estrategia.

Instrucciones

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 representa el analizador de rendimiento anualizado ,  SharpeRatio representa el analizador de índice de Sharpe y DrawDown representa el analizador de backtest. Los resultados de cada analizador generalmente se devuelven en forma de un diccionario OrderedDict, como se muestra a continuación. Puede obtener los valores requeridos a través de claves, como 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)]))])

Se puede ver que los resultados generados por el analizador son solo valores numéricos y no hay ningún dibujo. Por SharpeRatio ejemplo, la relación de Sharpe se calcula con un valor de 0,3360518820606975. De hecho, Analyzers el objeto de líneas no está incluido, lo que también significa que el objeto analizador es muy amigable con la memoria y no ocupa mucha memoria.

  • Explicación adicional: un analizador analiza el desempeño de una estrategia en lugar del desempeño de todo el sistema. Para la clase de analizador agregada a través de la función addanalyzer, en cerebro.run tiempo de ejecución, cada instancia del analizador se vinculará a cada estrategia. Si el backtest contiene 3 estrategias, se crearán 3 instancias del mismo analizador y cada instancia se vinculará a diferentes estrategias.

  • Algunos Analyzer objetos analizadores utilizan otros analizadores para completar tareas, como SharpeRatio utilizar TimeReturn la salida del analizador para cálculos adicionales, pero estas dependencias no son visibles para el usuario.

Analizadores que vienen con backtrader

  • AnnualReturn: tasa de rendimiento anualizada

  • Calmar:  Relación Calmar

  • DrawDown: retroceso

  • TimeDrawDown:  inconveniente en la granularidad de tiempo especificada

  • Apalancamiento bruto:  apalancamiento total

  • PositionsValue:  valor de posición

  • PyFolio:  Genera datos compatibles con pyfolio

  • LogReturnsRolling:  retornos continuos de registros

  • PeriodStats:  Información estadística básica para un período determinado

  • Rentabilidad:  calcule la rentabilidad total, media, compuesta y anualizada utilizando el método logarítmico

  • SharpeRatio:  relación de nitidez

  • SharpeRatio_A:  ratio de Sharpe anualizado

  • SQN: Número de calidad del sistema

  • TimeReturn: tasa de rendimiento en diferentes periodos

  • TradeAnalyzer: estadísticas comerciales como ganancias, pérdidas, etc.

  • Transacciones:  el tema, el precio, la cantidad y otra información de cada transacción.

  • VWR:  rentabilidad ponderada por variabilidad, rentabilidad ponderada por volatilidad

Los analizadores Analyzer más utilizados incluyen: AnnualReturn, DrawDown, PyFolio, SharpeRatio, TimeReturn.

Crear un nuevo analizador Analizador

Si el analizador que viene con backtrader no puede satisfacer sus necesidades, puede crear su propio analizador. Tomemos SharpeRatio como ejemplo, el código de referencia es el siguiente. El índice de Sharpe es uno de los indicadores de evaluación del desempeño más utilizados y refleja el exceso de tasa de retorno aportado por la fluctuación de las unidades. Cuanto mayor, mejor. El índice de Sharpe es el exceso de rendimiento de la estrategia en relación con el rendimiento libre de riesgo dividido por la desviación estándar del rendimiento.

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

Como se puede ver en el código anterior, aunque Analyzer el objeto no tiene un objeto Líneas y no necesita iterar en líneas, siguen el mismo modo de operación que la estrategia. Por supuesto, también existe este método get_analysis único para devolver resultados de análisis. .

Usando PyFolio en backtrader

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 También se puede ejecutar fuera de Jupyter Notebook, pero se admite mejor cuando se ejecuta dentro de Jupyter.

Comparar con el punto de referencia de referencia

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)

Registro de salida:

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

Tenga en cuenta que no todos los analizadores admiten la comparación de puntos de referencia.

Conclusión y comunicación

Siga la cuenta pública de WeChat: Zhuge Shuo Talk para obtener más contenido. Al mismo tiempo, también puede recibir invitaciones para unirse a grupos de intercambio de inversiones y grupos de seminarios de inversión cuantitativa, donde podrá comunicarse y discutir con muchos entusiastas de las inversiones, profesionales cuantitativos y expertos en tecnología, y mejorar rápidamente su nivel de inversión.

Escribir artículos no es fácil, si crees que este artículo te resulta útil, dale me gusta.

referencia

Supongo que te gusta

Origin blog.csdn.net/richardzhutalk/article/details/125239927
Recomendado
Clasificación