English Русский Deutsch
preview
知っておくべきMQL5ウィザードのテクニック(第08回):パーセプトロン

知っておくべきMQL5ウィザードのテクニック(第08回):パーセプトロン

MetaTrader 5トレーディングシステム | 20 3月 2024, 11:01
99 0
Stephen Njuki
Stephen Njuki

はじめに

MQL5ウィザードのExpert-Signalクラスには、「Include\Expert\Signal」フォルダの下に多数のサンプルインスタンスが付属しています。ウィザードでEAを組み立てる際に、それらのそれぞれを独立して使用することも、相互に組み合わせて使用​​することもできます。この記事では、EAでそのようなファイルを1つ作成して使用することを目指します。このアプローチでは、事前のコーディング作業を最小限に抑えるだけでなく、使用する各シグナルに重み付けを割り当てることで、単一のEAで複数のシグナルをテストすることができます。

ファイル「Include\Math\Alglib\dataanalysis.mqh」では、Alglibパーセプトロンクラスは広範で相互リンクされたネットワークインターフェイスで表示されています。初めて見ると圧倒されてしまいがちですが、ここでは、この領域を簡単にナビゲートできるようにするために、いくつかの重要なクラスを見ていきます。

これらのAlglibクラスを使用してEAを開発する主な動機は、MQL5ウィザードを使用する場合と同じ、つまりアイデアのテストです。アイデアxまたは入力データセットyが、真剣に取引システムをさらに開発する努力に値するものであるかどうかを簡潔に判断するにはどうすればよいでしょうか。ここで検討する内容は、この質問に答えるのに役立つ可能性があります。

バナー

ただし、本題に入る前に、なぜパーセプトロン、そしておそらくニューラルネットワークが一般的に多くの分野で大きな注目を集めているのかについて、より広範な主張をすることが役に立つかもしれません。金融と市場に注目すると、市場の動きを予測する際にかなりの課題があり、これには従来の分析の限界が暗黙のうちに存在していることがわかります。

こうした課題が存在するのは、市場が非常に複雑で、ニュース(公開情報)に掲載されているもの以上の影響を受ける動的なシステムであることが多いためです。さまざまな市場変数間の関係は、ほとんどの場合直線的ではなく、非常に気まぐれです。線形性に依存する従来の分析手法では、これらの複雑さを効果的に捉えて説明できない可能性があります。これらの従来の手法の例には、相関主成分分析線形回帰などのアプローチが含まれます。どれも非常に健全な戦術ですが、もはや効果的または適切ではない課題や状況に直面し始めています。さらに、市場データは本質的にノイズが多く、市場の動きは投資家心理だけでなく消費者の行動バイアスにも影響されます。したがって、従来のテクニカル分析は、これらすべての市場ダイナミクスを適切に考慮せずに、この履歴データに依存することによって制限されてしまいます。同様に、本質的価値を重視し、長期的な視点に立つファンダメンタルズ分析は、特に価格変動に関係するものであるため、短期的なリスクを招きやすいとある程度主張できます。ファンダメンタルズ分析に依存する人は通常レバレッジを利用しませんが、レバレッジはAUMをレベルアップする上で重要な要素であるため、長期的なリスクはあるものの、短期的な価格変動を無視してレバレッジを活用することはできないことにほとんどの人が同意するでしょう。

これら2つの従来のアプローチに代わる新たな選択肢として、行動経済学とニューラルネットワークを使用したAI技術があります。前者は投資家の行動を把握するために心理学と行動経済学の洞察を組み込んでいますが、ここで詳しく説明する後者のニューラルネットワークの控えめな形式です。

最近、金融市場は、ChatGPTの立ち上げに伴うAI技術の導入により激変しました。かなりの数の大手企業が参加しています。たとえばBloombergGPTやSalesForceによるEinsteinGPTは流行です。さて、GPTはここでは主題ではありませんが、過度に簡略化されたバージョン、別名パーセプトロンがあります。

それにもかかわらず、予測に対するAI技術への関心の高まりは、現在収集され保存される量が増加している膨大な金融データに部分的に起因しています。たとえば、テクニカルアナリストが注目していたのは証券の毎日の終値だけだった時代を覚えていらっしゃるでしょうか。今日では誰もが、一般的に最小値となるのは1分足のOHLC価格であることを知っていますが、これはティックについて語る以前のことであり、その頻度は証券会社ごとに異なります。

