《WonderTrader架構詳解》系列文章已經寫了四篇了,對於筆者這樣的懶人來講,實在是一個大工程。此次先暫時不介紹架構了,本文將給你們介紹一下如何在WonderTrader上編寫一個跨品種套利策略,旨在給你們演示一下WonderTrader下多標的策略的通常寫法,同時也介紹一下筆者在wtpy最新版本v0.6.3
中最新發布的績效分析模塊。git
WonderTrader架構文章列表:github
相信每個作量化的人,都研究過套利策略。套利策略以其邏輯的相對簡單、收益的相對穩定而獲得多數人的青睞。同時,套利策略和趨勢策略有較強的互補性,這就意味着,若是配合得當,對平滑收益曲線,下降績效的波動,提升夏普有極大的促進做用。
套利策略的分類就很是多了,筆者曾在《WonderTrader架構詳解之四——淺談平臺對策略的支持》文中引用了丁鵬博士的《量化投資——策略與技術》對於策略的分類,裏面提到的套利的模式就有不少種,例如:期現套、跨期套、跨品種套、配對交易等等。
筆者爲了開發該策略,查閱資料的時候,看到一個觀點,深覺得然:無論套利策略分類多麼繁複,套利策略的本質是在不一樣合約之間的價差波動中尋找交易機會。segmentfault
鑑於筆者的量化策略的技能樹,還沒點亮,因此本文中的策略示例,是從互聯網上學習到的,筆者在此由衷地感謝此策略的分享者。該策略基本設計以下:api
SHFE.rb.HOT
和鐵礦石主力連續合約DCE.i.HOT
N
分鐘兩組收盤價序列進行線性迴歸,獲得一個係數beta
、一個常量c
和一個殘差序列beta
和常量c
,以及最新的價格計算新的殘差參數設計
根據上文的介紹,策略核心的參數以下:網絡
code1
:套利合約1,本例設置爲SHFE.rb.HOT
code2
:套利合約2,本例設置爲DCE.i.HOT
period
:數據週期,本例設置爲m1
,即一分鐘線threshold
:閾值,本例設置爲0.9
N
:統計的K線條數,本例設置爲360
,即一個交易日的一分鐘線bar_cnt
:策略讀取的K線條數,大於N
,主要考慮預留滾動計算的空間def __init__(self, name:str, code1:str, code2:str, bar_cnt:int, period:str, N:int, threshold:float=1): BaseCtaStrategy.__init__(self, name) self.__n__ = N self.__threshold__ = threshold self.__period__ = period self.__bar_cnt__ = bar_cnt self.__code_1__ = code1 self.__code_2__ = code2
協整檢驗
策略核心的邏輯在於協整檢驗,只有協整檢驗經過了,才能進行信號觸發。架構
# 協整檢驗函數 def cointegration_check(series01, series02): # 對兩個序列分別進行ADF檢驗 urt_1 = ts.adfuller(np.array(series01), 1)[1] urt_2 = ts.adfuller(np.array(series02), 1)[1] # 同時平穩或不平穩則差分再次檢驗 if (urt_1 > 0.1 and urt_2 > 0.1) or (urt_1 < 0.1 and urt_2 < 0.1): urt_diff_1 = ts.adfuller(np.diff(np.array(series01)), 1)[1] urt_diff_2 = ts.adfuller(np.diff(np.array(series02), 1))[1] # 同時差分平穩進行OLS迴歸的殘差平穩檢驗 if urt_diff_1 < 0.1 and urt_diff_2 < 0.1: matrix = np.vstack([series02, np.ones(len(series02))]).T beta, c = np.linalg.lstsq(matrix, series01, rcond=None)[0] resid = series01 - beta * series02 - c # 最後對殘差序列再進行ADF檢驗 if ts.adfuller(np.array(resid), 1)[1] > 0.1: result = False else: result = True return beta, c, resid, result else: result = False return 0.0, 0.0, 0.0, result else: result = False return 0.0, 0.0, 0.0, result
信號發出
當殘差超出上邊界,說明殘差正向擴大,根據殘差均值迴歸的特性,這時就須要作空價差;相反的,當殘差超出下邊界,說明殘差反向擴大,這時就須要作多價差;當參加在上下邊界範圍以內,則清掉已有的頭寸,等待下一次機會。框架
# 計算新殘差 resid_new = close_ay1[-1] - self.beta * close_ay2[-1] - self.c if resid_new > self.up and curPos1 != 1: context.stra_log_text("[%d.%04d]殘差正向擴大,作空價差" % (curDate, curTime)) context.stra_enter_short(self.__code_1__, 1, 'OpenSA') context.stra_enter_long(self.__code_2__, 1, 'OpenLB') elif resid_new < self.down and curPos1 != -1: context.stra_log_text("[%d.%04d]殘差反向擴大,作多價差" % (curDate, curTime)) context.stra_enter_long(self.__code_1__, 1, 'OpenLA') context.stra_enter_short(self.__code_2__, 1, 'OpenSB') elif curPos1 != 0 and self.down <= resid_new and resid_new <= self.up: context.stra_log_text("[%d.%04d]殘差迴歸,清掉頭寸" % (curDate, curTime)) context.stra_set_position(self.__code_1__, 0, 'CutA') context.stra_set_position(self.__code_2__, 0, 'CutB')
本例中採用的wtpy在v0.6.3
版本中發佈的加強版績效分析工具進行分析,調用方法和老版本基本同樣,可是分析的入口有所變化。函數
analyst = WtBtAnalyst() analyst.add_strategy("t1_rb_i", folder="./outputs_bt/t1_rb_i/", init_capital=350000, rf=0.02, annual_trading_days=240) # 績效分析的入口,老版本run的仍然可用 analyst.run_new()
績效分析截圖工具
策略績效概要學習
詳細交易列表
整體交易分析
連續交易分析
收益分佈
日度績效分析
其餘週期績效
逐日績效概覽
從前面能夠看出,新版本的績效分析模塊提供了更多維度的分析功能。新版本的績效分析模塊,主要參考了MultiCharts
的績效分析報告,因此從分析結果的全面性和實用性來講,應該是有保障的。
回到策略自己,從前面的績效報告能夠看出,該策略顯然是不大成功的。如何優化該策略呢?筆者考慮是否能夠經過加入止盈止損邏輯來進行優化,或者經過調整閾值進行優化。不過這些已經超出本文的宗旨了,若是有朋友感興趣,能夠自行研究。
本文中的示例策略已經分享到github上wtpy項目中的/demos/cta_arbitrage_bt下,有興趣的朋友能夠自行去下載。點此跳轉
本文對利用WonderTrader編寫套利策略的介紹就到此結束了。筆者今日一邊寫文章,一邊感到忐忑不安。筆者雖然一直在優秀的量化團隊裏跟你們一塊兒合做,可是因爲筆者是從事技術方面的工做,因此對策略的瞭解畢竟仍是停留在表面,所以生怕今天分享的策略出現了低級錯誤。好在筆者最後仍是決定從網絡上尋找現成的策略,這樣才稍稍緩解了筆者的不安。即使是這樣,本文及本文演示的策略也不免有錯漏之處,也但願各位看客可以包涵指正。所幸本文的終極目標是經過筆者今日拋出的「磚頭」引發你們找到更多的「美玉」,若是可以對你們有所裨益,那就再好不過了。
最後再安利一下WonderTrader
WonderTrader旨在給各位量化從業人員提供更好的輪子,將技術相關的東西都封裝在平臺中,打造更高效的底層框架,力求給策略研發帶來更好的策略開發和交易體驗。
WonderTrader的github
地址:https://github.com/wondertrad...
WonderTrader官網地址:https://wondertrader.github.io
wtpy的github
地址:https://github.com/wondertrad...
市場有風險,投資需謹慎。以上陳述僅做爲對於歷史事件的回顧,不表明對將來的觀點,同時不做爲任何投資建議。