English Русский Español Deutsch
preview
新しい指標と条件付きLSTMの例

新しい指標と条件付きLSTMの例

MetaTrader 5 | 10 12月 2024, 10:51
307 0
Javier Santiago Gaston De Iriarte Cabrera
Javier Santiago Gaston De Iriarte Cabrera

はじめに

金融市場のダイナミックな世界では、トレーダーやアナリストは常に、競合他社よりも優位に立つための新しい創造的な方法を模索しています。この記事では、ディープラーニングの予測スキルと従来のテクニカル分析の強みを組み合わせた、自動取引の新しい方法について検討します。複雑な条件付き長期短期記憶(LSTM)ニューラルネットワークモデルと独自のテクニカル指標であるボラティリティ調整モメンタム(VAM)を融合することで、現代の市場の複雑さに対応できる安定した柔軟な取引手法の開発を目指します。

テクニカル指標は、金融業界ではトレンドや潜在的な取引機会を見つけるために長い間使用されてきました。これらの指標は重要であるにもかかわらず、特に極端なボラティリティや突然の変化の時期には、市場の動向の複雑さを十分に捉えきれないことがよくあります。しかし、特にLSTMなどのディープラーニングアーキテクチャは、複雑で時間に依存するデータにおけるパターン認識と予測のための機械学習モデルにおいて驚くべき可能性を実証しています。ただし、これらのモデルは、従来のテクニカル分析のような解釈可能性とドメイン固有の知識を常に提供するわけではありません。

私たちの戦略は、両方のアプローチの利点を融合することでこのギャップを埋めることを目指しています。この記事では、基礎となるボラティリティを考慮しながら市場の勢いを測定しようとする、ボラティリティ調整モメンタム(VAM)指標と呼ばれる新しいツールを紹介します。従来のモメンタム指標と比較すると、市場の動向をより詳細に把握できます。VAMは、ボラティリティを考慮して、平穏から荒波までさまざまな市場シナリオでより信頼性の高いシグナルを提供することを目指しています。

VAM指標を強化するために、追加のコンテキストデータを含むシーケンシャルデータを処理するように調整された再帰型ニューラルネットワークの一種である条件付きLSTMモデルを利用します。このモデルは過去の価格データとテクニカル指標を使用して訓練されているため、従来の分析手法では見逃される可能性のある複雑で非線形な市場関連性を識別できます。LSTMの「条件付き」機能により、モデルはより多くの市場変数を考慮でき、より正確でコンテキストを認識した予測が可能になります。

EAは、VAM指標と条件付きLSTMモデルの予測を組み合わせた特別に設計された自動取引システムであり、私たちの戦略の頭脳です。このEAは、両方のコンポーネントからのシグナルを使用して、有名なMetaTrader 5プラットフォームに統合され、トレーダーが十分な情報に基づいた意思決定をおこなうのに役立ちます。さらに、市場の変動に応じて利益確定レベルと損切りレベルを変更する動的なリスク管理機能も備えています。

この投稿では、条件付きLSTMおよびVAM指標モデルの理論的根拠を検討し、それぞれの利点と、これらを最も効果的に連携させる方法についての洞察を提供します。データの準備、モデルの訓練、およびMetaTrader 5環境での統合作業を含む、EAの作成と実践の各ステップについて説明します。さらに、包括的な最適化とバックテストの結果を紹介し、VAMのみの手法とVAMと条件付きLSTMを組み合わせた手法の有効性を比較します。

この新しい取引戦略を調査しながら、最先端の機械学習手法と従来のテクニカル分析を融合する際の困難さと要因について説明します。私たちは、データの品質やモデルの解釈可能性から、リアルタイムの取引状況で複雑なモデルを実行するための計算要件まで、このようなシステムを導入するための実用的な要素の徹底的な概要を提供することを目指しています。

このエッセイを読み終える頃には、読者は最先端の機械学習技術をどのように活用して従来のテクニカル分析を強化し、取引結果を改善する可能性があるのかを徹底的に理解できるようになります。自動取引におけるVAMと条件付きLSTMに関するこの調査は、トレーダー、データサイエンティスト、または定量的金融の限界を調査している研究者としての経歴に関係なく、アルゴリズム取引の将来に関する洞察に満ちた情報を提供します。

