English Русский 中文 Español Português
preview
取引におけるニューラルネットワーク:金融市場向けマルチモーダルツール拡張エージェント(FinAgent)

取引におけるニューラルネットワーク:金融市場向けマルチモーダルツール拡張エージェント(FinAgent)

MetaTrader 5トレーディングシステム |
14 2
Dmitriy Gizlyk
Dmitriy Gizlyk

はじめに

金融市場は、経済の安定維持、資本配分、リスク管理において重要な役割を果たしています。現代の金融取引システムは、テクニカル分析を広く活用することでこれらのプロセスを強化しています。しかし、市場の変動性や不確実性が高い状況では、従来のシステムはしばしば大きな制約に直面します。ルールベースの取引システムは柔軟性に欠け、急速に変化する市場環境への適応が難しく、効果が低下することが多いです。一方、強化学習(RL)ベースのシステムはより高い適応性を示しますが、次のような課題も抱えています。

  • 大量の学習データを必要とする
  • 意思決定の説明が難しい
  • 異なる市場環境への一般化が困難
  • 市場のノイズに敏感
  • マルチモーダル市場情報の統合が制限される

近年、大規模言語モデル(LLM)は意思決定の分野でも顕著な可能性を示しており、その応用は自然言語処理を超えて拡大しています。メモリやプランニングモジュールの統合により、LLMは動的に変化する環境に適応することが可能です。マルチモーダルLLMは、テキスト情報と視覚情報の両方を処理することでこの能力をさらに強化し、外部ツールの追加により、複雑な金融シナリオを含む幅広いタスクへの対応も可能になります。

しかし、金融データ分析におけるLLMエージェントにはいくつかの制約があります。

  • 数値データ、テキスト、視覚情報のマルチモーダル処理が限定的
  • 複数ソースからのデータ統合の精度が必要
  • 急速に変化する市場への適応性が低い
  • 専門知識や従来の手法の活用が困難
  • 意思決定の透明性が不十分

研究「A Multimodal Foundation Agent for Financial Trading:Tool-Augmented, Diversified, and Generalist」の著者らは、これらの課題を解決するためにFinAgentフレームワークを提案しました。FinAgentは、マルチモーダルの基盤エージェントとして、テキスト情報と視覚情報を統合し、市場の動向や履歴データを分析します。FinAgentの主要な構成要素には、重要な市場トレンドを特定するマルチモーダルデータ処理、短期および長期の意思決定を分析する二層のリフレクションモジュール、分析におけるノイズを最小化するメモリシステム、専門知識や高度な取引戦略を組み込む意思決定モジュールが含まれます。


FinAgentアルゴリズム

FinAgentフレームワークは、金融市場におけるデータ分析と合理的な意思決定のためのツールです。市場プロセスの理解、動向の予測、取引戦略の最適化をおこなうための一連の手段をユーザーに提供します。FinAgentは5つの主要モジュールで構成されており、これらが相互に連携することで、データ処理と意思決定のためのエコシステムを形成します。

マーケット分析モジュール(Market Analysis Module)は、市場ニュース、価格変動、企業レポートなど、さまざまなデータソースの収集、処理、解釈を担当します。高度な分析手法を用いて隠れたパターンを特定し、エージェントが現在の市場状況に応じて行動を適応させることを可能にします。

最大限の効率を実現するため、FinAgentは現在の市場データと蓄積された過去の情報の両方を分析します。ニュースや価格変動などの日次更新データは短期的な意思決定の基盤となります。一方で、過去のイベントを分析することで長期的なパターンを明らかにし、将来の運用に向けた堅牢な戦略の構築を可能にします。この二重のアプローチにより、高い適応性と柔軟性が確保されます。

FinAgentのデータ取得プロセスでは、大規模言語モデル(LLM)を用いて市場情報をテキストクエリに変換します。これらのクエリは、メモリモジュール内の履歴データベースから類似データを検索するために使用されます。ベクトル類似度手法の適用により検索精度が向上し、最も関連性の高い情報に焦点を当てることができます。さらに、専用のテキストフィールドを利用することでデータ処理が改善され、重要な詳細の欠落を防ぎます。得られたデータは構造化および要約され、分析が容易になり、副次的な情報の影響が最小化されます。

