選自Medium
參與:黃小天、路雪
近日,Medium 上出現了一篇題為《Neural networks for algorithmic trading: enhancing classic strategies》的文章,作者Alex Honchar在文章中通過一個實際預測用例總結了金融時序預測,使用神經網絡真正改善了經典的移動平均線策略,提高了最終預測結果。
在之前的5 篇教程中,我們討論了用於金融預測的人工神經網絡,比較金融時序預測的不同架構,意識到如何通過正確的數據處理和正則化實現充分的預測,執行基於多變量時序的預測,並取得了非常好的波動率(volatility)預測結果,以及自定義損失函數的實現。在第 6 篇教程中,我們藉助不同來源的數據進行設置和實驗,用一個神經網絡完成兩個任務,優化超參數從而實現更優預測。
今天,我想藉助一個實際的預測用例,對金融時序預測做個總結:我們將使用神經網絡改善經典的移動平均線策略,證明它可以真正提升最後的結果,並介紹了一些大家可能感興趣的新的預測目標。
以下是之前的 6 篇教程:
你可以在 Github 查看神經網絡訓練的代碼: https://github.com/Rachnog/Deep-Trading/blob/master/strategy/skew.py。
主要內容
如上所述,我們能夠預測完全不同的值,從股價變化到波動率。過去我們把這些預測看作是抽象的,甚至試圖僅根據這些「上下」變動的預測進行交易。但是我們也知道,存在基於技術分析和金融指標的其他大量交易策略。比如,我們可以建立不同窗口的移動平均線(一個是長線,比如說 30 天,另一個是短線,很可能是 14 天),我們認為交叉點即代表趨勢改變的時刻:
兩條移動平均線交叉的示例
但是這一交易策略有個主要的缺點:在平滑區域,我們依然在那些無實際變化的點上做交易,從而遭受金錢損失。
平滑區域中移動平均線交叉的示例
我們如何通過機器學習解決這一問題?
讓我們看看下面的策略假設:我們在移動平均線交叉處預測某些特徵的變化。如果出現一個跳躍,我們便將其作為交易信號;否則就跳過它,因為我們不想在平滑區域損失錢。
我想嘗試把偏度(skewness)作為預測目標,偏度即度量分佈非對稱性的指標。假設我們預測分佈出現變化,這意味著當前的趨勢(不只是平滑區域)將在未來發生改變。
分佈偏度
輸入數據
這裡我們使用 pandas 和 PyTi 來生成更多指標,並將其作為輸入。我們將使用 MACD、Ichimocku cloud、RSI、波動率等。所有這些值將形成多變量時序,並逐漸變得平滑,以方便之後在 MLP 中使用,或者停留在 CNN/RNN。
nine_period_low = pd.rolling_min(pd.DataFrame(lowp), window= ROLLING / 2)
ichimoku = (nine_period_high + nine_period_low) /2
ichimoku = ichimoku.replace([np.inf, -np.inf], np.nan)
ichimoku = ichimoku.fillna(0.).values.tolist()
macd_indie = moving_average_convergence(pd.DataFrame(closep))
wpr = williams_percent_r(closep)
rsi = relative_strength_index(closep, ROLLING / 2)
volatility1 = pd.DataFrame(closep).rolling(ROLLING).std().values#.tolist()
volatility2 = pd.DataFrame(closep).rolling(ROLLING).var().values#.tolist()
volatility = volatility1 / volatility2
volatility = [v[0] forv in volatility]
rolling_skewness = pd.DataFrame(closep).rolling(ROLLING).skew().values
rolling_kurtosis = pd.DataFrame(closep).rolling(ROLLING).kurt().values
我把獲取的指標特徵和 OHLCV 元組串聯起來,以生成最終向量。
網絡架構
這裡,我想展示如何訓練正則化 MLP 用於時序預測:
main_input = Input(shape=(len(X[0]), ), name='main_input')
x = GaussianNoise(0.05)(main_input)
x = Dense(64, activation='relu')(x)
x = GaussianNoise(0.05)(x)
output = Dense(1, activation = "linear", name = "out")(x)
final_model = Model(inputs=[main_input], outputs=[output])
opt = Adam(lr=0.002)
final_model.compile(optimizer=opt, loss='mse')
這裡比較新奇的地方在於向輸入和神經網絡單個層的輸出中添加了小噪聲。這樣神經網絡的運行和 L2 正則化類似,其數學解釋請參見 https://www.deeplearningbook.org。
示例來自 http://www.deeplearningbook.org/contents/regularization.html
神經網絡按照常規方式進行訓練,我們來檢查一下偏度預測如何改善(不改善)移動平均線策略(moving averages strategy)。
我們基於2012 到2016 年的AAPL 價格訓練神經網絡,然後在2016-2017 年的數據上進行測試(測試教程: https://medium.com/machine-learning-world/neural-networks-for-algorithmic- trading-1-2-correct-time-series-forecasting-backtesting-9776bfd9e589)。
訓練完成後,我繪製了收盤價、移動平均線和交叉點處的垂直線:紅線和橙線是我們想要進行交易的點,綠線是我們不想進行交易的點。看起來並不完美,我們用回溯測試的方法來判斷。
哪一種移動平均線交叉(moving average intersection)有用?
未使用神經網絡的結果
我使用這篇文章( https://medium.com/machine-learning-world/neural-networks-for-algorithmic-trading-1-2-correct-time-series-forecasting-backtesting-9776bfd9e589)介紹的回溯測試方法進行操作,下面是一些關鍵度量和圖:
[(‘Total Return’, ‘1.66%’),
(‘Sharpe Ratio’, ‘16.27’),
(‘Max Drawdown’, ‘2.28%’),
(‘Drawdown Duration’, ‘204’)]
Signals: 9
Orders: 9
Fills: 9
滾動平均策略(rolling mean strategy)的回溯測試結果
使用神經網絡的結果
我們只使用「紅色」和「橙色」交易信號,跳過綠色交易信號。我們可以看到,這樣的策略少進行了 2 次交易,幫助我們稍微減少首次回落,且最終收益幾乎是原來的兩倍!
[(‘Total Return’, ‘3.07%’),
(‘Sharpe Ratio’, ‘27.99’),
(‘Max Drawdown’, ‘1.91%’),
(‘Drawdown Duration’, ‘102’)]
Signals: 7
Orders: 7
Fills: 7
使用神經網絡的策略的回溯測試結果
可能的改進
看起來這個想法有點作用呢!我還想介紹一些可能有效的改進,大家可以自己試一下:
不同的指標策略:MACD、RSI
將能夠極好優化的交易策略與提出的方法相結合
試著預測不同的時序特徵:赫斯特指數(Hurst exponent)、自相關係數(autocorrelation coefficient),或者其他的統計動差(statistical moment)
這篇文章介紹瞭如何使用神經網絡實現金融時序預測,也暫時完結了該系列教程。坦白講,我們無法使用神經網絡來預測價格趨勢。我們考慮不同的數據源和目標,認真處理過擬合和優化超參數。我們得出的結論是:
處理過擬合時要小心! 99% 的案例都需要處理過擬合,如果準確率達到 80% 就不要相信了,肯定是哪裡出錯了……
嘗試使用收盤價或收益以外的其他因素,比如波動率、偏度等。
如果你有不同的數據源,那就使用多模態學習。
不要忘記找出合適的超參數!
創建一個由多個經典策略組合而成的策略,並將其建立在機器學習之上,然後再進行回溯測試。