ボラティリティ調整モメンタム(VAM)

VAMの中心的な概念は、モメンタムを評価する際に市場のボラティリティを考慮することです。現在の価格と過去の価格(モメンタム)の差を計算し、それをボラティリティとモメンタム期間の平方根の積で割ります。この値は係数でスケーリングされ、最近の市場変動に合わせて調整された勢いの強さを示します。

ディープラーニングモデル

この記事では、金融時系列データに適した再帰型ニューラルネットワーク(RNN)の一種である条件付きLSTMモデルを利用します。このモデルは、過去の価格データとテクニカル指標(ここで使用されているMACDなど)を入力として受け取り、将来の価格変動を予測します。条件付きLSTMの利点は、さまざまな市場要因間の複雑な関係を捉えることができる点にあります。

EA

この記事では、ディープラーニングモデルの予測とVAMを組み合わせたEAの作成について説明します。主な機能の概要は次のとおりです。

  • 初期化:EAは、事前訓練済みのONNXディープラーニングモデルの入力および出力パラメータを読み込んで構成します。
  • データの取得と正規化:EAはMACDの読み取り値と以前の価格データを収集します。これらの変数をディープラーニングモデルに入力する前に、それらを正規化します。
  • VAM計算:EAは、過去および現在の価格データを使用して、VAM指標を計算します。
  • 取引ロジックと予測:EAはディープラーニングモデルから価格予測を取得します。
予測とVAM値を組み合わせます。

  • VAMが高く、予測が価格上昇を示している場合、EAは買い取引を開始します。
  • 対照的に、VAMが低く、予測が価格の下落を示している場合、EAは売り取引を開始します。

EAは、ATRに基づき、ストップロスとテイクプロフィットのレベルを動的に調整してリスクを管理します。

結果

この記事では、条件付きLSTM戦略の有無にかかわらずVAMを使用したEAのバックテスト結果について説明します。


新しい指標(VAM)の作成

たとえば次のような新しい指標を作成するとどうなるでしょうか。

// Calcular Momentum
   double momentum = close_price - iClose(NULL, 0, momentum_period);

// Calcular Volatilidad
   double volatility = iMA(NULL, 0, volatility_period, 0, MODE_SMA, PRICE_CLOSE);

// Calcular VAM
   double vam =( momentum / (volatility * MathSqrt(momentum_period)))*10000;

モメンタムとボラティリティを使用して新しい指標を作成します。この指標はVAMと呼ばれます。

モメンタムは、モメンタム期間の平方根とボラティリティの積で割ります。

スケーリングの目的で、結果は10,000倍されます。

VAM指標はボラティリティを考慮して、勢いを定量化しようとします。これは、モメンタムをボラティリティで割ることで、さまざまな市場状況にわたってモメンタムを均等化しようとします。モメンタム期間の分母の平方根は、さまざまな期間にわたって指標を標準化するのに役立ちます。

正のVAM値は上昇の勢いを示し、負の値は下降の勢いを示します。VAMの大きさは、最近の市場変動性に合わせて調整された勢いの強さを表します。

この指標は、市場のボラティリティを考慮しながら、潜在的なトレンドの反転を特定したり、現在の市場トレンドの強さを測定したりするために使用できます。

この指標だけでEAを作成し、収益性があるかどうかを確認できます。

戦略は次のようになります。

void OnTick()
  {
   int bars = iBars(NULL, 0);
   if(bars < MathMax(momentum_period, MathMax(volatility_period, (vam_period))))//, MathMax(ma_long_period, rsi_period)))))
      return;

   double close_price = iClose(NULL, 0, 0);

// Calcular Momentum
   double momentum = close_price - iClose(NULL, 0, momentum_period);

// Calcular Volatilidad
   double volatility = iMA(NULL, 0, volatility_period, 0, MODE_SMA, PRICE_CLOSE);

// Calcular VAM
   double vam =( momentum / (volatility * MathSqrt(momentum_period)))*10000;


   double atr = iATR(_Symbol,PERIOD_CURRENT,14)*_Point;
   double Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double slPriceBuy = NormalizeDouble(Bid - slmul*atr,_Digits);
   double tpPriceBuy = NormalizeDouble(Ask + tpmul*atr,_Digits);
   double slPriceSell = NormalizeDouble(Ask + slmul*atr,_Digits);
   double tpPriceSell = NormalizeDouble(Bid - tpmul*atr,_Digits);

// Señales
   if(vam > VAMTHRESH)// && ma_short > ma_long)// && rsi < 70 && ma_short > ma_long )
     {
      // Comprar
      trade.Buy(lot_size,_Symbol,   Ask, slPriceBuy, tpPriceBuy, " BUY EA ");
     }
   else
      if(vam < -VAMTHRESH)// && ma_short < ma_long)// rsi > 30 && ma_short < ma_long )
        {
         // Vender
         trade.Sell(lot_size,_Symbol,   Bid, slPriceSell, tpPriceSell, " SELL EA ");
        }
  }

