PR

【AI FX】MQL5でCNNを活用したEA開発 ※重要記事

MQL5記事

畳み込みニューラルネットワーク(CNN)は、画像認識の分野で革命を起こしましたが、その可能性はFX市場分析にも及びます。本記事では、CNNの基本構造から、MQL5を用いた実装、さらにはFX取引戦略の開発と評価まで解説します。具体的に以下の内容をカバーします:

  • CNNの基本構造とFX市場分析への応用
  • MQL5を使用したCNNの実装手法
  • CNN based取引戦略の開発とバックテスト
  • パフォーマンス評価と最適化のテクニック

CNNを用いたFX市場分析の可能性を探り、あなたの取引戦略を次のレベルに引き上げましょう。

WAN
WAN

MQL5のCNNのライブラリは初めてかな?

こういった有識者のおかげで、Pythonを使用しなくてもMQL5だけで学習と予測が可能になってきてるね!

まじでありがとうございます!

CNNの基本構造とその役割

WAN
WAN

CNNは音声データや文章の分析にも使用されるよ(‘ω’)

CNNを使えばチャートも言葉のように分析してくれるかもね!

たとえば、音声波形がどの文字に対応しているかを分析するのに使われるんだ。

畳み込みニューラルネットワークの概要

畳み込みニューラルネットワーク(CNN)は、深層学習の一種で、主に画像認識や処理のために開発されました。その特徴は、入力データに対して畳み込み演算を行うことで、局所的な特徴を効率的に抽出できる点にあります。

CNNは、画像内のパターンや構造を識別する能力に優れており、これが画像分類や物体検出などのタスクで高い性能を発揮する理由となっています。

画像処理から金融データ分析への応用

金融市場のチャートを考えてみると、価格の動きや各種指標のパターンは、ある種の「画像」として捉えることができます。例えば、ローソク足チャートの形状、移動平均線の交差パターン、あるいはボリンジャーバンドの拡大縮小などは、すべて視覚的なパターンとして認識できます。

CNNは、これらのパターンを効率的に学習し、将来の市場動向を予測するのに役立つ可能性があります。

しかし、金融データにCNNを適用する際には、いくつかの課題があります。まず、金融市場のデータは非常にノイズが多く、不確実性が高いという特徴があります。

WAN
WAN

短い時間足になればなるほどノイズだらけになって検証が難しいのはAIも一緒(‘Д’)

そのためにノイズを減らす作業がプーリングだよ

人間でいうと移動平均でみる感じに近いかな?

CNNの主要コンポーネントと処理ステップ

パディング:入力データの前処理

パディングは、CNNの入力データの周囲に追加のデータを付加するプロセスです。主な目的は、畳み込み演算後も入力データのサイズを維持することです。これには二つの重要な利点があります。

  • 情報の保持:パディングなしでは、畳み込み演算を繰り返すごとに出力サイズが小さくなり、エッジ部分の情報が失われてしまいます。パディングを行うことで、エッジ部分の情報も保持できます。
  • より深いネットワークの構築:パディングにより入力サイズが維持されるため、より多くの畳み込み層を重ねることが可能になり、より深いネットワークを構築できます。
void Ccnn::Pad()
{  
   if(!validated)
   {  
      printf(__FUNCSIG__ + " network invalid! ");
      return;
   }
   if(padding != PADDING_NONE)
   {  
      matrix _padded;
      _padded.Init(inputs.Rows() + 2, inputs.Cols() + 2);
      _padded.Fill(0.0);
      for(int i = 0; i < int(_padded.Cols()); i++)
      {  
         for(int j = 0; j < int(_padded.Rows()); j++)
         {  
            if(i == 0 || i == int(_padded.Cols()) - 1 || j == 0 || j == int(_padded.Rows()) - 1)
            {  
               if(padding == PADDING_ZERO)
               {  
                  _padded[j][i] = 0.0;
               }
               else if(padding == PADDING_EDGE)
               {  
                  // エッジパディングの実装
               }
               else if(padding == PADDING_REFLECT)
               {  
                  // リフレクトパディングの実装
               }
            }
            else
            {  
               _padded[j][i] = inputs[j - 1][i - 1];
            }
         }
      }
      Set(_padded, false);
   }
}

