用Python编写的第一个回测程序
2016-08-06
1 def savfig(figureObj, fn_prefix1=‘backtest8‘, fn_prefix2=‘_1_‘): 2 import datetime 3 fmt= ‘%Y_%m_%d_%H_%M_%S‘ 4 now = datetime.datetime.now() 5 fname_savfig = fn_prefix1 + fn_prefix2 + now.strftime(fmt)+ ‘.png‘ 6 figureObj.savefig(fname_savfig, facecolor=fig.get_facecolor()) 7 8 9 def backtest8(ohlc=ohlc, SD=1.0, n_short=2, n_long=20, f_savfig=False): 10 u‘‘‘ 11 双均线策略回测函数 12 signature: backtest8(ohlc=ohlc, SD=1.0, n_short=2, n_long=20, f_savfig=False) 13 param:: 14 ohlc - dohlcva 数据, dataFrame结构的 15 SD - MA1/MA2 > SD 触发多头买入的快均线/慢均线的阀值 16 f_savefig - flag for saving Matplot output figures 17 18 19 20 ‘‘‘ 21 import matplotlib 22 #import seaborn as sns 23 #sns.set_style(‘white‘) 24 25 myfontprops = matplotlib.font_manager.FontProperties( 26 fname=‘C:/Windows/Fonts/msyh.ttf‘)#微软雅黑 27 28 maShort = pd.Series.rolling(ohlc.C, n_short).mean() 29 maLong = pd.Series.rolling(ohlc.C, n_long).mean() 30 31 32 fig=plt.figure() # create new figure 33 ohlc.C.plot(grid=True, figsize=(8,4)) 34 maShort.plot(label=‘MA‘+str(n_short)) 35 maLong.plot(grid=True,label=‘MA‘+str(n_long)) 36 # ohlc.iloc[:,[0,1,2,3]].plot(grid=False, figsize=(8,4)) 37 # ohlc.iloc[:,[0,1,2,3]].plot(grid=True,figsize=(8,4)) 38 plt.legend(loc=‘best‘) 39 plt.title( s=u‘历史股价‘, fontproperties=myfontprops) 40 if f_savfig: 41 savfig(fig, ‘backtest8‘, ‘_0_‘) 42 43 # SD=1.0 44 regime = np.where( maShort/maLong > SD, 1, 0) 45 regime = pd.Series(regime, index=maShort.index) 46 print (‘Regime Length = %s‘%regime.size) 47 48 fig=plt.figure() # create new figure 49 regime[:].plot(lw=1.5, ylim=(-0.1, 1.1), figsize=(8,4), title=u‘Regime‘) 50 if f_savfig: 51 savfig(fig, ‘backtest8‘, ‘_1_‘) 52 53 fig=plt.figure() # create new figure 54 regime[-100:].plot(lw=1.5, ylim=(-0.1, 1.1), figsize=(8,4), title=u‘Regime‘) 55 if f_savfig: 56 savfig(fig, ‘backtest8‘, ‘_2_‘) 57 58 59 60 pp_ratio_bnh = np.log(ohlc.C / ohlc.C.shift(1) ) 61 pp_ratio_strategy = regime.shift(1) * pp_ratio_bnh 62 #最后我们把每天的收益率求和就得到了最后的累计收益率 63 #(这里因为我们使用的是指数收益率,所以将每日收益累加是合理的), 64 #这个累加的过程也可以通过DataFrame的内置函数cumsum轻松完成: 65 norm_return_bnh = pp_ratio_bnh .cumsum().apply(np.exp) 66 norm_return_strategy = pp_ratio_strategy.cumsum().apply(np.exp) 67 68 fig=plt.figure() # create a new figure 69 norm_return_strategy. plot(lw=1.5, figsize=(8,4), label=u‘Strategy‘) 70 norm_return_bnh. plot(lw=1.5, label=u‘BnH‘) 71 72 plt.legend(loc=‘best‘) 73 plt.title(s=u‘策略收益率与历史价格对比‘, fontproperties=myfontprops) 74 if f_savfig: 75 savfig(fig, ‘backtest8‘, ‘_3_‘) 76 77 assert (regime.index == ohlc.C.index).all()==True # ‘signal index not equals price index‘ 78 # assert用来判断语句的真假,如果为假的话将触发AssertionError错误, 为开发人员提示出错的表达式 79 return norm_return_strategy, n_short, n_long, SD
结果图: 有四张, 主要用于质量控制的目的.
1. 历史价格
2. 交易信号
3. 第2的子集, 放大后才能看清楚, 技术指标择时模型的细节(如何触发交易信号)
4. 策略的收益率
后续补充内容:
封装成类
添加优化
原文:http://www.cnblogs.com/duan-qs/p/duanqs.html