関数iBars(NULL, 0):指定された銘柄と時間枠でアクセス可能なバーの合計数を生成します。
bars int:バーの合計数、または返された値は、bars変数に格納されます。

MathMax:この関数は、指定された数値の最大値を返します。この例では、ネストは複数の期間にわたる最大値を決定するために使用されます。

以前に確立された変数momentum_period、volatility_period、vam_period、ma_long_period、rsi_periodは、さまざまな指標または計算の間隔を示します。

If:条件は、バーの合計数が割り当てられた時間の合計よりも少ないかどうかを判断します。

「if」条件がtrueの場合(つまり、バーが足りない場合)、関数は直ちに停止し、残りのコードは実行されません。


VAMの結果

結果は次のようになります(簡単な最適化の後、完了していません)。

設定VAM

入力VAM

グラフVAM

VAMバックテスト

シンプルな戦略とシンプルな指標としては、これは良いようです。

これにディープラーニングモデルを使用した場合に何を達成できるかを見てみましょう(ただし、今日は別のものを使用します)。いくつかの指標を使用してディープラーニングモデルを作成し、どれがより適合するかを確認します。


ディープラーニングモデル

このモデルをONNXでエクスポートしますが、まずはどちらが優れているかを比較します。

これらすべてを実行するには、Google Colabと、添付されているPythonスクリプトを使用します(PCのリソースを消費しないようにするため)。

これはMQL5 Webなので、Pythonコードについては説明しません。

pyスクリプトは2つあります。最初のものはすべての指標が使用されているpyスクリプトで、2番目は同じスクリプトですが、MACD指標のみを使用しています(最初のスクリプトでは、MACDはヒット率とR2が高く、エラーが少ないと想定していたため)。

最初のスクリプトからのグラフィック結果は次のとおりです。

ヒット率

MAE比較

MAPE比較

r2比較

RMSE比較

MACDを使用することを決定したら、スクリプトを準備し、2024年1月1日の日付を合わせました(2024年1月1日以降の結果をMQL5でバックテストできるようにします)。

2番目のスクリプトの結果は次のようになります(非常に似ています)。

ヒット率2

などなど...(自分で作ってcolabで結果を確認することもできます)。

PythonスクリプトはColab用です。最初に最初のセルを実行し、すべてのライブラリがインストールされたら2番目のセルを実行し、それを承認してモデルとグラフをドライブに保存し、完了するまで待機します。

MetaTraderがColabにインストールされていないため、データはmlq5から取得されます(値は類似しているはずです)。

2番目の画像グループでわかるように、MACDモデルのヒット率は非常に高いため、これを選択しました。


条件付きLSTM

従来の長期短期記憶ニューラルネットワークの拡張バージョンは、条件付きLSTMと呼ばれます。LSTMアーキテクチャの予測プロセスにさらに多くのコンテキストデータまたは状況を追加することで、予測プロセスが改善されます。金融市場では価格変動に非常に多くの要因が影響するため、金融市場の予測にとって特に興味深いものです。

株式や外国為替の予測の分野で効果的なツールは、条件付きロジスティック回帰マシンです。これにより、モデルは過去の価格データに加えて、さまざまな市場指標や外部変数を考慮できるようになります。これには、感情データ、より一般的な経済指標、RSIや移動平均などのテクニカル指標が含まれる場合があります。このモデルは、これらの多くの入力を統合することで、市場の動向をより包括的に把握することを目指しています。

