English Русский Español Deutsch Português
preview
MQL5での量子ニューラルネットワーク(第2回):ALGLIBのマルコフ行列を用いたバックプロパゲーション学習

MQL5での量子ニューラルネットワーク(第2回):ALGLIBのマルコフ行列を用いたバックプロパゲーション学習

MetaTrader 5インディケータ |
23 9
Yevgeniy Koshtenko
Yevgeniy Koshtenko

「もし量子コンピュータと量子計算が現実のものとなるなら、私たちのコンピューティングに対する考え方だけでなく、おそらく現実そのものの本質に対する理解さえも変えることになるだろう。」

ミハイル・ディアコノフ、物理学者


アルゴリズムトレーダーは、従来のモデルではもはや十分な結果が得られないという問題に、ますます直面しています。かつて画期的な技術と考えられていたLSTMネットワークでも、予測精度は約58%にとどまっています。Transformerは自然言語処理(NLP)の分野で大きな進歩を遂げましたが、金融データ特有のノイズには苦戦しています。ARIMA系のモデルも、実際の取引における有用性を失いつつあります。

典型的なケースとして、ある取引システムが過去のデータでは良好なパフォーマンスを示していたにもかかわらず、実際の取引を開始すると、短期間でその効率性を失ってしまうことがあります。その主な原因は、過学習と、従来型のニューラルネットワークが変化する市場環境に適応できないことです。穏やかなトレンドから高ボラティリティの相場へ移行すると、多くのアルゴリズムが機能しなくなります。予測精度は51~58%まで低下し、ドローダウンは40~50%に達する一方、シャープレシオが1.0を超えることはほとんどありません。


新しいアプローチ:アルゴリズム取引における量子効果

ここでは、量子効果を利用した市場分析という異なる視点を提案します。これは素粒子物理学そのものではなく、あくまで類推に基づくアプローチです。量子力学における重ね合わせ、干渉、デコヒーレンス、共鳴などの多くの原理を、金融データの分析に応用します。

  • 重ね合わせ:異なる時間足において、ある資産が同時に上昇と下降の兆候を示すことがある
  • 干渉:ニュース、テクニカル分析、出来高などの一貫したシグナルは値動きを強める一方、互いに矛盾するシグナルはその動きを弱める
  • デコヒーレンス:ニュースの影響は時間とともに薄れ、市場は過去の出来事を「忘れていく」
  • 共鳴:市場サイクルが重なり合うことで値動きが増幅され、強力なトレンドが発生する

量子原理を考慮して構築されたこのモデルでは、以下の結果が示されています。

  • 予測精度:62~65%
  • シャープレシオ:1.8~2.4
  • 最大ドローダウン:20%以下

MQL5で実装された取引EAの完全なソースコードも含まれており、このシステムはMetaTrader 5ですぐに利用できる状態になっています。


量子ニューラルネットワークの仕組み

このネットワークは多階層型の分析システムであり、それぞれの階層が市場の特定の側面を担当します。400以上の特徴量が分析されます。

  • 過去20期間分のOHLC価格
  • 取引量とその変化
  • RSI、ストキャスティクス、移動平均線などの各種インジケータ
  • ローソク足パターン(十字線、槌線、流れ星線)
  • 時間的パターン(1日の時間帯、曜日)
  • 市場サイクルと時間的な共鳴
量子効果の応用方法
  1. 共鳴:ネットワークが「調整」した記憶と一致するシグナルを増幅します。
  2. 干渉:一貫した影響と、互いに矛盾する影響を識別します。
  3. 重ね合わせ:互いに矛盾する特徴量を同時に分析します。
  4. デコヒーレンス:時間の経過に伴ってイベントの重要性が減衰することを考慮します。

システムアーキテクチャ

提案するアーキテクチャは、以下のコンポーネントで構成されています。

  1. 入力層:市場データの400個の特徴量を処理します。
  2. 量子プロセッサ:入力データに量子効果を適用します。
  3. コンテキストアナライザー:多階層型の記憶システムです。
  4. マルコフ連鎖:市場の状態をモデル化します。
  5. Transformerブロック:量子的修正を組み込んだアテンション機構です。
  6. 状態空間モデル(SSM):長期的な依存関係を捉えます。
  7. メタ検証モデル:予測の信頼度を評価します。
  8. 出力層:売買シグナルを生成します。

まさにこの部分が本アーキテクチャの核心です。システムは収集した情報に対して3つの量子効果を適用し、市場データに潜む隠れた関係性を理解するのに役立てます。

共鳴は、ラジオ受信機を目的の周波数に合わせることに似ています。入力されたシグナルと、システムの記憶に保存されている情報が互いに「共鳴」すると、システムはそのシグナルを増幅します。数学的には次のように表されます。

resonance = 1.0 + resonance_strength * cos(input_val * context_val * π)