このデータ過負荷は、チッププロバイダー間の健全な競争によるコンピューティング能力の向上と並行して発生しています。昨日、現在GPTで大流行しているGPUの需要の急増のおかげで、NVIDIAが間もなく世界最大のチップサプライヤーになると発表されました。そのため、データストレージの増加とコンピューティング能力の向上により、アルゴリズム取引が増加しています。また、アルゴリズム取引は従来のテクニカル分析やファンダメンタル分析でもおこなうことができますが、ニューラルネットワークを活用するAI技術がますます注目を集めています。

ニューラルネットワークは、大規模なデータの処理と複雑な非線形パターンの特定に優れている傾向があります。さらに、特定の隠れ層が特殊化される多層ネットワークの高揚法であるディープラーニングと呼ばれるものを通じて、変化する環境に適応しながらこれを達成する傾向があります。特定のタスクでは、典型的な乱流/変化する環境での予測が適切に使用されます。金融以外でも、ニュース記事やソーシャルメディアの投稿などの非構造化データを分析して市場センチメントを測定し、医薬品の臨床試験の有効性やその他の多数の事例の評価に役立てることができます。


Alglibパーセプトロンクラスの概要

すでにほのめかしたように、Alglibパーセプトロンクラス階層は、この記事で検討している単純なパーセプトロンから、ニューラルネットワークのスタックを表すトランスフォーマーと同義のアンサンブルに至るまで、ニューラルネットワークを実装するクラスの膨大なライブラリです。パーセプトロンと呼ばれる非常に基本的なニューラルネットワークのみを見て、CMLPBase、CMLPTrain、CMLPTrainer、CMultilayerPerceptronクラスについてのみ触れます。レポートを処理するクラスやデータセットの正規化に役立つクラスなど、他にも使用する小さな補助クラスがありますが、これらが強調表示する主なクラスです。

CMLPBaseクラスは、ネットワークに含まれる隠れ層の数と各層のニューロンの数を厳密に設定することにより、ネットワークを初期化するために使用されます。CMLPTrainクラスは、ネットワークが受け取る入力の数とその出力の数を設定することによってトレーナークラスを初期化します。さらに、トレーナーに訓練データセットを入力します。このデータセットは、使用するネットワークの種類に応じて、最初の列に独立変数が含まれ、最後の列に回帰子または分類子が含まれる行列形式である必要があります。私たちの場合、パーセプトロンは通常ブール出力を提供するため、これは分類子になります。CMLPTrainerクラスは、CMLPTrainクラスのMLPTrainNetwork関数を呼び出す際に学習に使用されます。MLPEBaggingLM関数で呼び出されるブートストラップ集約など、別の非常に興味深い訓練方法もありますが、これらはアンサンブル(ネットワークのスタック)でのみ使用できます。さらに、早期停止、LBFGS、レーベンバーグマルカートなどのアルゴリズムもネットワークの訓練に使用できます。

これらのクラスで使用されるメソッドには、訓練データの読み込みから実際の訓練の実行、そして最後に予測のための現在のデータセットのフォワードパスの実行までのニューラルネットワークの典型的な行程が含まれます。

したがって、クラスはニューラルネットワークの動作方法に基づいてコード化されています。動作中、入力データはネットワークを介して最初の層(これらのクラスでは入力層と呼ばれます)から始まり、次に隠れ層、最後に出力層にフィードフォワードされます。さらに、値の活性化は通常、各ニューロンで実行され、この活性化により、選択された値が次の層に進むことを可能にするフィルターとして機能することで、ネットワークが線形関係を超えた複雑な関係を処理できるようになります。このプロセスは反復的ですが、ほとんどの場合、乗算と加算がおこなわれ、結果として出力層が各層の重みとバイアスの影響を受けるという点で比較的単純です。したがって、ニューラルネットワークの核心を形成するのはこれらの重みとバイアスであり、それらを調整するプロセスは計算量が多いだけでなく、フォワードパスほど単純ではないため、さまざまなアプローチの開発につながりました。ニューラルネットワークには複数のアプリケーションがあるため、この方法はさまざまなタイプのネットワークで最も効果的に機能します。