二層構造のリフレクションモジュールは、人間の学習プロセスに類似した機能を果たします。低レベルリフレクションモジュールは、価格変動と市場動向の相関を特定し、短期的な市場変動の予測を可能にします。これは、下位時間足で取引をおこなうトレーダーにとって特に重要です。一方、高レベルリフレクションモジュールは、過去データやこれまでの取引結果に基づき、より複雑で深い関係性を分析します。これにより、エラーの検出や修正戦略の策定が可能になります。このプロセスには、売買ポイントなどの重要な局面の可視化と、その有効性の評価が含まれます。反復的な学習アプローチにより、エージェントは経験を蓄積し、将来の行動改善に活用します。

記憶(メモリ)モジュールは、FinAgentの安定した動作を支える中核的な役割を担います。このモジュールはデータの保存と効率的な検索を担当します。ベクトル検索手法により、大規模データセット内から関連情報へ高速にアクセスでき、ノイズを低減し分析精度を向上させます。FinAGentにおける記憶機構は、重要なコンテキストと認知的能力を提供します。金融取引において記憶は、正確性、適応性、過去経験からの学習に不可欠です。現在のニュースやレポートを基に将来の市場変化を予測し、変動の激しい環境に適応しながら、戦略を継続的に洗練させることを可能にします。

意思決定モジュールは、市場サマリー、低レベルリフレクションによる価格動向分析、過去の意思決定から得られた知見などの重要データを統合し、処理します。また、専門的な投資助言や実績のある取引戦略を補完するツールも組み込まれています。このモジュールの重要な機能の一つが市場センチメント分析であり、現在の価格動向に基づいて強気または弱気のトレンドを予測し、過去の学習内容を反映します。さらに、専門家の助言を考慮し、従来型インジケーターの有効性も評価します。

これらの分析結果と現在の金融コンテキストを総合し、モジュールは最終的な判断、すなわち資産を買う、売る、または保有するかを決定します。文脈学習の原則を適用することで、論理的な意思決定構造が構築されます。これにより、すべての取引行動が妥当性を持ち、関連する市場動向を包括的に理解したうえで実行されることが保証されます。このアプローチは市場環境への適応力を高め、戦略的に合理的な意思決定を可能にします。

このように、FinAgentはデータ分析、リフレクション、プロセス自動化を統合した包括的なツールです。トレーダーやアナリストが市場に効果的に適応し、リスクを最小化し、収益性を向上させることを可能にし、戦略的計画における新たな可能性を切り開きます。

FinAgentフレームワークのオリジナルの可視化図は次のとおりです。

著者によるFinAgentフレームワークの可視化


MQL5での実装

FinAgentフレームワークの理論的側面を検討した後は、この記事の実践部分に進み、MQL5を使用して提案されたアプローチのビジョンを実装します。

これまでの研究と同様に、大規模言語モデルの使用は除外し、利用可能なツールを用いて提案手法を実装することが重要です。

本作業では、まず低レベルおよび高レベルのリフレクションモジュールの作成から始めます。

低レベルリフレクションモジュール

低レベルリフレクションモジュールの開発を開始するにあたり、FinAgentフレームワークの著者が提案したメモリモジュールのアーキテクチャに注目する必要があります。メモリモジュールは概念的に、市場分析モジュールと、異なるレベルの2つのリフレクションモジュールから情報を収集する3つのオブジェクトに分割できます。これにより、全体の情報フローを変更することなくモデルのモジュール構成を再編成し、個別のメモリブロックを対応するモジュールへ統合することが可能になります。この特性を活かし、本研究では、この情報ストリーム用のメモリブロックを低レベルリフレクションモジュールに組み込みます。

修正後の低レベルリフレクションモジュールは、CNeuronLowLevelReflectionオブジェクトとして実装されます。その構造を以下に示します。

