特徴量エンジニアリング
AI(DeepLearning)に未来の為替レートを予測させるための特徴量(Open, High, Volume, etc.)を選択します。
過去の記事で為替レートを含む市場情報の時系列データを取得したんだから、それを使うんじゃないの?
と思うかもしれませんが、個人が所有するPCで学習モデルを生成する場合、
処理スペックが足りず、時間がかかりすぎるため、すべての特徴量を用いるわけにはいきません。
また取得できて10年分程度なので、特徴量の種類が多すぎると、パターンが足りず、
未学習のパターンに対して予測精度が大きく落ちてしまいます(過学習といいます)
そのため、真に必要とする特徴量を抽出・選択・生成する必要があります。
この過程を「特徴量エンジニアリング」や「特徴選択」「特徴抽出」と呼ぶようです。
Coffee Break
多変量解析の分野だと、相関関係のある複数の特徴量を統合し次元削減するために、主成分分析(PCA)を用いたりします。私も「為替レートをDeepLearningで予測したい!」と思い立った10年ほど前は、為替レートを知るために、統計モデリングを学習したり、多変量解析を学習し実践したり、独自の特徴量を生成したりして遊んでいました(かなり回り道しました)
FXのための特徴量分析
実は為替レートの場合、ここで多変量解析など面倒な分析を行う必要はありません。
先人たちが英知を結集して考案したテクニカルチャートというものがあるからです。
これもある種の特徴量の統合です。
一番メジャーなのは「移動平均線」ですが、その他にも、
- ボリンジャーバンド
- RSI
- MACD
- ストキャスティクス
- 一目均衡表(日本人が生み出したチャート分析手法です)
などなど
たくさんあります。MT5の画面上にテクニカルチャートを表示すると、下記のような感じです。
人間はこれを見て、未来の為替レートを予測するのです
(図のUSDJPYは短期的にみるともう少しだけ上昇しそうですが、長期的に見るとまだ下がりそうですね)
詳しくは、FXチャートの専門書をご参照ください。
そしてこのテクニカルチャートの取得方法ですが、
数式が好きな人は、為替レートの時系列データ(Open, Close, High, Low, Volume)からゴリゴリ計算してもいいですが、MT4(MQL4)やMT5(MQL5)を使うと簡単なプログラムで取得することができ、CSVファイルへ出力することもできます。
MQL4でテクニカルチャートを取得し、CSVファイルへ出力する例は以下の通りです。
// 時刻
datetime timeValue = iTime(Symbol(), PERIOD_M30, 1);
// Open
double open = iOpen(Symbol(), PERIOD_M30, 1);
// Close
double close = iClose(Symbol(), PERIOD_M30, 1);
// High
double high = iHigh(Symbol(), PERIOD_M30, 1);
// Low
double low = iLow(Symbol(), PERIOD_M30, 1);
// Volume
long volume = iVolume(Symbol(), PERIOD_M30, 1);
// 移動平均(SMA)
double sma20 = iMA(Symbol(),PERIOD_M30,SMA20_KAIRI,0,MODE_SMA,PRICE_CLOSE,1);
// MACD(基本線)
double macd_main = iMACD(Symbol(),PERIOD_M30, MACD_TANKI, MACD_TYOUKI, MACD_SIGNAL, PRICE_CLOSE, MODE_MAIN, 1);
// MACD(シグナル線)
double macd_signal = iMACD(Symbol(),PERIOD_M30, MACD_TANKI, MACD_TYOUKI, MACD_SIGNAL, PRICE_CLOSE, MODE_SIGNAL, 1);
// 一目均衡表(転換線)
double ichi_tenkan = iIchimoku(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU, MODE_TENKANSEN, 1);
// 一目均衡表(基準線)
double ichi_kijun = iIchimoku(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU, MODE_KIJUNSEN, 1);
// 一目均衡表(先行スパンA)
double ichi_spanA = iIchimoku(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU, MODE_SENKOUSPANA, 1);
// 一目均衡表(先行スパンB)
double ichi_spanB = iIchimoku(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU, MODE_SENKOUSPANB, 1);
// 一目均衡表(遅行線)
double ichi_chikou = iIchimoku(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU, MODE_CHIKOUSPAN, ICHIMOKU_KIJUN + 1);
// ボリンジャーバンド(MAIN)
double bands_middle = iBands(Symbol(),PERIOD_M30, BANDS_PERIOD, BANDS_DEVIATION, BANDS_SHIFT, PRICE_CLOSE, MODE_MAIN, 1);
// ボリンジャーバンド(UPPER)
double bands_upper = iBands(Symbol(),PERIOD_M30, BANDS_PERIOD, BANDS_DEVIATION, BANDS_SHIFT, PRICE_CLOSE, MODE_UPPER, 1);
// ボリンジャーバンド(LOWER)
double bands_lower = iBands(Symbol(),PERIOD_M30, BANDS_PERIOD, BANDS_DEVIATION, BANDS_SHIFT, PRICE_CLOSE, MODE_LOWER, 1);
// RSI
double rsi = iRSI(Symbol(),PERIOD_M30, RSI_PERIOD, PRICE_CLOSE, 1);
// 書き込みモードでファイルオープン
int fileHandle = FileOpen(fileName, FILE_CSV|FILE_WRITE, ",");
// 書き込み
FileWrite(fileHandle, timeValue, open, close, high, low,
sma20, macd_main, macd_signal,ichi_main, ichi_senkou, ichi_kumo, ichi_chinkou,
bands_middle,bands_upper,bands_lower,rsi);
// ファイルクローズ
FileClose(fileHandle);
MQL4に専用メソッドが用意されているので簡単ですね。
つぎにMQL5ですが、テクニカルチャート用の標準ライブラリを使用するため、クラス定義から行う必要があります。
MQL4 ≒ C言語、MQL5 ≒ C++言語
かなと個人的には思っています。MQL4のソースコードをMQL5へ変換するのは、少し苦労しました。
MQL5でテクニカルチャートを取得し、CSVファイルへ出力する例は以下の通りです。
#include <Indicators\Trend.mqh>
// テクニカルチャート変数定義
CiMA isma20;
CiMACD macd;
CiIchimoku ichimoku;
CiBands bands;
CiRSI rsi;
// オブジェクト生成
isma20.Create(Symbol(),PERIOD_M30,SMA20_KAIRI,0,MODE_SMA,PRICE_CLOSE);
macd.Create(Symbol(),PERIOD_M30, MACD_TANKI, MACD_TYOUKI, MACD_SIGNAL, PRICE_CLOSE);
ichimoku.Create(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU);
bands.Create(Symbol(),PERIOD_M30, BANDS_PERIOD, BANDS_DEVIATION, BANDS_SHIFT, PRICE_CLOSE);
rsi.Create(Symbol(),PERIOD_M30, RSI_PERIOD, PRICE_CLOSE);
// 更新
isma20.Refresh();
macd.Refresh();
ichimoku.Refresh();
bands.Refresh();
rsi.Refresh();
// 時刻
datetime timeValue = iTime(Symbol(), PERIOD_M30, 1);
// Open
double open = iOpen(Symbol(), PERIOD_M30, 1);
// Close
double close = iClose(Symbol(), PERIOD_M30, 1);
// High
double high = iHigh(Symbol(), PERIOD_M30, 1);
// Low
double low = iLow(Symbol(), PERIOD_M30, 1);
// Volume
long volume = iVolume(Symbol(), PERIOD_M30, 1);
// 移動平均(SMA)
double sma20 = isma20.Main(1);
// MACD(基本線)
double macd_main = macd.Main(1);
// MACD(シグナル線)
double macd_signal = macd.Signal(1);
// 一目均衡表(転換線)
double ichi_tenkan = ichimoku.TenkanSen(1);
// 一目均衡表(基準線)
double ichi_kijun = ichimoku.KijunSen(1);
// 一目均衡表(先行スパンA)
double ichi_spanA = ichimoku.SenkouSpanA(1);
// 一目均衡表(先行スパンB)
double ichi_spanB = ichimoku.SenkouSpanB(1);
// 一目均衡表(遅行線)
double ichi_chikou = ichimoku.ChinkouSpan(ICHIMOKU_KIJUN+1);
// ボリンジャーバンド(MAIN)
double bands_middle = bands.Base(1);
// ボリンジャーバンド(UPPER)
double bands_upper = bands.Upper(1);
// ボリンジャーバンド(LOWER)
double bands_lower = bands.Lower(1);
// RSI
double rsi = rsi.Main(1);
// 以降はMQL4と同じ
// 書き込みモードでファイルオープン
int fileHandle = FileOpen(fileName, FILE_CSV|FILE_WRITE, ",");
// 書き込み
FileWrite(fileHandle, timeValue, open, close, high, low,
sma20, macd_main, macd_signal,ichi_main, ichi_senkou, ichi_kumo, ichi_chinkou,
bands_middle,bands_upper,bands_lower,rsi);
// ファイルクローズ
FileClose(fileHandle);
面倒な数式を実装する必要がないので簡単ですね。
ただし、MT4は32bitアプリ、MT5は64bitアプリの影響なのか、
CSVファイルの文字コードがそれぞれ、UTF-8とUTF-16になります。
読み込む際は注意しましょう。
特徴量選択
さて、テクニカルチャートのおかげで、予測に使えそうな特徴量へと変換できたわけですが、それでもまだまだテクニカルチャートの種類はたくさんあります。
そこで、テクニカルチャートの中から未来の為替レート予測に影響ありそうなチャートを見つけます。これを「特徴量選択」といいます。
テクニカルチャートに詳しい方なら、
「一目均衡表、ボリンジャーバンド、MACD」のように、好きなチャートを選んでもいいと思います。きっと、ご自身が行っているテクニカルチャート分析より、より統計的な判断ができる学習モデルができることでしょう。
機械学習を用いて特徴量を選択する方法もあります。
「特徴量を微小変化させて、予測結果の変動が大きいものを選択する」という方法です。
詳しく手法を説明すると、とてもなが~い記事となってしまうため、躊躇していたら、
下記記事がとても参考になりましたので、引用させて頂きます。
私は上記記事の「勾配ブースティング(XGBoost、LightGBM)を用いた例」のとおり、
LightGBMを用いて、特徴量選択を行いました。
下記のような手順で行います。
【特徴量選択の手順】
- 上述した通りテクニカルチャートを出力する。もしくは、前々回の記事「1.学習用データの集め方」のとおり、任意の指標値を集める。
- 前回の記事「2.データの前処理方法」のとおり、学習用データを差分化・標準化する。
- 次回の記事で記載する、時系列データの生成のとおり、入力データと出力データを生成する。
- 上述の参考記事のように、LightGBMを用いて、重要度の高い特徴量をリストアップする。
- 重要度の高い特徴量から、上位数件ピックアップし、入力データに用いる。
以上
正確には、次回の記事で記載する時系列データの入力データの期間によって、重要度の高い特徴量は変わるので、期間を変えて何度か試すのがいいと思います。
他通貨ペア・他指標値の選択
有効な特徴量を見つけたので、あとは学習モデルを組んで、学習させるだけ。
といきたいところですが、実は単通貨ペアだけでは、良い予測精度は全く出ません。経験上、良くて未学習の正答率が50~55%といったところです。
なぜかというと、特徴量が(というか、固有ベクトル数が?)圧倒的に足りないからです。当たり前のことですが、通貨というものは、他の通貨の影響を大いに受けます。全通貨が通過安・通貨高になることは有り得ません。USD/JPYの通貨ペアも、EURの影響を受けているのです。
そこで、他の通貨ペアのテクニカルチャートも使って学習させます。
本当は全通貨ペアが相関関係にあるため、全て使いたいところですが、上述した通り、多すぎると過学習を起こしてしまうため、適度に相関が強い通貨ペアを選択していきます。
この選択作業は、各通貨ペアの相関マップをつくって、独自の理論で選択してもいいです。
専門家の意見を取り入れるのもいいと思います。下記のような専門書もあります。
この本では、一緒に見るべき通貨ペアを提示してくれています。参考までに。
各通貨ペアの相関関係を検索できるサイトもあるようです。
まとめ
学習に用いる特徴量の選択方法の案を提示しました。
ここに記載した内容が絶対的な正ではありません。1つの案としてご認識下さい。
少しでも参考にしていただけますと幸いです。
次は、「時系列データの生成方法」について、投稿する予定です。
よろしくお願い致します。