条件付きLSTMの主な利点の1つは、文脈認識能力です。金融市場は、さまざまな変数の影響を受ける複雑なシステムです。条件付きLSTMは複数の指標を組み合わせることができるため、多数の市場動向間の複雑な相関関係を明らかにできる可能性があります。静的な特徴と時系列データの両方を管理できるため、過去の傾向と現在の状況が同様に重要な金融市場に最適です。

さらに、条件付きLSTMは、従来のLSTMと同様に、時系列データの長期的な依存関係をキャプチャするのに優れています。これは、長期的なパターンが現れる可能性がある金融市場で特に役立ちます。このモデルは、拡張されたシーケンス全体にわたって関連情報を保持する能力があるため、より単純なモデルでは見逃される可能性のあるパターンを検出できます。

ただし、金融予測に条件付きLSTMを使用するには、一定の困難が伴います。モデルの複雑さが増すことには利点もあるかもしれませんが、課題も生じます。訓練が複雑になるにつれて、特に小さなデータセットを扱う場合には、過剰適合が発生する可能性が高くなります。この複雑さによりコンピューティングコストが上昇し、これがリアルタイム取引アプリケーションでは大きな要因となる可能性があります。

条件付きLSTMでは、データの品質と関連性がさらに重要になります。モデルには価格データだけでなく、高品質で関連性の高い指標データも必要です。金融市場の急速に変化する、時には不透明な世界では、これらすべての側面にわたって一貫性のある正確なデータを確保することは困難な場合があります。

条件付きLSTMの可能性を評価する際には、金融市場の基本的な性質を考慮することも重要です。市場は予測不可能な出来事や人間の行動の影響を受けるため、どれほど洗練された予測モデルであってもその有効性が制限される可能性があります。このモデルは、過去のデータにおけるパターンの識別には優れているかもしれませんが、前例のない市場状況や大きな経済ショックに直面すると苦戦する可能性があります。

多くのディープラーニングモデルと同様に、条件付きLSTMのもう1つの問題は解釈可能性です。正確な予測を生成できたとしても、その背後にある理由を理解するのは難しい場合があります。この「ブラックボックス」の側面は、説明可能性とオープン性が頻繁に必要となる金融アプリケーションでは問題を引き起こす可能性があります。

最後に、条件付きLSTMは指標ベースの株式およびFX予測にとって興味深い機会を秘めていますが、慎重にアプローチすることが重要です。複雑で多面的なデータを取り込む能力により、より正確で微妙なニュアンスに富んだ予測が可能になります。ただし、複雑性の増大、データ要件、金融市場の本質的な予測不可能性によって生じる困難さのため、これらは、より包括的で慎重に検討された分析アプローチのコンポーネントとして利用する必要があります。実際の状況でのモデルの限界を十分に理解し、広範囲にわたるバックテストを実施する必要があります。このような高度な技術を金融取引のハイリスクな分野に適用するには、広範なバックテストと実際の設定におけるモデルの限界に関する知識が必要です。

モデル(pyスクリプトで作成されたもの)は次のようになります。

ONNXモデル

入力と出力は次のようになります。

入力と出力ONNXモデル


EAコード

このEAの主な目的は、テクニカル指標とディープラーニング(ONNX)モデルからの予測の組み合わせに基づいて取引の決定を自動化することです。EAは、ボラティリティ調整モメンタム(VAM)指標とMACD(移動平均収束拡散)、および機械学習モデルによる価格予測を使用します。これらの要素の組み合わせに応じて取引を実行します。

EAは、いくつかのプロパティとライブラリを定義することから始まります。取引実行用のCTradeクラスと、統計関数および配列管理用のその他のヘッダーが含まれています。VAMの計算と取引実行には、momentum_period、volatility_period、vam_periodなどの入力パラメータが定義されており、これらはモメンタムとボラティリティを計算するロジックを制御するために使用されます。lot_sizeなどの取引パラメータや、ストップロス(slmul)とテイクプロフィット(tpmul)の乗数もここで定義され、EAの動作に柔軟性が提供されます。さらに、データがディープラーニングモデルに渡される方法を管理するために、BATCH_SIZE、SEQUENCE_LENGTHなどのONNXモデルパラメータを定義する定数も含まれています。