そこで、AlgLibのネットワーク向けフォワードフィード関数はMLPProcessと名付けられました。バリエーションはありますが、原則として入力データをベクトルまたは配列で受け取り、通常は出力層の値もベクトルまたは配列で提供します。出力層に単一のニューロンを持つネットワークがあり、そのような場合には、配列ではなく単一の値を返すこの関数のオーバーロードがあります。

単一の隠れ層パーセプトロンをコーディングして使用しているにもかかわらず、参照クラスは多層パーセプトロンと呼ばれることに注意することが重要です。これは、初期化されたネットワークの隠れ層の数を実行時に0から2までに設定でき、その範囲が広いという点でスケーラブルであるためです。

典型的なフィードフォワードの仕組みを少し詳しくみてみるならば、MLPInternalProcessVector関数に注目することができます。この関数の最初の行動の1つは、この入力配列のすべての値がより関連付けられるように入力データ行を正規化することです。

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CBdSS::DSNormalize(CMatrixDouble &xy,const int npoints,
                        const int nvars,int &info,CRowDouble &means,
                        CRowDouble &sigmas)
  {
//--- function call
   DSNormalizeC(xy,npoints,nvars,info,means,sigmas);
//--- calculation
   for(int j=0; j<nvars; j++)
     {
      //--- change values
      for(int i=0; i<npoints; i++)
         xy.Set(i,j,(xy.Get(i,j)-means[j])/sigmas[j]);
     }
  }

これを実行するには、入力ベクトル内の各列の平均と標準偏差(シグマ)を使用して、0~1の範囲の値を算出する必要があります。したがって、平均値とシグマは訓練データセットから手動で定義し、ネットワークに割り当てる必要があります。このリストに示すように、同じAlglibファイルDSNormalize内でこの計算を実行できる関数がすでに存在します。

//+------------------------------------------------------------------+
//| Normalize                                                        |
//+------------------------------------------------------------------+
void CBdSS::DSNormalize(CMatrixDouble &xy,const int npoints,
                        const int nvars,int &info,double &means[],
                        double &sigmas[])
  {
   CRowDouble Means,Sigmas;
   DSNormalize(xy,npoints,nvars,info,Means,Sigmas);
   Means.ToArray(means);
   Sigmas.ToArray(sigmas);
  }

また、注目に値するのは、ニューロンの総数、使用するアクティベーションの種類、重みの総数、入力層のニューロンの数、出力層でのニューロンの数など、ネットワークに関する重要な情報を保存するために使用されるm_structinfo配列です。

正規化後、データはネットワークを介して、独自の活性化関数を持つことができる各層の各ニューロンに供給されます。このカスタマイズはMLPSetNeuronInfo関数で定義でき、ネットワーク構築時のエッジとして簡単に活用できます。

パーセプトロンへの順方向フィードは、ネットワークの重みを調整する訓練と比較すると比較的簡単です。Alglibは、主にLevenbergMarquadtとLBFGSという2つの訓練アプローチを用意しています。

非線形最小二乗解を求める場合のレーベンバーグ・マルカート法アルゴリズムは、ガウスニュートンアルゴリズムの速度と解の高曲率点における勾配降下アルゴリズムの巧みな機能を組み合わせます。これをおこなう際、ヘッセ行列を使用して、解にどれだけ近づいているかの推定値として表面の曲率を記録します。その用途は主にニューラルネットワークであり、特にヘッセ行列の計算が負担になるため、比較的単純なネットワークアーキテクチャに小さなデータセットが含まれる状況で、非凸誤差曲面の処理に効果的です。

一方、LBFGS法は、Limited memory Broyden-Fletcher-Goldfarb-Shannoアルゴリズムの略で、ヘッセ行列を計算するのではなく、制限されたメモリを使用して、最新のネットワーク重みの更新をログに記録して近似するため、計算とメモリの面で全体的に非常に効率的になります。そのため、大規模なデータセットの状況や比較的複雑なネットワークアーキテクチャにより適しています。