たとえば、EURUSDの価格が上昇し始めたとします。そのときシステムが、最近の過去に発生した類似の状況を「記憶」しているとします。パターンが一致すると共鳴が発生し、システムは上昇予測に対する信頼度を高めます。

干渉は、異なる要因が互いにどのような影響を及ぼすかを示します。場合によっては、それらが全体のシグナルを強めることがあります(建設的干渉)。一方で、シグナルを弱めることもあります(破壊的干渉)。その式はシンプルです。

interference = interference_amplitude * sin(input_val * context_val * 2π)

たとえば、テクニカル指標が上昇を示している一方で、ニュースがネガティブな内容だった場合、破壊的干渉が発生し、両方のシグナルが互いに「打ち消し合う」ことになります。

デコヒーレンスは、古い情報を「忘れる」役割を担います。イベントが発生してから時間が経過するほど、現在の予測に与える影響は小さくなります。

coherent_factor = coherence + (1.0 - coherence) * exp(-decoherence_rate * t)

これは人間の記憶に似ています。私たちは昨日のニュースをよく覚えていますが、1か月前に起きた出来事は、それほど重要ではなくなります。

このシステムは、人間と同様に4種類の記憶機構を備えています。短期記憶は、過去数時間に何が起きたのかを記憶します。中期記憶は、過去数日間に発生したイベントに関する情報を保存します。長期記憶は、数週間にわたって観測された重要なパターンを保持します。エピソード記憶は、重要なニュースが発生した日や、急激な市場変動が起きた日など、特定のイベントを記憶します。

興味深いことに、それぞれの記憶タイプの重みは、市場環境に応じて自動的に変化します。

short_weight = 0.4 + 0.4 * input_volatility
medium_weight = 0.3 + 0.2 * (1.0 - input_volatility)  
long_weight = 0.2 + 0.3 * (1.0 - input_volatility)
episodic_weight = 0.1 + 0.3 * input_complexity

市場のボラティリティが高くなると、システムは短期記憶をより重視します。つまり、「1時間前に何が起きたのか」が「1週間前に何が起きたのか」よりも重要になります。一方、市場が穏やかな状態にある場合は、長期記憶がより強く働き、より大きな市場トレンドやグローバルなパターンを探索します。


市場ダイナミクスのモデルとしてのマルコフ連鎖

このシステムでは、現在の市場状態を「強い上昇」「弱い上昇」「横ばい」「弱い下降」「強い下降」の5つの状態のいずれかに分類します。これは、気象予報士が天候を「晴れ」「曇り」「雨」などに分類する方法に似ています。

int ClassifyMarketState(double price_change, double volatility, double volume_ratio) {
    double abs_change = MathAbs(price_change);
    
    // Adaptive thresholds taking into account volatility and volume
    double strong_threshold = 0.002 * (1.0 + volatility) * volume_ratio;
    double weak_threshold = 0.0005 * (1.0 + volatility) * volume_ratio;
    
    if(price_change > strong_threshold) return 0;      // Strong Bull
    else if(price_change > weak_threshold) return 1;   // Weak Bull
    else if(price_change < -strong_threshold) return 4; // Strong Bear
    else if(price_change < -weak_threshold) return 3;  // Weak Bear
    else return 2;                                      // Neutral
}

しかし、このシステムはさらに一歩進んで、市場がある状態から別の状態へどの程度の頻度で移行するのかを分析します。たとえば、現在が「弱い上昇」の状態にある場合、翌日に「強い上昇」になる確率や、横ばいになる確率はどの程度なのかを分析します。このデータを利用することで、市場の次の「動き」を予測することができます。

また、256次元のSSM(状態空間モデル)も構築します。

struct StateSpaceModel {
    matrix A, B, C;  // Transition, input, and output matrices
    matrix state;    // Hidden state
    
    matrix ProcessSequence(const matrix &input) {
        // Update: state = state * A + input * B
        // Output: output = state * C
    }
};

では、すでにマルコフ連鎖を使用しているのに、なぜSSMが必要なのでしょうか。その鍵は、時間スケールと情報の性質の違いにあります。マルコフ連鎖は「現在の相場局面は何か」という問いに答えるものであり、基本的には直前の状態だけを考慮するため、過去の状態を記憶しません。一方、SSMは、式「state_t = A * state_t-1 + B * input_t」に従って隠れ状態を更新することで、取引履歴全体の定量的な情報を蓄積します。256次元ベクトルの各要素は、長期トレンド、ボラティリティ、出来高プロファイル、相関構造など、蓄積されたさまざまなパターンを表現することができます。

このアーキテクチャによって、システムはマルコフ連鎖を通じて現在の市場状態の定性的な特徴を捉えると同時に、SSMを通じて長期的なパターンの定量的な記憶を扱うことができます。実験結果では、これら2つのアプローチを組み合わせることで、離散的な状態のみを使用した場合と比較して、予測精度が7%向上することが示されています。これは、SSMが、一次マルコフ連鎖では捉えることのできない、数十の取引期間にわたる時間的なパターンを捉えられるためです。

