量子计算与交易:价格预测的新方法·综合运用
(3/3)·前两部分铺垫了量子概念与单点算法,本篇把七个小节串成能用于实时决策的完整框架
◍ 把波动、RSI与布林压缩成0/1信号
做价格行为量化时,先把连续行情压成布尔特征,能显著降低后续模型过拟合概率。下面三个编码函数直接产出 0/1 列,方便和趋势、量能等维度做与或组合。 volatility_encoding 用 20 根 K 线的高低差均值作基准:当根振幅大于 20 根平均振幅时记 1,否则 0。这意味着近期波动扩张会被显式标注,黄金或外汇在 data 跳空时常触发连续 1。 rsi_encoding 没用传统 Wilder 平滑,而是以 alpha=1/14 的 EWMA 算增益与损耗,再得 RSI;阈值默认 50,高于即 1。和 MT5 内置 RSI 相比,该写法对近期价格权重更敏感,欧元兑美元 15M 上拐头往往更早半根 K 线。 bollinger_encoding 取 20 根收盘均值与 2 倍标准差通道,若收盘价处在区间下半((close-lower)/(upper-lower) > 0.5 的反向逻辑注意是大于 0.5 记 1,即偏上半通道)记 1。实战中该位为 1 时,价格倾向沿上轨惯性,但外汇高风险,需结合波动信号过滤假突破。 get_all_patterns 把七类编码汇总成字典,其中 volatility、rsi、bollinger 即上面三段。开 MT5 用 Python 桥接回测时,可直接拷这段逻辑验证信号密度。
def volatility_encoding(self): volatility = self.df[&class="macro">#x27;high&class="macro">#x27;] - self.df[&class="macro">#x27;low&class="macro">#x27;] avg_volatility = volatility.rolling(class="num">20).mean() class="kw">return (volatility > avg_volatility).astype(class="type">int) def rsi_encoding(self, period=class="num">14, threshold=class="num">50): delta = self.df[&class="macro">#x27;close&class="macro">#x27;].diff() gain = (delta.where(delta > class="num">0, class="num">0)).ewm(alpha=class="num">1/period).mean() loss = (-delta.where(delta < class="num">0, class="num">0)).ewm(alpha=class="num">1/period).mean() rs = gain / loss rsi = class="num">100 - (class="num">100 / (class="num">1 + rs)) class="kw">return (rsi > threshold).astype(class="type">int) def bollinger_encoding(self, window=class="num">20): ma = self.df[&class="macro">#x27;close&class="macro">#x27;].rolling(window=window).mean() std = self.df[&class="macro">#x27;close&class="macro">#x27;].rolling(window=window).std() upper = ma + (std * class="num">2) lower = ma - (std * class="num">2) class="kw">return ((self.df[&class="macro">#x27;close&class="macro">#x27;] - lower)/(upper - lower) > class="num">0.5).astype(class="type">int) def get_all_patterns(self): patterns = { &class="macro">#x27;direction&class="macro">#x27;: self.direction_encoding(), &class="macro">#x27;momentum&class="macro">#x27;: self.momentum_encoding(), &class="macro">#x27;volume&class="macro">#x27;: self.volume_encoding(), &class="macro">#x27;convergence&class="macro">#x27;: self.convergence_encoding(), &class="macro">#x27;volatility&class="macro">#x27;: self.volatility_encoding(), &class="macro">#x27;rsi&class="macro">#x27;: self.rsi_encoding(), &class="macro">#x27;bollinger&class="macro">#x27;: self.bollinger_encoding() } class="kw">return patterns
「把行情塞进量子线路再喂给 CatBoost」
这段 Python 实现展示了混合模型怎么把价格转成量子特征:先用相邻量子比特的 CX 门织 entanglement,再把 current_price 对 0.01 取模后乘 100 再乘 π 得到旋转角,施加到 qr[0] 的 RY 门上。也就是说,价格的小数部分(如 1.2345 中的 0.0045)被映射成了 [0, π] 区间内的相位,EURUSD 这种小数点后四位品种的细节能直接进线路。 采样阶段用 transpile 优化等级 3 编译,跑 2000 shots 拿计数分布,再按 2**num_qubits 长度铺成概率特征向量——8 量子比特就是 256 维特征,每个维度是某条 bitstring 出现频率。外汇与贵金属杠杆高,量子特征仅描述历史分布,对未来方向只提供概率倾向。 HybridQuantumBinaryPredictor 把量子生成器与 CatBoost 拼起来:CatBoost 设 500 轮、学习率 0.03、深度 6、Logloss,属于轻量配置。prepare_features 里对 BinaryPatternGenerator 产出的 pattern 先做 fillna(0),再按 lookback=10 到 len(df)-forecast_window=5 滑窗抽样本,缺失二进制模式不会打断训练。 直接在 MT5 导出的收盘价 CSV 上跑这段,把 num_qubits 从 8 降到 4 能看 16 维向量是否还保留拐点信号;若 2000 shots 下特征向量过于平滑,可把 shots 提到 4000 观察小概率 bitstring 是否冒出来。
特征拼装与涨跌标注的循环逻辑
这段逻辑跑在一个按索引遍历的循环里,每一步先取当前收盘价,再向量子特征生成器要一组 market_data 对应的 quantum_features。注意 current_price 在循环体里被取了两次:一次在特征段,一次在打标签段,若 df 长度不足 i+forecast_window 会直接触发 except 被跳过。 二进制特征段把 binary_patterns 里每个 key 的近 lookback 根窗口拉出来,塞进三个量:窗口内信号总数、最后一根信号值、最后三根信号之和。假设 lookback=20、有 5 个 key,仅这部分就贡献 15 维,维度膨胀得盯着点。 技术指标直接取 rsi / bollinger / momentum 在 i 时刻的标量,和 quantum_features、binary_vector 用 np.concatenate 拼成一条 feature_vector。标签用 i+forecast_window 处的收盘价减当前价,涨则标 1 跌则标 0,是典型的二分类监督设定。 异常被 catch 后只 print 并 continue,所以一段数据里若前面几百根有缺损,你可能在不知情下少了几百条样本。开 MT5 导出的 CSV 先跑 len(df)-forecast_window 看预期样本数,再对比 features 实际长度,差得多的就去查日志里的 Error at index。外汇与贵金属杠杆高,这套特征仅供概率参考,实盘前务必自行回测。
current_price = df[&class="macro">#x27;close&class="macro">#x27;].iloc[i] quantum_features = self.quantum_generator.get_quantum_features(market_data, current_price) # Binary features binary_vector = [] for key in binary_patterns: window = binary_patterns[key].iloc[i-self.lookback:i].values binary_vector.extend([ sum(window), # Total number of signals window[-class="num">1], # Last signal sum(window[-class="num">3:]) # Last class="num">3 signals ]) # Technical indicators rsi = binary_patterns[&class="macro">#x27;rsi&class="macro">#x27;].iloc[i] bollinger = binary_patterns[&class="macro">#x27;bollinger&class="macro">#x27;].iloc[i] momentum = binary_patterns[&class="macro">#x27;momentum&class="macro">#x27;].iloc[i] # Combine all features feature_vector = np.concatenate([ quantum_features, binary_vector, [rsi, bollinger, momentum] ]) # Label: price movement direction future_price = df[&class="macro">#x27;close&class="macro">#x27;].iloc[i + self.forecast_window] current_price = df[&class="macro">#x27;close&class="macro">#x27;].iloc[i] label = class="num">1 if future_price > current_price else class="num">0 features.append(feature_vector) labels.append(label) except Exception as e: print(f"Error at index {i}: {str(e)}") class="kw">continue class="kw">return np.array(features), np.array(labels)
◍ 训练切分与下一步方向概率输出
模型训练前先把特征矩阵按 8:2 切分:前 80% 作训练集,后 20% 留作测试集,这种固定比例切法在外汇小时线回测里可能让近期行情漏进训练集,建议按时间顺序外推而非随机洗牌。 训练时用 eval_set 挂测试集,fit 过程会同步计算泛化误差;跑完直接拿 X_test 出预测类别与概率矩阵,再用 accuracy_score、precision_score、recall_score、f1_score 四个指标量化表现。若某次回测 f1 低于 0.55,说明涨跌边界混淆严重,贵金属品种上这种现象更频繁。 特征重要性被拆成量子位段与二进制段分别求均值:feature_importance[:2**num_qubits] 是量子特征贡献,其后归为传统特征贡献,两者对比能看出哪类因子在欧元兑美元上更主导。 predict_next 只取最后一根 K 线的特征做推理,返回 UP/DOWN 方向及对应概率。confidence 取两类概率的最大值,若该值仅 0.51,则方向信号可信度极低,实盘需搭配价格行为结构过滤。外汇与贵金属杠杆高,模型输出仅作概率参考,不构成入场依据。
print("Preparing features...") X, y = self.prepare_features(df) # Split into training and test samples split_point = class="type">int(len(X) * class="num">0.8) X_train, X_test = X[:split_point], X[split_point:] y_train, y_test = y[:split_point], y[split_point:] print("Training model...") self.model.fit(X_train, y_train, eval_set=(X_test, y_test)) # Model evaluation predictions = self.model.predict(X_test) probas = self.model.predict_proba(X_test) # Calculate metrics metrics = { &class="macro">#x27;accuracy&class="macro">#x27;: accuracy_score(y_test, predictions), &class="macro">#x27;precision&class="macro">#x27;: precision_score(y_test, predictions), &class="macro">#x27;recall&class="macro">#x27;: recall_score(y_test, predictions), &class="macro">#x27;f1&class="macro">#x27;: f1_score(y_test, predictions) } # Feature importance analysis feature_importance = self.model.feature_importances_ quantum_importance = np.mean(feature_importance[:class="num">2**self.num_qubits]) binary_importance = np.mean(feature_importance[class="num">2**self.num_qubits:]) metrics.update({ &class="macro">#x27;quantum_importance&class="macro">#x27;: quantum_importance, &class="macro">#x27;binary_importance&class="macro">#x27;: binary_importance, &class="macro">#x27;test_predictions&class="macro">#x27;: predictions, &class="macro">#x27;test_probas&class="macro">#x27;: probas, &class="macro">#x27;test_actual&class="macro">#x27;: y_test }) class="kw">return metrics def predict_next(self, df): """Next movement forecast""" X, _ = self.prepare_features(df) if len(X) > class="num">0: last_features = X[-class="num">1].reshape(class="num">1, -class="num">1) prediction_proba = self.model.predict_proba(last_features)[class="num">0] prediction = self.model.predict(last_features)[class="num">0] class="kw">return { &class="macro">#x27;direction&class="macro">#x27;: &class="macro">#x27;UP&class="macro">#x27; if prediction == class="num">1 else &class="macro">#x27;DOWN&class="macro">#x27;, &class="macro">#x27;probability_up&class="macro">#x27;: prediction_proba[class="num">1], &class="macro">#x27;probability_down&class="macro">#x27;: prediction_proba[class="num">0], &class="macro">#x27;confidence&class="macro">#x27;: max(prediction_proba) } class="kw">return None
「跑通混合模型的全流程脚本」
下面这段 Python 脚本把 MT5 接入、数据拉取、混合模型训练到预测输出串成了一条线,直接在本地跑就能看到 EURUSD 的 H1 回测指标。默认取 1000 根 K 线,若你手头 MT5 终端没开或账号未登录,initialize() 会直接抛异常,先确认终端在后台挂着。 脚本核心在 model.train(df) 返回的 metrics 字典:accuracy / precision / recall / f1 四个二分类指标以百分比打印,另外拆出 quantum_importance 与 binary_importance,能直观比出量子特征与二值特征谁更主导。实际跑下来,若 quantum_importance 长期低于 20%,说明该混合结构在 EURUSD 上可能只是徒增算力。 predict_next(df) 给出下一根方向及涨/跌概率与置信度,注意这只是模型输出,外汇和贵金属杠杆高、滑点大,实盘前务必用策略测试器交叉验证。把 symbol 和 periods 改掉,比如换 XAUUSD 取 500 根,就能快速横向比不同品种的表现倾向。
def test_hybrid_model(symbol="EURUSD", timeframe=mt5.TIMEFRAME_H1, periods=class="num">1000): """Full test of the hybrid model""" try: # MT5 initialization if not mt5.initialize(): raise Exception("Failed to initialize MT5") # Download data print(f"Loading {periods} periods of {symbol} {timeframe} data...") loader = MT5DataLoader(symbol, timeframe) df = loader.get_historical_data(periods) # Create and train model print("Creating hybrid model...") model = HybridQuantumBinaryPredictor() # Training and assessment print("Training and evaluating model...") metrics = model.train(df) # Output results print("\nModel Performance Metrics:") print(f"Accuracy: {metrics[&class="macro">#x27;accuracy&class="macro">#x27;]:.class="num">2%}") print(f"Precision: {metrics[&class="macro">#x27;precision&class="macro">#x27;]:.class="num">2%}") print(f"Recall: {metrics[&class="macro">#x27;recall&class="macro">#x27;]:.class="num">2%}") print(f"F1 Score: {metrics[&class="macro">#x27;f1&class="macro">#x27;]:.class="num">2%}") print("\nFeature Importance Analysis:") print(f"Quantum Features: {metrics[&class="macro">#x27;quantum_importance&class="macro">#x27;]:.class="num">2%}") print(f"Binary Features: {metrics[&class="macro">#x27;binary_importance&class="macro">#x27;]:.class="num">2%}") # Current forecast print("\nCurrent Market Prediction:") prediction = model.predict_next(df) if prediction: print(f"Predicted Direction: {prediction[&class="macro">#x27;direction&class="macro">#x27;]}") print(f"Up Probability: {prediction[&class="macro">#x27;probability_up&class="macro">#x27;]:.class="num">2%}") print(f"Down Probability: {prediction[&class="macro">#x27;probability_down&class="macro">#x27;]:.class="num">2%}") print(f"Confidence: {prediction[&class="macro">#x27;confidence&class="macro">#x27;]:.class="num">2%}") class="kw">return model, metrics finally: mt5.shutdown() if __name__ == "__main__": print("Starting Quantum-Binary Hybrid Trading System...")
混合模型测试的收口动作
在 hybrid 模型跑完训练与验证后,直接调用 test_hybrid_model() 拿回模型实例与指标字典,这一步决定了你能否在 MT5 外接 Python 环境里确认系统可用。 打印 'System test completed.' 只是给终端一个明确信号,表示本轮回测或实时推演已结束,不会阻塞后续 EA 的 onTick 逻辑。 若 metrics 里 sharpe 或 max_drawdown 异常,优先检查特征窗口是否和训练时一致,外汇与贵金属品种在高波动时段容易让分布漂移,实盘前务必小仓位验证风险。
model, metrics = test_hybrid_model() print("\nSystem test completed.")
◍ 一点提醒
那套量子分类器在回测里只跑出 42% 的准确率,比抛硬币还低;花几周搓的量子特征仅带来 27% 增益,反倒是顺手加的老技术指标把效果拉高了 122%。外汇与贵金属市场高杠杆、高波动,这类实验性模型远未到能实盘托付的阶段。 把价格走势编码成量子态确实可行,只是当前更像坏掉的计算器而非印钞机。附带的 Quant_Predict_p_1.py、Quant_Neural_Link.py、Quant_ML_Model.py 三个草案(10.2KB / 8.37KB / 11.58KB)值得下载下来自己跑一遍,看看哪段逻辑拖了后腿。 别急着信任何‘量子战胜市场’的说法。先在本机复现那 42% 的尴尬数字,再决定要不要重写——至少比瞎猜强,但离靠谱还差得远。