標籤:

股票策略回測的框架、實現、測試——以動量策略為例

股票策略回測的框架、實現、測試——以動量策略為例

不同於期貨品種(國內目前大概上市的期貨品種50個左右),股票的標的眾多(A股目前大概2700隻左右),然而不管說選股還是擇時,交易策略都可以抽象為一個從行情序列到資金曲線的映射:

f(ts,para) = E

即f是一種規則,給出了一些交易信號規定了在T時刻使用P價格買賣Amount數量的某種投資標的ts,para是交易系統的參數組(規則的生成方式),E是資金曲線。

股票的回測框架可以如下描述:

Data Generatorn-> Singal Generator

-> BackTest Modular -> InvestmentnPerformance Metrics

細節層面,其中:

數據Data Generator模塊中,需要支持不同種類、不同來源、不同格式的數據,在Data Generator中將數據格式統一定義,方便後續模塊的調用。

信號Singal Generator模塊中,這塊是開放給用戶自行開發的,無外乎按照其交易規則產生買賣信號(比如1買、-1賣、0空倉或其他確定的量化定義)。

回測BackTest Modular模塊中,先回想回測的目的:儘可能真實地還原實際交易過程,進而檢測策略的表現!回測中一定要避免未來數據的使用(即要用T日之前產生的信號來指導T日的交易),還有進行買賣時,對於漲停、跌停、停牌等狀態,需要按照交易實際做一些相關處理,這裡給出一種參考的處理方式:

(1)「買入時漲停狀態」:若某隻股票當天需要買入時,產生了某種定義的漲停狀態(比如一字漲停或者開盤漲幅超過9.8%),實際交易中大概率是買不到的,所以在回測中需要剔除該只股票。

(2)「買入時跌停狀態」:若某隻股票當天需要買入時,產生了某種定義的跌停狀態,實際交易中是不應該買的,所以在回測中需要剔除該只股票。

(3)「買入時停牌狀態」:若某隻股票當天需要買入時,當日停牌,這種情況可以設定一個時間參數N1,允許推遲買入,如果停牌交易天數超過N1,則剔除此股票。

(4)「賣出時漲停狀態」:若某隻股票當天需要賣出時,產生了某種定義的漲停狀態,這種情況可以設定一個時間參數N2,即延遲賣出,多持有幾天,以期再抓幾個漲停;若在延遲賣出N2天數內,發生了跌停或停牌狀態,則進行「賣出時跌停狀態」或「賣出時停牌狀態」處理方式(見下面)。

(5)「賣出時跌停狀態」: 若某隻股票當天需要賣出時,產生了某種定義的跌停狀態,則只能延遲賣出,一旦跌停打開就賣出;但若出現漲停狀態,則進入「賣出時漲停狀態」處理方式。

(6)「賣出時停牌狀態」: 若某隻股票當天需要賣出時,當日停牌,則只能延遲賣出,一旦復牌就賣出;但若出現復牌漲停狀態,則進入「賣出時漲停狀態」處理方式。

上面的處理方式僅作參考,且後面的(4)(5)(6)有一定的邏輯缺陷,即若一隻股票出現漲停、跌停、漲停、跌停或漲停、停牌、漲停、停牌等等幾種「變態」模式時,(4)(5)(6)會出現一定的邏輯死循環,但事實上上面的幾種「變態」模式,實際中幾乎不會出現,但為了避免這種死循環,可以適定一個持股時間閾值來跳出死循環。

績效指標Investment PerformancenMetrics模塊中,需要實現多種評價指標的計算,且圖形和數據可以自動保存至指定的文件夾,方便回測結果的後續查看對比。

還有其他一些細節的東西,比如回測BackTest Modular模塊中,需要給出一個AcountTotal來記錄整體組合的績效收益情況用來監控整體風險,還需要給出AcountSub來記錄初始股票池中每一隻股票的績效收益情況用來監控單一個股的風險。

手續費和衝擊成本的默認設置為:

手續費(包括印花稅等等)雙邊分別計算千分之一(即入場千分之一,離場千分之一);

衝擊成本雙邊分別計算1bp(即入場1bp,離場1bp)。

下面以一個動量策略為例,看下回測平台的實現結果。

測試策略:動量策略

策略簡介:按照過去LookBack(20)個交易日收益率排序,並且選擇前Snum(50)個的股票作為買入候選,調倉頻率RefreshRate(20)個交易日。

測試股票池:滬深300。

測試對比標的:000300.SH。

測試周期:2010年至今

測試代碼:

%% Main_FQBKT_Momentumn% 按照過去LookBack日收益率排序,並且選擇前Snum個的股票作為買入候選n% by LiYang_faruton% Email:farutoliyang@foxmail.comn% 2015/07/01n%% A Little Clean Workntic;n% clear;n% clc;n% close all;nformat compact;nn%% FQBKTnnfBKT = FQBKT();nn%% GetDatanrun = 1;nif 1 == runn fBKT.Benchmark = 000300.SH;n fBKT.Universe_Mode = 0;n fBKT.Universe = {HS300;};n Flag = 0;n [PoolFileStr,BenmarkFileStr] = fBKT.SaveData2Local(Flag);n n load(PoolFileStr);n load(BenmarkFileStr);nendn%% 參數設置nnfBKT.ParaStra_StraName = 測試策略-Momentum;nn% % 離場模式參數選擇n% 0 RefreshRate通過定期調倉離場n% 1 使用InputSignal自帶的離場信號離場n% InputSignal:1-做多;-1-做空;0-空倉nnfBKT.Exist_Mode = 1;nnfBKT.isDebug = 1;nn% 初始資金nfBKT.Capital_base = 1e6;nfBKT.RiskFreeRate = 4e-2;nn% 調倉頻率nfBKT.RefreshRate = 20;nfBKT.StockNumMax = 50;nnfBKT.SimPara_SusDayMax = 5;nfBKT.SimPara_SellUpLimitDayOffset = 10;nn%% 數據清洗、時間軸對齊nfBKT.StartDateTest = 20100101;nn[tStockData,tBenchmarkData] = ...n fBKT.DataCleanCalibration(StockDataRaw,BenchmarkData);nn%% 初始交易信號生成nnfBKT.isPlot = 0;nnPara.LookBack = 20;nPara.Snum = fBKT.StockNumMax;nnTSignal = fBKT.SignalMomentum(tStockData, Para);nn%% 進行回測nn% % 離場模式參數選擇nfBKT.Exist_Mode = 0nn% 調倉頻率nfBKT.RefreshRate = 20;nnfBKT.ParaStra_StraName = [測試策略-Momentum-LookBack,num2str(Para.LookBack), ...n Hold,num2str(fBKT.RefreshRate),-,fBKT.StartDateTest,-,fBKT.EndDateTest];nnInputSignal = TSignal;nInputStockData = tStockData;nInputBenchmarkData = tBenchmarkData;nnbktTradeStat = ...n fBKT.BackTest(InputSignal,InputStockData,InputBenchmarkData);nn%% 回測報告生成nfBKT.isPlot = 1;nfBKT.isSave = 0;nn% fBKT.XDateFormat = DateTime;nfBKT.XDateFormat = PureDouble;nnbktReport = fBKT.Report(bktTradeStat);nn%% Record Timentoc;ndisplayEndOfDemoMessage(mfilename);n

測試結果:

整體的測試結果的圖片和數據會自動保存至FQReport文件夾內按照策略名字生成的一個文件夾內:

通過可以看到動量因子還是蠻有效的,但每一個因子都有其輪動周期和強弱區間,動量因子也不例外,在其局部失效期,動量因子整體的回測也是挺大的。

至此本篇結束,大致介紹了股票策略回測的框架、實現細節,並用一個動量策略為例展示了回測平台的實現結果。

推薦閱讀:

大數據指數對比分析

TAG:FQuantStudio |