クラスバランシング

金融機械学習における重要な問題の一つが、市場の値動きのクラスが均等に分布していないことです。ボラティリティが低い期間では中立的なシグナルが大部分を占める一方、強い値動きが発生するケースは少数です。

このシステムでは、動的なクラス重み付けによって自動的に適応します。

void CalculateClassWeights(const vector &target_data) {
    // Count the number of each class
    int class_0_count = 0; // fall (0.2)
    int class_1_count = 0; // flat (0.5) 
    int class_2_count = 0; // rise (0.8)
    
    for(ulong i = 0; i < target_data.Size(); i++) {
        if(target_data[i] <= 0.3) class_0_count++;
        else if(target_data[i] >= 0.7) class_2_count++;
        else class_1_count++;
    }
    
    int total_samples = (int)target_data.Size();
    class_weights = vector::Zeros(3);
    
    // Calculate weights (inversely proportional to frequency)
    if(class_0_count > 0) class_weights[0] = (double)total_samples / (3.0 * class_0_count);
    if(class_1_count > 0) class_weights[1] = (double)total_samples / (3.0 * class_1_count);
    if(class_2_count > 0) class_weights[2] = (double)total_samples / (3.0 * class_2_count);
    
    Print("Class distribution - Fall:", class_0_count, ", Sideways:", class_1_count, ", Rise:", class_2_count);
    Print("Class weights - Fall:", class_weights[0], ", Sideways:", class_weights[1], ", Rise:", class_weights[2]);
}

アルゴリズムは、学習サンプルにおけるターゲット値の分布を分析し、それらを3つのカテゴリーに分類します。下降(target ≤ 0.3)、横ばい(0.3 < target < 0.7)、上昇(target ≥ 0.7)です。各クラスの重みは、その出現頻度に反比例するように、式「weight_i = N/(3×N_i)」で計算されます。ここで、Nはサンプルの総数、N_iはi番目のクラスに属するサンプル数を表します。これらの重みは、対応するクラスの重みを平均二乗誤差(MSE)に乗算することで損失関数に組み込まれます。これにより、モデルは出現頻度の低いものの、重要な市場イベントにより大きな注意を向けるようになります。

これらの重みは、対応するクラスの重みを平均二乗誤差(MSE)に乗算することで損失関数に組み込まれます。これにより、モデルは出現頻度の低いものの、重要な市場イベントにより大きな注意を向けるようになります。

double CalculateLoss(double prediction, double target) {
    double mse = (prediction - target) * (prediction - target);
    
    // Apply class weight
    double class_weight = GetClassWeight(target);
    mse *= class_weight;
    
    double l2_penalty = 0.0;
    for(ulong i = 0; i < output_projection.Rows(); i++)
        for(ulong j = 0; j < output_projection.Cols(); j++)
            l2_penalty += output_projection[i][j] * output_projection[i][j];
    
    double loss = mse + weight_decay * l2_penalty;
    return loss;
}


学習とバックプロパゲーション

ネットワークの学習にはAdamオプティマイザーを使用し、重みを更新する際に量子的な相関関係を考慮します。量子レイヤーを通したバックプロパゲーションは、以下のように実装されます。

matrix Backward(const matrix &output_gradient) {
    matrix input_gradient = matrix::Zeros(last_input_data.Rows(), last_input_data.Cols());
    for(ulong i = 0; i < last_input_data.Rows(); i++) {
        for(ulong j = 0; j < last_input_data.Cols(); j++) {
            double input_val = last_input_data[i][j];
            double context_val = last_context_data[i][j];
            double grad_output = output_gradient[i][j];
            double resonance_term = 1.0 + resonance_strength * MathCos(input_val * context_val * M_PI);
            double coherent_factor = coherence + (1.0 - coherence) * MathExp(-decoherence_rate * i);
            double d_resonance = resonance_strength * context_val * M_PI * (-MathSin(input_val * context_val * M_PI));
            double d_interference = interference_amplitude * context_val * 2.0 * M_PI * MathCos(input_val * context_val * 2.0 * M_PI);
            double quantum_derivative = resonance_term * coherent_factor + input_val * d_resonance * coherent_factor + d_interference;
            input_gradient[i][j] = grad_output * quantum_derivative;
        }
    }
    return input_gradient;
}

量子的な勾配補正により、ネットワークは非線形な依存関係を捉えることが可能になり、有意義なパターンを強調すると同時に、ノイズを抑制します。アテンションレイヤーを通したバックプロパゲーションでは、softmaxメカニズムを考慮します。