そうは言っても、この2つの収束特性は、最初の推測が大きく外れた状況(ネットワークがランダムな重みで初期化される場合など)であっても、正確な解に迅速に収束できるため、レーベンバーグ・マルコートが有利になる傾向があります。さらに、勾配降下法のような極小値で行き詰まる傾向が少なく、ラムダ減衰係数(英語)の使用のおかげで、もう少し堅牢になります。一方、LBFGSは、初期推定(この場合は初期ネットワーク重み)の影響をより強く受け、収束が遅くなるか、局所的最小値で行き詰まる可能性があります。


Expert Signalクラスのインスタンスのコーディング

パーセプトロンの仕組みについて簡単に紹介しましたが、詳細な資料と参考文献はここにあります。インスタンスのコーディングを検討し始めましょう。MQL5ウィザードを使用して新しいEAを作成するプロセスでは、このウィザードベースのEAを定義する3つの典型的なクラス、すなわち、この記事の焦点であるシグナルクラス、ポジションのストップロスの設定方法をガイドするトレーリングクラス、取引ロットサイズの設定に役立つ資金管理クラスです。これについては以前の記事ですでに触れています。3つすべてをアセンブリ中にウィザードで定義して選択する必要があります。資金管理クラスはサイズに最適化された取引量を提供しますが、リスクを検討する追加の4番目のウィザードクラスが必要になる可能性があります。EAが1つのポジション内で複数の注文をおこなうことがどの程度安全であるのでしょうか。これは取引履歴や何らかの指標に基づいている可能性もありますが、これはまだ利用できないため考慮されません。

Alglibパーセプトロンクラスのインスタンスを単層パーセプトロンとして実装するには、カスタムエキスパートシグナルクラスのインターフェイスでキークラスインスタンスを宣言することから始めます。シグナルクラスファイルには常にLongCondition関数とShortCondition関数があり、パーセプトロンからのシグナルの計算または処理を支援するためにこれに追加する関数が、初期化関数と検証関数以外に必要な唯一の重要なメソッドになります。

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CSignalPerceptron          : public CExpertSignal
  {
protected:
   
   int                           m_hidden;                              // 
   int                           m_features;                            // 
   int                           m_hidden_1_size;                       //
   int                           m_hidden_2_size;                       //  
   int                           m_training_points;                     //
   int                           m_training_restarts;                   //
   int                           m_activation_type;                     // 
   double                        m_hidden_1_bias;                       //
   double                        m_hidden_2_bias;                       //
   double                        m_output_bias;                         //

public:

...

protected:

   CBdSS                         m_norm;
   CMLPBase                      m_base;
   CMLPTrain                     m_train;
   CMatrixDouble                 m_xy;
   CMLPReport                    m_report;
   CMLPTrainer                   m_trainer;
   CMultilayerPerceptron         m_network;
   
   bool                          m_in_training;
      
   int                           m_inputs;
   int                           m_outputs;
   
   double                        m_last_long_y;
   double                        m_last_short_y;
   
   bool                          ReadWeights();
   bool                          WriteWeights(CRowDouble &Export);
   
   void                          Process(double &Y);
  };

検証関数は、エキスパートシグナルクラスのこのインスタンス内でデファクトの初期化関数として機能します。確かに組み込みの初期化関数はありますが、検証を使用する方が効果的です。その中には、検討する価値のある、やらなければならないことがいくつかあります。まず最初に、パーセプトロンの入力と出力の数を割り当てます。入力の数は最適化できるため、パラメータから読み取られますが、出力の数は、これは分類であり回帰ではないため、少なくとも2である必要があります。

そのために、物事を単純にして、出力として2を割り当てます。次に、方向を処理するときに各バーで考慮する訓練ポイントの数と一致する行が含まれるように訓練データ行列のサイズを変更します。その列は、入力と出力の数の合計と一致する必要があります。出力が2であるのは、強気と弱気の2つの重み付けを訓練するときを表し、実際、フォワードパスは同様に、両方の合計が1になる2つの確率を返します。1つはロング、もう1つはショートです。この後、入力と出力の数を設定してトレーナーを作成します。

   m_train.MLPCreateTrainerCls(m_inputs,m_outputs,m_trainer);

