文章來源于量化小白上分記 ,作者量化小白H。 看多了前面的鋪墊,接下來寫一寫可以實操的。本篇給出寫擇時策略回測的詳細步驟,并用代碼展示全過程,代碼用python寫,數據和代碼后臺回復“擇時”獲取,可以自己測試。 擇時策略 根據百度百科的解釋,擇時交易是指利用某種方法來判斷大勢的走勢情況,是上漲還是下跌或者是盤整。如果判斷是上漲,則買入持有;如果判斷是下跌,則賣出清倉,如果是盤整,可以高拋低吸。 從量化角度來說,擇時是通過資產的數據構造出買賣信號,按照買賣信號進行交易?;販y就是實現這整個過程。 本文以最簡單的雙均線策略為例進行回測,具體規(guī)則如下:
回測評價 對于策略的評價,總體分為收益和風險兩方面,或者將兩者綜合起來,列一些最常用的評價指標。 年化收益 回測起點到終點的累積收益年化,算復利或單利都可以,復利假設策略的盈利也會被用于投資,因此復利算出來結果會更好看一些。 夏普比 夏普比 = (策略期望收益率 - 無風險收益率)/策略波動率 夏普比綜合衡量了收益和風險,是最廣泛應用的指標。 勝率 統(tǒng)計勝率要先統(tǒng)計交易次數,然后計算所以交易中盈利次數占的比例 最大回撤率 回撤是策略從前期最高點到當前時點的虧損,最大回撤是所有回撤中的最大值,反映的是策略的最大可能損失。 單次最大虧損 所有單次交易中的最大虧損 策略階段性表現 對策略時間段進行分割,統(tǒng)計每個時間段內上述指標的變化情況,本文按年進行分割,統(tǒng)計測年逐年的收益率和相對于基準的超額收益率。 其他 除此外,還有波動率、下行風險、索提諾比率等各種指標,python中有專門的模塊可以計算各種指標,這里我們自己算出各種指標,供參考。 此外,還需要測試策略的穩(wěn)定性,對策略中參數進行擾動,檢驗策略的敏感性情況,好的策略應該是參數不敏感的。 回測說明 回測標的:滬深300指數 回測區(qū)間:2010年1月-2019年3月 代碼說明:回測代碼分成兩塊,一塊是策略函數(Strategy),一塊是評價函數(Performance),策略函數通過指數的收盤價構造信號,計算策略凈值,統(tǒng)計策略的每筆交易的情況。評價函數根據策略凈值和策略每筆交易的情況計算策略的上述各個指標。 策略代碼 回測函數 def Strategy(pdatas,win_long,win_short,lossratio = 999): # pdatas = datas.copy();win_long = 12;win_short = 6;lossratio = 999; ''' pma:計算均線的價格序列 win:窗寬 lossratio:止損率,默認為0 ''' pdatas = pdatas.copy() pdatas['lma'] = pdatas.CLOSE.rolling(win_long,min_periods = 0).mean() pdatas['sma'] = pdatas.CLOSE.rolling(win_short,min_periods = 0).mean() pdatas['position'] = 0 # 記錄持倉 pdatas['flag'] = 0 # 記錄買賣 pricein = [] priceout = [] price_in = 1 for i in range(max(1,win_long),pdatas.shape[0] - 1): # 當前無倉位,短均線上穿長均線,做多 if (pdatas.sma[i-1] < pdatas.lma[i-1]) & (pdatas.sma[i] > pdatas.lma[i]) & (pdatas.position[i]==0): pdatas.loc[i,'flag'] = 1 pdatas.loc[i + 1,'position'] = 1 date_in = pdatas.DateTime[i] price_in = pdatas.loc[i,'CLOSE'] pricein.append([date_in,price_in]) # 當前持倉,下跌超出止損率,止損 elif (pdatas.position[i] == 1) & (pdatas.CLOSE[i]/price_in - 1 < -lossratio): pdatas.loc[i,'flag'] = -1 pdatas.loc[i + 1,'position'] = 0 priceout.append([pdatas.DateTime[i],pdatas.loc[i,'CLOSE']]) # 當前持倉,死叉,平倉 elif (pdatas.sma[i-1] > pdatas.lma[i-1]) & (pdatas.sma[i] < pdatas.lma[i]) &(pdatas.position[i]==1): pdatas.loc[i,'flag'] = -1 pdatas.loc[i+1 ,'position'] = 0 priceout.append([pdatas.DateTime[i],pdatas.loc[i,'CLOSE']]) # 其他情況,保持之前倉位不變 else: pdatas.loc[i+1,'position'] = pdatas.loc[i,'position'] p1 = pd.DataFrame(pricein,columns = ['datebuy','pricebuy']) p2 = pd.DataFrame(priceout,columns = ['datesell','pricesell']) transactions = pd.concat([p1,p2],axis = 1) pdatas = pdatas.loc[max(0,win_long):,:].reset_index(drop = True) pdatas['ret'] = pdatas.CLOSE.pct_change(1).fillna(0) pdatas['nav'] = (1 + pdatas.ret*pdatas.position).cumprod() pdatas['benchmark'] = pdatas.CLOSE/pdatas.CLOSE[0] stats,result_peryear = performace(transactions,pdatas) return stats,result_peryear,transactions,pdatas 說明
評價函數
說明
回測結果 nav為策略凈值,benchmark為基準凈值,RS為相對強弱曲線,可以看出,策略表現并不穩(wěn)定。 transcation中記錄每筆交易的買賣時點和價格 result_peryear中是策略的逐年表現情況,也并不會比基準好多少 綜上,是一個完整的策略回測和評價過程,當然實際操作中還有許多需要細化的地方,僅供參考,歡迎指正! 關于Python金融量化 |
|
來自: 追夢文庫 > 《量化交易系統(tǒng)》