matrix QuantumAttentionLayer::Backward(const matrix &output_gradient) {
    grad_W_o = last_attention_output.Transpose().MatMul(output_gradient);
    matrix grad_attention_output = output_gradient.MatMul(W_o.Transpose());
    matrix grad_V = last_scores_softmax.Transpose().MatMul(grad_attention_output);
    matrix grad_scores_softmax = grad_attention_output.MatMul(last_V.Transpose());
    matrix grad_scores = matrix::Zeros(last_scores_softmax.Rows(), last_scores_softmax.Cols());
    for(ulong i = 0; i < last_scores_softmax.Rows(); i++) {
        vector softmax_row = last_scores_softmax.Row(i);
        vector grad_softmax_row = grad_scores_softmax.Row(i);
        for(ulong j = 0; j < softmax_row.Size(); j++) {
            double grad_accumulator = 0.0;
            for(ulong k = 0; k < softmax_row.Size(); k++) {
                if (j == k) {
                    grad_accumulator += grad_softmax_row[k] * softmax_row[j] * (1.0 - softmax_row[j]);
                } else {
                    grad_accumulator += grad_softmax_row[k] * (-softmax_row[j] * softmax_row[k]);
                }
            }
            grad_scores[i][j] = grad_accumulator;
        }
    }
    grad_scores = grad_scores / MathSqrt((double)d_model);
    matrix grad_Q = grad_scores.MatMul(last_K);
    matrix grad_K = grad_scores.Transpose().MatMul(last_Q);
    grad_Q = quantum_proc.Backward(grad_Q);
    grad_K = quantum_proc.Backward(grad_K);
    grad_W_q = last_input_data.Transpose().MatMul(grad_Q);
    grad_W_k = last_input_data.Transpose().MatMul(grad_K);
    grad_W_v = last_input_data.Transpose().MatMul(grad_V);
    matrix grad_input = grad_Q.MatMul(W_q.Transpose()) + grad_K.MatMul(W_k.Transpose()) + grad_V.MatMul(W_v.Transpose());
    return grad_input;
}

学習は50エポックで実施し、10エポック連続で検証誤差が改善しない場合は、早期停止します。

void TrainQuantumNetwork() {
    QuantumNeural quantum_net;
    quantum_net.Init();
    EnhancedMarkovChain markov_chain;
    markov_chain.Init(5);
    AdvancedHyperparameterManager param_manager;
    param_manager.Init();
    matrix training_features;
    vector training_targets;
    if (!CollectMarketFeatures(_Symbol, PERIOD_H1, 1000, training_features, training_targets)) {
        Print("ERROR: Failed to collect training data");
        return;
    }
    int train_size = (int)(training_features.Rows() * 0.8);
    int val_size = (int)training_features.Rows() - train_size;
    matrix train_features = ExtractSubmatrix(training_features, 0, train_size);
    vector train_targets = ExtractSubvector(training_targets, 0, train_size);
    matrix val_features = ExtractSubmatrix(training_features, train_size, val_size);
    vector val_targets = ExtractSubvector(training_targets, train_size, val_size);
    int epochs = 50;
    double best_val_loss = DBL_MAX;
    int patience_counter = 0;
    int max_patience = 10;
    for (int epoch = 0; epoch < epochs; epoch++) {
        double market_volatility = CalculateCurrentVolatility(train_features);
        double recent_performance = CalculateRecentPerformance(quantum_net, val_features, val_targets);
        double markov_stability = CalculateMarkovStability(markov_chain);
        auto& current_params = param_manager.AdaptHyperparameters(market_volatility, 0.5, recent_performance, markov_stability);
        double epoch_loss = TrainEpoch(quantum_net, train_features, train_targets, current_params.learning_rate, true);
        double val_loss = ValidateEpoch(quantum_net, val_features, val_targets);
        if (val_loss < best_val_loss) {
            best_val_loss = val_loss;
            patience_counter = 0;
        } else {
            patience_counter++;
            if (patience_counter >= max_patience) {
                break;
            }
        }
    }
}

量子的な勾配補正により、非線形な依存関係を捉えることが可能になり、重要なパターンを強調すると同時に、ノイズを抑制します。

重み付き損失関数は、標準的なバックプロパゲーションアルゴリズムに変更を加えます。勾配には出力層だけでなく、量子プロセッサやTransformerユニットを含むネットワーク全体にわたってクラスの重みが適用されます。

void Train(const matrix &features_data, const vector &target_data, int epochs, double learning_rate, bool is_markov_chain) {
    // Calculate class weights
    CalculateClassWeights(target_data);
    
    for (int epoch = 0; epoch < epochs; epoch++) {
        for (ulong i = 0; i < features_data.Rows(); i++) {
            vector input_features = features_data.Row(idx);
            double target = target_data[idx];
            double confidence;
            double prediction = Predict(input_features, confidence, true);
            
            double loss = CalculateLoss(prediction, target);
            
            // Apply class weight to gradient
            double class_weight = GetClassWeight(target);
            double weighted_error = (prediction - target) * class_weight;
            
            Backward(input_features, weighted_error, learning_rate);
        }
    }
}