class CNeuronLowLevelReflection :   public CNeuronMemory
  {
protected:
   CNeuronLSTMOCL    cChangeLSTM;
   CNeuronMambaOCL   cChangeMamba;
   CNeuronRelativeCrossAttention cCrossAttention[2];
   //---
   virtual bool      feedForward(CNeuronBaseOCL *NeuronOCL) override;
   virtual bool      calcInputGradients(CNeuronBaseOCL *NeuronOCL) override;
   virtual bool      updateInputWeights(CNeuronBaseOCL *NeuronOCL) override;

public:
                     CNeuronLowLevelReflection(void) {};
                    ~CNeuronLowLevelReflection(void) {};
   //---
   virtual bool      Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
                          uint window, uint window_key,
                          uint units_count, uint heads,
                          ENUM_OPTIMIZATION optimization_type, uint batch) override;
   //---
   virtual int       Type(void) override   const   {  return defNeuronLowLevelReflection; }
   //---
   virtual bool      Save(int const file_handle) override;
   virtual bool      Load(int const file_handle) override;
   //---
   virtual bool      WeightsUpdate(CNeuronBaseOCL *source, float tau) override;
   virtual void      SetOpenCL(COpenCLMy *obj) override;
   //---
   virtual bool      Clear(void) override;
  };

記憶オブジェクトを親クラスとして使用することで、市場情報の分析プロセスと認知的メモリ機能を統合した単一の情報パイプラインを構築できます。これにより、システムは生データを効率的に処理するだけでなく、過去の情報を考慮し、現在の分析に文脈を与えることが可能になります。

クラス構造には、さまざまなアーキテクチャを持つ再帰オブジェクトやクロスアテンションブロックが含まれています。これらのコンポーネントは、情報処理および意思決定において重要な役割を果たします。それぞれの目的や機能は、オブジェクトのメソッド実装の過程で詳細に説明されており、システム性能への影響をより深く理解できるようになっています。

すべての内部オブジェクトは静的として宣言されているため、コンストラクタとデストラクタを空のままにすることができます。これらの宣言済みおよび継承されたオブジェクトの初期化は、Initメソッド内でおこなわれます。

bool CNeuronLowLevelReflection::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
                            uint window, uint window_key, uint units_count, uint heads,
                                       ENUM_OPTIMIZATION optimization_type, uint batch)
  {
   if(!CNeuronMemory::Init(numOutputs, myIndex, open_cl, window, window_key, units_count, heads,
                                                                      optimization_type, batch))
      return false;

このメソッドのパラメータ構造は、親クラスから完全に継承されています。メソッド本体では、受け取ったすべてのパラメータを渡して、同名の親クラスメソッドを直ちに呼び出します。

親クラスのメソッドには、受け取ったパラメータの制御および継承オブジェクトの初期化をおこなうアルゴリズムがすでに実装されています。

次に、新たに宣言したオブジェクトの初期化をおこないます。まず、分析対象パラメータの動態を識別するために設計された2つの再帰オブジェクトを初期化します。これらに異なるアーキテクチャの設計を採用することで、より深い分析が可能となり、システムは短期的および長期的な変化の双方に効果的に適応し、複数の時間スケールにわたるトレンドを検出できるようになります。

   int index = 0;
   if(!cChangeLSTM.Init(0, index, OpenCL, window, units_count, optimization, iBatch))
      return false;
   index++;
   if(!cChangeMamba.Init(0, index, OpenCL, window, 2 * window, units_count, optimization, iBatch))
      return false;

分析結果はクロスアテンションブロックを介して統合され、異なるソースやレベルからの情報を効果的に結合し、パラメータ間の重要な関係性や依存関係に焦点を当てた統一的な解を形成します。クロスアテンションは、隠れたパターンや相互関連性の発見を促進し、意思決定の質を向上させるとともに、より正確で一貫性のある情報認識を可能にします。

   for(int i = 0; i < 2; i++)
     {
      index++;
      if(!cCrossAttention[i].Init(0, index, OpenCL, window, window_key, units_count, heads,
                                                window, units_count, optimization, iBatch))
         return false;
     }
//---
   return true;
  }

すべての内部オブジェクトの初期化が完了した後、処理の論理結果を呼び出し元プログラムに返し、メソッドの実行を終了します。

次の段階では、低レベルリフレクションモジュールのフィードフォワードアルゴリズムを構築します。これらはfeedForwardメソッド内に実装されます。