一般的なパディング方法には、ゼロパディング(0で埋める)、エッジパディング(エッジの値で埋める)、リフレクトパディング(エッジを軸に反転させて埋める)などがあります。金融データの場合、データの性質に応じて適切なパディング方法を選択する必要があります。

WAN
WAN

学習データが100個のローソク足で、20個ずつデータを区切って学習する場合、90個目のデータを使うと、最後のセットが10個しかないよね (‘Д’)

でも、学習は20個で進む設定だから、10個だけではなく20個のデータを使いたい。

そんなときは、101~110個目のデータが存在しない部分を0で埋めて、データのサイズを20に合わせるんだよ。これを「パディング」と言って、データが足りないときに使うテクニックなんだ。

畳み込み(フィードフォワード):特徴抽出の核心

畳み込み演算は、CNNの中核をなす処理です。ここでは、フィルタ(またはカーネル)と呼ばれる小さな行列を入力データ上でスライドさせ、要素ごとの積の和を計算します。この操作により、局所的な特徴を抽出することができます。

void Ccnn::Convolve()
{  
   if(!validated)
   {  
      printf(__FUNCSIG__ + " network invalid! ");
      return;
   }
   for (int f = 0; f < kernels; f++)
   {  
      bool _stop = false;
      int _stride_row = 0, _stride_col = 0;
      output[f].Fill(0.0);
      for (int g = 0; g < int(output[f].Cols()); g++)
      {  
         for (int h = 0; h < int(output[f].Rows()); h++)
         {  
            for (int i = 0; i < int(kernel[f].weights.Cols()); i++)
            {  
               for (int j = 0; j < int(kernel[f].weights.Rows()); j++)
               {  
                  output[f][h][g] += (kernel[f].weights[j][i] * inputs[_stride_row + j][_stride_col + i]);
               }
            }
            output[f][h][g] += kernel[f].bias;
            _stride_col += padding_stride;
            if(_stride_col + int(kernel[f].weights.Cols()) > int(inputs.Cols()))
            {  
               _stride_col = 0;
               _stride_row += padding_stride;
               if(_stride_row + int(kernel[f].weights.Rows()) > int(inputs.Rows()))
               {  
                  _stride_col = 0;
                  _stride_row = 0;
               }
            }
         }
      }
   }
}

金融データに適用する場合、畳み込み演算は時系列データ内のパターンや、異なる指標間の関係性を捉えるのに役立ちます。例えば、価格の上昇トレンドや、複数の技術指標が示す特定のシグナルなどを検出できる可能性があります。

活性化関数:非線形性の導入

活性化関数は、ニューラルネットワークに非線形性を導入する重要な要素です。CNNでよく使用される活性化関数には、ReLU(Rectified Linear Unit)、Leaky ReLU、Sigmoid、Tanhなどがあります。

金融データ分析においては、ReLUやLeaky ReLUが人気です。これらは計算が簡単で、勾配消失問題を軽減できるためです。

プーリング:特徴の圧縮と選択

プーリング層は、特徴マップのサイズを縮小し、最も重要な情報を選択する役割を果たします。一般的なプーリング方法には、最大プーリングと平均プーリングがあります。

金融データ分析では、最大プーリングが好まれることが多いです。これは、価格のピークや底、あるいは指標の極値など、重要なシグナルを捉えるのに適しているためです。

バックプロパゲーション:ネットワークの学習と最適化

バックプロパゲーションは、ネットワークの重みを調整し、予測誤差を最小化するプロセスです。金融市場データのような時系列データに適用する場合、いくつかの注意点があります:

  • 学習率の調整:金融データは非常に変動が激しいため、適切な学習率の設定が重要です。
  • 正則化:過学習を防ぐため、ドロップアウトやL1/L2正則化などの技術が有効です。
  • バッチ正規化:金融データの分布は時間とともに変化するため、バッチ正規化が有効な場合があります。
