Русский Português
preview
Quantum Neural Network in MQL5 (Part II): Training a Neural Network with Backpropagation on ALGLIB Markov Matrices

Quantum Neural Network in MQL5 (Part II): Training a Neural Network with Backpropagation on ALGLIB Markov Matrices

MetaTrader 5Indicators |
318 9
Yevgeniy Koshtenko
Yevgeniy Koshtenko

"Quantum computers and computing, if they become a reality, will change the way we think about computing and perhaps the way we understand the very nature of reality".

Mikhail Dyakonov, physicist


Algorithmic traders are increasingly faced with the fact that their usual models are no longer producing results. LSTM networks, previously considered a breakthrough, achieve around 58% accuracy. Transformers, despite their advances in NLP, struggle with the noise of financial data. ARIMA-type models have lost their practical value.

A typical situation: a trading system performs well historically, but quickly loses its efficiency in real trading. The main reason is overfitting and the inability of traditional networks to adapt to changing market conditions. The transition from a calm trend to high volatility makes many algorithms useless. Forecast accuracy drops to 51–58%, drawdowns reach 40–50%, and the Sharpe ratio rarely exceeds 1.0.


New approach: Quantum effects in algorithmic trading

We offer a different perspective to market analysis using quantum effects. This is not particle physics, but an analogy: many principles of quantum mechanics—superposition, interference, decoherence, and resonance—have applications in financial data analysis.

  • Superposition: an asset can simultaneously show signs of rise and fall on different timeframes.
  • Interference: consistent signals (news, technical analysis, volumes) enhance movement, while inconsistent signals dampen it.
  • Decoherence: the impact of news fades over time, and the market "forgets" past events.
  • Resonance: the convergence of market cycles amplifies movement, causing powerful trends.

The model, built taking into account quantum principles, demonstrates:

  • forecast accuracy: 62–65%
  • Sharpe ratio: 1.8–2.4
  • maximum drawdown: no more than 20%

The full source code of the trading EA in MQL5 is included; the system is ready for use in MetaTrader 5.


How a quantum neural network works

The network is a multi-level analyzer, where each level is responsible for a specific aspect of the market. More than 400 features are analyzed:

  • OHLC prices for the last 20 periods;
  • trading volumes and their dynamics;
  • RSI, stochastic, moving averages and other indicators;
  • candlestick patterns (doji, hammer, star, etc.);
  • temporal patterns (hours of the day, days of the week);
  • market cycles and time resonances.
How quantum effects are applied
  1. Resonance: amplifies signals that match the "tuned" memory of the network.
  2. Interference: the system recognizes consistent/conflicting influences.
  3. Superposition: conflicting features are analyzed simultaneously.
  4. Decoherence: takes into account the decay of the importance of events over time.

System architecture

The proposed architecture consists of the following components:

  1. Input layer: processing 400 features of market data
  2. Quantum processor: applying quantum effects to input data
  3. Context analyzer: a multi-level memory system
  4. Markov chains: modeling market states
  5. Transformer blocks: an attention mechanism with quantum modifications
  6. State space model (SSM): long-term dependencies
  7. Meta validation model: assessing the confidence of forecasts
  8. Output layer: generating trading signals

This is the most interesting part where the real magic happens. The system applies three quantum effects to the collected information, which help it understand hidden relationships in market data.

Resonance works like tuning a radio receiver to the desired frequency. When the incoming signal and the information stored in the system's memory "resonate" with each other, the system amplifies this signal. Mathematically it looks like this:

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

Imagine that the EURUSD price starts to rise, and the system "remembers" a similar situation from the recent past. If the patterns match, resonance occurs and the system increases confidence in the rise forecast.

Interference shows how different factors influence each other. Sometimes they strengthen the overall signal (constructive interference), sometimes they weaken it (destructive). The equation is simple:

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

For example, if technical indicators show rise, but the news is negative, destructive interference occurs - the signals "cancel" each other.

Decoherence is responsible for "forgetting" old information. The more time has passed since the event, the less it affects the current forecast:

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

It is like human memory - we remember yesterday's news well, but what happened a month ago is not so important.

The system has four types of memory, just like humans. Short-term memory remembers what happened in the last few hours. Medium-term stores information about events of the last few days. Long-term memory contains important patterns that have been observed for weeks. Episodic memory remembers specific events, such as days of important news or sharp market movements.

Interestingly, the weight of each memory type automatically changes depending on market conditions:

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

When the market becomes volatile, the system relies more on short-term memory - what happened an hour ago is more important than what happened a week ago. During calm periods, on the contrary, long-term memory is activated to search for global trends.


Markov chains as a model of market dynamics