bool CNeuronLowLevelReflection::feedForward(CNeuronBaseOCL *NeuronOCL)
  {
   if(!cChangeLSTM.FeedForward(NeuronOCL))
      return false;
   if(!cChangeMamba.FeedForward(NeuronOCL))
      return false;

このメソッドは、環境の現在状態を記述した生データオブジェクトへのポインタを受け取ります。このデータは、パラメータの動態を識別するために、対応する再帰オブジェクトのメソッドへ渡されます。これにより、システムは環境変化を追跡し、それに応じて意思決定を適応させることが可能になります。

次に、クロスアテンションブロックを使用して、検出された変化に関する情報を現在の環境状態の記述へ付加します。これにより、新しいデータと既存データが統合され、文脈が強化されるとともに、環境動態の認識精度が向上します。このアプローチにより、分析対象状態の変化を反映した「軌跡トレース」が形成されます。

   if(!cCrossAttention[0].FeedForward(NeuronOCL, cChangeLSTM.getOutput()))
      return false;
   if(!cCrossAttention[1].FeedForward(cCrossAttention[0].AsObject(), cChangeMamba.getOutput()))
      return false;

分析結果は、親クラスによって実装されたメモリモジュールへ渡されます。このモジュールは持続的なトレンドを特定し、将来の価格変動を予測するための基盤を形成します。

   return CNeuronMemory::feedForward(cCrossAttention[1].AsObject());
  }

ご覧の通り、フィードフォワードパスでは、環境を記述する生データを3つの内部オブジェクトが処理します。そのため、バックプロパゲーションパスでは、これら3つすべての情報ストリームから誤差勾配を収集する必要があります。誤差勾配を分配するアルゴリズムは、calcInputGradientsメソッドに実装されています。

bool CNeuronLowLevelReflection::calcInputGradients(CNeuronBaseOCL *NeuronOCL)
  {
   if(!NeuronOCL)
      return false;

このメソッドは、同じ入力元データオブジェクトへのポインタを受け取ります。ただし今回は、入力データがモデルの出力に与える影響を反映した誤差勾配を渡します。まず、ポインタの有効性を確認します。これが無効な場合、データの伝播は不可能です。

親クラスを使用して、メモリモジュールを通じて誤差勾配をクロスアテンションブロックまで伝播させます。

   if(!CNeuronMemory::calcInputGradients(cCrossAttention[1].AsObject()))
      return false;
   if(!cCrossAttention[0].calcHiddenGradients(cCrossAttention[1].AsObject(),
                       cChangeMamba.getOutput(), cChangeMamba.getGradient(), 
                                (ENUM_ACTIVATION)cChangeMamba.Activation()))
      return false;

次に、得られた誤差を再帰ブロック間で分配します。

続いて、3つの情報ストリームを通じて誤差勾配を生入力レベルまで逆伝播させます。ここではまず、クロスアテンションブロックのパイプラインに沿って勾配を計算します。

   if(!NeuronOCL.calcHiddenGradients(cCrossAttention[0].AsObject(), cChangeLSTM.getOutput(),
                      cChangeLSTM.getGradient(), (ENUM_ACTIVATION)cChangeLSTM.Activation()))
      return false;

その後、生入力データオブジェクトの勾配バッファへのポインタを差し替え、再帰オブジェクトのパイプラインを通じて誤差を伝播させ、異なる情報ストリームから得られた値を加算します。

   CBufferFloat *temp = NeuronOCL.getGradient();
   if(!NeuronOCL.SetGradient(cChangeMamba.getPrevOutput(), false) ||
      !NeuronOCL.calcHiddenGradients(cChangeMamba.AsObject()) ||
      !SumAndNormilize(NeuronOCL.getGradient(), temp, temp, iWindow, false, 0, 0, 0, 1))
      return false;
   if(!NeuronOCL.calcHiddenGradients(cChangeLSTM.AsObject()) ||
      !SumAndNormilize(NeuronOCL.getGradient(), temp, temp, iWindow, false, 0, 0, 0, 1))
      return false;

最後に、データバッファへのポインタを元の状態に戻し、以降の処理で正しく使用できるようにします。

   if(!NeuronOCL.SetGradient(temp, false))
      return false;
//---
   return true;
  }

メソッドの最後で、処理結果の論理値が呼び出し元プログラムに返されます。

以上で、低レベルリフレクションモジュールにおける各メソッド構築アルゴリズムの説明は完了です。このクラスの完全なコードとすべてのメソッドは添付ファイルにあります。

高レベルリフレクションモジュール

次に、より深く包括的な依存関係の分析を目的とした高レベルリフレクションモジュールを作成します。現在の状態の短期的な変化や動態に焦点を当てる低レベルリフレクションモジュールとは異なり、高レベルリフレクションモジュールは、過去の取引操作から特定された長期的なトレンドや関係性を分析します。