//+------------------------------------------------------------------+
//|                                                      VAM + DL(MACD) EA |
//|                                      Copyright 2024, Javier Santiago Gaston de Iriarte Cabrera |
//|                                       https://www.mql5.com/ja/users/jsgaston/news |
//+------------------------------------------------------------------+
#property copyright "Javier Santiago Gaston de Iriarte Cabrera"
#property link      "https://www.mql5.com/ja/users/jsgaston/news"
#property version   "1.01"


#include <Trade\Trade.mqh>
#include <Math\Stat\Math.mqh>
#include <Arrays\ArrayFloat.mqh>

CTrade trade;

// Inputs
input int momentum_period = 13;
input int volatility_period = 7;
input int vam_period = 9;
input double lot_size = 0.01;
input int slippage = 3;
input double VAMTHRESH = 9.0;
input int slmul = 2;
input int tpmul = 4;

// ONNX model parameters
#define BATCH_SIZE 1
#define SEQUENCE_LENGTH 30
#define INPUT_FEATURES 3
#define CONDITION_FEATURES 2
#define HIDDEN_DIM 128
#define NUM_LAYERS 2

float input_x[][SEQUENCE_LENGTH][INPUT_FEATURES];
float input_condition[][CONDITION_FEATURES];
float h0[][BATCH_SIZE][HIDDEN_DIM];
float c0[][BATCH_SIZE][HIDDEN_DIM];

#define PRICE_UP   0
#define PRICE_SAME 1
#define PRICE_DOWN 2

long ExtHandle = INVALID_HANDLE;
int ExtPredictedClass = -1;
datetime ExtNextBar = 0;
datetime ExtNextDay = 0;
float ExtMin = 0.0;
float ExtMax = 1.0;  // Initialize to 1.0 to prevent division by zero
float predicted_last;

#resource "/Files/stock_prediction_model_MACD.onnx" as uchar ExtModel[]

初期化関数OnInit()は、バイナリリソース(stock_prediction_model_MACD.onnx)からONNXモデルをロードし、モデルの入力と出力の形状を設定するため、非常に重要です。ONNXモデルへの入力は、過去の価格データ、MACD値、およびモデルの再帰層の初期化された隠し状態とセル状態(h0、c0)で構成されます。モデルが正常にロードされると、関数は最小価格値と最大価格値(ExtMinとExtMax)も初期化します。これらは、入力データをONNXモデルに正規化するために使用されます。モデルの読み込み中にエラーが発生した場合は、INIT_FAILEDが返され、EAの動作が事実上停止します。

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   Print("BATCH_SIZE: ", BATCH_SIZE, ", CONDITION_FEATURES: ", CONDITION_FEATURES);
   ExtHandle = OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT);
   if(ExtHandle == INVALID_HANDLE)
     {
      Print("OnnxCreateFromBuffer error ", GetLastError());
      return(INIT_FAILED);
     }

// Set input shapes
   long input_shape[] = {BATCH_SIZE, SEQUENCE_LENGTH, INPUT_FEATURES};
   if(!OnnxSetInputShape(ExtHandle, ONNX_DEFAULT, input_shape))
     {
      Print("OnnxSetInputShape for input_x error ", GetLastError());
      return(INIT_FAILED);
     }

   long condition_shape[] = {BATCH_SIZE,CONDITION_FEATURES};
   if(!OnnxSetInputShape(ExtHandle, 1, condition_shape))
     {
      Print("OnnxSetInputShape for input_condition error ", GetLastError());
      return(INIT_FAILED);
     }

   long h0_shape[] = {NUM_LAYERS, BATCH_SIZE, HIDDEN_DIM};
   if(!OnnxSetInputShape(ExtHandle, 2, h0_shape))
     {
      Print("OnnxSetInputShape for h0 error ", GetLastError());
      return(INIT_FAILED);
     }

   long c0_shape[] = {NUM_LAYERS, BATCH_SIZE, HIDDEN_DIM};
   if(!OnnxSetInputShape(ExtHandle, 3, c0_shape))
     {
      Print("OnnxSetInputShape for c0 error ", GetLastError());
      return(INIT_FAILED);
     }



   const long output_shape[] = {1,1};
   if(!OnnxSetOutputShape(ExtHandle,0,output_shape))
     {
      Print("OnnxSetOutputShape error ",GetLastError());
      return(INIT_FAILED);
     }