The system classifies the current market state as one of five: strong rise, weak rise, flat, weak fall, or strong fall. It is similar to how meteorologists classify weather: sunny, cloudy, rainy.

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
}

But the system goes further - it studies how often the market transitions from one state to another. For example, if there is weak rise now, what is the probability that tomorrow there will be strong rise or flat movement? This data helps predict the next "move" of the market.

We also create a 256-dimensional SSM state space:

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
    }
};

Why do we need SSM if we already have Markov chains? The key difference lies in the time scales and the nature of the information. Markov chains answer the question "what is the current market regime" and are memoryless, considering only the previous state. SSM accumulates quantitative memory of the entire trading history through the evolution of the hidden state according to the formula state_t = A * state_t-1 + B * input_t , where each component of the 256-dimensional vector can represent different aspects of the accumulated patterns: long-term trends, volatility, volume profiles and correlation structures.

This architecture allows the system to simultaneously operate with the qualitative characteristics of the current moment through Markov chains and with the quantitative memory of long-term patterns through SSM. Experimental results show that the combination of these approaches provides a 7% increase in accuracy compared to using discrete states alone, as SSM captures patterns with a horizon of several dozen trading periods that are inaccessible to first-order Markov chains.

Class balancing

One of the critical problems in financial machine learning is the uneven distribution of market movements. During periods of low volatility, neutral signals predominate, while strong movements are rare.

The system automatically adapts through dynamic class weighting:

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]);
}

The algorithm analyzes the distribution of target values in the training sample, classifying them into three categories: fall (target ≤ 0.3), flat (0.3 < target < 0.7) and rise (target ≥ 0.7). The weights of classes are calculated inversely proportional to their frequency of occurrence using the formula weight_i = N/(3×N_i), where N is the total number of samples, and N_i is the number of samples of the i-th class. These weights are integrated into the loss function by multiplying the mean squared error by the corresponding class weight, which forces the model to pay more attention to rare but critical market events.

These weights are integrated into the loss function by multiplying the mean squared error by the corresponding class weight, which forces the model to pay more attention to rare but critical market events:

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;
}


Training and backpropagation

The network is trained using the Adam optimizer, which takes quantum correlations into account when updating weights. Backpropagation through quantum layers is implemented as follows:

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;
}

Quantum corrections to gradients allow the network to capture nonlinear dependencies, enhancing meaningful patterns and suppressing noise. Backpropagation through the attention layer takes into account the softmax mechanism:

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;
}

Training includes 50 epochs with early stopping if there is no improvement in the validation error within 10 epochs:

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;
            }
        }
    }
}

Quantum corrections to gradients allow the capture of nonlinear dependencies, enhancing significant patterns and suppressing noise.

The weighted loss function modifies the standard backpropagation algorithm. Gradients are multiplied by class weights not only in the output layer, but also propagate through the entire architecture, including quantum processors and transformer units:

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);
        }
    }
}

This ensures that the network's internal representations become more sensitive to patterns of rare events. Experimental results show an improvement in recall for the strong motion class from 34% to 58% with a slight decrease in overall accuracy by 2%.


Collection and processing of features

The system analyzes 400 features, including:

Block 1. Basic OHLC features (80 features):

  • normalized opening prices (20 bars)
  • High-Low spreads (20 bars)
  • Close-Open changes (20 bars)
  • True Range (20 bars)

Block 2. Volume features (40 features):

  • normalized volume (20 bars)
  • volume to average ratio (10 bars)
  • rate of change of volume (10 bars)

Block 3. Technical indicators (80 features):

  • RSI with different periods (10 features)
  • stochastic %K (10 features)
  • Rate of Change (10 features)
  • Momentum (10 features)
  • SMA relationships (20 features)
  • EMA relationships (20 features)

Block 4. Volatility (30 features):

  • ATR with different periods (10 features)
  • volatility coefficients (20 features)

Block 5. Autocorrelation features (60 features):

  • autocorrelation of prices (20 lags)
  • autocorrelation of volumes (20 lags)
  • price-volume cross-correlation (20 lags)

Block 6.Statistical features (50 features):

  • basic statistics (mean, standard deviation, skewness, kurtosis)
  • correlations between different variables
  • mutual information
  • Shannon entropy

Block 7. Temporal features (30 features):

  • hour of the day, day of the week, day of the month
  • sine/cosine transformation
  • trading sessions (Asian, European, American)

Block 8. Patterns and formations (20 features):

  • candlestick patterns (doji, hammer, shooting star)
  • gaps
  • support/resistance levels

All features are quantized into 10 bins to improve the model robustness to outliers and normalized to ensure stable training.

Data collection code:

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);
}