このモジュールの主な目的は、これまでに下された意思決定の妥当性を徹底的に評価し、実際の結果を分析することです。このプロセスにより、現在の取引戦略がどれほど効果的に適用されているか、また設定された目標とどの程度整合しているかを評価できます。分析の重要な要素は、戦略の強みと弱みを特定することです。

さらに、高レベルリフレクションモジュールは、取引戦略を最適化するための具体的な提言を提供することが期待されます。これらの提言は、取引の収益性を向上させる、あるいはリスクを低減することを目的としています。

当然ながら、高レベルリフレクションモジュールの機能を完全に実装するには、より多くの入力データが必要です。まず、分析対象としてエージェントの実際の行動が必要となります。

さらに、意思決定がおこなわれた時点での環境状態の記述も必要です。これにより、各判断が特定の市場条件下でどれほど妥当であったか、またそれらの条件が結果にどのような影響を与えたかを評価できます。

同様に重要なのが損益情報です。これは、意思決定が財務結果にどのような影響を与えたかを評価するのに役立ちます。このデータは取引の成否を判断するだけでなく、調整が必要な戦略上の潜在的な弱点を特定することにもつながります。

さらに、高レベルリフレクションモジュールを効果的に機能させるためには、分析結果を将来の利用のために保存する必要があります。これにより、システムは過去の結論を考慮し、蓄積された経験に基づいて意思決定を改善できます。FinAgentフレームワークの著者らはこの要件を考慮し、対応するメモリモジュールブロックをアーキテクチャに組み込んでいます。

その結果、次の4つの入力情報ストリームが必要になります。

  • エージェントの行動
  • 環境状態
  • 財務結果(口座状態)
  • 記憶

しかし、現在のオブジェクト間データ交換インターフェースの実装では、2つの情報ストリームのみが許可されています。

低レベルリフレクションモジュールと同様に、高レベルリフレクションモジュールでも新しいオブジェクトの親クラスとしてメモリモジュールを使用します。この設計により、メモリストリームをオブジェクト内部で直接形成でき、追加の入力ソースが不要になります。その結果、モジュールの自律性が高まり、自身の構造内で効率的にデータを処理および保存できます。

また、高レベルリフレクションモジュールの出力は、エージェントの行動テンソルの潜在表現として解釈できる可能性があります。これは、エージェントの行動が本質的に本モジュールが提供する結果の関数であるためです。その結果、分析結果の変化はエージェント行動の調整に直接影響します。このアプローチにより、高レベルリフレクションから得られた情報に基づいてエージェントの行動が動的に最適化される、より適応的な行動モデルを構築できます。

以上の前提およびアーキテクチャ上の判断に基づき、2つの入力データソースを扱う新しいオブジェクトの基本的なインターフェースモデルを構築します。これらは、現在の状況と過去の行動結果を分析するために必要な情報を提供します。

ただし、もう一つ重要な側面があります。個々の取引のみに注目するのではなく、エージェント全体の行動方針を分析するために、FinAgentフレームワークの著者らは、実行された取引のマーカーを付加した口座残高チャートの分析を含めることを提案しています。このアプローチにより、エージェントの戦略結果を俯瞰的に把握できます。本実装では、口座状態およびエージェント行動を表すテンソルを処理するための再帰オブジェクトを追加することで、この手法を再現しています。これらのオブジェクトは、残高推移と取引行動の関係をモデル化し、適用された方針をより深く分析することを可能にします。

以上で説明したソリューションは、新しいオブジェクトCNeuronHighLevelReflectionに実装されています。このオブジェクトの構造を以下に示します。