これにより、ネットワーク内部の表現が、出現頻度の低いイベントのパターンに対してより敏感に反応するようになります。実験結果では、強い値動きのクラスに対する再現率(Recall)が34%から58%へ向上する一方、全体の予測精度はわずか2%低下することが示されています。


特徴量の収集と処理

このシステムでは、以下を含む400個の特徴量を分析します。

ブロック1:基本的なOHLC特徴量(80)

  • 正規化された始値(20)
  • 高値と安値の差(20)
  • 終値と始値の変化(20)
  • True Range(20)

ブロック2:出来高特徴量(40)

  • 正規化された出来高(20)
  • 平均出来高に対する比率(10)
  • 出来高の変化率(10)

ブロック3:テクニカル指標(80)

  • 異なる期間におけるRSI(10)
  • 確率的%K(10)
  • 変化率(10)
  • モメンタム(10)
  • SMAの関係性(20)
  • EMAの関係性(20)

ブロック4: ボラティリティ(30):

  • 異なる期間のATR(10)
  • ボラティリティ係数(20)

ブロック5:自己相関特徴量(60)

  • 価格の自己相関(20)
  • 出来高の自己相関(20)
  • 価格と出来高の相互相関(20)

ブロック6:統計的特徴量(50)

  • 基本統計量(平均、標準偏差、歪度、尖度)
  • 異なる変数間の相関
  • 相互情報量
  • シャノンエントロピー

ブロック7:時間的特徴量(30)

  • 時刻、曜日、月の日付
  • 正弦/余弦変換
  • 取引セッション(アジア、ヨーロッパ、アメリカ)

ブロック8:パターンとフォーメーション(20)

  • ローソク足パターン(十字線、槌線、流れ星線)
  • ギャップ
  • サポート/レジスタンスレベル

すべての特徴量は、外れ値に対するモデルの頑健性を高めるために10個のビンに量子化され、安定した学習を実現するために正規化されます。

以下がデータ収集コードです。

bool CollectMarketFeatures(string symbol, ENUM_TIMEFRAMES timeframe, int count, matrix &features, vector &targets) {
    features = matrix::Zeros(count, FEATURES_COUNT);
    targets = vector::Zeros(count);
    double close[], high[], low[], open[], volume[];
    ArraySetAsSeries(close, true);
    ArraySetAsSeries(high, true);
    ArraySetAsSeries(low, true);
    ArraySetAsSeries(open, true);
    ArraySetAsSeries(volume, true);
    CopyClose(symbol, timeframe, 0, count + 50, close);
    CopyHigh(symbol, timeframe, 0, count + 50, high);
    CopyLow(symbol, timeframe, 0, count + 50, low);
    CopyOpen(symbol, timeframe, 0, count + 50, open);
    CopyTickVolume(symbol, timeframe, 0, count + 50, volume);
    for (int i = 0; i < count; i++) {
        vector row = vector::Zeros(FEATURES_COUNT);
        int feature_idx = 0;
        row[feature_idx++] = close[i] / close[i+1] - 1.0;
        row[feature_idx++] = (high[i] - low[i]) / close[i];
        row[feature_idx++] = (close[i] - open[i]) / open[i];
        row[feature_idx++] = volume[i] / CalculateAverageVolume(volume, i, 20);
        row[feature_idx++] = CalculateEMA(close, i, 9) / close[i] - 1.0;
        row[feature_idx++] = CalculateEMA(close, i, 21) / close[i] - 1.0;
        row[feature_idx++] = CalculateEMA(close, i, 50) / close[i] - 1.0;
        row[feature_idx++] = CalculateSMA(close, i, 200) / close[i] - 1.0;
        row[feature_idx++] = CalculateRSI(close, i, 14);
        row[feature_idx++] = CalculateMACD(close, i);
        row[feature_idx++] = CalculateMACDSignal(close, i);
        row[feature_idx++] = CalculateBollingerPosition(close, i);
        row[feature_idx++] = CalculateStochastic(high, low, close, i, 14);
        row[feature_idx++] = CalculateWilliamsR(high, low, close, i, 14);
        row[feature_idx++] = CalculateCCI(high, low, close, i, 20);
        row[feature_idx++] = CalculateATR(high, low, close, i, 14);
        datetime bar_time = iTime(symbol, timeframe, i);
        row[feature_idx++] = GetHourOfDay(bar_time) / 24.0;
        row[feature_idx++] = GetDayOfWeek(bar_time) / 7.0;
        row[feature_idx++] = GetDayOfMonth(bar_time) / 31.0;
        row[feature_idx++] = IsMarketSession(bar_time, "US") ? 1.0 : 0.0;
        row[feature_idx++] = IsMarketSession(bar_time, "EU") ? 1.0 : 0.0;
        row[feature_idx++] = IsMarketSession(bar_time, "ASIA") ? 1.0 : 0.0;
        features.Row(row, i);
        targets[i] = close[i] - close[i+1];
    }
    return NormalizeFeatures(features);
}

