股指期貨高頻數據機器學習預測

更多精彩內容,歡迎關注公衆號:數量技術宅。想要獲取本期分享的完整策略代碼,請加技術宅微信:sljsz01html

問題描述

經過對交易委託帳本(訂單簿)中數據的學習,給定特定一隻股票10個時間點股票的訂單簿信息,預測下20個時間點中間價的均值。node

評價標準爲均方根偏差。算法

交易時間爲工做日9:30-11:30,13:00-15:00,快照頻率3秒。數組

股價的造成分爲集合競價和連續競價– 集合競價:9:15-9:25,開盤集合競價,肯定開盤價微信

– 連續競價:9:30以後,根據買賣雙方的委託造成的價格網絡

競價原則:價格優先,時間優先。app

交易委託帳本具體信息:– Date - 日期– Time - 時間– MidPrice - 中間價(買入價與賣出價的平均值)– LastPirce - 最新成交價– Volume - 當日累計成交數量– BidPrice1 - 申買最高價– BidVolume1 - 申買最高價對應的量– AskPrice1 - 申賣最高價框架

– AskVolume1 - 申賣最高價對應的量dom

問題分析

在這個問題中,咱們利用10個時間點股票的訂單簿信息,預測特定一隻股票下20個時間點中間價的均值,來判斷其在一分鐘內的價格變化特徵,以便於高頻交易。高頻交易的意義在於,對於人類來講,很難在一分鐘以內判斷出股價變化狀況,並完成交易。所以,只能利用計算機進行自動化交易。對於無信息無模型預測,即利用訂單簿中最後一個價格「預測」,獲得的均方根偏差爲0.00155。試圖經過分析數據、創建模型,作出高於此偏差的預測。機器學習

數據分析

數據集

訓練集(raw training data,train_data.csv):430039條訂單簿信息測試集(test data, test_data.csv):1000條(100組)訂單簿信息爲了不概念的混淆,下文中若是特別說明,「測試集」均指public board所依賴的數據。此外,這裏的「訓練集」下文中包含通過數據清理和預處理的訓練集(training data)和驗證集(development data)。

數據清洗

爲了將訓練集轉換爲測試集的格式,即經過10個間隔3秒的訂單簿記錄,來預測後20個間隔3秒的訂單簿記錄中中間價的均值,必須對數據清洗。將訓練集集中連續的nGiven+(nPredict平方)條數據做爲一組數據。

檢查每一組數據,去掉含有時間差不爲3秒的連續兩條數據的組。這樣能夠跳過跨天的以及不規整的數據。

數據預處理

歸一化

給定的數據特徵(日期、時間、價格、成交量等)的量綱不一樣,而且數據絕對值差的較大。如測試集第一條數據:

MidPrice和Volume差6個數量級。首先,數據歸一化後,最優解的尋優過程明顯會變得平緩,更容易正確地收斂到最優解。其次,在支持向量機(SVM)等不具備伸縮不變性的模型中,大數量級的數據會掩蓋小數量級的數據。這是由於隨機進行初始化後,各個數據擁有一樣的或近似的縮放比例,相加以後小數量級的數據便被大數量級的數據「吃掉了」。此外,對於具備伸縮不變性的模型,如邏輯迴歸,進行歸一化也有助於模型更快地收斂。綜上所述,對模型進行歸一化是十分有必要的。

Prices

訓練集MidPrice分佈:

 

測試集MidPrice分佈:

 

從上面兩張圖片中能夠看出,訓練集和測試集中最重要的特徵以及待遇測量——中間價只有約三分之一重合。這意味着若是按照數值直接進行歸一化,可能會有較差的結果。

我採起的第一種方式是預測差值——+即每組數據待預測量——下20條數組中MidPrice的均值與最後一個MidPrice的差值,並將各個價格減去最後一個MidPriced的值,這樣可使訓練集和驗證集分佈更爲接近,可是這樣形成的問題是,在量綱存在的狀況下,最後一個MidPriced的值還是有價值的,將它直接消去不合適。

第二種方式是徹底消除量綱,將預測任務變爲變化率的預測。即將全部與Price相關的變量都減去併除以最後一條數組的中間價。這樣就能夠將量綱徹底消除。

last_mp = x_cur[nGiven-1,0]
for axis in [0,1,3,5]: # MidPrice, LastPrice, BidPrice1, AskPrice1
    x_cur[:,axis] -= last_mp
    x_cur[:,axis] /= last_mp