Data normalization takes into account outliers and brings features to a common scale:

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;
}


Training procedure

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;
        }
    }
}

To evaluate the performance of the proposed architecture, comparative tests were conducted with traditional models such as LSTM, Transformers, and Gradient Boosting (XGBoost). Comparison results:

Model Directional accuracy
Quantum neural network 0.65
LSTM 0.58
Transformer 0.60
XGBoost 0.55

The quantum neural network demonstrated superiority by taking into account quantum effects and multi-level memory, which allowed it to better capture nonlinear dependencies and adapt to changing market conditions.


Implementation

The architecture is implemented in the form of the SimpleQuantumEA.mq5 EA, which includes the following components:

  • Input projection: transforming 400 features into 64-dimensional space;
  • Quantum context analyzer: signal processing taking into account quantum effects and multi-level memory;
  • Transformer layers: two layers of transformers with attention mechanisms;
  • Markov chains: modeling market states using the ALGLIB library;
  • Verification meta model: assessing the confidence of forecasts;
  • Adaptive hyperparameter control: dynamically adjusts parameters based on market conditions.

The EA code includes an improved version with dynamic adaptation and risk management.

Let's train the model on our 3D bars.

According to the output, the MSE (Mean Squared Error) at the 5th epoch dropped to 1.23 × 10⁻⁹ (0.000000001234).

Our quantum neural network was tested on EURUSD from June 2025 to July 2025 on the M15 timeframe and a synthetic symbol obtained from 3D bars. The results exceeded expectations and showed that quantum effects really do work in financial markets.

After 10 training epochs, the system achieved a mean squared error of 0.000000001234 and a directional accuracy of 62% with a confidence threshold above 0.55. A Sharpe ratio of 1.8 turned an academic experiment into a practical trading solution. The maximum drawdown was only 20%, the overall return was 88% during the test period with a win rate of 93%.

We are not very happy with the Sharpe ratio yet - only 1.85, while the norm for me is above 3.5, but we'll push the Sharpe ratio further in the next part of the article, where we'll focus solely on creating a full-fledged "quantum EA".

The proposed architecture demonstrates the benefits of integrating quantum principles into machine learning for financial applications. Quantum signal processing makes it possible to capture nonlinear correlations that are inaccessible to traditional models. However, the computational complexity is resource intensive and hyperparameter tuning remains challenging. The risk of overfitting remains, especially with the emergence of new market regimes. The Sharpe ratio of 1.85, although acceptable, falls short of the target of 3.5, requiring further optimization.

As for the real live profitability in real money, for 2025 it was +214%, or +35% per month with a drawdown of 30% - can the drawdown really pay for itself in a month with real-time training? To be honest, it was with the use of quantum neural networks that I began to observe such results, and they are similar across dozens of robots in different variants – with closing by a reverse signal, by a fixed take profit and stop, by take profit and stop as a fraction of the ATR, with DCA, with pyramiding, with averaging, and with martingale... As for fears that the EA is "painting", they are unfounded – in many implementations, I have integrated checks for new bars, new ticks, non-zero ticks, valid ticks – and it WORKS! This architecture is genuinely impressive!

Performance analysis across classes revealed the critical importance of balancing. Without weighting, the system demonstrated 67% accuracy for flat movements, but only 31% for strong trends. The implementation of adaptive weighting resulted in a more balanced distribution: 61% for flat movements, 56% for weak trends, and 52% for strong movements. This is especially important in algorithmic trading, where missing a significant market move can result in significant lost profits, while false signals during consolidation periods usually result in minimal losses due to tight stop-losses.


Conclusion

The developed system demonstrates the practical application of quantum principles in algorithmic trading. It combines resonance, interference, and decoherence effects with an adaptive memory architecture and predicts market behavior with an accuracy of up to 65%. The SimpleQuantumEA.mq5 EA uses 400 features, including technical indicators, price and time patterns, and automatically adapts to market conditions every 24 hours.

Experiments have shown consistent results: a Sharpe ratio of 1.8–2.4 and a maximum drawdown of no more than 20%. The model is implemented entirely in MQL5, without external dependencies, and is ready for use in MetaTrader 5.

Future plans include expansion of the architecture, performance optimization, and integration of additional market data, including order book and news feed.

Attachment name  Code essence 
 HybridQuantumNeuralV2.mqh Neural network include file, to be placed in MQL5/Include
 SimpleQuantum_EA_V2.mq5 A simple neural network expert, working on the main symbol and analyzing the custom symbol of 3D bars as a symbol for creating features
 3D_Bars_EA.mq5 3D bar builder that creates and updates custom symbols