void Ccnn::Evolve(double LearningRate = 0.05)
{  
   if(!validated)
   {  
      printf(__FUNCSIG__ + " network invalid! ");
      return;
   }
   
   for(int f = 0; f < kernels; f++)
   {  
      matrix _output_error = target[f] - output[f];
      matrix _output_gradients;
      _output_gradients.Init(output[f].Rows(),output[f].Cols());
      for (int g = 0; g < int(output[f].Rows()); g++)
      {  
         for (int h = 0; h < int(output[f].Cols()); h++)
         {  
            _output_gradients[g][h] =  LeakyReLUDerivative(output[f][g][h]) * _output_error[g][h];
         }
      }
      
      int _stride_row = 0, _stride_col = 0;
      for (int g = 0; g < int(output[f].Cols()); g++)
      {  
         for (int h = 0; h < int(output[f].Rows()); h++)
         {  
            double _bias_sum = 0.0;
            for (int i = 0; i < int(kernel[f].weights.Cols()); i++)
            {  
               for (int j = 0; j < int(kernel[f].weights.Rows()); j++)
               {  
                  kernel[f].weights[j][i] += (LearningRate * _output_gradients[_stride_row + j][_stride_col + i]);
                  _bias_sum += _output_gradients[_stride_row + j][_stride_col + i];
               }
            }
            kernel[f].bias += LearningRate * _bias_sum;
            _stride_col += padding_stride;
            if(_stride_col + int(kernel[f].weights.Cols()) > int(_output_gradients.Cols()))
            {  
               _stride_col = 0;
               _stride_row += padding_stride;
               if(_stride_row + int(kernel[f].weights.Rows()) > int(_output_gradients.Rows()))
               {  
                  _stride_col = 0;
                  _stride_row = 0;
               }
            }
         }
      }
   }
}

また、金融市場の性質上、モデルは定期的に再学習させる必要があります。市場の状況は常に変化しているため、過去のデータだけに基づいたモデルは、時間が経つにつれて精度が低下する可能性があります。

WAN
WAN

コードを使えればいいから、コードの内容は流しとこう(‘Д’)

さすがに理解するのに時間かかりそうw

MQL5を用いたCNNの実装

カスタムCNNクラスの設計

MQL5でCNNを実装する際は、まずカスタムCNNクラスを設計します。このクラスには、前述の各コンポーネント(パディング、畳み込み、活性化、プーリング、バックプロパゲーション)をメソッドとして実装します。

クラスの主要な属性には、入力データ、重み行列(カーネル)、バイアス、出力データなどが含まれます。また、ハイパーパラメータ(学習率、エポック数、バッチサイズなど)も設定できるようにします。

シグナルクラスへのCNNの統合

CNNクラスを実装したら、次にこれをMQL5のシグナルクラスに統合します。シグナルクラスは、取引シグナルを生成するためのクラスで、EAの中核をなす部分です。

double CSignalCNN::GetOutput()
{  
   int _index = 5;
   matrix _inputs;
   vector _ma, _h, _l, _c;
   _inputs.Init(m_input_size, m_input_size);
   for(int g = 0; g < m_epochs; g++)
   {  
      for(int h = m_train_set - 1; h >= 0; h--)
      {  
         _inputs.Fill(0.0);
         _index = 0;
         for(int i = 0; i < m_input_size; i++)
         {  
            for(int j = 0; j < m_input_size; j++)
            {  
               if(_ma.CopyIndicatorBuffer(m_ma[_index].Handle(), 0, h, __KERNEL + 1))
               {  
                  _inputs[i][j] = _c[0] - _ma[0];
                  _index++;
               }
            }
         }
         
         _h.CopyRates(m_symbol.Name(), m_period, 2, h, __KERNEL + 1);
         _l.CopyRates(m_symbol.Name(), m_period, 4, h, __KERNEL + 1);
         _c.CopyRates(m_symbol.Name(), m_period, 8, h, __KERNEL + 1);
         
         CNN.Set(_inputs);
         CNN.Pad();
         CNN.Convolve();
         CNN.Activate();
         CNN.Pool();
         
         // ターゲットデータの準備
         matrix _targets[];
         ArrayResize(_targets, __KERNEL_SIZES.Size());
         for(int i = 0; i < int(__KERNEL_SIZES.Size()); i++)
         {  
            _targets[i].Init(__KERNEL_SIZES[i], __KERNEL_SIZES[i]);
            for(int j = 0; j < __KERNEL_SIZES[i]; j++)
            {  
               // ターゲットデータの計算(高値、安値、終値の変化)
            }
         }
         CNN.Get(_targets);
         CNN.Evolve(m_learning_rate);
      }
   }
   
   // 予測の生成
   double _long = 0.0, _short = 0.0;
   if(CNN.output[0].Median() > 0.0)
   {  
      _long = fabs(CNN.output[0].Median());
   }
   if(CNN.output[1].Median() < 0.0)
   {  
      _short = fabs(CNN.output[1].Median());
   }
   double _neutral = fabs(CNN.output[2].Median());
   if(_long+_short+_neutral == 0.0)
   {  
      return(0.0);
   }
   return((_long-_short)/(_long+_short+_neutral));
}

