English Русский Español Deutsch 日本語 Português
preview
MQL5中的量子神经网络(第一部分):创建包含文件

MQL5中的量子神经网络(第一部分):创建包含文件

MetaTrader 5EA交易 |
35 8
Yevgeniy Koshtenko
Yevgeniy Koshtenko

试想有这样一位交易者:永不休息、从不陷入恐慌,能够同时解析数千种市场形态;另外,还拥有如大象般惊人的记忆力、天才般的直觉,并且可以做到即时学习。听起来像科幻情节?欢迎来到MQL5量子神经网络的世界。

我们当下所要搭建的体系,远不止简单的机器学习。它是量子力学与人工智能的结合体,以代码形式实现,可直接在您的MetaTrader 5中运行。这套架构不只是预测价格走势,它能够以人类意识难以企及的层面理解市场。 


记忆机制的革新

人类大脑会同时调用多种类型的记忆。当经验丰富的交易者观察行情图表时,会瞬间回忆起历史上的相似行情,分析当下市场环境,凭借直觉预判后续可能发生的行情。这一原理正是我们的上下文分析器(ContextAnalyzer)的设计基础,该创新组件以数字化的方式复现人类交易直觉。

我们的记忆系统分为五个层级,每一层都各司其职。短期记忆捕捉市场的瞬时变化,记录每一笔Tick数据、每一次价格波动。中期记忆积累小时级别和日线级别趋势的相关信息。长期记忆存储历经数月乃至数年沉淀形成的底层市场模式。

而真正的魔力始于情景记忆。只有发生重大市场事件时它才会被激活:例如波动率剧烈飙升、突发消息、趋势发生切换。这些时刻会被着重标记留存,形成独有的“记忆片段”,供系统日后识别同类行情场景。

该架构融合不同时间跨度(从短期到长期)的记忆,以此适配市场动态变化。注意力机制与Transformer模型完成关键信息筛选与特征抽象。状态空间模型负责处理时序依赖关系,上下文分析器结合波动率完成记忆信息整合。量子处理器放大有效信号、抑制噪声,元验证模型(MetaVerificationModel)校验预测结果的可靠程度。整套架构是一套具备自我评判能力的自调节系统。


量子力学实际应用

经典神经网络以线性方式处理信息:数据经过一连串变换,从输入层流向输出层。而本系统的运行机理有着本质区别。我们引入量子力学原理:叠加态、干涉效应以及共振效应。

不同层级的记忆相互作用时,会生成干涉图样,原理类似光波可以相互增强或者相互抵消。经由这类干涉效应会涌现出新的特性,仅仅把各个组件简单相加是无法得到这类特性的。

double resonance_factor = 1.0 + 0.5 * MathCos(input_val * linear_context * M_PI);
double interference = 0.3 * MathSin(short_context * medium_context * 2.0 * M_PI) +
                     0.2 * MathCos(long_context * episodic_context * M_PI) +
                     0.1 * MathSin(pattern_context * input_val * 3.0 * M_PI);

这些公式并不仅仅是数学运算。它们描述了市场中不同“现实层级”如何相互共振,生成复杂的谐波信号,而我们的系统能够识别这类谐波,并将其用于预测。


Transformer是一场架构层面的革新

现代AI的核心是注意力机制 —— 即模型能够聚焦真正关键的信息,同时忽略噪声干扰。我们所设计的UShapeTransformer将这一理念提升到了新的高度。

想象一位管弦乐队指挥,他可以同时听见每一件乐器的演奏,并理解乐器之间如何相互配合。注意力机制的工作原理与之类似:它会计算输入序列中每一个元素相对于其余所有元素的重要程度。

void Forward(Matrix &input_matrix, Matrix &output_matrix)
{
    // Create matrices of queries, keys, and values
    MatrixMultiply(input_matrix, W_q, Q);
    MatrixMultiply(input_matrix, W_k, K);
    MatrixMultiply(input_matrix, W_v, V);
    
    // Calculate attention weights
    for(int i = 0; i < seq_len; i++)
    {
        for(int j = 0; j < seq_len; j++)
        {
            double dot_product = 0.0;
            for(int k = 0; k < d_model; k++)
                dot_product += Q.Get(i, k) * K.Get(j, k);
            attention_weights.Set(i, j, dot_product / MathSqrt(d_model));
        }
    }
}

