(9条消息) backtrader量化平台教程(三)分析策略的优劣
分析策略的优劣
定投真的可行么?
上文我们写了第一个简单的策略,买入并持有指数基金。
我们通过回测发现,指数基金在中国是否能取得很好的收益,本质上是存疑的。
那有的同学可能说,那我们使用定投策略投资指数基金的话会怎么样呢?
第二个策略(定投指数基金)
假设我们每月投入1万元购买指数基金,期限从2010-1-1到2019-12-31。
我们回测下这个数据。
图形化plot
我们可能想图形化展示下我们的投资过程,各种指标的变化情况。
backtrader提供了基本的图形能力。
backtrader的图形化依赖于mataplotlib,因此必须安装该lib。
cerebo.plot()
显示效果如下:
analyzer
backtrader提供了analyzer工具,可以用来对投资过程进行分析。
比如我们熟知的sharp ratio,买卖次数,回撤情况等等。
可以在回测运行前通过addanalyzer增加分析器,然后回测后查看分析结果。
# Analyzer cerebro.addanalyzer(btanalyzers.SharpeRatio, _name='mysharpe') cerebro.addanalyzer(btanalyzers.AnnualReturn, _name='myannual') cerebro.addanalyzer(btanalyzers.DrawDown, _name='mydrawdown') # Run over everything thestrats = cerebro.run() thestrat = thestrats[0] print('Sharpe Ratio:', thestrat.analyzers.mysharpe.get_analysis()) print('Annual Return:', thestrat.analyzers.myannual.get_analysis()) print('Drawdown Info:', thestrat.analyzers.mydrawdown.get_analysis())
分析结果如下:
$python example3.pyStarting Portfolio Value: 1200000.00Final Portfolio Value: 1335469.29Sharpe Ratio: OrderedDict([('sharperatio', 0.08794344140568065)])Annual Return: OrderedDict([(2010, 0.009994798081538692), (2011, -0.06385257455175308), (2012, -0.001059256049693591), (2013, 0.0513281370753218), (2014, 0.18051195171848144), (2015, 0.2553421396965294), (2016, -0.12786696056384306), (2017, -0.0024386306434659444), (2018, -0.2973329165832902), (2019, 0.23710565581150012)])Drawdown Info: AutoOrderedDict([('len', 1110), ('drawdown', 44.11989120158515), ('moneydown', 1054413.8328226043), ('max', AutoOrderedDict([('len', 1110), ('drawdown', 56.18897640055283), ('moneydown', 1342850.8628497515)]))])
总结
从回测结果可以看出来,十年的收益可以说很一般,即使算XIRR收益估计也就是和货币基金差不多。
另外从analyzer数据看回撤也非常之大。
回测完整代码
#!/usr/bin/env python# -*- coding: utf-8; py-indent-offset:4 -*-"""计算定投某个标的的盈利情况"""from __future__ import (absolute_import, division, print_function, unicode_literals)import datetime # For datetime objects# Import the backtrader platformimport backtrader as btimport backtrader.analyzers as btanalyzersimport backtrader.feeds as btfeedimport click# Create a Strateyclass TestStrategy(bt.Strategy): def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # Keep a reference to the "close" line in the data[0] dataseries self.dataclose = self.datas[0].close # To keep track of pending orders self.month = -1 def next(self): # Simply log the closing price of the series from the reference # 每月进行购买一次 if self.month != self.datas[0].datetime.date(0).month: self.month = self.datas[0].datetime.date(0).month self.buy(size=10000/self.dataclose[0])class TSCSVData(btfeed.GenericCSVData): params = ( ("fromdate", datetime.datetime(2010, 1, 1)), ("todate", datetime.datetime(2019, 12, 31)), ('nullvalue', 0.0), ('dtformat', ('%Y-%m-%d')), ('openinterest', -1) )def backtest(): filename = "bs_sh.000905.csv" cash = 1200000.0 # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(TestStrategy) # Create a Data Feed data = TSCSVData(dataname="./datas/{0}".format(filename)) # Add the Data Feed to Cerebro cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(cash) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Analyzer cerebro.addanalyzer(btanalyzers.SharpeRatio, _name='mysharpe') cerebro.addanalyzer(btanalyzers.AnnualReturn, _name='myannual') cerebro.addanalyzer(btanalyzers.DrawDown, _name='mydrawdown') # Run over everything thestrats = cerebro.run() # Print out the final result print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) thestrat = thestrats[0] print('Sharpe Ratio:', thestrat.analyzers.mysharpe.get_analysis()) print('Annual Return:', thestrat.analyzers.myannual.get_analysis()) print('Drawdown Info:', thestrat.analyzers.mydrawdown.get_analysis()) cerebro.plot()if __name__ == '__main__': backtest()
赞 (0)