duan-qs

用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. 策略的收益率

后续补充内容:


 

  1. 封装成类

  2. 添加绩效策略指标: 一大堆的东西
  3. 优化

  4. 完善绘图程序, 智能地选择输入(data_obj, param, **kwargs)

 

 

 

 

 

 

分类:

技术点:

相关文章:

  • 2021-09-13
  • 2021-12-22
  • 2021-12-29
  • 2021-11-05
  • 2022-12-23
猜你喜欢
  • 2021-12-05
  • 2021-12-28
  • 2021-11-21
  • 2021-11-05
  • 2021-11-14
  • 2021-11-05
相关资源
相似解决方案