U型架构引入了另一层复杂度。信息首先经过编码器,编码器对输入数据做压缩与抽象处理,凸显最重要的特征。接下来,解码器对该信息进行重建,并且融入上下文信息以及对深层关联关系的理解。


代码的炼金术:打造数字大脑

基础:矩阵结构
任何复杂体系都离不开稳固的底层根基。在本实例中,根基就是矩阵结构 —— 它不只是数值的存储容器,更是一套用于管理多维数据的智能系统。

struct Matrix
{
    double data[];
    int rows, cols;

    void Init(int r, int c)
    {
        rows = r;
        cols = c;
        ArrayResize(data, r * c);
        ArrayInitialize(data, 0.0);
    }

    double Get(int r, int c)
    {
        if(r < 0 || r >= rows || c < 0 || c >= cols) return 0.0;
        return data[r * cols + c];
    }

    void Set(int r, int c, double val)
    {
        if(r < 0 || r >= rows || c < 0 || c >= cols) return;
        data[r * cols + c] = val;
    }

    void Random(double range = 0.5)
    {
        for(int i = 0; i < ArraySize(data); i++)
            data[i] = (MathRand() / 32767.0 - 0.5) * 2.0 * range;
    }
}

这似乎只是一套简单的数据结构。但它的设计理念根植于安全性与可靠性。每一次数据访问都会被校验,每一项运算都会被管控。这对于金融系统而言尤为关键,因为一处错误就可能造成真实的资金损失。

StateSpaceModel:铭记过往,展望未来
市场具备记忆效应。昨日发生的行情会影响今日走势;而当下的市场状态,又决定了明天的各种可能性。状态空间模型以数学形式具体实现了这条底层客观规律。

struct StateSpaceModel
{
    Matrix A, B, C;  // State, input, and output matrices
    Matrix state;    // Current state of the system
    int input_size, state_size;

    void ProcessSequence(Matrix &_input, Matrix &output)
    {
        output.Init(_input.rows, _input.cols);
        
        for(int t = 0; t < _input.rows; t++)
        {
            // Extract the current input vector
            Matrix input_row;
            input_row.Init(1, _input.cols);
            for(int j = 0; j < _input.cols; j++)
                input_row.Set(0, j, _input.Get(t, j));

            // Update internal state
            Matrix new_state;
            new_state.Init(1, state_size);
            
            // state = A * state + B * input
            for(int i = 0; i < state_size; i++)
            {
                double sum = 0.0;
                for(int k = 0; k < state_size; k++)
                    sum += A.Get(i, k) * state.Get(0, k);
                
                for(int k = 0; k < _input.cols; k++)
                    sum += B.Get(k, i) * input_row.Get(0, k);
                    
                new_state.Set(0, i, sum);
            }
            
            state = new_state;

            // Calculate output: output = C * state
            for(int j = 0; j < _input.cols; j++)
            {
                double sum = 0.0;
                for(int k = 0; k < state_size; k++)
                    sum += C.Get(k, j) * state.Get(0, k);
                output.Set(t, j, sum);
            }
        }
    }
}

该模型的精妙之处在于简洁且能力强大。由三个矩阵决定系统随时间演化的方式:矩阵A描述内部动力学 —— 历史状态如何对未来状态产生影响;矩阵B定义外部输入(新数据)如何改变系统状态;矩阵C体现内部状态如何反映为外部观测结果。

ContextAnalyzer:数字直觉
本系统最复杂且最具创新性的组件是ContextAnalyzer。真正的核心能力就在此处实现:将原始数据转化为对市场的理解。