CNNをシグナルクラスに統合する際は、CNNの出力を取引シグナルに変換する方法を定義する必要があります。例えば、CNNの出力が特定のしきい値を超えた場合に買いシグナル、下回った場合に売りシグナルを生成するなどの方法が考えられます。

入力データと目標データの準備

CNNの学習と予測には、適切な入力データと目標データが必要です。

  • 入力データ:価格データ(OHLC)、出来高、各種技術指標(移動平均、RSI、MACD等)を使用します。これらのデータを正規化し、2次元の「画像」として表現します。
  • 目標データ:将来の価格変動や、上昇・下降・横ばいといった市場の状態を表すラベルを使用します。

データの前処理として、異常値の処理、欠損値の補完、スケーリングなども重要です。また、学習データとテストデータの適切な分割も忘れずに行います。

CNNを用いた取引戦略の開発と評価

EAの構築とパラメータ設定

CNNを組み込んだEAを構築する際は、以下の点に注意します:

  • リスク管理:CNNの予測に基づいて、適切なポジションサイズやストップロス、利益確定レベルを設定します。
  • 取引頻度:CNNの予測更新頻度と、実際の取引執行頻度のバランスを取ります。
  • フィルタリング:市場の状況に応じて、CNNの予測をフィルタリングする追加ロジックの実装を検討します。

パラメータ設定では、CNNの構造(層の数、ニューロン数など)、学習率、エポック数などのハイパーパラメータを最適化する必要があります。これには、グリッドサーチや遺伝的アルゴリズムなどの手法が有効です。

まとめ

CNNの金融市場への応用可能性

CNNを金融市場データ分析に応用することで、従来の技術分析では捉えきれなかった複雑なパターンや関係性を識別できる可能性があります。特に、多数の指標や異なる時間枠のデータを同時に考慮する能力は、CNNの強みといえるでしょう。

しかし、CNNの金融市場への応用にはいくつかの課題もあります。市場の非定常性、ノイズの多さ、予測の難しさなどは、CNNを含む機械学習モデル全般に共通する課題です。また、モデルの「ブラックボックス」性も、規制の厳しい金融分野では問題となる可能性があります。

改善点と研究の方向性

今後の研究方向として、以下のような点が考えられます:

  • データの前処理技術の改善:金融データの特性に合わせた、より効果的なデータ表現方法の開発。
  • アンサンブル手法の適用:CNNと他の機械学習モデル(例:LSTM、強化学習)を組み合わせたハイブリッドモデルの開発。
  • 解釈可能性の向上:CNNの判断根拠を可視化し、理解しやすくする技術の開発。
  • リアルタイム学習:市場の変化に迅速に適応できる、オンライン学習手法の研究。
  • マルチタスク学習:複数の金融商品や時間枠を同時に予測するモデルの開発。

CNNを金融市場分析に応用する試みは、まだ始まったばかりです。技術の進歩と共に、より洗練されたモデルとアプローチが登場することが期待されています。

WAN
WAN

MQLでの学習に関しては、GPUを使用した学習ができるかも課題かな。

オンラインコミュニティ

こちらのコミュニティで、AIや機械学習をトレードに活かすために日々探求しています。
興味のある方は覗いてみてください。

参考記事

知っておくべきMQL5ウィザードのテクニック(第23回):CNN
畳み込みニューラルネットワーク(Convolutional Neural Network: CNN)もまた、多次元のデータセットを主要な構成要素に分解することに特化した機械学習アルゴリズムです。一般的にどのように達成されるかを見て、別のMQ...
タイトルとURLをコピーしました