// Initialize ExtMin and ExtMax
   GetMinMax();

   Print("Initializing EA with VAM and ONNX integration");
   return(INIT_SUCCEEDED);
  }

OnTick()関数は、すべての価格ティックで実行されるコアロジックです。まず、新しい日かどうかを確認し、それに応じてGetMinMax()を使用して最小価格と最大価格を更新します。次のブロックは、新しい価格バーが利用可能になった場合にのみ関数が続行されることを保証します。次に、EAはExtMinおよびExtMax変数を最新の価格値に更新します。この機能の中心は、VAM計算とONNX予測の組み合わせです。VAMは、価格差(モメンタム)をボラティリティとmomentum_periodの平方根の積で割り、10,000倍して計算されます。VAMが閾値(VAMTHRESH)を超えると、市場に強いトレンドがあることを示し、取引の可能性があることを知らせます。 

次に、EAは予測とVAMの結果を組み合わせます。VAMが高く(VAMTHRESHより大きい)、ONNXモデルが価格上昇を予測する場合、EAはATRに基づいて計算されたストップロスとテイクプロフィットで買い取引を開始します。同様に、VAMが低く(負のVAMTHRESHを下回る)、ONNXモデルが価格の下落を予測した場合、EAは売り取引を開始します。これらの取引は、MetaTrader 5プラットフォームの取引機能と対話するCTradeクラスを使用して実行されます。

リスク管理の観点から、ストップロスとテイクプロフィットのレベルは、資産のATRに基づいて動的に計算されます。これにより、戦略が市場のボラティリティに合わせて調整され、現在の市場状況に応じてより適応性の高い取引終了が可能になります。

void OnTick()
  {
// Check for new day and update ExtMin and ExtMax
   if(TimeCurrent() >= ExtNextDay)
     {
      GetMinMax();
      ExtNextDay = TimeCurrent() - TimeCurrent() % PeriodSeconds(PERIOD_D1) + PeriodSeconds(PERIOD_D1);
     }

// Check for new bar
   if(TimeCurrent() < ExtNextBar)
      return;
   ExtNextBar = TimeCurrent() - TimeCurrent() % PeriodSeconds() + PeriodSeconds();

// Update ExtMin and ExtMax
   double close = iClose(_Symbol, _Period, 0);
   if(ExtMin > close)
      ExtMin = (float)close;
   if(ExtMax < close)
      ExtMax = (float)close;

   int bars = iBars(_Symbol, PERIOD_CURRENT);
   if(bars < MathMax(momentum_period, MathMax(volatility_period, MathMax(vam_period, SEQUENCE_LENGTH))))
      return;

// Calculate VAM
   double momentum = close - iClose(_Symbol, PERIOD_CURRENT, momentum_period);
   double volatility = iStdDev(_Symbol, PERIOD_CURRENT, volatility_period, 0, MODE_SMA, PRICE_CLOSE);
   double vam = (momentum / (volatility * MathSqrt(momentum_period))) * 10000;
   Print("VAM ", vam);

// Get ONNX prediction
   int result=GetPrediction();

// Trading logic combining VAM and ONNX prediction
   double atr = iATR(_Symbol, PERIOD_CURRENT, 14)*_Point;
   double Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double slPriceBuy = NormalizeDouble(Bid - slmul * atr, _Digits);
   double tpPriceBuy = NormalizeDouble(Ask + tpmul * atr, _Digits);
   double slPriceSell = NormalizeDouble(Ask + slmul * atr, _Digits);
   double tpPriceSell = NormalizeDouble(Bid - tpmul * atr, _Digits);
   
   //Print(result);

   if(vam > VAMTHRESH && result == 0)
     {
      trade.Buy(lot_size, _Symbol, Ask, slPriceBuy, tpPriceBuy, "BUY VAM+ONNX");
     }
   else
      if(vam < -VAMTHRESH && result == 2)
        {
         trade.Sell(lot_size, _Symbol, Bid, slPriceSell, tpPriceSell, "SELL VAM+ONNX");
        }
  }

