ニートの言葉

元ニートがやってみたこと・その過程で学んだこと・考えたこと・技術メモあたりを主に書いています。情報革命が起きた後に訪れるであろう「一億総ニート時代」の生き方を考え中です。

ディープラーニングでFXの値動きを予想できるか試してみた

こんにちは、あんどう(@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

入力したデータ 説明変数

下記のパターンで試してみました。

  1. 過去25分の4本値とボリンジャーバンドの値
  2. 過去25分の前の終値からの値段の変化+ボリンジャーバンド
  3. 論文に書いてあるもの
  4. 使えるテクニカル指標全部

また、入力時に値を[0:1]に正規化したり、平均0で分散が1になるように標準化するべきということなのですが、どちらがいいのかわからなかったので、上記の各パターンで正規化・標準化を試してみました。

ネットワークの構造 

ネットワークの構造を色々と変えてみましたが、結果はほとんど変わりませんでした。

最終的に使ったのはこんな感じです。(このモデルに根拠はありません。)

model = Sequential()
model.add(Dense(col_num, init='glorot_uniform',input_dim=col_num, activation='relu', W_regularizer=l1l2(l1=0.0001, l2=0.0001)))
model.add(Dropout(0.1))
model.add(Dense(col_num, init='glorot_uniform', activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='Adadelta',
              loss='binary_crossentropy',metrics=['accuracy']) 

結果

以上の条件で色々と試してみました。

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

  1. AD Chaikin A/D Line
  2. ADOSC Chaikin A/D Oscillator
  3. ADX Average Directional Movement Index
  4. ADXR Average Directional Movement Index Rating
  5. APO Absolute Price Oscillator
  6. AROON Aroon
  7. AROONOSC Aroon Oscillator
  8. ATR Average True Range
  9. AVGPRICE Average Price
  10. BBANDS Bollinger Bands
  11. BETA Beta
  12. BOP Balance Of Power
  13. CCI Commodity Channel Index
  14. CDL2CROWS Two Crows
  15. CDL3BLACKCROWS Three Black Crows
  16. CDL3INSIDE Three Inside Up/Down
  17. CDL3LINESTRIKE Three-Line Strike
  18. CDL3OUTSIDE Three Outside Up/Down
  19. CDL3STARSINSOUTH Three Stars In The South
  20. CDL3WHITESOLDIERS Three Advancing White Soldiers
  21. CDLABANDONEDBABY Abandoned Baby
  22. CDLADVANCEBLOCK Advance Block
  23. CDLBELTHOLD Belt-hold
  24. CDLBREAKAWAY Breakaway
  25. CDLCLOSINGMARUBOZU Closing Marubozu
  26. CDLCONCEALBABYSWALL Concealing Baby Swallow
  27. CDLCOUNTERATTACK Counterattack
  28. CDLDARKCLOUDCOVER Dark Cloud Cover
  29. CDLDOJI Doji
  30. CDLDOJISTAR Doji Star
  31. CDLDRAGONFLYDOJI Dragonfly Doji
  32. CDLENGULFING Engulfing Pattern
  33. CDLEVENINGDOJISTAR Evening Doji Star
  34. CDLEVENINGSTAR Evening Star
  35. CDLGAPSIDESIDEWHITE Up/Down-gap side-by-side white lines
  36. CDLGRAVESTONEDOJI Gravestone Doji
  37. CDLHAMMER Hammer
  38. CDLHANGINGMAN Hanging Man
  39. CDLHARAMI Harami Pattern
  40. CDLHARAMICROSS Harami Cross Pattern
  41. CDLHIGHWAVE High-Wave Candle
  42. CDLHIKKAKE Hikkake Pattern
  43. CDLHIKKAKEMOD Modified Hikkake Pattern
  44. CDLHOMINGPIGEON Homing Pigeon
  45. CDLIDENTICAL3CROWS Identical Three Crows
  46. CDLINNECK In-Neck Pattern
  47. CDLINVERTEDHAMMER Inverted Hammer
  48. CDLKICKING Kicking
  49. CDLKICKINGBYLENGTH Kicking - bull/bear determined by the longer marubozu
  50. CDLLADDERBOTTOM Ladder Bottom
  51. CDLLONGLEGGEDDOJI Long Legged Doji
  52. CDLLONGLINE Long Line Candle
  53. CDLMARUBOZU Marubozu
  54. CDLMATCHINGLOW Matching Low
  55. CDLMATHOLD Mat Hold
  56. CDLMORNINGDOJISTAR Morning Doji Star
  57. CDLMORNINGSTAR Morning Star
  58. CDLONNECK On-Neck Pattern
  59. CDLPIERCING Piercing Pattern
  60. CDLRICKSHAWMAN Rickshaw Man
  61. CDLRISEFALL3METHODS Rising/Falling Three Methods
  62. CDLSEPARATINGLINES Separating Lines
  63. CDLSHOOTINGSTAR Shooting Star
  64. CDLSHORTLINE Short Line Candle
  65. CDLSPINNINGTOP Spinning Top
  66. CDLSTALLEDPATTERN Stalled Pattern
  67. CDLSTICKSANDWICH Stick Sandwich
  68. CDLTAKURI Takuri (Dragonfly Doji with very long lower shadow)
  69. CDLTASUKIGAP Tasuki Gap
  70. CDLTHRUSTING Thrusting Pattern
  71. CDLTRISTAR Tristar Pattern
  72. CDLUNIQUE3RIVER Unique 3 River
  73. CDLUPSIDEGAP2CROWS Upside Gap Two Crows
  74. CDLXSIDEGAP3METHODS Upside/Downside Gap Three Methods
  75. CMO Chande Momentum Oscillator
  76. CORREL Pearson's Correlation Coefficient (r)
  77. DEMA Double Exponential Moving Average
  78. DX Directional Movement Index
  79. EMA Exponential Moving Average
  80. HT_DCPERIOD Hilbert Transform - Dominant Cycle Period
  81. HT_DCPHASE Hilbert Transform - Dominant Cycle Phase
  82. HT_PHASOR Hilbert Transform - Phasor Components
  83. HT_SINE Hilbert Transform - SineWave
  84. HT_TRENDLINE Hilbert Transform - Instantaneous Trendline
  85. HT_TRENDMODE Hilbert Transform - Trend vs Cycle Mode
  86. KAMA Kaufman Adaptive Moving Average
  87. LINEARREG Linear Regression
  88. LINEARREG_ANGLE Linear Regression Angle
  89. LINEARREG_INTERCEPT Linear Regression Intercept
  90. LINEARREG_SLOPE Linear Regression Slope
  91. MA All Moving Average
  92. MACD Moving Average Convergence/Divergence
  93. MACDEXT MACD with controllable MA type
  94. MACDFIX Moving Average Convergence/Divergence Fix 12/26
  95. MAMA MESA Adaptive Moving Average
  96. MAX Highest value over a specified period
  97. MAXINDEX Index of highest value over a specified period
  98. MEDPRICE Median Price
  99. MFI Money Flow Index
  100. MIDPOINT MidPoint over period
  101. MIDPRICE Midpoint Price over period
  102. MIN Lowest value over a specified period
  103. MININDEX Index of lowest value over a specified period
  104. MINMAX Lowest and highest values over a specified period
  105. MINMAXINDEX Indexes of lowest and highest values over a specified period
  106. MINUS_DI Minus Directional Indicator
  107. MINUS_DM Minus Directional Movement
  108. MOM Momentum
  109. NATR Normalized Average True Range
  110. OBV On Balance Volume
  111. PLUS_DI Plus Directional Indicator
  112. PLUS_DM Plus Directional Movement
  113. PPO Percentage Price Oscillator
  114. ROC Rate of change : ( (price/prevPrice)-1)*100
  115. ROCP Rate of change Percentage: (price-prevPrice)/prevPrice
  116. ROCR Rate of change ratio: (price/prevPrice)
  117. ROCR100 Rate of change ratio 100 scale: (price/prevPrice)*100
  118. RSI Relative Strength Index
  119. SAR Parabolic SAR
  120. SAREXT Parabolic SAR - Extended
  121. SMA Simple Moving Average
  122. STDDEV Standard Deviation
  123. STOCH Stochastic
  124. STOCHF Stochastic Fast
  125. STOCHRSI Stochastic Relative Strength Index
  126. SUM Summation
  127. T3 Triple Exponential Moving Average (T3)
  128. TEMA Triple Exponential Moving Average
  129. TRANGE True Range
  130. TRIMA Triangular Moving Average
  131. TRIX 1-day Rate-Of-Change (ROC) of a Triple Smooth EMA
  132. TSF Time Series Forecast
  133. TYPPRICE Typical Price
  134. ULTOSC Ultimate Oscillator
  135. VAR Variance
  136. WCLPRICE Weighted Close Price
  137. WILLR Williams' %R
  138. 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%以上のものをプロットしてみると、どこで売買の予想をしているかが可視化できそうです。

正解が何かわからないので強化学習で出来ないかを試したい。

*1:この期間を選んだ理由は特にありません。

*2:この考えで合っているかは自信はありません。

*3:期間などが違うので同じ条件とは言えませんが

*4:そもそも期間が違うのでなんとも言えないですね。

*5:アルパカさん( http://www.alpaca.ai/ja/ )がそういうことをやられてるみたいですね。