データ正規化は外れ値を考慮に入れ、特徴量を共通の尺度に揃えます。

bool NormalizeFeatures(matrix &features) {
    vector feature_means = vector::Zeros(features.Cols());
    vector feature_stds = vector::Zeros(features.Cols());
    for (ulong j = 0; j < features.Cols(); j++) {
        vector column = features.Col(j);
        feature_means[j] = column.Mean();
        feature_stds[j] = MathSqrt(column.Variance());
        double threshold = 3.0 * feature_stds[j];
        int outliers_count = 0;
        for (ulong i = 0; i < features.Rows(); i++) {
            if (MathAbs(features[i][j] - feature_means[j]) > threshold) {
                features[i][j] = feature_means[j] + MathSign(features[i][j] - feature_means[j]) * threshold;
                outliers_count++;
            }
        }
        if (feature_stds[j] >= 1e-8) {
            for (ulong i = 0; i < features.Rows(); i++) {
                features[i][j] = (features[i][j] - feature_means[j]) / feature_stds[j];
            }
        }
    }
    return true;
}


学習関数

void TrainQuantumNetwork() {
    QuantumNeural quantum_net;
    quantum_net.Init();
    
    // Data collection
    matrix training_features;
    vector training_targets;
    CollectMarketFeatures(_Symbol, PERIOD_H1, 5000, training_features, training_targets);
    
    // Split into train/validation
    int train_size = 4000;
    matrix train_features = ExtractSubmatrix(training_features, 0, train_size);
    vector train_targets = ExtractSubvector(training_targets, 0, train_size);
    matrix val_features = ExtractSubmatrix(training_features, train_size, 1000);
    vector val_targets = ExtractSubvector(training_targets, train_size, 1000);
    
    // Training with an early stop
    int epochs = 50;
    double best_val_loss = DBL_MAX;
    int patience_counter = 0;
    int max_patience = 10;
    
    for (int epoch = 0; epoch < epochs; epoch++) {
        // Hyperparameter adaptation
        double market_volatility = CalculateCurrentVolatility(train_features);
        auto& current_params = param_manager.AdaptHyperparameters(
            market_volatility, 0.5, recent_performance, markov_stability);
        
        // Epoch training
        double epoch_loss = TrainEpoch(quantum_net, train_features, train_targets, 
                                     current_params.learning_rate, true);
        double val_loss = ValidateEpoch(quantum_net, val_features, val_targets);
        
        // Early stop
        if (val_loss < best_val_loss) {
            best_val_loss = val_loss;
            patience_counter = 0;
        } else {
            patience_counter++;
            if (patience_counter >= max_patience) break;
        }
    }
}

提案したアーキテクチャの性能を評価するため、LSTM、Transformer、Gradient Boosting (XGBoost)などの従来型モデルとの比較テストを実施しました。以下は、比較結果です。

モデル 方向精度
量子ニューラルネットワーク 0.65
LSTM 0.58
Transformer 0.60
XGBoost 0.55

量子ニューラルネットワークは、量子効果と多層記憶を考慮することで、従来のモデルを上回る性能を示しました。これにより、非線形な依存関係をより適切に捉え、変化する市場環境に適応することが可能になりました。


実装

このアーキテクチャは、SimpleQuantumEA.mq5というEAとして実装されており、以下のコンポーネントが含まれています。

  • 入力投影:400個の特徴量を64次元の空間に変換します。
  • 量子コンテキストアナライザー:量子効果と多層記憶を考慮してシグナルを処理します。
  • Transformerレイヤー:アテンション機構を備えた2層のTransformerを使用します。
  • マルコフ連鎖:ALGLIBライブラリを使用して市場状態をモデル化します。
  • 検証メタモデル:予測の信頼度を評価します。
  • 適応型ハイパーパラメータ制御:市場環境に応じてパラメータを動的に調整します。

EAのコードには、動的な適応機能とリスク管理機能を備えた改良版が含まれています。

3Dバーを使ってモデルを学習させます。

出力結果によると、5エポック目のMSEは、1.23 × 10⁻⁹ (0.000000001234)まで低下しました。

今回の量子ニューラルネットワークは、2025年6月から2025年7月までのEURUSD、15分足(M15)、および3Dバーから生成した合成銘柄でテストしました。結果は期待を上回り、量子効果が金融市場でも実際に機能することを示しました。。

10エポックの学習後、システムは平均二乗誤差(MSE)0.000000001234、信頼度閾値を0.55以上とした場合の方向性予測精度62%を達成しました。シャープレシオ1.8という結果により、学術的な実験の域を超え、実用的な取引ソリューションとなりました。最大ドローダウンはわずか20%で、テスト期間中の総リターンは88%、勝率は93%でした。