ONNXモデルの予測は、GetPrediction()を呼び出すことによって取得されます。モデルへの入力はPrepareInputs()関数によって準備されます。この関数は、過去の終値とMACDデータを収集し、価格範囲(ExtMinとExtMax)を使用してそれらを正規化し、モデルが期待する入力配列を入力します。隠し状態(h0、c0)をリセットしながら、入力価格シーケンス(input_x)とMACDベースの条件(input_condition)のデータを設定します。入力の準備が整うと、モデルはOnnxRun()関数によって実行され、予測価格が計算されます。予測価格と前回の予測価格の差は、モデルが価格が上がるか、下がるか、あるいは同じままかを予測するために使用されます。予測の変化が小さすぎる場合、モデルは動きがない(価格は同じまま)と示唆します。

void PrepareInputs()
  {
   ArrayResize(input_x, BATCH_SIZE);
   ArrayResize(input_condition, BATCH_SIZE);
   ArrayResize(h0, NUM_LAYERS);
   ArrayResize(c0, NUM_LAYERS);

   for(int i = 0; i < SEQUENCE_LENGTH; i++)
     {
      input_x[0][i][0] = (float)((iClose(_Symbol, PERIOD_CURRENT, i) - ExtMin) / (ExtMax - ExtMin));

      double macd_main[], macd_signal[];
      int macd_handle = iMACD(_Symbol, PERIOD_CURRENT, 12, 26, 9, PRICE_CLOSE);
      CopyBuffer(macd_handle, 0, i, 1, macd_main);
      CopyBuffer(macd_handle, 1, i, 1, macd_signal);
      input_x[0][i][1] = (float)((macd_main[0] - ExtMin) / (ExtMax - ExtMin));
      input_x[0][i][2] = (float)((macd_signal[0] - ExtMin) / (ExtMax - ExtMin));
     }

   double macd_main2[], macd_signal2[];
   int macd_handle2 = iMACD(_Symbol, PERIOD_CURRENT, 12, 26, 9, PRICE_CLOSE);
   CopyBuffer(macd_handle2, 0, 0, 1, macd_main2);
   CopyBuffer(macd_handle2, 1, 0, 1, macd_signal2);
   input_condition[0][0] = (float)macd_main2[0];
   input_condition[0][1] = (float)macd_signal2[0];

   ArrayInitialize(h0, 0.0f);
   ArrayInitialize(c0, 0.0f);
  }
//+------------------------------------------------------------------+
//| Get prediction from ONNX model                                   |
//+------------------------------------------------------------------+
int GetPrediction()
  {
   PrepareInputs();
   

   float output_data[];
   ArrayResize(output_data, 1);

// Run the ONNX model
   if(!OnnxRun(ExtHandle,
               ONNX_NO_CONVERSION,
               input_x,
               input_condition,
               h0,
               c0,
               output_data))
     {
      Print("OnnxRun error: ", GetLastError());
      return ExtPredictedClass = -1;
     }

   float predicted=output_data[0]*(ExtMax-ExtMin)+ExtMin;
   Print("Predicted last ", predicted_last);
   Print("Predicted ",predicted);
   float last_close = (float)iClose(_Symbol, PERIOD_CURRENT, 0);
   Print("last close ",last_close);
   float delta = predicted_last - predicted;
   predicted_last=predicted;
   Print("Delta ",delta);

   if(MathAbs(delta) <= 0.00001)
      ExtPredictedClass = PRICE_SAME;
   else
      if(delta < 0)
         ExtPredictedClass = PRICE_UP;
      else
         ExtPredictedClass = PRICE_DOWN;
   Print(ExtPredictedClass);

   return ExtPredictedClass;
   
  }

GetMinMax()関数は、データの最終日における最小(ExtMin)および最大(ExtMax)の価格値を設定する役割を果たします。これらの値は、入力をONNXモデルに渡す前に正規化するために使用され、モデルが一貫した範囲で入力を受け取ることが保証されます。EAが必要な価格データを取得できない場合、ゼロ除算を回避するためにデフォルトで安全な範囲に設定されます。