...
y.append((sum(mid_price[k+nGiven:k+nGiven+nPredict])/
  nPredict-mid_price[k+nGiven-1])/mid_price[k+nGiven-1])

Volume

Volume是指當日累計成交數量。在每組數據中,Volume的大小差異很大,這主要是由於每組數據開始的時間不一樣。開始,我試圖保留時間信息和Volume,來更好地利用Volume信息。事實上,雖然一天中的Volume是相關的,可是幾乎不可能經過時間信息來估計Volume,況且高頻交易簿的精度很高。所以,經過加入時間信息避免對Volume的歸一化是不可行的。

第二個嘗試是利用相似於對Prices的處理,將每組數據中的Volume減去該組數據中第一條數據的Volume。但這樣效果並很差,這是由於Volume在一組中是遞增的,將它們進行如上處理後還是遞增的,利用普通的歸一化手段沒法將它們映射在同一尺度上。

第三種嘗試是利用變化量。將每一組Volume數據減去上一條信息的Volume,將這個特徵轉化爲:3秒內累計成交數量。至此,每組/條數據的Volume便爲同一分佈了。此外,對於第一條數據,沒有辦法得知它與上一條數據(沒有給出)的差值,只能用均值填充。具體方法是利用迄「今」(這條數據)爲止獲得的Volume插值的均值。

for i in range(9,0,-1):
    x_cur[i,2]-=x_cur[i-1,2]
    volume_sum+=x_cur[i,2]
    volume_len+=1
x_cur[0,2]=volume_sum/volume_len

時間信息

因爲時間是遞增的,能夠經過將它們映射在每一天(即,刪除日期,保留時間),而後進行預測。可是因爲數據只有約120天,將它們映射在每個時間點會致使這部分數據過於稀疏。所以,在保證每組數據中,每連續兩條數據的時間差值爲3秒的狀況下,能夠直接將時間信息刪除。

此外,我發如今多種模型的實驗中,是否將時間信息加入並不會有太大的改變。

對於預測值的處理

在前文中提到過,將預測數值任務改變爲預測變化率的任務。這樣作除了爲了消除量綱,更主要的緣由是加快收斂。若果不進行這樣的處理,對於CNN/DNN/RNN等基於神經網絡的模型,須要大約20epoch才能收斂到baseline RMSE=0.00155,可是若是採起變化率預測,只須要一個epoch就能夠收斂到RMSE=0.00149.4

所以,若是不進行這樣的處理,將會極度增長訓練的時間,對調參和模型分析形成很大困難。

噪聲

加入噪聲。對於某些數據而言——尤爲是Price相關的數據,因爲有不少組相同或類似的數組以及線性映射的不變性,致使處理後結果是離散的。所以,我在每一個值中加入±1%的噪聲,以提升模型的泛化能力。

下降噪聲。在固定模型的狀況下,我發現改變任務爲預測下15條數據的中間價均值,亦或是下10條數據的中間價均值,獲得的leaderboard成績要優於預測下20條的數據的中間價均值。我想這是由於經過跨度爲30秒的10條數據可能沒法預測到更遠的時間點,如跨度爲60秒的20條數據中的後幾條數據。在沒有更多信息的狀況下,極可能以後的數值對於預測來講是噪聲。在實驗中也證實了這一點,後文將會詳細說明。在下文中將這個nPredict「超參數」視爲MN(Magic Number)。

模型探索

基於LSTM的RNN模型

這個模型是我所實現最優的模型,採起這個模型的主要緣由是基於LSTM的RNN模型具備很好的處理時間序列的能力。

遞歸神經網絡(RNN)

循環神經網絡(Recurrent Neural Network,RNN)是一類具備短時間記憶能力的神經網絡。在循環神經網絡中,神經元不但能夠接受其它神經元的信息,也能夠接受自身的信息,造成具備環路的網絡結構。和前饋神經網絡相比,循環神經網絡更加符合生物神經網絡的結構。循環神經網絡已經被普遍應用在語音識別、語言模型以及天然語言生成等任務上。循環神經網絡的參數學習能夠經過隨時間反向傳播算法 [Werbos, 1990] 來學習。隨時間反向傳播算法即按照時間的逆序將錯誤信息一步步地往前傳遞。當輸入序列比較長時,會存在梯度爆炸和消失問題[Bengio et al., 1994, Hochreiter and Schmidhuber, 1997, Hochreiteret al., 2001],也稱爲長期依賴問題。爲了解決這個問題,人們對循環神經網絡進行了不少的改進,其中最有效的改進方式引入門控機制。

長短時間記憶(LSTM)網絡

長短時間記憶(long short-term memory,LSTM)網絡 [Gers et al., 2000, Hochreiter and Schmidhuber, 1997]是循環神經網絡的一個變體,能夠有效地解 決簡單循環神經網絡的梯度爆炸或消失問題。在公式(6.48)的基礎上,LSTM網絡主要改進在如下兩個方面:新的內部狀態 LSTM網絡引入一個新的內部狀態(internal state)ct專門進行線性的循環信息傳遞,同時(非線性)輸出信息給隱藏層的外部狀態ht。
在每一個時刻t,LSTM網絡的內部狀態ct記錄了到當前時刻爲止的歷史信息。
循環神經網絡中的隱狀態h存儲了歷史信息,能夠看做是一種記憶(memory)。在簡單循環網絡中,隱狀態每一個時刻都會被重寫,所以能夠看做是一種短時間記憶(short-term memory)。在神經網絡中,長期記憶(long-term memory)能夠看做是網絡參數,隱含了從訓練數據中學到的經驗,並更新週期要遠遠慢於短時間記憶。而在LSTM網絡中,記憶單元c能夠在某個時刻捕捉到某個關鍵信息,並有能力將此關鍵信息保存必定的時間間隔。記憶單元c中保存信息的生命週期要長於短時間記憶h,但又遠遠短於長期記憶,所以稱爲長的短時間記憶(long short-term memory)

 

 

模型實現

利用Keras框架,實現基於LSTM的RNN模型。具體結構爲兩層LSTM網絡和兩層Dense層網絡。試圖利用LSTM網絡提取時間序列中的特徵信息,並利用Dense層將提取出的特徵信息進行迴歸。

model = Sequential()
model.add(LSTM(input_shape=(None, nFeature),activation='softsign',dropout=0.5, units=256, return_sequences=True))
model.add(LSTM(units=256,activation='softsign',dropout=0.5, return_sequences=False))
model.add(Dense(64,kernel_initializer="glorot_normal",activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1,kernel_initializer="uniform",activation='linear'))
model.compile(loss='mean_squared_error', optimizer='Adam')

在這個較大的模型中,爲了防止過擬合訓練集和驗證集,我採起了如下的措施:

在全鏈接(Dense)層和LSTM層中,加入Dropout。在訓練中,dropout掉近似50%的參數,能夠將網絡模型減少至一半。在實驗發現,減少至該網絡一半的網絡更不容易出現過擬合的狀況(下文中會詳細說明)。

提早結束訓練(Early-stopping)。在兩個相同的網絡中,改變MN(即nPredict)的值,獲得以下的測試集RMSE~epochs。因而可知,Early-stopping是很是有必要的。

 

注:MN=20的一樣模型RMSE最好達到0.00148。

參數調整

我沒有進行大規模的網格搜索以肯定最好的超參數,我主要調整了網絡的規模。基本想法是先選擇一個較大的網絡,訓練至過擬合,判斷其有足夠擬合數據的能力,而後減少網絡規模或進行正則化,消除過擬合以保留足夠的泛化能力。

大網絡(units = 256):

 

中網絡(units = 128):

 

小網絡(units = 64):

 

在實驗中發現,三個網絡均會產生過擬合的問題。可是很明顯小網絡的擬合能力不足(在更大的RSME開始出現過擬合),而大網絡的擬合能力極其嚴重。因而我選擇了中網絡規模的網絡——大網絡+50%dropout。

卷積神經網絡

採起這個模型的主要緣由是卷積神經網絡模型能夠經過共享(1,nFeature)卷積覈減小參數,並將一組中每條數據進行一樣地處理。

卷積神經網絡由一個或多個卷積層和頂端的全連通層(對應經典的神經網絡)組成,同時也包括關聯權重和池化層(pooling layer)。這一結構使得卷積神經網絡可以利用輸入數據的二維結構。與其餘深度學習結構相比,卷積神經網絡在圖像和語音識別方面可以給出更好的結果。這一模型也可使用反向傳播算法進行訓練。相比較其餘深度、前饋神經網絡,卷積神經網絡須要考量的參數更少,使之成爲一種頗具吸引力的深度學習結構。

 

 

模型實現

利用Keras框架,實現卷積神經網絡模型。具體結構爲兩層卷積網絡和三層Dense層網絡。其中兩層卷積網絡分別爲1 ∗ 7卷積核和10 ∗ 1卷積核。

model = Sequential()
model.add(Conv2D(input_shape=(10,7,1),filters = 256, kernel_size = (1,7), strides=(1, 1), padding='valid',activation='relu'))
model.add(Dropout(0.5))
model.add(Conv2D(filters = 256, kernel_size = (10,1), strides=(1, 1), padding='valid',activation='relu'))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(512,kernel_initializer="glorot_normal",activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(256,kernel_initializer="glorot_normal",activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1,kernel_initializer="uniform",activation='linear'))
model.compile(loss='mean_squared_error', optimizer='Adam')

全連接的神經網絡模型

神經網絡模型的主要優勢是具備極強的近似能力:模型能夠以任意精度擬合一切連續函數。同時,進行這個模型的嘗試,也能夠判斷卷積神經網絡是否比樸素的全連接神經網絡模型更好。

人工神經網絡(英語:Artificial Neural Network,ANN),簡稱神經網絡(Neural Network,NN)或類神經網絡,在機器學習和認知科學領域,是一種模仿生物神經網絡(動物的中樞神經系統,特別是大腦)的結構和功能的數學模型或計算模型,用於對函數進行估計或近似。神經網絡由大量的人工神經元聯結進行計算。大多數狀況下人工神經網絡能在外界信息的基礎上改變內部結構,是一種自適應系統,通俗的講就是具有學習功能。現代神經網絡是一種非線性統計性數據建模工具。

 

模型實現

利用Keras框架,實現卷積神經網絡模型。具體結構爲兩層卷積網絡和三層Dense層網絡。其中兩層卷積網絡分別爲1 ∗ 7卷積核和10 ∗ 1卷積核。