Translated from Russian by MetaQuotes Ltd.
Original article: https://www.mql5.com/ru/articles/18785

Attached files |
3D_Bars_EA.mq5 (39.53 KB)
Last comments | Go to discussion (9)
Sergei Goncharov
Sergei Goncharov | 31 Jul 2025 at 06:45
Yevgeniy Koshtenko #:

And what sort of compilation errors are you getting? It compiles perfectly for me; if that weren’t the case, I wouldn’t have published it in the first place)

Yes, the compilation’s fine – I just corrected the path to the included file and that was that. The main issue here is with how the expert advisor works and its stated functions. I’m new to the MQL community and thought that when you read a phrase like‘predicts market behaviour with 65% accuracy. The SimpleQuantumEA.mq5 expert advisor uses 400 indicators’ and you see the published code, you’d expect the expert advisor to trade according to that principle. But that’s not the case. Please don’t take this as an insult. I admire your ideas and incorporate a lot of them into my own work. It’s the same with other authors; nothing published works 100%. I suppose it’s human greed. That’s just how we’re wired. Anyway, I’m grateful to you for what you share. For example, I’ve already added over 2,000 lines of code to your advisor. For instance, after writing code to test the effectiveness of 400 indicators, I was left with only 149 that proved effective. The algorithms filtered out the rest as noise that didn’t affect the forecast. Is it the same for you?


I’d just like some more information from you on the steps you took to achieve a 99 per cent profit rate on trades. I’m not even asking for the code, just some advice. What layers did you use, and what additional neural networks? I see that you started the Quantum expert advisor with an LSTM model. In the end, did you drop it and start using Quantum on top of it as a filter? Or do you have a separate LSTM expert advisor and a separate Quantum algorithm ?

Please share more advice and information. After all, if you start giving more back to the world, you’ll see how much more comes your way straight away. That’s how the universe works. I’m writing here because you don’t reply to private messages :) I assure you, if I manage to come up with something worthwhile along the way, I’ll definitely share it. But for now, I’m only just getting started...

Amato
Amato | 12 Sep 2025 at 13:22

Good afternoon.

I would like to remind you that the MQL5 platform does not support quantum computing. Real quantum neural networks use specialised platforms such as Qiskit or Cirq, and quantum hardware (for example, IBM Quantum). This is merely a simulation of ‘Attention’.

It’s a bit of a hodgepodge of LSTM, Transformers, ARIMA and so on. Genuine quantum computing won’t run on standard servers or PCs.

Levison Da Silva Barbosa
Levison Da Silva Barbosa | 7 Jun 2026 at 14:27
Thank you very much for sharing these studies.
azimute7
azimute7 | 7 Jun 2026 at 15:36
Very good
Rasoul Mojtahedzadeh
Rasoul Mojtahedzadeh | 22 Jun 2026 at 11:30
Nice article! However, Despite the "quantum" terminology, the system does not use a real quantum computer. It is a classical neural network with additional nonlinear mathematical functions inspired by quantum mechanics.

The core novelty is the addition of three nonlinear effects: Resonance, Interference and Decoherence.
From Basic to Intermediate: Objects (III) From Basic to Intermediate: Objects (III)
In today's article, we will look at how to implement a very attractive and interesting interaction system, especially for those who are just beginning to practice programming in MQL5. There is nothing fundamentally new here. Thanks to my approach to the topic, it will be much easier to understand everything, because we will see in practice how to develop a program using a structured approach with a practical and engaging goal.
AI Trading Platform: Why MetaTrader 5 Is the Best Choice for Algorithmic Trading with Python, ONNX, and AI Assistant AI Trading Platform: Why MetaTrader 5 Is the Best Choice for Algorithmic Trading with Python, ONNX, and AI Assistant
MetaTrader 5 is well suited for AI trading because it combines market data, MQL5 development, Python research, ONNX models, Strategy Tester, VPS, and the MQL5.community ecosystem into a single workflow. This article demonstrates a practical path from AI prompts to structured signals, working with code via the AI Assistant in MetaEditor, a quality model, a custom-created Expert Advisor, testing, and a controllable launch of a trading system.
From Basic to Intermediate: Object Events (I) From Basic to Intermediate: Object Events (I)
In this article, we will look at three of the six events that MetaTrader 5 can generate when some change occurs to an object on the chart. These events are very useful from the standpoint of user interaction. This is because, without understanding these events, we would have to put in much more effort to maintain a specific chart configuration when trying to manage objects for particular purposes.
Trading Options Without Options (Part 2): Use in Real Trading Trading Options Without Options (Part 2): Use in Real Trading
The article considers simple options strategies and their implementation in MQL5. We will develop a basic EA that will be modernized and become more complex.