void GetMinMax()
  {
   double close[];
   int copied = CopyClose(_Symbol, PERIOD_D1, 0, SEQUENCE_LENGTH, close);

   if(copied > 0)
     {
      ExtMin = (float)MathMin(close);
      ExtMax = (float)MathMax(close);
     }
   else
     {
      Print("Failed to copy price data. Error: ", GetLastError());
      ExtMin = 0;
      ExtMax = 1;  // Prevent division by zero
     }
  }

最後に、EAには、EAが削除されたときにONNXモデルハンドルを解放する初期化解除関数OnDeinit()が含まれており、メモリが適切に管理され、リソースリークが回避されます。

void OnDeinit(const int reason)
  {
   if(ExtHandle != INVALID_HANDLE)
     {
      OnnxRelease(ExtHandle);
      ExtHandle = INVALID_HANDLE;
     }
  }

要約すると、このEAは、テクニカル分析(VAMおよびMACD経由)とONNXモデルからの機械学習予測を組み合わせて、情報に基づいた自動取引決定をおこないます。テクニカル分析はトレンドの発見に役立ち、機械学習モデルは価格変動を予測し、ハイブリッド戦略を実現します。


結果

最適化後

設定VAM + 条件付きLSTM

入力VAM + 条件付きLSTM

グラフVAM + 条件付きLSTM

VAM + 条件付きLSTMのバックテスト


結論

この記事では、ディープラーニング、特に条件付きLSTMモデルとボラティリティ調整モメンタム(VAM)指標の統合を検討し、自動取引システムを強化しました。この戦略は、LSTMの予測機能とVAMのボラティリティに敏感なモメンタム分析を組み合わせることで、複雑な市場動向を捉えることを目指しています。MetaTrader 5に実装されたこのシステムは、取引シグナルを生成し、リスク管理を動的に適応させます。

バックテストでは、LSTMとVAMを組み合わせると結果が改善されることが示されています。過剰適合や計算負荷などの課題があるにもかかわらず、この研究では、ディープラーニングとテクニカル分析を統合することで、アルゴリズム取引戦略を大幅に改善できることが示唆されています。

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

MQL5-Telegram統合エキスパートアドバイザーの作成(第7回):チャート上のインジケーター自動化のためのコマンド解析 MQL5-Telegram統合エキスパートアドバイザーの作成(第7回):チャート上のインジケーター自動化のためのコマンド解析
この記事では、TelegramコマンドをMQL5と統合して、取引チャートへのインジケーターの追加を自動化する方法について解説します。ユーザーからのコマンドを解析し、MQL5で実行し、インジケーターベースの取引を円滑におこなうためのシステムをテストするプロセスについて説明します。
どんな市場でも優位性を得る方法(第5回):FRED EURUSD代替データ どんな市場でも優位性を得る方法(第5回):FRED EURUSD代替データ
本日の議論では、セントルイス連邦準備銀行の広義のドル指数に関する代替日次データとその他のマクロ経済指標の集合を使用して、EURUSDの将来の為替レートを予測しました。残念ながら、データはほぼ完璧な相関関係にあるように見えますが、モデルの精度において際立った向上は実現できず、投資家は代わりに通常の市場相場を使用した方がよい可能性があることを示唆している可能性があります。
古典的な戦略を再構築する(第9回):多時間枠分析(II) 古典的な戦略を再構築する(第9回):多時間枠分析(II)
本日のディスカッションでは、AIモデルがどの時間枠で最高のパフォーマンスを発揮するかを明らかにするため、多時間枠分析の戦略を検討します。この分析により、EURUSDペアにおいて月次および時間足の時間枠が比較的誤差の少ないモデルを生成することが分かりました。この結果を活用し、月次時間枠でAIによる予測を行い、時間枠で取引を実行するアルゴリズムを作成しました。
MetaTraderとGoogleスプレッドシートを使用して取引ジャーナルを作成する方法 MetaTraderとGoogleスプレッドシートを使用して取引ジャーナルを作成する方法
MetaTraderとGoogleスプレッドシートを使用して取引ジャーナルを作成しましょう。HTTP POST経由で取引データを同期し、HTTPリクエストを使用して取得する方法を学習します。最終的には、取引を効果的かつ効率的に追跡するのに役立つ取引ジャーナルが手に入ります。