こんにちは、あんどう(@t_andou)です。
以前、日経平均の値動きをディープラーニングで予想するという記事を書きましたが、その記事の反応として「FXでやってほしい」というものを多く見かけましたので今回はディープラーニングでFXの値動き予想を試してみました。
初めに書いておきますが、今回の記事では大した成果は得られませんでした。
ですが、「どんなことをやってみてダメだったか」という記録として残しておきます。
学習させた環境
学習させた環境は下記です。
- ubuntu14.04
- GTX970
- メモリ16GB
- Keras
学習させたデータ
FXDDのサイトからUSD/JPYの1分足のデータを持ってきました。
全データではなく、2010年1月1日の10:00以降データを使いました。*1
教師ラベル
- 5分後に1pips以上下がっていたら「0」
- 5分後に1pips以上上がっていたら「1」
- 5分後が1pips以内の値動きだった場合のデータは削除(学習対象から除外)
としました。
教師ラベルをどう設定するかが最重要なのかなと思ってますが…ここについては最後にまとめで書きます。
ちなみに上の条件で教師ラベルをつけた結果
- 0(下がった):815670件
- 1(上がった):802863件
- 削除(変化なし):933793件
となりました。
この合計2552326件から
- 「変化なし」の場合
- 移動平均などが計算できない行(=先頭の方の行で、それより古い行が存在しない行)
を学習対象から除外した結果
- 下がった 815661件
- 上がった 802859件
となります。
ハイ・ローの割合を計算する
件数の多い「下がった」方の件数が815661件で合計が1618520件ですので、下がった割合は (815661/1618520)*100 = 50.39%
となります。
ですので、50.4%以上の正解率が出れば、ランダムで答えただけ・多い方を答えただけではなく、何かしらの特徴を学習したと考えることにします。*2
入力したデータ 説明変数
下記のパターンで試してみました。
- 過去25分の4本値とボリンジャーバンドの値
- 過去25分の前の終値からの値段の変化+ボリンジャーバンド
- 論文に書いてあるもの
- 使えるテクニカル指標全部
また、入力時に値を[0:1]に正規化したり、平均0で分散が1になるように標準化するべきということなのですが、どちらがいいのかわからなかったので、上記の各パターンで正規化・標準化を試してみました。
ネットワークの構造
ネットワークの構造を色々と変えてみましたが、結果はほとんど変わりませんでした。
最終的に使ったのはこんな感じです。(このモデルに根拠はありません。)
結果
以上の条件で色々と試してみました。
val_accと書かれている数字が最終的な正解率のようなものです。
1.時系列+ボリンジャーバンド
まずは過去25分の4本値と2σのボリンジャーバンドの値を入れてみました。
標準化
Epoch 99/100
1375742/1375742 [==============================] - 5s - loss: 0.6915 - acc: 0.5242 - val_loss: 0.6922 - val_acc: 0.5196
Epoch 100/100
1375742/1375742 [==============================] - 5s - loss: 0.6915 - acc: 0.5237 - val_loss: 0.6923 - val_acc: 0.5193
正規化
Epoch 99/100
1375742/1375742 [==============================] - 5s - loss: 0.6932 - acc: 0.5040 - val_loss: 0.6932 - val_acc: 0.5035
Epoch 100/100
1375742/1375742 [==============================] - 5s - loss: 0.6932 - acc: 0.5040 - val_loss: 0.6932 - val_acc: 0.5035
パターン1のまとめ
標準化の時は51.93%でしたが、正規化の時は全く学習しませんでした。
2.時系列の変化+ボリンジャーバンド
次に4本値ではなく、一つ前から見た値の変化とボリンジャーバンドを入れてみました。
標準化
Epoch 99/100
1375742/1375742 [==============================] - 5s - loss: 0.6903 - acc: 0.5342 - val_loss: 0.6921 - val_acc: 0.5263
Epoch 100/100
1375742/1375742 [==============================] - 5s - loss: 0.6904 - acc: 0.5345 - val_loss: 0.6920 - val_acc: 0.5249
正規化
Epoch 99/100
1375742/1375742 [==============================] - 5s - loss: 0.6932 - acc: 0.5040 - val_loss: 0.6932 - val_acc: 0.5035
Epoch 100/100
1375742/1375742 [==============================] - 5s - loss: 0.6932 - acc: 0.5040 - val_loss: 0.6932 - val_acc: 0.5035
パターン2のまとめ
こちらも正規化の時は全く学習してくれませんでした。標準化の時はパターン1よりは少しマシになっているようです。
3.論文にあるテクニカル指標
シストレプログラムで特徴量として利用しているテクニカル指標を整理してみた - Qiita
こちらの記事で紹介されているこの論文に書いてあるテクニカル指標を入れてみました。*3
標準化
Epoch 99/100
1375742/1375742 [==============================] - 3s - loss: 0.6891 - acc: 0.5394 - val_loss: 0.6912 - val_acc: 0.5295
Epoch 100/100
1375742/1375742 [==============================] - 3s - loss: 0.6891 - acc: 0.5392 - val_loss: 0.6912 - val_acc: 0.5307
正規化
Epoch 99/100
1375742/1375742 [==============================] - 3s - loss: 0.6897 - acc: 0.5369 - val_loss: 0.6911 - val_acc: 0.5292
Epoch 100/100
1375742/1375742 [==============================] - 3s - loss: 0.6897 - acc: 0.5367 - val_loss: 0.6912 - val_acc: 0.5272
パターン3のまとめ
53%まで上がりました。また、正規化の時でも予想をするようになったようです。
4.テクニカル指標を全部突っ込んでみた
PythonのTa-Libというライブラリで使えるテクニカル指標をとりあえず全部突っ込んでみました。
入れたのは下記のものです。
http://ta-lib.org/function.html
- AD Chaikin A/D Line
- ADOSC Chaikin A/D Oscillator
- ADX Average Directional Movement Index
- ADXR Average Directional Movement Index Rating
- APO Absolute Price Oscillator
- AROON Aroon
- AROONOSC Aroon Oscillator
- ATR Average True Range
- AVGPRICE Average Price
- BBANDS Bollinger Bands
- BETA Beta
- BOP Balance Of Power
- CCI Commodity Channel Index
- CDL2CROWS Two Crows
- CDL3BLACKCROWS Three Black Crows
- CDL3INSIDE Three Inside Up/Down
- CDL3LINESTRIKE Three-Line Strike
- CDL3OUTSIDE Three Outside Up/Down
- CDL3STARSINSOUTH Three Stars In The South
- CDL3WHITESOLDIERS Three Advancing White Soldiers
- CDLABANDONEDBABY Abandoned Baby
- CDLADVANCEBLOCK Advance Block
- CDLBELTHOLD Belt-hold
- CDLBREAKAWAY Breakaway
- CDLCLOSINGMARUBOZU Closing Marubozu
- CDLCONCEALBABYSWALL Concealing Baby Swallow
- CDLCOUNTERATTACK Counterattack
- CDLDARKCLOUDCOVER Dark Cloud Cover
- CDLDOJI Doji
- CDLDOJISTAR Doji Star
- CDLDRAGONFLYDOJI Dragonfly Doji
- CDLENGULFING Engulfing Pattern
- CDLEVENINGDOJISTAR Evening Doji Star
- CDLEVENINGSTAR Evening Star
- CDLGAPSIDESIDEWHITE Up/Down-gap side-by-side white lines
- CDLGRAVESTONEDOJI Gravestone Doji
- CDLHAMMER Hammer
- CDLHANGINGMAN Hanging Man
- CDLHARAMI Harami Pattern
- CDLHARAMICROSS Harami Cross Pattern
- CDLHIGHWAVE High-Wave Candle
- CDLHIKKAKE Hikkake Pattern
- CDLHIKKAKEMOD Modified Hikkake Pattern
- CDLHOMINGPIGEON Homing Pigeon
- CDLIDENTICAL3CROWS Identical Three Crows
- CDLINNECK In-Neck Pattern
- CDLINVERTEDHAMMER Inverted Hammer
- CDLKICKING Kicking
- CDLKICKINGBYLENGTH Kicking - bull/bear determined by the longer marubozu
- CDLLADDERBOTTOM Ladder Bottom
- CDLLONGLEGGEDDOJI Long Legged Doji
- CDLLONGLINE Long Line Candle
- CDLMARUBOZU Marubozu
- CDLMATCHINGLOW Matching Low
- CDLMATHOLD Mat Hold
- CDLMORNINGDOJISTAR Morning Doji Star
- CDLMORNINGSTAR Morning Star
- CDLONNECK On-Neck Pattern
- CDLPIERCING Piercing Pattern
- CDLRICKSHAWMAN Rickshaw Man
- CDLRISEFALL3METHODS Rising/Falling Three Methods
- CDLSEPARATINGLINES Separating Lines
- CDLSHOOTINGSTAR Shooting Star
- CDLSHORTLINE Short Line Candle
- CDLSPINNINGTOP Spinning Top
- CDLSTALLEDPATTERN Stalled Pattern
- CDLSTICKSANDWICH Stick Sandwich
- CDLTAKURI Takuri (Dragonfly Doji with very long lower shadow)
- CDLTASUKIGAP Tasuki Gap
- CDLTHRUSTING Thrusting Pattern
- CDLTRISTAR Tristar Pattern
- CDLUNIQUE3RIVER Unique 3 River
- CDLUPSIDEGAP2CROWS Upside Gap Two Crows
- CDLXSIDEGAP3METHODS Upside/Downside Gap Three Methods
- CMO Chande Momentum Oscillator
- CORREL Pearson's Correlation Coefficient (r)
- DEMA Double Exponential Moving Average
- DX Directional Movement Index
- EMA Exponential Moving Average
- HT_DCPERIOD Hilbert Transform - Dominant Cycle Period
- HT_DCPHASE Hilbert Transform - Dominant Cycle Phase
- HT_PHASOR Hilbert Transform - Phasor Components
- HT_SINE Hilbert Transform - SineWave
- HT_TRENDLINE Hilbert Transform - Instantaneous Trendline
- HT_TRENDMODE Hilbert Transform - Trend vs Cycle Mode
- KAMA Kaufman Adaptive Moving Average
- LINEARREG Linear Regression
- LINEARREG_ANGLE Linear Regression Angle
- LINEARREG_INTERCEPT Linear Regression Intercept
- LINEARREG_SLOPE Linear Regression Slope
- MA All Moving Average
- MACD Moving Average Convergence/Divergence
- MACDEXT MACD with controllable MA type
- MACDFIX Moving Average Convergence/Divergence Fix 12/26
- MAMA MESA Adaptive Moving Average
- MAX Highest value over a specified period
- MAXINDEX Index of highest value over a specified period
- MEDPRICE Median Price
- MFI Money Flow Index
- MIDPOINT MidPoint over period
- MIDPRICE Midpoint Price over period
- MIN Lowest value over a specified period
- MININDEX Index of lowest value over a specified period
- MINMAX Lowest and highest values over a specified period
- MINMAXINDEX Indexes of lowest and highest values over a specified period
- MINUS_DI Minus Directional Indicator
- MINUS_DM Minus Directional Movement
- MOM Momentum
- NATR Normalized Average True Range
- OBV On Balance Volume
- PLUS_DI Plus Directional Indicator
- PLUS_DM Plus Directional Movement
- PPO Percentage Price Oscillator
- ROC Rate of change : ( (price/prevPrice)-1)*100
- ROCP Rate of change Percentage: (price-prevPrice)/prevPrice
- ROCR Rate of change ratio: (price/prevPrice)
- ROCR100 Rate of change ratio 100 scale: (price/prevPrice)*100
- RSI Relative Strength Index
- SAR Parabolic SAR
- SAREXT Parabolic SAR - Extended
- SMA Simple Moving Average
- STDDEV Standard Deviation
- STOCH Stochastic
- STOCHF Stochastic Fast
- STOCHRSI Stochastic Relative Strength Index
- SUM Summation
- T3 Triple Exponential Moving Average (T3)
- TEMA Triple Exponential Moving Average
- TRANGE True Range
- TRIMA Triangular Moving Average
- TRIX 1-day Rate-Of-Change (ROC) of a Triple Smooth EMA
- TSF Time Series Forecast
- TYPPRICE Typical Price
- ULTOSC Ultimate Oscillator
- VAR Variance
- WCLPRICE Weighted Close Price
- WILLR Williams' %R
- WMA Weighted Moving Average
それぞれが独立した説明変数にならないと思うので気になりますが…それでもディープラーニングなら…
問題発生
ここで問題が発生しました。
OSError: [Errno 12] Cannot allocate memory
メモリが足りないよ。というエラー
FXで稼いでらっしゃる投資家さま、学習用の機材を買ってください。
https://www.amazon.co.jp/gp/registry/wishlist/C1WLEZF27DHM/
ということで、泣く泣く期間を変えました。
2013年1月1日以降の1分足を扱うことにしました。
- 0(下がった):486661
- 1(上がった):476269
標準化
Epoch 99/100
818490/818490 [==============================] - 3s - loss: 0.6891 - acc: 0.5427 - val_loss: 0.6930 - val_acc: 0.5277
Epoch 100/100
818490/818490 [==============================] - 3s - loss: 0.6891 - acc: 0.5427 - val_loss: 0.6927 - val_acc: 0.5281
正規化
Epoch 99/100
818490/818490 [==============================] - 3s - loss: 0.6904 - acc: 0.5338 - val_loss: 0.6919 - val_acc: 0.5237
Epoch 100/100
818490/818490 [==============================] - 3s - loss: 0.6904 - acc: 0.5330 - val_loss: 0.6916 - val_acc: 0.5272
パターン4まとめ
テクニカル指標を全部入れたパターンが一番正解率が高くなるだろうと思ったのですが、そうでもなかったです。*4
まとめ
最高で53%の正解率になりましたので、53-50.4 = 2.6%分の何かを学習したということになるでしょうか。
ランダムではないにしても、ちょっと満足できる結果にはなりませんでした。
考察的な
全然纏まってませんが、感じたことを思いつくままに記載しておきます。
金曜終わり・月曜始まりの扱い
FXは土日には動かないので金曜の終わりと月曜の始まりでは価格が大きく違ってくることが多いのですが、今回使った1分足のデータでは金曜〜月曜も連続しているかのように扱っていますので、金曜日の終わり近く・月曜日の初めの方のデータは除外すべきかもしれないです。
各取引所の値動きの特徴
日本時間・欧州時間・ニューヨーク時間など市場が開く時間帯が違うので、どの時間帯なのかを変数として入れるべきかもしれません。
というより、全く別物のモデルとして作ってしまってもいいかもしれない。
テクニカル指標の調整不足
「テクニカル指標を全部」と書きましたが、それぞれの指標が期間など細かいパラメータを持っているので適切なパラメータを与えられていない可能性が高い
1分足ではテクニカルが効きづらい
今回は1分足で試しましたが、以前書いた記事のとあるMT4(システムトレーダー)の検証記録(ロジックテスト)という本の中では1分足/5分足などよりも15分足/30分足の方がバックテストが良かったと書かれていた気がします。
短すぎるとテクニカルが効かないなどもあるのかもしれません。
正しい教師データを与えられているのか?
今回は5分後に1pips以上上下するものを教師ラベルにしましたが、本当はもっと具体的な条件で教師ラベルを付けてあげるべきだと思ってます。
ですが、「どんな時に買うべきか・売るべきか」という正しいタイミングは素人の僕にはわからないので、プロの人に期間を指定してもらって、それを教師データにするのもいいかもしれません。(教師データを作るのがすごく面倒臭そうですが)*5
そもそも予想できないのかも
これは無いと考えたいですが、可能性としては十分ありそうです。
次回以降
予想をする際に確度(自信の度合いみたいなもの)も出せるので、実際のチャートに確度70%以上のものをプロットしてみると、どこで売買の予想をしているかが可視化できそうです。
正解が何かわからないので強化学習で出来ないかを試したい。