从Python到MQL5:量子启发式交易系统的探索之旅·综合运用
量子模拟系统在 MT5 里的落地与边界
把量子计算思路搬进交易,核心不是真去跑量子硬件,而是在 MQL5 里用确定性演化模拟一套量子电路。作者从 Python 原型切到 MQL5 实现后,在模拟与真实环境都拿到了稳定的命中率,高波动段尤其比传统模型抗压。 但要注意,这只是一套量子『模拟』系统。市场状态、数据质量都会直接干扰输出,作者本人也在讨论区提醒:附带 set #2 是优化跑出来的失败参数,别直接挂。正确做法是你自己跑优化找适配参数。 外汇和贵金属本身高杠杆高风险,这类受量子启发的 EA 只算算法探索,实盘前务必在策略测试器用历史数据复核,别把回测满意当保本凭证。 下面这段是状态向量演化的核心函数,决定了特征怎么转成量子幅值: [CODE] double SimulatePureQuantumCircuit(double &features[]) { const int num_states = (int)MathPow(2.0, (double)NUM_QUBITS); // 1. 创建并初始化状态向量(确定性演化) double state[]; ArrayResize(state, num_states); ArrayInitialize(state, 0.0); state[0] = 1.0; // 状态 |000...0> double next_state[]; ArrayResize(next_state, num_states); // --- [演变:Ry旋转阀] --- for(int qubit = 0; qubit < NUM_QUBITS; qubit++) { const int feature_idx = qubit % ArraySize(features); const double angle = MathMax(MathMin(features[feature_idx] * M_PI, M_PI), -M_PI); const double cos_a = MathCos(angle / 2.0); const double sin_a = MathSin(angle / 2.0); ArrayCopy(next_state, state); for(int i = 0; i < num_states; i++) { if((i & (1 << qubit)) == 0) { const int i1 = i | (1 << qubit); next_state[i] = cos_a * state[i] - sin_a * state[i1]; next_state[i1] = sin_a * state[i] + cos_a * state[i1]; } } ArrayCopy(state, next_state); 逐行拆解:第 3 行按量子比特数算总状态数 2^N;第 7–10 行把状态向量清零并把初态置为 |000...0>;第 14 行把特征索引对特征数组取模,避免越界;第 15 行把特征值乘 π 并夹在 ±π 内当旋转角;第 16–17 行算 Ry 门的半角余弦正弦;第 20–29 行对每个量子比特做受控旋转,把幅值在基态间重新分配;最后一行把本轮结果写回主状态供下一比特继续演化。
class="type">class="kw">double SimulatePureQuantumCircuit(class="type">class="kw">double &features[]) { const class="type">int num_states = (class="type">int)MathPow(class="num">2.0, (class="type">class="kw">double)NUM_QUBITS); class=class="str">"cmt">// class="num">1. 创建并初始化状态向量(确定性演化) class="type">class="kw">double state[]; ArrayResize(state, num_states); ArrayInitialize(state, class="num">0.0); state[class="num">0] = class="num">1.0; class=class="str">"cmt">// 状态 |class="num">000...class="num">0> class="type">class="kw">double next_state[]; ArrayResize(next_state, num_states); class=class="str">"cmt">// --- [演变:Ry旋转阀] --- for(class="type">int qubit = class="num">0; qubit < NUM_QUBITS; qubit++) { const class="type">int feature_idx = qubit % ArraySize(features); const class="type">class="kw">double angle = MathMax(MathMin(features[feature_idx] * M_PI, M_PI), -M_PI); const class="type">class="kw">double cos_a = MathCos(angle / class="num">2.0); const class="type">class="kw">double sin_a = MathSin(angle / class="num">2.0); ArrayCopy(next_state, state); for(class="type">int i = class="num">0; i < num_states; i++) { if((i & (class="num">1 << qubit)) == class="num">0) { const class="type">int i1 = i | (class="num">1 << qubit); next_state[i] = cos_a * state[i] - sin_a * state[i1]; next_state[i1] = sin_a * state[i] + cos_a * state[i1]; } } ArrayCopy(state, next_state);
「纠缠门与振幅平方取概率」
这段逻辑在模拟两比特间的纠缠相位门:当特征 i 与 j 的乘积把相位推过 π/4 时,凡是在状态位图里同时置位 i 和 j 的基态振幅直接翻负号。NUM_QUBITS 设成 3,状态向量长度就是 2^3=8,外层双重循环跑完最多触发 C(3,2)=3 次纠缠判断。 相位计算用 M_PI/2.0 乘特征积,阈值卡在 M_PI/4.0;越过阈值才进最里层按位与筛查。这种条件翻转不改变概率模长,只动相对符号,属于典型干涉操控,不是凭空造信号。 取概率那步很直白:exact_probs[i] = state[i] * state[i],振幅平方即 Born 规则下的理论概率,不经过任何采样近似。MIN_CONFIDENCE 默认 0.1 只用于上游过滤平移信号,本段把精确概率直接喂给 GetWeightedVote 做加权投票。 CountBits 用 n &= (n-1) 清最低置位来计数,比逐位移位快;GetWeightedVote 里 state_value 映射成 (2*num_ones/NUM_QUBITS)-1,把 0~3 个置位线性拉伸到 -1~1 区间。外汇贵金属波动大,这类量子启发模型仅作概率参考,实盘前务必在 MT5 策略测试器跑多品种回测。
for(class="type">int i = class="num">0; i < NUM_QUBITS - class="num">1; i++) { for(class="type">int j = i + class="num">1; j < NUM_QUBITS; j++) { const class="type">class="kw">double phase = M_PI / class="num">2.0 * (features[i] * features[j]); if(MathAbs(phase) > M_PI / class="num">4.0) { for(class="type">int k = class="num">0; k < num_states; k++) { if(((k & (class="num">1 << i)) != class="num">0) && ((k & (class="num">1 << j)) != class="num">0)) state[k] = -state[k]; } } } } class=class="str">"cmt">// --- [真实概率的计算] --- class="type">class="kw">double exact_probs[]; ArrayResize(exact_probs, num_states); for(class="type">int i = class="num">0; i < num_states; i++) { class=class="str">"cmt">// 振幅的平方即为根据波尔定理计算出的纯理论概率 exact_probs[i] = state[i] * state[i]; } class=class="str">"cmt">// class="num">2. 直接将理想概率传递给投票权重计算 const class="type">class="kw">double prediction = GetWeightedVote(exact_probs); class="kw">return prediction; } class=class="str">"cmt">// 全局设置(请根据您的交易系统进行调整) class="macro">#define NUM_QUBITS class="num">3 class=class="str">"cmt">// 量子比特数(状态向量大小 = class="num">2^NUM_QUBITS) class="macro">#define MIN_CONFIDENCE class="num">0.1 class=class="str">"cmt">// 过滤平移信号的最低置信度阈值 class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 快速计算已设置的位(布莱恩·柯尼汉的方法) | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int CountBits(class="type">int n) { class="type">int count = class="num">0; while(n > class="num">0) { n &= (n - class="num">1); count++; } class="kw">return count; } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 期望值(Expectation Value)的计算 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">double GetWeightedVote(const class="type">class="kw">double &state_probs[]) { class="type">class="kw">double expected_value = class="num">0.0; class="type">class="kw">double total_weight = class="num">0.0; const class="type">int size = ArraySize(state_probs); for(class="type">int i = class="num">0; i < size; i++) { const class="type">class="kw">double vote_weight = state_probs[i]; if(vote_weight <= class="num">0.000001) class="kw">continue; const class="type">int num_ones = CountBits(i); const class="type">class="kw">double state_value = (class="num">2.0 * (class="type">class="kw">double)num_ones / (class="type">class="kw">double)NUM_QUBITS) - class="num">1.0;
◍ 复数量子态的编码与归一化落地
这段 MQL5 片段把‘投票加权’和‘复数量子电路模拟’拼在同一节里,核心是两件事:先用权重把多个状态值揉成一个有界预测,再用 complex 类型在 MT5 里真跑一个多 qubit 态向量。 expected_value += state_value * vote_weight 这一步就是按票权累加,total_weight 做分母前先判 <=0.0001 直接 return 0.0,避免除零把 EA 卡死;final_prediction 夹在 [-1.0, 1.0] 之间,意味着模型输出天生被限幅,不会给出离谱极值。 下面 SimulateQuantumCircuitComplex 用 num_states = 2^NUM_QUBITS 算出态数,比如 NUM_QUBITS=3 就是 8 个基态。state[0].real=1.0 把系统钉在 |000> 基态,其余振幅清零,这是确定性复路模拟的标准初值。 特征编码段把 features_matrix[][0] 当 Ry 角、[][1] 当 Rz 角,统一 clamp 到 [-M_PI, M_PI];cos(theta/2)、sin(theta/2) 配欧拉指数 e^(i*phi) 写进 complex,next_state 做原子缓冲。开 MT5 把 NUM_QUBITS 调到 4,观察 ArrayResize 后 state 长度变 16,能直接验证振幅展开成本。外汇与贵金属行情受杠杆与跳空影响,这类信号仅作概率参考,实盘前务必在策略测试器跑历史回测。
expected_value += state_value * vote_weight; total_weight += vote_weight; } if(total_weight <= class="num">0.0001) class="kw">return class="num">0.0; class="type">class="kw">double final_prediction = expected_value / total_weight; if(final_prediction > class="num">1.0) final_prediction = class="num">1.0; if(final_prediction < -class="num">1.0) final_prediction = -class="num">1.0; class="kw">return final_prediction; } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 确定性复量子电路模拟器 | class=class="str">"cmt">//| features[][class="num">0] - 振幅参数,features[][class="num">1] - 相位 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">double SimulateQuantumCircuitComplex(class="type">class="kw">double &features_matrix[][]){ const class="type">int num_states = (class="type">int)MathPow(class="num">2.0, (class="type">class="kw">double)NUM_QUBITS); const class="type">int num_features = ArrayRange(features_matrix, class="num">0); if(num_features == class="num">0) { Print("错误:特征矩阵为空!"); class="kw">return class="num">0.0; } class=class="str">"cmt">// 基于内置类型 complex 的量子态向量 complex state[]; ArrayResize(state, num_states); class=class="str">"cmt">// 将系统初始化为严格状态 |class="num">000...class="num">0> for(class="type">int i = class="num">0; i < num_states; i++) { state[i].real = class="num">0.0; state[i].imag = class="num">0.0; } state[class="num">0].real = class="num">1.0; class=class="str">"cmt">// 基态振幅为1 class=class="str">"cmt">// 用于向量原子(同时)更新的临时缓冲区 complex next_state[]; ArrayResize(next_state, num_states); class=class="str">"cmt">// --- class="num">1. 特征的综合编码(U-Gate:Ry + Rz) --- for(class="type">int qubit = class="num">0; qubit < NUM_QUBITS; qubit++) { const class="type">int feat_idx = qubit % num_features; class=class="str">"cmt">// 将输入角度限制在 [-PI; PI] 范围内 const class="type">class="kw">double theta = MathMax(MathMin(features_matrix[feat_idx][class="num">0] * M_PI, M_PI), -M_PI); class=class="str">"cmt">// 适用于 Ry const class="type">class="kw">double phi = MathMax(MathMin(features_matrix[feat_idx][class="num">1] * M_PI, M_PI), -M_PI); class=class="str">"cmt">// 对于 Rz const class="type">class="kw">double cos_t = MathCos(theta / class="num">2.0); const class="type">class="kw">double sin_t = MathSin(theta / class="num">2.0); class=class="str">"cmt">// 相位移的欧拉指数:e^(i*phi) = cos(phi) + i*sin(phi) complex e_phase; e_phase.real = MathCos(phi); e_phase.imag = MathSin(phi); ArrayCopy(next_state, state); for(class="type">int i = class="num">0; i < num_states; i++) {
单比特旋转与纠缠门的状态演进
这段逻辑把量子态的演进拆成两步:先对每个 qubit 施加受控旋转(Rx 类门),再做两两之间的纠缠相位混淆。旋转部分只处理目标位为 0 的基态索引 i,用位运算 (i & (1 << qubit)) == 0 跳过已置位的分支,避免重复计算。 旋转矩阵 U(theta, phi) 的实部直接用 cos(theta/2) 与 sin(theta/2) 线性组合 state[i] 与 state[i1],虚部同理;相位偏移 e^(i*phi) 通过 MQL5 的 complex 原生乘法 temp_i1 * e_phase 施加到目标位为 1 的分量上,比手写欧拉展开更不易出错。 纠缠阶段用双层循环遍历 i<j 的 qubit 对,cross_phase 取 M_PI/2.0 乘以两个特征矩阵槽位的乘积,构造一个 cz_gate 复数(cos 为实、sin 为虚)。仅当基态 k 中 i 与 j 两位同时为 1((k & (1<<i))!=0 且 (k & (1<<j))!=0)时才把 state[k] 乘以该门,相当于受控相位门。 在 MT5 里把 NUM_QUBITS 设成 4、num_features 设成 2 跑这套,能看到 16 个基态里只有同时满足双 1 的 4 个索引(3、7、11、15)相位被扭动,其余保持原幅——外汇与贵金属市场高杠杆高风险,这类特征纠缠仅作非线性状态编码实验,不预示任何方向。
if((i & (class="num">1 << qubit)) == class="num">0) { const class="type">int i1 = i | (class="num">1 << qubit); class=class="str">"cmt">// 旋转风门的复矩阵 U(theta, phi): class=class="str">"cmt">// [ cos(theta/class="num">2) , -sin(theta/class="num">2) ] class=class="str">"cmt">// [ sin(theta/class="num">2)*e^(i*phi), cos(theta/class="num">2)*e^(i*phi) ] class=class="str">"cmt">// 目标位 = class="num">0 的计算 next_state[i].real = cos_t * state[i].real - sin_t * state[i1].real; next_state[i].imag = cos_t * state[i].imag - sin_t * state[i1].imag; class=class="str">"cmt">// 目标位 = class="num">1 的计算(考虑相位偏移 e^i*phi) complex temp_i1; temp_i1.real = sin_t * state[i].real + cos_t * state[i1].real; temp_i1.imag = sin_t * state[i].imag + cos_t * state[i1].imag; class=class="str">"cmt">// 通过 MQL5 原生复数乘法实现相位偏移 next_state[i1] = temp_i1 * e_phase; } } ArrayCopy(state, next_state); class=class="str">"cmt">// --- class="num">2. 诚实的综合量子纠缠(Controlled-Phase Gate) --- for(class="type">int i = class="num">0; i < NUM_QUBITS - class="num">1; i++) { for(class="type">int j = i + class="num">1; j < NUM_QUBITS; j++) { const class="type">int idx_i = i % num_features; const class="type">int idx_j = j % num_features; class=class="str">"cmt">// 将两个相互关联的参数的复数相位相互混淆 const class="type">class="kw">double cross_phase = M_PI / class="num">2.0 * (features_matrix[idx_i][class="num">0] * features_matrix[idx_j][class="num">1]); complex cz_gate; cz_gate.real = MathCos(cross_phase); cz_gate.imag = MathSin(cross_phase); for(class="type">int k = class="num">0; k < num_states; k++) { class=class="str">"cmt">// 如果两个量子比特都处于1态,则平滑地旋转它们的总复相位 if(((k & (class="num">1 << i)) != class="num">0) && ((k & (class="num">1 << j)) != class="num">0)) { state[k] = state[k] * cz_gate; } } } }
「把工具请下神坛」
| 上面这段收尾代码把量子态的实部虚部平方相加,就是波恩定律说的观测概率 P = | ψ | ²,循环里逐状态算完 exact_probs 数组,再交给 GetWeightedVote 出加权预测值。 |
|---|
当 MathAbs(prediction) 低于 MIN_CONFIDENCE 时直接 return 0.0,意味着从这套量子链视角看,价格处于盘整或方向不明的区间,此时任何多空信号都该搁置。 外汇与贵金属杠杆高、跳空频繁,这类 AIGC 辅助判定只提供概率倾向,不能替代仓位风控;开 MT5 把 MIN_CONFIDENCE 从默认改到 0.15 试一周,你会看到触发空仓的次数明显多于趋势市。 工具就是工具,跑出来的 confidence 只是帮你过滤噪声,真要下单还得看实时盘口与止损位置。
class=class="str">"cmt">// --- class="num">3. 精确理论概率的计算(确定性步骤) --- class="type">class="kw">double exact_probs[]; ArrayResize(exact_probs, num_states); for(class="type">int i = class="num">0; i < num_states; i++) { class=class="str">"cmt">// 根据波恩定律,概率 P = |ψ|² = 实部² + 虚部² exact_probs[i] = (state[i].real * state[i].real) + (state[i].imag * state[i].imag); } class=class="str">"cmt">// --- class="num">4. 获取最终预测 --- const class="type">class="kw">double prediction = GetWeightedVote(exact_probs); const class="type">class="kw">double confidence = MathAbs(prediction); if(confidence < MIN_CONFIDENCE) { class="kw">return class="num">0.0; class=class="str">"cmt">// 从量子链的角度来看,市场处于盘整/不明朗状态 } class="kw">return prediction; }