これに続いてネットワークの作成がおこなわれ、選択した隠れ層の数に応じて、これを達成するために異なる関数を使用します。各関数では、入力ニューロンの数、各隠れ層のニューロンの数(使用されている場合)、そして最後に 出力層のニューロンの数を定義できます。

   if(m_hidden==0)
   {
      m_base.MLPCreateC0(m_inputs,m_outputs,m_network);
   }
   else if(m_hidden==1)
   {
      m_base.MLPCreateC1(m_inputs,m_hidden_1_size,m_outputs,m_network);
   }
   else if(m_hidden==2)
   {
      m_base.MLPCreateC2(m_inputs,m_hidden_1_size,m_hidden_2_size,m_outputs,m_network);
   }
   else if(m_hidden>2||m_hidden<0)
   {
      printf(__FUNCSIG__+" invalid number of hidden layers should be 0, 1, or 2. ");
      return(false);
   }

最後に、隠れ層と出力層の活性化関数と層バイアスを設定して終了します。Alglibクラスはかなり多用途であり、活性化関数とバイアスを各層だけでなく実際には各ニューロンに対してカスタマイズできます。ただし、この記事では、簡略化したものを検討します。

ネットワークの初期化と検証に加えて、ネットワークの理想的な重みをファイルし、必要に応じて読み取るシステムを介して学習するための適切な準備が必要です。ここではさまざまなアプローチが考えられますが、ここで使用するのは、EAのテスト基準が以前のベンチマークを上回ったテストに合格した後で単純にネットワーク重みの配列にファイルを書き込むことです。次回の実行時に、ネットワークはこれらの重みを読み取ることで初期化され、訓練を続けるたびに重みが改善されます。ファイルへの重みの書き込みと読み取りは、それぞれWriteWeights関数とReadWeights関数によっておこなわれます。

最後に、Process関数が新しいバーごとに実行され、新しいデータでネットワークを訓練し、変数Yと呼ばれる現在のシグナルを処理します。ここで注目すべき点がいくつかあります。まず、テストデータ行列m_xyを、行列内の各値が-1.0から+1.0の範囲内になるように列ごとに正規化する必要があります。上でほのめかしたように、これはAlglibクラス内の他の関数によって実行でき、それらはパーセプトロンクラスと同じファイルからのものです。もちろん、このアプローチをカスタマイズして状況により適したものにすることもできますが、ここでは組み込み関数を使用します。

      //normalise data
      CRowDouble _means,_sigmas;
      m_norm.DSNormalize(m_xy,m_training_points,m_inputs,_info,_means,_sigmas);

次に、ネットワークの訓練は、訓練プロセスを開始したばかりか、すでに訓練実行を実行しているかに応じて2つの関数によって実行されます。ランダムな重みを再び扱わないようにするために訓練を開始したら、前のパスから学習した重みを保存して、それらを使用して訓練を続けることができます。デフォルトのtrain関数は常に重みをランダム化します。これを使用すると、新しいバーごとに重みをランダム化することになります。

      m_train.MLPSetDataset(m_trainer,m_xy,m_training_points);
      //
      if(!m_in_training)
      {
         m_train.MLPStartTraining(m_trainer,m_network,false);
         m_in_training=true;
      }
      else if(m_in_training)
      {
         while(m_train.MLPContinueTraining(m_trainer,m_network))
         {
            //
         }
      }

ウィザードのおかげで、この完成したシグナルクラスをトレイリングクラスおよび資金管理クラスとEAにシームレスに統合できます。

<images:7 steps to assemble in wizard/>

上の7つの画像で強調表示されている7つの手順に従えば、最終的には以下のようなインクルードヘッダーを持つEAが得られるはずです。

//+------------------------------------------------------------------+
//| Include                                                          |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
//--- available signals
#include <Expert\Signal\My\SignalPerceptron.mqh>
//--- available trailing
#include <Expert\Trailing\TrailingNone.mqh>
//--- available money management
#include <Expert\Money\MoneyFixedMargin.mqh>

EAの組み立てとテスト

したがって、上記のスクリーンショットからわかるように、ウィザードを使用してカスタムエキスパートシグナルクラスをEAにまとめるのは簡単です。

s_1


s_4


s_5


s_6


s_7


最適化の前にコンパイルされたEAでバックテストを実行すると、次のレポートが得られます。

