用Python編寫的第一個回測程序


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

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM