开发Python交易机器人(第三部分):实现基于模型的交易算法·综合运用
(3/3)·训练好的模型停在笔记本里毫无价值,本篇打通从预测信号到MT5实盘下单的最后一米
◍ 用线程把多个货币对跑成一套系统
想让策略同时覆盖 EURUSD、GBPUSD、USDJPY、AUDUSD、USDCAD 这五个品种,核心是把它们塞进一个 symbols 列表,再给每个品种拉一条独立线程去跑 process_symbol。线程之间互不阻塞,整体数据下载、特征构造和 XGBoost 训练的速度会明显快于单品种串行。 process_symbol 内部是一条完整流水线:先取数,再做数据增强、标注、生成 100 个新特征,用 GMM 聚成 4 类,挑出 10 个关键特征,然后以 1000 轮 boosting 训练分类器。线上部分每 6 秒刷新一次行情,用最近 6000 根 bar 做推断并下单。 实测有个恼人的副作用:多线程的 print 会互相穿插,屏幕日志糊成一团,调试时很难定位单个品种的状态。试过几种加锁和缓冲办法都没彻底解决,不过这不影响算法本身正常开平仓。 外汇与贵金属属高杠杆品种,多币种并行虽分散了单品种风险,但同向波动时会放大回撤,跑这套代码前先在 MT5 策略测试器里用 10000 初始余额回测确认。
class="kw">import threading def process_symbol(symbol): try: # Retrieve data for the specified symbol raw_data = retrieve_data(symbol) if raw_data is None: print("No data found for symbol {}".format(symbol)) class="kw">return None # Augment data augmented_data = augment_data(raw_data) # Markup data marked_data = markup_data(augmented_data.copy(), &class="macro">#x27;close&class="macro">#x27;, &class="macro">#x27;label&class="macro">#x27;) # Label data labeled_data = label_data(marked_data, symbol) # Generate new features labeled_data_generate = generate_new_features(labeled_data, num_features=class="num">100, random_seed=class="num">1) # Cluster features by GMM labeled_data_clustered = cluster_features_by_gmm(labeled_data_generate, n_components=class="num">4) # Feature engineering labeled_data_engineered = feature_engineering(labeled_data_clustered, n_features_to_select=class="num">10) # Train XGBoost classifier train_data = labeled_data_engineered[labeled_data_engineered.index <= FORWARD] test_data = labeled_data_engineered[labeled_data_engineered.index > FORWARD] xgb_clf = train_xgboost_classifier(train_data, num_boost_rounds=class="num">1000) # Test XGBoost classifier test_features = test_data.drop([&class="macro">#x27;label&class="macro">#x27;, &class="macro">#x27;labels&class="macro">#x27;], axis=class="num">1) test_labels = test_data[&class="macro">#x27;labels&class="macro">#x27;] initial_balance = class="num">10000.0 markup = class="num">0.00001 test_model(xgb_clf, test_features, test_labels, markup, initial_balance) # Online trading position_id = None while True: # Get the last class="num">2000 data points for online trading features = raw_data[-class="num">6000:].drop([&class="macro">#x27;label&class="macro">#x27;, &class="macro">#x27;labels&class="macro">#x27;], axis=class="num">1).values.tolist() # Update features every class="num">6 seconds time.sleep(class="num">6) new_data = retrieve_data(symbol) if new_data is not None: raw_data = pd.concat([raw_data, new_data]) raw_data = raw_data.dropna() # Online trading position_id = online_trading(symbol, features, xgb_clf, position_id) except Exception as e: print("Error processing {} symbol: {}".format(symbol, e)) class="kw">return None symbols = ["EURUSD", "GBPUSD", "USDJPY", "AUDUSD", "USDCAD"] # Create a list of threads for each symbol threads = [] for symbol in symbols:
多线程拉数据时的空窗与重试现象
用线程并行抓多个品种时,主循环会把每个 symbol 丢进独立线程跑 process_symbol,再统一 join 等全部收工。这种写法在 MT5 终端品种数较多时,会暴露数据未就绪的竞争问题。 实测终端里挂了 31 个品种,USDCAD、NZDUSD、AUDUSD、GBPUSD 在首轮线程启动后直接报“No data yet (attempt 1)”,说明行情缓存还没预热完。 重试机制会持续轮询:GBPUSD 在 attempt 2、attempt 3 依旧无数据,而终端品种数始终稳定输出 31,证明线程池本身没崩,只是个别符号的 tick 流迟到。外汇与贵金属波动剧烈、高风险,这类空窗可能导致策略在头几秒误判信号。 开 MT5 跑类似并行脚本时,建议在 join 前加短 sleep 或判断 SymbolInfoTick 返回值,别让 attempt 3 还空仓的品种触发首单。
thread = threading.Thread(target=process_symbol, args=(symbol,)) thread.start() threads.append(thread) # Wait for all threads to complete for thread in threads: thread.join()
「给系统加装的三类学习引擎」
当前这套价格行为模型跑在经典机器学习上,推理延迟和过拟合是两块硬伤。把训练迁移到量子比特上看似遥远,但 Qiskit、PennyLane 这类框架已经能在本机模拟 20+ 量子位的电路,先用模拟器验证特征映射是否有加速收益,比等真机更实际。 让策略直接当市场代理做强化学习,是另一条可落地的路。把每笔平仓盈亏转成 reward 信号,亏损单给负反馈,用深度 Q 网络(DQN)更新 Q 表,模型会自发避开反复被打脸的价位结构。MT5 的策略测试器本身不支持在线交互训练,得用 Python 侧 socket 接 Tester 的每 tick 状态自己写 loop。 止损止盈不再拍脑袋,可以交给粒子群优化(PSO)。让 30 个粒子各自带一组 SL/TP 组合在历史数据里飞,适应度取夏普比率,迭代 200 代后群体的最优位置往往比网格搜索省 60% 算力。外汇与贵金属杠杆高,PSO 选出的参数仅降低回测风险,实盘仍可能因跳空失效。
◍ 别急着下结论
这套机器学习交易模型走的是典型流程:先做数据预处理与分析,再上 XGBoost 类算法,过程中叠了噪声添加、时间平移、特征计算、类别平衡和交叉验证。测试集上的准确率大约在 60%,放在外汇与贵金属这类高噪声市场里,只能算刚过随机基准、远没到可盲信的程度。 后续作者计划接量子计算、强化学习和群体智能来选止损止盈,方向是提训练质量与真实数据效率,但这类迭代在 MT5 实盘里大概率还要反复调参验证。 更现实的一层是:当越来越多人把同类算法搬上盘,竞争就从人跟人变成了算法跟算法,谁的模型鲁棒谁才活得久。外汇贵金属波动杠杆高,60% 准确率模型直接实盘仍属高风险,先开 MT5 接 Python 回测一遍再谈部署。