class CNeuronHighLevelReflection :  public CNeuronMemory
  {
protected:
   CNeuronBaseOCL    cAccount;
   CNeuronLSTMOCL    cHistoryAccount;
   CNeuronRelativeCrossAttention cActionReason;
   CNeuronLSTMOCL    cHistoryActions;
   CNeuronRelativeCrossAttention cActionResult;
   //---
   virtual bool      feedForward(CNeuronBaseOCL *NeuronOCL) override { return false; }
   virtual bool      feedForward(CNeuronBaseOCL *NeuronOCL, CBufferFloat *SecondInput) override;
   virtual bool      calcInputGradients(CNeuronBaseOCL *NeuronOCL) override { return false; }
   virtual bool      calcInputGradients(CNeuronBaseOCL *NeuronOCL, CBufferFloat *SecondInput,
                                        CBufferFloat *SecondGradient, 
                                        ENUM_ACTIVATION SecondActivation = None) override;
   virtual bool      updateInputWeights(CNeuronBaseOCL *NeuronOCL) override {return false; }
   virtual bool      updateInputWeights(CNeuronBaseOCL *NeuronOCL, 
                                        CBufferFloat *SecondInput) override;

public:
                     CNeuronHighLevelReflection(void) {};
                    ~CNeuronHighLevelReflection(void) {};
   //---
   virtual bool      Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
                          uint window, uint window_key, uint units_count, uint heads,
                          uint desc_account, uint actions_state,
                          ENUM_OPTIMIZATION optimization_type, uint batch) override;
   //---
   virtual int       Type(void) override   const   {  return defNeuronHighLevelReflection; }
   //---
   virtual bool      Save(int const file_handle) override;
   virtual bool      Load(int const file_handle) override;
   //---
   virtual bool      WeightsUpdate(CNeuronBaseOCL *source, float tau) override;
   virtual void      SetOpenCL(COpenCLMy *obj) override;
   //---
   virtual bool      Clear(void) override;
  }; 

このオブジェクト構造には、既知のオーバーライド可能なメソッド一式が含まれており、全体のシステムアーキテクチャを損なうことなく、機能面での柔軟性と拡張性を提供します。さらに、新しいクラスには複数の内部オブジェクトが含まれており、それらの機能についてはメソッドの実装過程で詳細に説明します。

すべての内部オブジェクトは静的として宣言されているため、コンストラクタとデストラクタを空のままにすることができます。宣言済みおよび継承されたすべてのオブジェクトの初期化は、Initメソッド内でおこないます。

bool CNeuronHighLevelReflection::Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl,
                                      uint window, uint window_key, uint units_count,
                                      uint heads, uint desc_account, uint actions_state,
                                      ENUM_OPTIMIZATION optimization_type, uint batch)
  {
   if(!CNeuronMemory::Init(numOutputs, myIndex, open_cl, 3, window_key, actions_state / 3,
                           heads, optimization_type, batch))
      return false;

初期化メソッドは、作成されるオブジェクトのアーキテクチャを定義する一連の定数を受け取ります。このパラメータのうちの一つは、エージェントの行動ベクトルの次元数を指定します。

前述の通り、このオブジェクトの出力は、エージェントの行動テンソルの潜在表現を生成することが期待されています。エージェントの各取引操作は、取引量、ストップロスレベル、テイクプロフィットレベルの3つのパラメータで特徴づけられます。買い取引と売り取引は別々のテンソル行として表現されるため、取引方向を示す追加パラメータは不要です。

メソッド本体では、同名の親クラスメソッドを呼び出します(この場合はメモリモジュールを使用します)。パラメータには、前述の前提に従って構造化されたエージェント行動テンソルデータが含まれます。このアプローチにより、機能的な連続性を維持しつつ、親クラスのデータ処理機能を活用できます。これにより、現在のオブジェクトの分析結果を全体モデル構造に統合し、後続のオブジェクトでも一貫性とアクセス性を確保できます。

親クラスの処理が正常に実行された後、ネストされたオブジェクトを初期化します。まず、基本的な全結合層を初期化します。これは、2番目の情報ストリームを正しく処理するために使用されます。

   int index = 0;
   if(!cAccount.Init(0, index, OpenCL, desc_account, optimization, iBatch))
      return false;

次に、口座状態の変化を追跡するための再帰ブロックを初期化します。

   index++;
   if(!cHistoryAccount.Init(0, index, OpenCL, desc_account, 1, optimization, iBatch))
      return false;

最新の取引決定の妥当性を分析するため、クロスアテンションブロックを使用して、エージェントの行動と環境状態テンソル間の依存関係を検証します。

   index++;
   if(!cActionReason.Init(0, index, OpenCL, iWindow, iWindowKey, iUnits, iHeads,
                          window, units_count, optimization, iBatch))
      return false;

エージェントの行動の動態は、対応する再帰ブロックで収集されます。

   index++;
   if(!cHistoryActions.Init(0, index, OpenCL, iWindow, iUnits, optimization, iBatch))
      return false;

次に、クロスアテンションブロック内で、取引活動の動態と口座状態を比較することで、エージェントの方針の有効性を評価します。

   index++;
   if(!cActionResult.Init(0, index, OpenCL, iWindow, iWindowKey, iUnits, iHeads,
                          desc_account, 1, optimization, iBatch))
      return false;;
//---
   return true;
  }