void ProcessWithContext(Matrix &_input, Matrix &output)
{
    output.Init(_input.rows, _input.cols);

    static Matrix short_term_memory, medium_term_memory, long_term_memory;
    static Matrix episodic_memory, pattern_memory;
    static bool memory_initialized = false;
    static int sequence_counter = 0;
    static double importance_buffer[100];
    static int buffer_index = 0;

    if(!memory_initialized)
    {
        short_term_memory.Init(5, context_size);
        medium_term_memory.Init(50, context_size);
        long_term_memory.Init(10, context_size);
        episodic_memory.Init(20, context_size);
        pattern_memory.Init(15, context_size);
        
        // Initialize all memory types
        ArrayInitialize(short_term_memory.data, 0.0);
        ArrayInitialize(medium_term_memory.data, 0.0);
        ArrayInitialize(long_term_memory.data, 0.0);
        ArrayInitialize(episodic_memory.data, 0.0);
        ArrayInitialize(pattern_memory.data, 0.0);
        ArrayInitialize(importance_buffer, 0.0);
        
        memory_initialized = true;
    }

    sequence_counter++;

    // Analyze input data characteristics
    double input_volatility = 0.0;
    double input_magnitude = 0.0;
    double input_complexity = 0.0;

    // Calculate volatility, magnitude, and complexity
    for(int i = 0; i < _input.rows; i++)
    {
        double row_sum = 0.0, row_variance = 0.0;
        for(int j = 0; j < _input.cols; j++)
        {
            double val = _input.Get(i, j);
            row_sum += val;
            input_magnitude += MathAbs(val);
        }

        double row_mean = row_sum / _input.cols;
        for(int j = 0; j < _input.cols; j++)
        {
            double val = _input.Get(i, j);
            row_variance += (val - row_mean) * (val - row_mean);
        }

        input_volatility += MathSqrt(row_variance / _input.cols);

        // Evaluate complexity through change analysis
        for(int j = 1; j < _input.cols; j++)
        {
            if(MathAbs(_input.Get(i, j) - _input.Get(i, j-1)) > 0.1)
                input_complexity += 1.0;
        }
    }

    input_volatility /= _input.rows;
    input_magnitude /= (_input.rows * _input.cols);
    input_complexity /= (_input.rows * (_input.cols - 1));

系统持续分析流入数据的特征属性。当市场处于高波动状态时,模型会更多侧重短期记忆;当出现复杂行情模式时,会触发情景记忆与模式记忆。以上并非硬性固定规则,而是会随当前市场环境自适应调整的动态权重。

现在到了最引人关注的部分:不同类型记忆之间的量子交互效应:

// Dynamic calculation of weights for different memory types
double short_weight = 0.4 + 0.4 * input_volatility;
double medium_weight = 0.3 + 0.2 * (1.0 - input_volatility);
double long_weight = 0.2 + 0.3 * (1.0 - input_volatility);
double episodic_weight = 0.1 + 0.3 * input_complexity;
double pattern_weight = 0.15 + 0.25 * input_complexity;

// Normalize weights
double total_weight = short_weight + medium_weight + long_weight + episodic_weight + pattern_weight;
short_weight /= total_weight;
medium_weight /= total_weight;
long_weight /= total_weight;
episodic_weight /= total_weight;
pattern_weight /= total_weight;

for(int i = 0; i < _input.rows; i++)
{
    for(int j = 0; j < _input.cols; j++)
    {
        double input_val = _input.Get(i, j);
        double context_idx = j % context_size;

        // Extract context from different memory types
        double short_context = short_term_memory.Get(sequence_counter % 5, context_idx);
        double medium_context = medium_term_memory.Get(sequence_counter % 50, context_idx);
        double long_context = long_term_memory.Get(sequence_counter % 10, context_idx);
        double episodic_context = episodic_memory.Get(sequence_counter % 20, context_idx);
        double pattern_context = pattern_memory.Get(sequence_counter % 15, context_idx);

        // Linear combination of contexts
        double linear_context = short_weight * short_context +
                               medium_weight * medium_context +
                               long_weight * long_context +
                               episodic_weight * episodic_context +
                               pattern_weight * pattern_context;

        // Quantum effects: resonance and interference
        double resonance_factor = 1.0 + 0.5 * MathCos(input_val * linear_context * M_PI);
        double interference = 0.3 * MathSin(short_context * medium_context * 2.0 * M_PI) +
                             0.2 * MathCos(long_context * episodic_context * M_PI) +
                             0.1 * MathSin(pattern_context * input_val * 3.0 * M_PI);

        double nonlinear_factor = 1.0 + input_volatility * MathSin(linear_context * 2.0 * M_PI);

        // Integrate all effects
        double integrated_context = linear_context * resonance_factor * nonlinear_factor + interference;

        // Determine the strength of contextual influence
        double context_strength = 0.4 + 0.3 * input_complexity;
        double final_output = (1.0 - context_strength) * input_val + context_strength * integrated_context;

        output.Set(i, j, final_output);
    }
}

这些并不只是单纯的数学运算。每一条公式都蕴含着深层含义。如果当前数据与累积的上下文信息发生“同步”,就会产生共振效应。干涉效应会催生不同时间尺度之间复杂的交互模式。非线性因子赋予系统自适应能力,使其能够应对不断变化的市场环境。

训练与自适应系统
真正的智能并不体现在记忆能力上,而在于学习与自适应能力。本系统会持续评估输入信息的重要程度,并据此更新自身记忆:

// Evaluate the importance of current data
double importance = input_volatility + input_complexity + MathAbs(input_val);
importance_buffer[buffer_index] = importance;
buffer_index = (buffer_index + 1) % 100;

double avg_importance = 0.0;
for(int k = 0; k < 100; k++) avg_importance += importance_buffer[k];
avg_importance /= 100.0;

// Adaptive learning rate
double learning_rate = (importance > avg_importance) ? 0.3 : 0.05;

// Update different memory types at different speeds
double new_short = short_context * (1.0 - 0.4) + final_output * 0.4;
short_term_memory.Set(sequence_counter % 5, context_idx, new_short);

double new_medium = medium_context * (1.0 - 0.1) + final_output * 0.1;
medium_term_memory.Set(sequence_counter % 50, context_idx, new_medium);

double new_long = long_context * (1.0 - 0.02) + final_output * 0.02;
long_term_memory.Set(sequence_counter % 10, context_idx, new_long);

// Episodic memory is activated only for important events
if(importance > avg_importance * 1.5)
{
    double new_episodic = episodic_context * 0.7 + final_output * 0.3;
    episodic_memory.Set(sequence_counter % 20, context_idx, new_episodic);
}

// Pattern memory is updated when correlations are detected
double pattern_correlation = input_val * linear_context;
if(MathAbs(pattern_correlation) > 0.1)
{
    double pattern_update = pattern_correlation * learning_rate;
    double new_pattern = pattern_context * 0.9 + pattern_update * 0.1;
    pattern_memory.Set(sequence_counter % 15, context_idx, new_pattern);
}

该系统的运行机制如同生命体一般。它并非单纯堆积信息,而是能够分辨哪些信息至关重要、哪些可以忽略。重要市场事件会被长期记忆,常规普通数据则会快速遗忘。反复出现的行情模式会被不断强化,随机噪声则被过滤剔除。

MetaVerificationModel:质疑的艺术
机器学习领域的一大难题就是模型过度自信问题。即便输入数据存在矛盾或者信息不足,系统依旧可能输出“置信度很高”的预测结果。MetaVerificationModel通过引入批判性评估层来解决该问题:

struct MetaVerificationModel
{
    Matrix meta_weights;
    Matrix meta_output_weights;

    void Init()
    {
        int meta_input_size = FEATURES_COUNT + 1 + 3; // features + forecast + metrics
        meta_weights.Init(meta_input_size, 16);
        meta_weights.Random(0.3);
        meta_output_weights.Init(16, 1);
        meta_output_weights.Random(0.5);
    }

    double Forward(double &original_features[], double first_model_prediction, double &error_metrics[])
    {
        // Forming the meta input
        double meta_input[];
        int total_input_size = ArraySize(original_features) + 1 + ArraySize(error_metrics);
        ArrayResize(meta_input, total_input_size);

        // Copy the original features
        for(int i = 0; i < ArraySize(original_features); i++)
            meta_input[i] = original_features[i];

        // Add the main model forecast
        meta_input[ArraySize(original_features)] = first_model_prediction;

        // Add error metrics
        for(int i = 0; i < ArraySize(error_metrics); i++)
            meta_input[ArraySize(original_features) + 1 + i] = error_metrics[i];

        // Forward propagation through the hidden layer
        double hidden[];
        ArrayResize(hidden, 16);

        for(int i = 0; i < 16; i++)
        {
            double sum = 0.0;
            for(int j = 0; j < ArraySize(meta_input) && j < meta_weights.cols; j++)
                sum += meta_input[j] * meta_weights.Get(j, i);
            hidden[i] = Tanh(sum);
        }

        // Calculate the final output
        double output = 0.0;
        for(int i = 0; i < 16; i++)
            output += hidden[i] * meta_output_weights.Get(i, 0);

        return Sigmoid(output); // Return confidence from 0 to 1
    }
}

该元模型不仅分析原始输入数据与主模型的预测结果,还会分析历史误差记录、当前质量指标以及市场行为模式。它能够识别出基础模型容易出错的场景,并据此降低对其预测结果的置信度。

记忆平衡机制
系统高效运行的关键要点之一,就是对各类记忆模块进行合理配置。不同市场具备各自的特性,不存在一套万能通用的参数设置。

对于加密货币这类高波动市场,应当提升短期记忆与情景记忆的作用权重。系统需要快速响应突发行情变化,并且记住极端市场事件。而对于国债这类走势更加平稳的交易品种,则需要赋予长期记忆与模式记忆更高权重。

// Adaptive adjustment of memory weights depending on the instrument
void AdaptMemoryWeights(string symbol)
{
    if(StringFind(symbol, "BTC") >= 0 || StringFind(symbol, "ETH") >= 0)
    {
        // Settings for cryptocurrencies
        short_term_base_weight = 0.5;
        episodic_base_weight = 0.25;
        long_term_base_weight = 0.1;
    }
    else if(StringFind(symbol, "USD") >= 0)
    {
        // Forex settings
        short_term_base_weight = 0.35;
        medium_term_base_weight = 0.35;
        long_term_base_weight = 0.2;
    }
    // And so on for different types of assets
}

自诊断系统
一套智能系统应当清楚自身能力的边界。我们实现了多项自诊断功能,以监控模型运行的各个维度:

void RunDiagnostics()
{
    static int diagnostic_counter = 0;
    diagnostic_counter++;
    
    if(diagnostic_counter % 1000 == 0) // every thousand ticks
    {
        // Entropy analysis in different types of memory
        double short_entropy = context_analyzer.CalculateMemoryEntropy(short_term_memory);
        double long_entropy = context_analyzer.CalculateMemoryEntropy(long_term_memory);
        double pattern_entropy = context_analyzer.CalculateMemoryEntropy(pattern_memory);
        
        // If short-term memory is too chaotic and long-term memory is too stable
        if(short_entropy > 2.5 && long_entropy < 0.5)
        {
            Print("DIAGNOSIS: Memory imbalance detected. Increasing connectivity.");
            // Increase interaction between memory types
            interference_strength += 0.1;
        }
        
        // If the system becomes too conservative
        if(pattern_entropy < 0.3)
        {
            Print("DIAGNOSIS: The system is too conservative. Adding exploratory noise.");
            exploration_noise += 0.05;
        }
        
        // Analyze forecast quality
        double recent_accuracy = prediction_history.GetRecentAccuracy(50);
        if(recent_accuracy < 0.4)
        {
            Print("DIAGNOSIS: Low accuracy of forecasts. Activating retraining mode.");
            learning_rate_multiplier = 1.5;
            confidence_threshold += 0.1; // Raise the bar for confidence
        }
    }
}



实际运行中的类量子效应

本系统最耐人寻味的部分,是各个组件之间受量子思想启发的交互机制。让我们来看一下它们在实际场景中如何运作。

当输入数据与已存储的记忆被“调谐”至同一“频率”时,就会产生共振。由此带来信号放大效应:重要行情模式变得更加突出,噪声则被抑制。

干涉效应发挥交叉校验系统的作用。当不同类型记忆的信息相互匹配时,整体信号强度得到增强。如果记忆之间彼此矛盾,则会产生"相消干涉",促使系统在给出预测结果时变得更加谨慎。

// Example of analysis of quantum effects
void AnalyzeQuantumEffects(double input_val, double linear_context)
{
    double resonance = MathCos(input_val * linear_context * M_PI);
    
    if(MathAbs(resonance) > 0.8)
    {
        if(resonance > 0)
            Print("QUANTUM EFFECT: Strong constructive resonance detected");
        else
            Print("QUANTUM EFFECT: Strong destructive resonance detected");
    }
    
    // Analyze interference patterns
    double interference_pattern = AnalyzeInterferencePattern();
    if(MathAbs(interference_pattern) > threshold)
    {
        Print("QUANTUM EFFECT: Complex interference pattern detected");
        // The market may be in a transitional state
    }
}


交易中的AI哲学

我们这套量子启发神经网络的诞生,引出了关于智能本质与金融市场可预测性的深刻问题。机器是否能够真正“理解”市场,抑或它仅仅是挖掘数据当中复杂的相关关系?我们提出第三条路线:架构不再局限于单纯记忆行情模式或是寻找数据关联。本系统构建对市场现实的多层表征,每一层分别负责一类独特的感知与分析维度。

  • 短期记忆捕捉市场参与者情绪的瞬时变化:每一笔Tick数据、每一次价格扰动。它如同灵敏的雷达,捕捉转瞬即逝的脉冲信号。

  • 中期记忆追踪小时和日线级别形成的趋势与周期,识别行情演化过程中的各类模式。

  • 长期记忆存储数月乃至数年尺度下形成的基本面经济规律,为系统赋予战略视角。

  • 情景记忆记录特殊的关键事件:波动率剧烈飙升、突发消息、趋势拐点。这些“记忆”让系统预判同类场景的再度出现。

  • 模式记忆如同数字直觉,提取跨不同时间尺度、不同市场环境下反复出现的深层结构。

类量子效应 —— 共振、干涉和相干,带来更高一层复杂度。系统不再把不确定性视作阻碍,而是将其视作有价值的信息来源。就像处于叠加态的量子粒子,本网络可以同时考量多种潜在市场情景,放大有效信号,抑制噪声。这就将不确定性转变为学习工具,让系统能够适配市场的混沌特性。


MQL5内置矩阵类型的优势:从自行车到宇宙飞船

项目初期,系统采用自研矩阵运算实现,相当于重复造轮子。然而,MQL5开发团队完成了出色的工作:提供内置矩阵类型、向量类型以及<matrix.mqh>库,把我们的“自行车”升级为高性能宇宙飞船。使用原生矩阵运算大幅缩减代码量,提升代码可读性与运行性能。

MQL5内置矩阵类型的优势

  • 高性能 —— 矩阵乘法(MatMul、@运算符)调用处理器向量指令,相比手写循环速度提升数倍。

  • 可靠性 —— 内置数据类型规避下标越界错误,保障数值稳定性。这对金融计算至关重要,任何计算偏差都可能带来资金亏损。

  • 简洁清晰 —— 代码形式贴近数学表达式,便于开发与维护。例如,不再需要繁琐循环实现矩阵乘法,直接书写Q = input @ W_q即可。

  • 现成的机器学习工具:RandUniform、Exp、Sigmoid、ReLU等函数,使开发者专注高层业务逻辑,不必纠结底层计算实现。

  • 优化内存管理:内置矩阵类型尽可能减少内存申请释放操作,对于实时处理海量市场数据尤为重要。

对比使用内置矩阵类型前后的代码示例如下:

之前  之后 
   void Forward(Matrix &input_matrix, Matrix &output_matrix)
   {
      int seq_len = input_matrix.rows;
      
      Matrix Q, K, V;
      Q.Init(seq_len, d_model);
      K.Init(seq_len, d_model);
      V.Init(seq_len, d_model);

      // Simple matrix multiplication Q = input * W_q
      for(int i = 0; i < seq_len; i++)
      {
         for(int j = 0; j < d_model; j++)
         {
            double q_sum = 0.0, k_sum = 0.0, v_sum = 0.0;
            for(int k = 0; k < d_model; k++)
            {
               double input_val = input_matrix.Get(i, k);
               q_sum += input_val * W_q.Get(k, j);
               k_sum += input_val * W_k.Get(k, j);
               v_sum += input_val * W_v.Get(k, j);
            }
            Q.Set(i, j, q_sum);
            K.Set(i, j, k_sum);
            V.Set(i, j, v_sum);
         }
      }

      // Calculate attention weights
      Matrix attention_weights;
      attention_weights.Init(seq_len, seq_len);

      for(int i = 0; i < seq_len; i++)
      {
         double max_score = -DBL_MAX;
         
         // Calculate scores
         for(int j = 0; j < seq_len; j++)
         {
            double score = 0.0;
            for(int k = 0; k < d_model; k++)
               score += Q.Get(i, k) * K.Get(j, k);
            
            score /= MathSqrt(d_model);
            attention_weights.Set(i, j, score);
            if(score > max_score) max_score = score;
         }

         // Softmax
         double sum_exp = 0.0;
         for(int j = 0; j < seq_len; j++)
         {
            double exp_val = MathExp(attention_weights.Get(i, j) - max_score);
            attention_weights.Set(i, j, exp_val);
            sum_exp += exp_val;
         }

         if(sum_exp > 0)
         {
            for(int j = 0; j < seq_len; j++)
               attention_weights.Set(i, j, attention_weights.Get(i, j) / sum_exp);
         }
      }

      // Apply weights to values
      output_matrix.Init(seq_len, d_model);
      for(int i = 0; i < seq_len; i++)
      {
         for(int j = 0; j < d_model; j++)
         {
            double sum = 0.0;
            for(int k = 0; k < seq_len; k++)
               sum += attention_weights.Get(i, k) * V.Get(k, j);
            output_matrix.Set(i, j, sum);
         }
      }
   }

   matrix Forward(const matrix &input_data)
   {
      // Calculate Q, K, V
      matrix Q = input_data.MatMul(W_q);
      matrix K = input_data.MatMul(W_k);
      matrix V = input_data.MatMul(W_v);
      
      // Apply quantum effects
      Q = quantum_proc.ApplyQuantumEffects(Q, input_data);
      K = quantum_proc.ApplyQuantumEffects(K, input_data);
      
      // Calculate attention weights
      matrix scores = Q.MatMul(K.Transpose()) / MathSqrt((double)d_model);
      
      // Softmax across rows
      for(ulong i = 0; i < scores.Rows(); i++)
      {
         vector row = scores.Row(i);
         
         // Find the maximum value for numerical stability
         double max_val = row.Max();
         
         // Subtract the maximum and apply the exponential element-wise
         for(ulong j = 0; j < row.Size(); j++)
         {
            row[j] = MathExp(row[j] - max_val);
         }
         
         // Normalize (divide by the sum)
         double sum = row.Sum();
         row = row / sum;
         
         // Write back to the matrix
         scores.Row(row, i);
      }
      
      // Apply to values and output projection
      matrix attention_output = scores.MatMul(V);
      return attention_output.MatMul(W_o);
   }
   

优化后的完整代码可在附件文件QuantumNeuralMQL.mqh.中查阅。

熟练掌握MQL5的各项能力,是搭建复杂神经网络的关键。我们无需耗费时间自行实现各类基础运算,能够将精力投入开发创新架构,如ContextAnalyzer(上下文分析器)与QuantumProcessor(量子处理器)。研究MQL5官方文档(例如矩阵运算相关内容),为高效实现数学复杂度较高的算法打开了大门,让神经网络开发不仅高效,也充满乐趣。

最后,我们将运行一段简短脚本,验证代码能够正常工作。

//+------------------------------------------------------------------+
//| Usage example                                                    |
//+------------------------------------------------------------------+
// Using in EA:
SimpleQuantumNeural neural_net;

int OnInit()
{
   neural_net.Init();
   return INIT_SUCCEEDED;
}

void OnTick()
{
   double features[];
   if(MarketDataCollector::CollectSimpleFeatures(_Symbol, PERIOD_H1, 10, features))
   {
      double prediction[];
      neural_net.Forward(features, prediction);
      
      if(ArraySize(prediction) > 0)
      {
         double signal = prediction[0];
         Comment("Quantum signal: ", DoubleToString(signal, 4));
         
         if(signal > 0.6)
         {
            // Buy
         }
         else if(signal < 0.4)
         {
            // Sell
         }
      }
   }
   
   // Diagnostics
   static int counter = 0;
   counter++;
   if(counter % 100 == 0)
      neural_net.PrintDiagnostics();
}




结论

最终成型的系统不只是一套算法,而是具备自学习能力的架构,能够不断自适应,并逐步形成自身对市场的理解。

关键组成部分:

  • 矩阵 —— 数学基础
  • 状态空间模型 —— 刻画时序动力学演化
  • Transformer —— 注意力机制与泛化能力
  • 上下文分析器 —— 多层级市场洞察
  • 元验证模型 —— 对输出结论做校验

系统的核心效果来源于上述模块之间的协同交互。本系列文章的第二部分将介绍实际使用示例、参数配置以及系统优化方法。交易中新一代AI形态的转变才刚刚开始。

本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/18759

最近评论 | 前往讨论 (8)
[删除] | 10 7月 2025 在 15:12

只有在替换了包含文件后,文章中的脚本才成功编译。否则神经网络无法识别。大概是因为我没把文章读完,就直接把它放到了“专家”板块里。

//#include <Shtenco_SimpleQuantumNeural.mqh>
#include  <QuantumNeuralMQL.mqh>

但之后还是完全搞不懂该用什么来测试 :) 就像是家庭作业——要把机器人补写完吗?
Yevgeniy Koshtenko
Yevgeniy Koshtenko | 11 7月 2025 在 14:32
Maxim Dmitrievsky #:

只有在替换了包含文件后,文章中的脚本才能编译成功。否则神经网络无法识别。大概是因为我没把文章读完,就直接把它放进了“专家”板块。


但之后还是完全搞不懂该在什么环境下进行测试 :) 就像是作业一样——要继续完善这个聊天机器人吗?

你好,马克西姆!我刚刚替换了文件——之前把不同版本文章中的包含文件搞混了

关于聊天机器人——下一部分会介绍一个基于这个神经网络的简单聊天机器人)

[删除] | 11 7月 2025 在 15:22
Yevgeniy Koshtenko #:

你好,马克西姆!我刚刚替换了文件——之前在不同版本的文章中把包含文件搞混了

关于机器人——下一部分将介绍一个基于这个编程语言的简单机器人)

好嘞,不错,咱们一起研究研究吧 :)

10748356
10748356 | 29 7月 2025 在 15:17
这篇文章的构思非常精彩且引人入胜。我完全理解了该系统的量子特性,这是我在MQL5社区中发现的第一个此类“大脑”。太棒了,继续努力!简体中文(大陆)
Renat Akhtyamov
Renat Akhtyamov | 29 7月 2025 在 17:53
Maxim Dmitrievsky #:

只有在替换了包含文件后,文章中的脚本才能编译成功。否则神经网络无法识别。大概是因为我没把文章读完,就直接把它放到了“专家”板块里。