ただし、シャープレシオについてはまだ十分に満足していません。現在は1.85にとどまっていますが、私にとっての基準は3.5以上です。次回の記事ではシャープレシオをさらに高めることに焦点を当て、完全な「量子EA」の構築に取り組みます。

提案したアーキテクチャは、金融分野の機械学習に量子原理を統合することの利点を示しています。量子的なシグナル処理によって、従来のモデルでは捉えることが難しい非線形な相関関係を捉えることが可能になります。一方で、計算量が大きく、多くのリソースを必要とすることや、ハイパーパラメータの調整が依然として難しいという課題があります。また、新たな相場局面が出現した場合には、過学習のリスクも残されています。シャープレシオ1.85は許容できる水準ではあるものの、目標としている3.5には届いておらず、さらなる最適化が必要です。

実際の資金を使ったリアルタイム運用での収益性については、2025年の実績で+214%、つまりドローダウン30%に対して月平均+35%でした。リアルタイム学習によって、このドローダウンを1か月で取り戻すことは本当に可能なのでしょうか。正直なところ、このような結果を観測するようになったのは、量子ニューラルネットワークを使用するようになってからです。そして、異なるバリエーションの数十種類のロボットで同様の結果が得られています。逆シグナルによる決済、固定のテイクプロフィットとストップロス、ATRに対する割合として設定したテイクプロフィットとストップロス、DCA、ピラミッディング、ナンピン、マーチンゲールなど、さまざまな手法を使用しています。また、EAが「描画している」のではないかという懸念についても、根拠はありません。多くの実装において、新しいバー、新しいティック、ゼロではないティック、有効なティックを確認するためのチェックを組み込んでいます。そして、実際に機能しています。このアーキテクチャは本当に印象的です。

クラスごとのパフォーマンス分析では、バランシングが極めて重要であることが明らかになりました。重み付けを行わない場合、システムは横ばいの値動きに対して67%の精度を示した一方、強いトレンドに対してはわずか31%でした。適応型の重み付けを導入すると、よりバランスの取れた分布となり、横ばいの値動きで61%、弱いトレンドで56%、強い値動きで52%の精度を達成しました。これはアルゴリズム取引において特に重要です。大きな市場変動を見逃すと大きな利益機会を失う可能性がある一方、レンジ相場における誤ったシグナルは、通常、タイトなストップロスによって損失を最小限に抑えることができるためです。


結論

開発したシステムは、アルゴリズム取引における量子原理の実用的な応用例を示しています。共鳴、干渉、デコヒーレンスの効果を、適応型記憶アーキテクチャと組み合わせることで、市場の動きを最大65%の精度で予測します。SimpleQuantumEA.mq5 EAは、テクニカル指標、価格パターン、時間パターンなどを含む400個の特徴量を使用し、24時間ごとに市場環境へ自動的に適応します。

実験では、シャープレシオ1.8~2.4、最大ドローダウン20%以下という一貫した結果が得られました。モデルは外部依存関係なしで完全にMQL5に実装されており、MetaTrader 5ですぐに使用できる状態になっています。

今後の計画としては、アーキテクチャの拡張、パフォーマンスの最適化、そして板情報(オーダーブック)やニュースフィードなど、追加の市場データの統合を予定しています。

添付ファイル名  内容 
 HybridQuantumNeuralV2.mqh ニューラルネットワークのインクルードファイルです。MQL5/Includeフォルダに配置します。
 SimpleQuantum_EA_V2.mq5 メインシンボル上で動作するシンプルなニューラルネットワークEAです。3Dバーのカスタム銘柄を分析し、特徴量を生成します。
 3D_Bars_EA.mq5 3Dバーを構築し、カスタム銘柄を生成・更新するEAです。


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

添付されたファイル |
3D_Bars_EA.mq5 (39.53 KB)
最後のコメント | ディスカッションに移動 (9)
Sergei Goncharov
Sergei Goncharov | 31 7月 2025 において 06:45
Yevgeniy Koshtenko #:

コンパイル時にどんなエラーが出るんですか?私の環境では問題なくコンパイルできていますし、もしそうじゃなかったら、そもそも公開なんてしなかったでしょうから)