init_pass

ウォークフォワードウィドウを使用してEAの最適化を実行し、次の結果が得られたとします。

back_pass

forward_pass

私たちはパーセプトロンを訓練し、EAの最適化基準に基づいてその重みをエクスポートしました。これをより簡潔におこなう方法は、組み込みの相互検証機能を使用するか、バギングが使用されていない場合はレポートの二乗平均平方根誤差値などのより単純なものを使用することです。どちらのシナリオでも、訓練分類子と一致する可能性が高い重みを保存できます。テストから、ネットワークは有望であることを示していますが、いつものように、他の考慮事項の中でも特に証券会社のティックデータを使用して、より長いスパンでテストをより熱心におこなうことを念頭に置く必要があります。


結論

要約すると、Alglibコードクラスのおかげで、ユーザー側で最小限のコードでパーセプトロンを実装できる方法について見てきました。データセットの正規化など、パーセプトロンをテストして学習する価値がある前に実行する必要があるいくつかの予備手順を強調しました。さらに、テストの準備ができたパーセプトロンを入手したら、検討する価値のある追加の対策を示しました。これらすべての手順と、調整可能なパラメータのエクスポートなどの追加の手段は、Alglibクラスの補助コードによって実行されます。

したがって、Alglibクラスを使用する利点は主に、コードの量とテスト可能なシステムを構築するのにかかる時間を最小限に抑えることです。しかし、特にカスタマイズに関しては、やはり欠点もあります。たとえば、パーセプトロンは2つ以上の隠れ層を持つことはできません。複雑なデータセットがモデル化されているシナリオでは、これがボトルネックになります。


MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/13832

添付されたファイル |
MQL5.zip (11.41 KB)
ソフトウェア開発とMQL5におけるデザインパターン(第3回):振る舞いパターン1 ソフトウェア開発とMQL5におけるデザインパターン(第3回):振る舞いパターン1
デザインパターンの新しい記事として、その1タイプである振る舞いパターンを取り上げ、作成されたオブジェクト間の通信を効果的に構築する方法について説明します。これらの振る舞いパターンを完成させることで、再利用可能かつ拡張可能で、テストされたソフトウェアをどのように作成し、構築できるかを理解できるようになります。
MQL5を使ったシンプルな多通貨エキスパートアドバイザーの作り方(第4回):三角移動平均 — 指標シグナル MQL5を使ったシンプルな多通貨エキスパートアドバイザーの作り方(第4回):三角移動平均 — 指標シグナル
この記事の多通貨エキスパートアドバイザー(EA)は、1つの銘柄チャートからのみ複数の銘柄ペアの取引(注文を出す、注文を決済する、トレーリングストップロスとトレーリングプロフィットなどで注文を管理するなど)ができるEAまたは自動売買ロボットです。今回は、多時間枠または単一時間枠の「三角移動平均」という1つの指標のみを使用します。
プログラミングパラダイムについて(第1部):プライスアクションエキスパートアドバイザー開発の手続き型アプローチ プログラミングパラダイムについて(第1部):プライスアクションエキスパートアドバイザー開発の手続き型アプローチ
プログラミングパラダイムとMQL5コードへの応用について学びます。この記事では、手続き型プログラミングの具体的な方法について、実践的な例を通して説明します。EMA指標とローソク足の価格データを使って、プライスアクションエキスパートアドバイザー(EA)を開発する方法を学びます。さらに、この記事では関数型プログラミングのパラダイムについても紹介しています。
モデル解釈をマスターする:機械学習モデルからより深い洞察を得る モデル解釈をマスターする:機械学習モデルからより深い洞察を得る
機械学習は複雑で、経験を問わず誰にとってもやりがいのある分野です。この記事では、構築されたモデルを動かす内部メカニズムに深く潜り込み、複雑な特徴、予測、そしてインパクトのある決断の世界を探求し、複雑さを解きほぐし、モデルの解釈をしっかりと把握します。トレードオフをナビゲートし、予測を強化し、確実な意思決定をおこないながら特徴の重要性をランク付けする技術を学びます。この必読書は、機械学習モデルからより多くのパフォーマンスを引き出し、機械学習手法を採用することでより多くの価値を引き出すのに役立ちます。