model = Sequential()
model.add(Flatten(input_shape=(10,7,1)))
model.add(Dense(1024,kernel_initializer="glorot_normal",activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(512,kernel_initializer="glorot_normal",activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(256,kernel_initializer="glorot_normal",activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1,kernel_initializer="uniform",activation='linear'))
model.compile(loss='mean_squared_error', optimizer='Adam')

利用XGBoost建立的模型

XGBoost介紹

XGBoost表明「Extreme Gradient Boosting」,其中術語「Gradient Boosting」源於弗裏德曼的貪婪函數逼近:梯度加強機。

XGBoost實質上是Gradient boosting Decision Tree(GBDT)的高效實現,若是使用最經常使用gbtree做爲學習器,那麼它基本至關於CART分類樹。CART分類迴歸樹是一種典型的二叉決策樹,能夠作分類或者回歸。若是待預測結果是離散型數據,則CART生成分類決策樹;若是待預測結果是連續型數據,則CART生成迴歸決策樹。數據對象的屬性特徵爲離散型或連續型,並非區別分類樹與迴歸樹的標準,例如表1中,數據對象xixi的屬性A、B爲離散型或連續型,並是不區別分類樹與迴歸樹的標準。做爲分類決策樹時,待預測樣本落至某一葉子節點,則輸出該葉子節點中全部樣本所屬類別最多的那一類(即葉子節點中的樣本可能不是屬於同一個類別,則多數爲主);做爲迴歸決策樹時,待預測樣本落至某一葉子節點,則輸出該葉子節點中全部樣本的均值。

模型實現

利用xgboost庫,實現XGB模型。

from xgboost import XGBRegressor
from sklearn.model_selection import GridSearchCV
cv_params = {'n_estimators': [600,800,1000,1200,1400,1600]}
other_params = {'learning_rate': 0.1, 'n_estimators': 100, 'max_depth': 4, 'min_child_weight': 5, 'seed': 0,
                    'subsample': 0.6, 'colsample_bytree': 0.9, 'gamma': 0.4, 'reg_alpha': 0, 'reg_lambda': 1}
model = XGBRegressor(**other_params)
optimized_GBM = GridSearchCV(estimator=model, param_grid=cv_params,
                             scoring='neg_mean_squared_error', cv=3, verbose=3, n_jobs=5)
optimized_GBM.fit(X_train_70, y_train)

參數調整

利用上述GridSearchCV函數以及相似於Gibbs採樣算法的思想,逐步調整參數。具體方法爲:首先設置每一個參數的取值區間。而後選取某個參數,將其設置爲取值區間中等間距的幾個點,進行訓練模型進行驗證,將最好的點設置爲這個參數的值,而後選取其餘參數,重複這一步,直到參數穩定。但實驗中,因爲過擬合狀況嚴重,n_estimators越大會致使近似狀況更好,但同時會致使模型的泛化能力下降。因而我經過提交結果,選定了n_estimator=200。而後調整其餘參數。

隨機迴歸森林模型

簡單來講,隨機森林就是多個迴歸樹的融合。隨機森林的優點在於

1.在沒有驗證數據集的時候,能夠計算袋外預測偏差(生成樹時沒有用到的樣本點所對應的類別可由生成的樹估計,與其真實類別比較便可獲得袋外預測)。
2.隨機森林能夠計算變量的重要性。
3.計算不一樣數據點之間的距離,從而進行非監督分類。

模型實現

利用sklearn庫提供的RandomForestRegressor。

from sklearn.ensemble import RandomForestRegressor
clf = RandomForestRegressor(
    oob_score = True,
    max_depth = 20,
    min_samples_split=20,
    min_samples_leaf=10,
    n_estimators=20,
    random_state=0,
    verbose=3)
clf.fit(X_train.reshape(-1,70),y_train.reshape((-1,)))

結果與討論

model public leader board score

*private leader board = 0.00140

討論:模型CNN vs DNN。利用卷積沒有取得更好的結果,這很大緣由是數據特徵只有7維,沒有必要進行降維,所以CNN模型中的池化層(Pooling Layer)沒法使用,下降了卷積模型能力。DNN vs RNN。RNN在epoch = 20開始lb = 0.00149,而DNN在較長區間[4,30+] epoches 中一直保持lb = 0.00148,這說明了RNN有更好的擬合時間序列的能力,但一樣有着更差的擬合能力,所以必須進行early-stopping防止過擬合。XGB。XGB有着很好的數據擬合能力,但因爲調參須要較多的時間(每一個模型擬合須要約40分鐘),而我沒有足夠的計算資源,只能放棄更細粒度的調參。

Random Forest。和XGB相似,它們對於多維數據的處理可能會比神經網絡模型更好,可是在7維的數據中,表現並不如神經網絡模型。

討論:模型以外特徵工程的重要性遠遠超過模型的選取以及調參。在最初的嘗試中,我只是簡單的進行了數據歸一化,獲得的結果並不理想,不少次訓練的RNN模型有RMSE>0.00155的狀況。在認真探索每一個數據特徵的意義並根據它們的意義進行數據處理後,採起的模型幾乎所有RMSE<0.00150。我想,思考特徵的特色並思考如何利用是十分關鍵的。畢竟說白了,這些模型只是泛用函數擬合器。將來的工做豐富訂單簿信息。能夠得到AskPrice2, AskPrice3,… 以及AskVolumn2,AskVolumn3等豐富信息。採起更多的輸入時間點。畢竟過去的數據是「免費」的,咱們能夠採用如過去一分鐘的數據進行預測。但可能結果和MN的狀況同樣——再多的數據只是噪聲。豐富數據集。用更多股票和更長時間的數據。RNN模型的泛化能力沒有被徹底利用,我想經過更多的數據能夠達到更好的效果。嘗試XGboost的精細調參。

模型融合。如XGBoost+LightGBM+LSTM。

若是你想要本次分享Pine語言策略的文本代碼,歡迎加小編微信,與我交流。

 


往期乾貨分享推薦閱讀

如何使用TradingView(TV)回測數字貨幣交易策略

如何投資股票型基金?什麼時間買?買什麼?

【數量技術宅|量化投資策略系列分享】基於指數移動平均的股指期貨交易策略

AMA指標原做者Perry Kaufman 100+套交易策略源碼分享

【 數量技術宅 | 期權系列分享】期權策略的「獨孤九劍」

【數量技術宅|金融數據系列分享】套利策略的價差序列計算,恐怕沒有你想的那麼簡單

【數量技術宅|量化投資策略系列分享】成熟交易者期貨持倉跟隨策略

如何獲取免費的數字貨幣歷史數據

【數量技術宅|量化投資策略系列分享】多週期共振交易策略

【數量技術宅|金融數據分析系列分享】爲何中證500(IC)是最適合長期作多的指數

商品現貨數據很差拿?商品季節性難跟蹤?一鍵解決沒煩惱的Python爬蟲分享

【數量技術宅|金融數據分析系列分享】如何正確抄底商品期貨、大宗商品

【數量技術宅|量化投資策略系列分享】股指期貨IF分鐘波動率統計策略

【數量技術宅 | Python爬蟲系列分享】實時監控股市重大公告的Python爬蟲

相關文章
相關標籤/搜索