但之后还是完全搞不懂该在什么环境下进行测试 :) 就像是家庭作业——要把机器人补写完吗?
Yevgeniy Koshtenko#:

那有什么问题吗?正是Transformer在当时有力地推动了自然语言处理技术的发展。与之前的RNN相比,它确实更厉害。我认为,未来我们将看到量子计算与神经网络的融合, 环形元神经网络架构进展得非常顺利,正如论文中所述,其中包含12个模型副本,它们像“增强学习”一样形成环路,相互提升效果,并基于彼此的输出、置信度和误差进行学习。 看,这甚至是在没有预训练的情况下进行的测试,它只是在线上学习……


测试数据是2017年的吗?

为什么不选24年或25年的数据呢?

交易策略 交易策略
各种交易策略的分类都是任意的,下面这种分类强调从交易的基本概念上分类。
交易中的神经网络:跨域时间序列预测框架(结论) 交易中的神经网络:跨域时间序列预测框架(结论)
本文聚焦于TimeFound时间序列预测模型的工程落地实现,探讨如何基于MQL5实现该框架核心算法的关键步骤。
新手在交易中的10个基本错误 新手在交易中的10个基本错误
新手在交易中会犯的10个基本错误: 在市场刚开始时交易, 获利时不适当地仓促, 在损失的时候追加投资, 从最好的仓位开始平仓, 翻本心理, 最优越的仓位, 用永远买进的规则进行交易, 在第一天就平掉获利的仓位,当发出建一个相反的仓位警示时平仓, 犹豫。
市场模拟(第 24 部分):仓位视图(二) 市场模拟(第 24 部分):仓位视图(二)
在本文中,我将展示如何以最简单、最实用的方式使用指标来跟踪交易服务器上的未平仓位。我将逐步演示,以表明您并不一定需要将所有这些操作都转移到 EA 中。你们中的许多人可能因为这样或那样的原因已经习惯了这样做。事实上,这并不完全合理,因为随着这种实现方式的演变,您将清楚地看到,您可以为此目的创建或实现不同类型的指标。