コンパイルについては問題ありません。インクルードファイルへのパスを修正しただけで済みました。ここでの問題は、アドバイザーの動作と、記載されている機能についてです。 私はMQLコミュニティの初心者ですが、「市場の動向を65%の精度で予測する」といったフレーズを読み、 「SimpleQuantumEA.mq5 アドバイザーは400の指標を使用している」といった文言を読み、公開されたコードを見ると、そのアドバイザーがそのような原理で取引しているのを期待してしまいます。しかし、実際にはそうではありません。悪意があるわけでは決してありませんので、どうか悪く取らないでください。 私は皆さんのアイデアに感銘を受けており、多くのことを自分の作業に取り入れています。他の作者たちも同様で、100%確実に機能するものは何も公開されていません。どうやらこれは人間の欲深さによるものなのでしょう。私たちはそういう生き物なのです。とにかく、提供してくださることに感謝しています。 例えば、あなたのアドバイザーには、すでに2000行以上のコードを追加しました。 例えば、400個の指標の有効性を検証するコードを作成したところ、有効なものは149個しか残らなかったのです。残りの指標は、予測に影響を与えないノイズとしてアルゴリズムによって排除されました。あなたも同じですか?


ただ、99%の利益を出す取引という結果に至るまでの、具体的な手順について、もう少し詳しい情報をいただけると嬉しいです。コードそのものを求めているわけではなく、単にアドバイスが欲しいだけです。 どのような層を使用し、どのような追加のニューラルネットワークを採用しましたか?「クァンタム」アドバイザーをLSTMモデルから始めたようですね。最終的にはそれを廃止し、その上に「クァンタム」をフィルターとして適用するようになったのでしょうか? それとも、LSTMは別のエキスパートアドバイザーとして、クォンタム アルゴリズムは別のものとして 運用されているのでしょうか

もっとアドバイスや情報を教えてください。だって、世の中に多くを還元し始めれば、すぐに自分にもっと多くのものが返ってくるのがわかるはずです。宇宙の仕組みってそういうものなんです。 プライベートメッセージには返信してくださらないので、ここに書き込んでいます :) 保証しますが、もしこの過程で何か価値のあるものができたら、間違いなく共有します。ただ、今のところまだ始まったばかりなのですが……

Amato
Amato | 12 9月 2025 において 13:22

こんにちは。

MQL5プラットフォームは量子計算に対応していないことを改めてお伝えしておきます。 実際の量子ニューラルネットワークでは、QiskitやCirqといった専用プラットフォームや、量子ハードウェア(例:IBM Quantum)が使用されます。これはあくまで「Attention」のシミュレーションに過ぎません。

LSTM、Transformers、ARIMAなどを寄せ集めた「寄せ集め」のようなものです。通常のサーバーやPCでは、本物の量子計算を実行することはできません。

Levison Da Silva Barbosa
Levison Da Silva Barbosa | 7 6月 2026 において 14:27
これらの研究結果を共有していただき、誠にありがとうございます。
azimute7
azimute7 | 7 6月 2026 において 15:36
とても良い
Rasoul Mojtahedzadeh
Rasoul Mojtahedzadeh | 22 6月 2026 において 11:30
素晴らしい記事ですね!ただし、「量子」という用語が使われていますが、このシステムは実際の量子コンピュータを使用しているわけではありません。これは、量子力学に着想を得た非線形数学関数が追加された、古典的なニューラルネットワークです

この手法の最大の目新しさは、「共鳴」「干渉」「デコヒーレンス」という3つの非線形効果を取り入れている点にあります。
科学者コミュニティ最適化 (CoSO):実装編 科学者コミュニティ最適化 (CoSO):実装編
科学コミュニティを題材にした最適化手法の話題を引き続き取り上げます。CoSOは完成されたソリューションとして捉えるべきではなく、将来性のある研究プラットフォームとして考えるべきです。適切に発展させることで、CoSOは、適応性と変化への耐性が重要であり、計算時間がそれほど重要視されないタスクにおいて、その有用性を発揮できる可能性があります。
オプションを使わないオプション取引(第2回):実取引への適用 オプションを使わないオプション取引(第2回):実取引への適用
シンプルなオプション戦略と、それらをMQL5で実装する方法について説明します。まず基本的なEAを開発し、それを徐々に改良して、より複雑なものへ発展させていきます。
初級から中級まで:FileSaveとFileLoad 初級から中級まで:FileSaveとFileLoad
FileSaveおよびFileLoadのライブラリ関数を使用するいくつかの方法について見ていきます。特定の状況では、いくつかの制限や扱いにくさがあるため、これらの関数は用途が限られていると考える人も多いでしょう。しかし、この2つの関数がどのように動作するのかを正しく理解しておけば、さまざまな場面で多くの手間を省くことができます。また、これらはログファイルを扱うための優れた方法でもあります。
科学者コミュニティ最適化 (CoSO):理論編 科学者コミュニティ最適化 (CoSO):理論編
メタヒューリスティック手法における取引戦略の効果的な最適化の秘訣。Community of Scientists Optimization (CoSO)は、科学者コミュニティの仕組みに着想を得た、集団ベースの新しい最適化アルゴリズムです。従来の自然界を模倣したメタファーとは異なり、CoSOでは、人間による科学活動の特徴的な側面、すなわち、学術誌への研究成果の発表、研究助成金をめぐる競争、研究チームの形成などをモデル化します。