すべての内部オブジェクトの初期化が完了した後、処理の論理結果を呼び出し元プログラムに返し、メソッドの実行を終了します。

次に、feedForwardメソッド内で高レベルリフレクションモジュールのフィードフォワードパスアルゴリズムを構築します。

bool CNeuronHighLevelReflection::feedForward(CNeuronBaseOCL *NeuronOCL, CBufferFloat *SecondInput)
  {
   if(!NeuronOCL || !SecondInput)
      return false;

このメソッドは、2つの情報ストリームの入力オブジェクトへのポインタを受け取ります。まず、ポインタの有効性を確認します。

なお、第2の情報ストリームはデータバッファとして表されます。以降の処理の前に、ポインタを用いてバッファを内部で特別に準備されたオブジェクトに差し替えます。これにより、内部オブジェクトの基本インターフェースを使用して受信データを処理できます。

   if(cAccount.getOutput() != SecondInput)
     {
      if(cAccount.Neurons() != SecondInput.Total())
         if(!cAccount.Init(0, 0, OpenCL, SecondInput.Total(), optimization, iBatch))
            return false;
      if(!cAccount.SetOutput(SecondInput, true))
         return false;
     }

次に、再帰ブロックを用いて口座状態の変化を評価します。

   if(!cHistoryAccount.FeedForward(cAccount.AsObject()))
      return false;

最新の取引決定の妥当性は、クロスアテンションブロックを使用して現在の環境状態と照らし合わせて確認します。

   if(!cActionReason.FeedForward(this.AsObject(), NeuronOCL.getOutput()))
      return false;

現在の環境状態を記述するテンソルと、意思決定に使用されるテンソルは区別することが重要です。モデルは、エージェントの行動が実行され、システムが新しい状態に遷移した後の環境状態テンソルを受け取ります。ただし、この違いが分析結果に大きな影響を与えることは想定されていません。

新しいバーが生成されるたびに、モデルの新しい反復が開始されます。分析対象となる履歴の深さは1バーを大きく超え、詳細かつ包括的な分析を可能にします。各状態遷移において、マルチモーダル時系列内のデータは1要素分シフトし、最も古いバーは除外されます。このバーは現在の行動に与える影響が最小であると考えられるため、除外しても分析への影響はほとんどありません。

意思決定時には未知であった新しいバーの追加は、取引の正当性を評価するための追加情報を提供します。この仕組みにより、取引の結果だけでなく、実際の市場変化と事前の予測との対応関係を評価できます。

分析結果は、エージェントの方針を監視するために再帰ブロックへ渡されます。

   if(!cHistoryActions.FeedForward(cActionReason.AsObject()))
      return false;

次に、クロスアテンションブロックを用いて、財務結果の文脈における方針を分析します。

   if(!cActionResult.FeedForward(cHistoryActions.AsObject(), cHistoryAccount.getOutput()))
      return false;

続いて、出力バッファを更新してエージェントの最新の行動を保持し、適切なバックワードパスを可能にします。その後、親クラスメソッドを呼び出して記憶モジュールの機能を実行します。

   if(!SwapBuffers(Output, PrevOutput))
      return false;
//---
   return CNeuronMemory::feedForward(cActionResult.AsObject());
  }

これらの操作の論理結果を呼び出し元プログラムに返して、メソッドを終了します。

フィードフォワードパスメソッドの実装が完了した後、バックプロパゲーションパスの整理に進みます。バックプロパゲーションの操作は線形アルゴリズムを使用するため、実装上大きな困難は生じません。そのため、詳細な説明は省略します。高レベルリフレクションオブジェクトおよびそのすべてのメソッドの完全なコードは添付ファイルで確認できます。

今回の記事はここで終了ですが、FinAgentフレームワークの実装に関する作業はまだ完了していません。ここで短い休憩を取り、次回の記事ではプロジェクトを論理的に完結させます。


結論

