首页 / 交易学院 / 小布知识库 / MetaTrader 5 中的并行计算:多核利用实测
MetaTrader 5 中的并行计算:多核利用实测
🖥️

MetaTrader 5 中的并行计算:多核利用实测

MT5 平台 难度 · 高阶 2013 12 分钟阅读
并行计算多核性能

一、MT5 并行计算的动机与限制

现代 PC 多核越来越多,但 MQL5 程序默认单线程跑,等于只用了 1 个核。处理器不会自动把“先输密码后验证”这类有依赖的逻辑拆开,必须由你标出“哪些部分可以并行”。MQL5 语言本身没有线程/并行运算符,要靠外部手段实现。

二、两条并行途径

三、实测结论:跨品种才能用多核

文章用任务管理器观测核心占用,关键规律是:同一交易品种的所有指标跑在同一线程;不同品种的指标/EA 跑在不同线程。所以——同图表 2 指标=1 核,不同货币对不同图表 2 指标=2 核,不同图表 2 个 EA=2 核。最方便的组合是:EA(主模块)用 iCustom 在不同货币对上自动建计算指标(CM),由终端分配多核。

四、分发与收集:用全局变量

主模块(MM)在 OnInit 按 Threads 循环,用 iCustom 在不同货币对创建 CM 指标,每个分配不同的历史段偏移(BarStart);OnTick 里填当前模式并 SetParam 发“开始计算”信号。CM 指标在 OnInit 里用 while(true) 死循环等 Query→计算→把结果写回全局变量(如 MultiThread_<Magic>_0_Prognoze)。MM 轮询等 Answer 再读取,选最佳 rating。

五、性能实测

环境 EURUSD M1,模式长度 1440 柱,历史搜索 375000 柱:单线程(Threads=1)耗时 52 秒;并行(Threads=2,EA+2 个跨货币对 CM 指标)耗时 27 秒,加速比约 1.9 倍,接近线性。两种模式找到的历史相似图形日期极接近,证明正确性一致。

六、注意事项

⚠ 并行不是无代价
1) 线程安全:MM 与 CM 不能直接通信,数据必须放外部公共区(全局变量/文件/缓冲);全局变量只存 double,文本要编码。2) 同品种同线程:一个指标若死循环会阻塞该品种所有指标及 EA 的 OnTick;CM 所用货币对绝不能和 MM 相同。3) 组合 7 下指标 OnTimer 实际不触发,只能用 OnInit 死循环,须防同品种冲突。4) DLL 方案可行但未实测,注意客户端多线程架构条件。

七、最小可运行骨架

下面是文章“EA 主模块 + 跨货币对指标”方案的核心骨架:MM 在 OnInit 用 iCustom 在不同货币对创建计算指标(CM),用全局变量传参、CM 算完写回结果,MM 轮询读取:

// 主模块 OnInit:为每个线程在不同货币对建计算指标
string syms[2]={ "EURUSD", "GBPUSD" };  // 必须与 MM 不同品种
for(int t=0;t<Threads;t++)
  iCustom(syms[t], _Period, "i-Thread", Prefix, t, _Symbol, Len, Len+t*Part, Part);

// 主模块 OnTick:发任务、等结果
SetParam(t, "Query");
while(!ParamExists(t,"Answer")) Sleep(100);
double progn = GetParam(t, "Prognoze");  // 取 CM 算回的结果

// 计算指标 i-Thread 的 OnInit 内:无限循环等 Query->算->写回
while(true)
  { Sleep(100); if(ParamExists(t,"Query")) { DeleteParam(t,"Query"); FindPrognoze(); SetParam(t,"Answer",1); } }

八、什么时候值得上并行

✦ 最划算的场景
并行最适合“历史数据批量处理”和“参数/模式搜索”:比如把一年 M1 历史切成几段,每段丢给一个跨货币对指标去搜相似图形,2 核实测约 1.9 倍加速。实时策略若计算不重,单线程足够,不必为了“看起来高级”而引入多指标复杂度——同品种死循环还会拖垮该品种所有 OnTick。

九、两种并行路线

MT5 并行计算有两条路:一是工作线程(Worker Thread),在主 EA 外起独立线程跑耗时任务,不阻塞 OnTick;二是 OpenCL,把海量并行计算(如大规模参数扫描、矩阵运算)丢给 GPU 或多核,速度数量级提升。

选哪条看任务形态:串行依赖强的逻辑用线程池分包,规整的 Numerical 计算用 OpenCL。两者都能把「单机跑几小时」压到「几分钟」。

十、用线程池扫参数

参数扫描天然可并行:把参数空间切成若干块,每个工作线程认领一块独立回测,结果汇总。这样 8 核机器接近 8 倍提速,且单线程崩了不影响其他块。

for(int i=worker_id; i<total; i+=num_workers)
   results[i] = Backtest(params[i]);   // 每个线程跑自己那块
✦ 扫描天然可并行
参数空间切成块、每线程认领一块、结果汇总,是并行回测的标准姿势。单块崩不影响整体,8 核近 8 倍速。

十一、线程安全与数据共享

多线程最大的坑是共享数据竞争:多个线程同时写同一个数组或变量会互相覆盖、结果错乱甚至崩溃。必须用临界区(CriticalSection)或把数据按线程分片(每人写自己的槽)来避免。

另一个坑是线程里不能调用某些终端 API(如交易函数),只能在主线程下单。并行层的职责要严格限定在「计算」,结果回主线程再执行。

十二、小结

✦ 小结
MT5 并行有工作线程(不阻塞 OnTick 跑耗时任务)和 OpenCL(GPU 多核跑海量数值计算)两路。参数扫描天然可并行:切块认领、结果汇总,8 核近 8 倍速。坑在线程安全(临界区或分片写)和「线程内不能交易,计算归计算、下单回主线程」。

常见问题

MT5 终端把“同一交易品种的所有指标”放在同一个线程里处理。所以你在 EURUSD 上挂 10 个指标,它们还是排队跑,只占 1 核。要真并行,必须让指标/EA 分布到不同品种上,终端才会分配不同线程/核心。
全局变量只能存 double 类型,如果你要传文本(比如品种名、状态描述)就得编码成数字。另外 MM 和 CM 各自跑在不同线程,不能直接共享内存变量,必须走全局变量或文件这种外部公共区,且要设计好“请求-应答”的轮询/等待机制避免竞争。
DLL 能在一个程序内开真正的多线程,理论上最灵活,但文章没实测,且涉及客户端 DLL 策略(部分经纪商禁止)。文章主推的“多指标+多货币对”方案不写 DLL、纯 MQL5 就能拿到近线性的加速,更适合大多数场景。