[提要]
隨着人工智能技術的快速發展, 深度學習,強化學習等技術不斷進入各行各業。金融領域也不例外,利用深度學習進行
大數據挖掘,分析客戶的畫像,提供對應的金融服務已經在現實中使用。 在金融交易領域其中一個分支量化交易(金融工程)
采用相關的人工智能技術,必將大勢所趨。 本文主要是針對證券期貨交易的量化交易采用深度神經,卷積神經網絡在交易
信號選取的一個落地應用。 深度學習和金融工程都是屬於高精尖專業, 不足,不周之處,請勘正。
關鍵詞:金融工程, 量化交易,深度學習,卷積神經網絡,VGG
[引言,背景]
在量化交易系統中, 一般系統分為三個部分: 交易信號(模式識別), 持倉控制, 資金管理。 交易信號指的是,在
什么時間點,買入什么股票(本文均已股票二級市場,且為散戶的角度做說明)。 持倉控制是指, 在買入股票后,根據
后期的股票走勢進行,加倉,減倉,平倉等操作。 而資金管理,是對許多交易策略進行資金分配,用來保證資金在固定時
間周期內達到最低的風險和最大的收益平衡。 下文是利用卷積神經網絡對交易信號的識別。
[正文]
人類識別股票行情的方式是直觀的,擬態的, 比如多根均線向上, 均線交叉,多根陽線,多根陰線等。 傳統的量化交易
把這些抽象的圖提取成數學數據, 再用條件判斷,形成信號。再利用統計學,統計后期的收益情況來分析信號的性能(准確率)。
在深度學習領域里, AI已經能高概率的識別數字, 圖像內容。 那人工智能是否能(依靠圖像感知,而非數據的表示)識別,讀
懂金融的k線, 折線呢?答案是肯定的。
(以下試驗論述會有較多多的神經網絡和編程術語)
我們將一個股票的當天分時線提取成 48 個5分鍾的k線,再根據k線繪制成圖像。 如下:
我們將日內走勢分型, 暫分為: 橫盤震盪, 上行, 下行, V形, A形, 例如:
我們根據2017年上半年實際滬深行情, 制作了40多萬個日內圖, 並對其中10萬個圖進行了,機器+人工標識。 我們得到了10萬個訓練/測試數據。
數據內容 : 480x480 分辨率的圖片 + 對應的分型標識(0,1,2,3,4 )
我們的試驗內容:把10萬個數據扔給卷積神經網絡進行訓練; 用另外的 1000 個數據進行測試(測試數據不參與訓練)。 試驗結果: VGG 卷積神經網絡
的准確為:94%(尚未調優)。 (實際實驗數據目前為 48000 )
在試驗過程中,我們碰到許多問題, 把這些問題也簡單的羅列一下,以便再研究深度學習的同學,同行,不再踩坑。
A. 內存溢出: 剛開始采用 480x480,3 的數據, 直接顯卡內存不夠 (out of memory )。 解決方法:調成 240x240,1
B. 訓練時間過長: 48000 個數據,1輪學習 需要 4個小時左右, 如果整個 30輪, 那還不瘋掉,需要等個4,5天才知道結果。
解決辦法:
1). 降低數據維度 480->240->120->28 ,
2). 放大卷積核 3x3 ->5x5->7x7 , 從文件讀取 --- > 一次讀入內存再訓練
C. 梯度不下降: 這個是做深度學習最要命的問題。
解決辦法:
1. 變更模型,調超參數;
2.圖像變換(裁剪成核心數據圖片), 圖像反色, 圖像歸1(0~1)
最后效率和結果: 45000 個圖片。 圖像縮小到 28x28。 20分鍾左右,跑完一次訓練/預測。
遺留問題:
圖像縮小是否會影響判斷的准確率?這個問題需要在細化求精的過程中,反復試驗驗證了。
准確率是否能提高,我相信肯定能提高。 ( 我會在最后開源代碼和數據,有興趣的朋友可以用更牛x的網絡模型,提升准確率。如能提高希望能在blog留言 )
[用途,意義]
1. 機器可以根據人的前期指導, 學會判別走勢形態。有別於傳統的數值分類統計的判別。判別的結果是一個可能性,比如80%,而傳統的為1,0.
2. 可以根據我上述論文的原理進行特定模型學習。 參考建議: 把特征進行二分類, 包含有你特征的圖片定義為1, 其它圖形為0; 進行訓練學習。以此得到模型識別器
3. 對於量化交易系統行業是一次革命性的提升, 因為它具有更強的泛化性。 它的使用可以使程序開發人員和策略開發人員 一定的程度的分開。 策略師不再依靠程序員一個思路一個思路編寫一個程序(指標)。 着一點對於 大智慧/通達信 提供神經網絡機構版,是一個相當不錯的思路。 機構策略開發變成了,不斷選取入場點。 (還有一個在期貨交易上也有貌似不錯的點子)
[總結]
深度神經網絡(卷積神經 CNN) 在量化交易里的模式(圖形)識別效果較好。 相信不久的將來, 深度神經網絡的相關技術會不斷進入金融工程(量化交易)
這個領域。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
代碼:
導入相關庫
# -*- coding: UTF-8 -*- print(__doc__) ''' author : hylas date:2017/8/19 discp: 用cnn給證券的行情進行分類, 未來用來識別當天的行情或者檢測某個特殊的特征模型 ''' import sys import os import time from keras.utils import np_utils import numpy as np from keras.models import Sequential from keras.layers import Dense, Dropout import numpy as np import PIL.Image as Image import keras from keras.layers import Conv2D, MaxPooling2D from keras.optimizers import SGD from keras.models import load_model from keras.layers import Dense, Dropout, Flatten from keras.utils import np_utils pngRootPath ='/home/hylas/dev/data/min5_png/' imgWidth =480 imgHeitht =480 nWidth = 28 nHeight = 28 nCannle = 1 input_dim = (nWidth, nHeight, nCannle ) # 卷積層中使用的卷積核的個數 nb_filters = 32 # 卷積核的大小 kernel_size = (3, 3) # 池化層操作的范圍 pool_size = (2, 2) nEpochs = 20 batch_size = 32 samples_per_epoch= 48000 #samples_per_epoch= 9600
網絡模型
# 類似VGG的卷積神經網絡: Conv2D --> Conv2D --> MaxPooling2D --> Conv2D --> Conv2D --> MaxPooling2D # --> Flatten -->Dense(256) -->Dense(10) def BuildMode_VGG(): print 'input_dim:', input_dim model = Sequential() model.add(Conv2D(nb_filters , kernel_size, activation='relu', input_shape= input_dim )) model.add(Conv2D(nb_filters , kernel_size, activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Conv2D( nb_filters*2 , kernel_size, activation='relu')) model.add(Conv2D( nb_filters*2 , kernel_size, activation='relu')) model.add(MaxPooling2D(pool_size= pool_size )) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(256, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(5, activation='softmax')) print model.summary() #return sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) model.compile(loss='categorical_crossentropy', optimizer=sgd) return model
訓練神經網絡及測試神經網絡
def do2_fit_mem(): t = time.time() #X,y = generate2mem( 'png_file_list.csv', samples_per_epoch) X, y = loaddatafromdisk() print type(X), type(y) print X.shape , y.shape print 'time:' , time.time() - t model = BuildMode_VGG() #print generate_arrays_from_file('png_file_list.csv', batch_size ) model.fit( X,y, batch_size, nb_epoch= nEpochs, verbose=1 , validation_split=0.10 ) model.save('stock_vgg2_'+ time.strftime('vgg2_%Y-%m-%d-%X', time.localtime()) +'.h5') x_test=X[:1000] y_test=y[:1000] x_test, y_test = loadtestdatafromdisk() testModle(model, x_test, y_test, batch_size= batch_size )
其它代碼:
def loaddatafromdisk(): data = np.loadtxt('data_table_' + str(samples_per_epoch) + '_x.txt' ) print 'from:', data.shape data = data.reshape( (samples_per_epoch, 28,28,1) ) print 'to:', data.shape y = np.loadtxt('data_table_' + str(samples_per_epoch) + '_y.txt' ) return data,y def loadtestdatafromdisk(): data = np.loadtxt('data_table_test_x.txt' ) print 'from:', data.shape data = data.reshape( (1000, 28,28,1) ) print 'to:', data.shape y = np.loadtxt('data_table_test_y.txt' ) return data,y def testModle(model, x_test ,y_test, batch_size= 32 ): y_pret= model.predict(x_test , batch_size= batch_size ) y_pret[0] = y_pret[0] / y_pret[0].max() y_pret[0][(y_pret[0] != y_pret[0].max() ) ] = 0 print y_pret[0] y_pret_ex = y_pret.copy() for i in range(0, len( y_pret ) ): y_pret_ex[i] = y_pret_ex[i] / y_pret_ex[i].max() y_pret_ex[i][(y_pret_ex[i] != y_pret_ex[i].max())] = 0 print '------------------------------------' #print y_pret_ex[:10] #print y_pret[:10] test_accuracy = np.mean(np.equal(y_test, y_pret_ex)) print("accuarcy:", test_accuracy) def test(): do2_fit_mem() pass if __name__ == "__main__": sys_code_type = sys.getfilesystemencoding() test()
代碼補充說明:
代碼文件: 一份為最終整理代碼, 一份包含調測過程,圖片處理可做參考。
相關截圖:
網絡模型參數
訓練過程
預測分類成績:
數據下載:
下載 http://pan.baidu.com/s/1mifxQNu
個人群: 杭州程序化交易群 375129936