本記事では、FinAgentフレームワークを紹介しました。FinAgentは、テキスト情報と視覚情報を統合し、市場動向や履歴データの包括的な分析を可能にする革新的なソリューションです。5つの主要コンポーネントを用いることで、FinAgentは取引意思決定において高い精度と適応性を提供します。これにより、変動の激しい市場環境下でも運用可能な、効果的で柔軟な取引戦略を開発するための有望なツールとなります。

実践部分では、MQL5を用いて2つのリフレクションモジュールの自分たちの実装バージョンを構築しました。次回の記事では、フレームワークの完成と、実際の過去データを用いた実装ソリューションの有効性の検証をおこなう予定です。


参照文献


記事で使用されているプログラム

# 名前 種類 説明
1 Research.mq5 EA サンプル収集用EA
2 ResearchRealORL.mq5
EA
Real-ORL法を用いたサンプル収集用EA
3 Study.mq5 EA モデル訓練EA
4 Test.mq5 EA モデルテスト用EA
5 Trajectory.mqh クラスライブラリ システム状態とモデルアーキテクチャ記述構造
6 NeuroNet.mqh クラスライブラリ ニューラルネットワークを作成するためのクラスのライブラリ
7 NeuroNet.cl コードライブラリ OpenCLプログラムコード

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/16850

添付されたファイル |
MQL5.zip (2327.7 KB)
最後のコメント | ディスカッションに移動 (2)
Dominic Michael Frehner
Dominic Michael Frehner | 9 1月 2025 において 13:19

英語の記事も書いていただけるとうれしいです。

Fernando Carreiro
Fernando Carreiro | 21 10月 2025 において 14:06

どの言語で投稿しましたか?この記事は英語でも読めます.トレーディングにおけるニューラルネットワーク:金融市場のためのマルチモーダル、ツール拡張エージェント(FinAgent)

この記事は多言語に翻訳されているため、まさに多言語ディスカッショントピックです。

リスク管理(第1回):リスク管理クラス構築の基礎 リスク管理(第1回):リスク管理クラス構築の基礎
本記事では、取引におけるリスク管理の基礎を解説し、適切なロットサイズやストップロスを計算するための最初の関数の作成方法を学びます。さらに、これらの機能がどのように動作するのかを、各ステップを追いながら詳しく説明します。本記事の目的は、自動売買においてこれらの概念をどのように適用するかを明確に理解することです。最後に、インクルードファイルを使用したシンプルなスクリプトを作成し、すべてを実践に落とし込みます。
取引におけるニューラルネットワーク:金融市場向けマルチモーダルツール拡張エージェント(最終部) 取引におけるニューラルネットワーク:金融市場向けマルチモーダルツール拡張エージェント(最終部)
マルチモーダル市場の動向データと過去の取引パターンを分析するために設計されたマルチモーダル金融取引エージェント「FinAgent」のアルゴリズム開発を続けます。
初心者からエキスパートへ:パラメータ制御ユーティリティ 初心者からエキスパートへ:パラメータ制御ユーティリティ
従来のEAやインジケーターの入力プロパティを、リアルタイムで操作可能なオンチャートのコントロールインターフェースへと変換することを想像してみてください。本記事は、これまでに取り組んできたMarket Periods Synchronizerインジケーターでの基礎的な成果を土台とし、上位足(HTF)の市場構造を可視化し、管理する手法を大きく進化させるものです。ここでは、その概念を完全にインタラクティブなユーティリティへと昇華させ、動的な操作性と強化されたマルチタイムフレーム(MTF)のプライスアクションの可視化を、チャート上に直接統合したダッシュボードとして実装します。この革新的なアプローチが、トレーダーとツールの関わり方をどのように変えていくのか、一緒に見ていきましょう。
多通貨エキスパートアドバイザーの開発(第21回):重要な実験の準備とコードの最適化 多通貨エキスパートアドバイザーの開発(第21回):重要な実験の準備とコードの最適化
さらなる前進のためには、自動最適化を定期的に再実行し、新しいエキスパートアドバイザー(EA)を生成することで結果を改善できるかどうかを検証することが有益でしょう。パラメータ最適化の利用を巡る多くの議論における最大の障害は、取得したパラメータを将来の期間において、収益性およびドローダウンを所定の水準に保ったまま、どれだけ長く取引に使用できるのかという点です。そして、そもそもそれは可能なのかという問題でもあります。