今天除了写了一个可转债的策略之外,一直在探索分析夏普率的计算方式,在阅读到 backtrader 的源代码的时候,忽然对如何使用 backtrader 计算夏普率有了更深刻的认识。
在常见的教程中,计算夏普率的时候,基本上是不会填入参数的,如果不填入参数,计算得到的夏普率有可能不是我们想要的值,尤其是可能和其他平台对比的时候差距比较大。
所以,需要根据自己的需要,传入具体的参数,如下面的代码中,我特别传入的几个值,
第一个是交易周期按天计算,即timeframe= bt.TimeFrame.Days
第二个是年化的无风险收益率,即 riskfreerate=0.04这个根据需要进行设置
第三个是一年有多少个交易日的设定,即factor=250现在设置的是一年有 250 个交易日
第四个是是否转化为年化的夏普率,即annualize=True,如果设置成 True 了,那么代表着计算出来的是年化夏普率,否则就是天化的夏普率
大家在使用的时候可以酌情考虑设置这四个参数,以便计算的夏普率更准确合理一些。
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='my_sharpe',timeframe= bt.TimeFrame.Days,riskfreerate=0.04,annualize=True,factor=250)
def run():
cerebro.addstrategy(CbStrategy)
cerebro.addanalyzer(bt.analyzers.TotalValue, _name='my_value')
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='my_sharpe',timeframe= bt.TimeFrame.Days,riskfreerate=0.04,annualize=True,factor=250)
cerebro.addanalyzer(bt.analyzers.Returns, _name='my_returns')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='my_drawdown')
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='my_trade_analyzer')
# cerebro.addanalyzer(bt.analyzers.TimeReturn, _name='my_time_return')
# cerebro.addanalyzer(bt.analyzers.PyFolio)
# 运行回测
results = cerebro.run()
sharpe_ratio = results[0].analyzers.my_sharpe.get_analysis()['sharperatio']
annual_return = results[0].analyzers.my_returns.get_analysis()['rnorm']
max_drawdown = results[0].analyzers.my_drawdown.get_analysis()["max"]["drawdown"]/100
trade_num = results[0].analyzers.my_trade_analyzer.get_analysis()['total']['total']
value_df = pd.DataFrame([results[0].analyzers.my_value.get_analysis()]).T
value_df.columns=['value']
value_df['datetime']=pd.to_datetime(value_df.index)
value_df['date']=[i.date() for i in value_df['datetime']]
value_df= value_df.drop_duplicates("date",keep="last")
value_df = value_df[['value']]
value_df.to_csv("可转债的测试结果.csv")
print(f"夏普率:{sharpe_ratio},年化收益率:{annual_return},最大回撤:{max_drawdown},交易次数:{trade_num}")
return results