多币种 EA 开发·交易品种信息工具:用架构重构解锁跨品种价格行为洞察(基础篇)
🛠️

多币种 EA 开发·交易品种信息工具:用架构重构解锁跨品种价格行为洞察(基础篇)

(1/3)·从库与项目分离出发,搭一个不写交易逻辑也能看清多品种蜡烛序列的脚手架

含代码示例实战向 第 1/3 篇

不少多币种 EA 开发者把参数范围一股脑丢给优化器,以为广撒网总能捞到有效组合,结果回测时间翻倍、命中率反而稀碎。不同品种在同一周期里的连续同向蜡烛分布差异很大,盲目统一区间只是在浪费算力。先摸清工具本身的行为边界,比急着跑策略更划算。

◍ 先给 EA 装上多币种眼睛

做多币种 EA 的第一道坎,不是策略逻辑,而是先把每个交易品种的基础参数读准。MT5 里 SymbolInfoInteger、SymbolInfoDouble 这一组函数,能在 EA 初始化阶段把点值、最小止损距离、交易时段状态一次性拉出来,避免后面下单时因为合约规格不同踩坑。 很多单币种写惯了的代码,直接把 _Point、_Digits 当全局常量用,换到跨品种环境就会出错——EURUSD 的 _Point 是 0.00001,XAUUSD 可能是 0.01,硬套同一个止损点数算出来偏差极大。 下面这段是品种信息初始化的核心骨架,建议在 OnInit 里跑一次,把结果存进结构体数组,后续下单模块直接查表,不再反复调用终端接口。外汇与贵金属跨品种交易杠杆差异大,属高风险操作,参数读错可能直接触发无效下单。

MQL5 / C++
class="type">MqlParam sym_info[class="num">10];
class="type">int sym_count = SymbolsTotal(false);
for(class="type">int i=class="num">0; i<sym_count && i<class="num">10; i++)
{
   class="type">class="kw">string name = SymbolName(i, false);
   sym_info[i].type = SYMBOL_INFO;
   sym_info[i].string_value = name;
   SymbolInfoDouble(name, SYMBOL_POINT, sym_info[i].double_value);
}

从单一策略到多线开发的架构转折

前一篇里我们已经把一套简单策略做成了能跨品种、跨周期同时跑的 EA,还接上了资本与风险管理器:不利或过于有利时都能自动停手。整个系列基本只用了那一种策略,直到功能成型后才试着换主策略,说明只要策略真有潜力,释放空间是可行的。 但这套做法走到现在,下一步方向反而变多了,选择更难的。第 23 部分我们把大部分代码拆进“库部分”,项目专有代码留在“项目部分”;后来又在迁移到新存储库的文章里迈出初步步子。我想让库部分能多线并行开发,是否真行得通还要看。 唯一能验证架构对不对的就是练手。所以我们先用已经写好的 Advisor 库起个新项目——不急着写复杂策略的 EA,反而先做一个根本不以交易 EA 为目标的工程,外汇与贵金属本身高风险,架构试错成本远低于实盘试错。

「先摸清连续蜡烛的分布再谈优化」

SimpleCandles 策略里有个参数是「某时间周期内同向连续蜡烛的数量」。如果盲目把这个参数范围设得很大,参数组合总数会膨胀,优化器找到有效组合的概率就会下降——虽然说不清具体降多少,但效率损失是实打实的。 与其全丢给优化器,不如先统计不同交易品种、不同周期里实际出现的同向连续蜡烛序列长度。这能直接回答一个问题:多个工具能不能共用同一段参数区间?能的话,第一阶段优化任务可以大幅简化;不能的话,就得按品种分开建任务。 顺带一提,这类统计最好写成可复用的辅助 EA 模块,既能给当前策略探路,以后别的项目也能直接挂上。外汇和贵金属价格行为差异大,这种预统计在高杠杆品种上更显必要,能少踩很多坑。

◍ 把每个项目拆成独立仓库

早期把整套 EA 代码塞进一个文件夹,复制粘贴就能开新项目,在原型阶段确实省事。重大改动频繁时,这种扁平结构不用操心向后兼容,改崩了重来成本也低。 但当项目膨胀后,代码明显裂成两块:一块长期不动,另一块反复重写。此时仍共用 MQL5/Include/antekov/Advisor 单一库路径,就会出问题。 假设两个项目并行跑,都引用同一套 Advisor 库。项目 A 改了库里的风控函数,项目 B 并不知道,编译直接带上 A 的改动——这类冲突在 MT5 里不会报错,只会在回测曲线上露馅。 更麻烦的是人工切换分支:忘切一次,就得把误改的代码从错误分支剥离、挪回正确分支,纯体力活。 解法是在每个项目根目录内置 Include 文件夹,里面放各自克隆的库仓库(可多个、分散在不同子目录)。这样项目间库版本物理隔离,MT5 加载时各找各的,互不踩踏。

把库搬进独立仓库并改走相对路径

原库名 Advisor 太泛,重命名为 Adwizard 后单独建仓,方便后续文章和新功能都从同一套代码基派生。仓库初始化只有 main 分支,另开 develop 作为功能集成分支,每篇文稿对应的临时分支在合并后关闭,最终回流进 main。 克隆到任意目录仍能编译,是关键约束。原先 #include 写死 MQL5/Include/antekov/Advisor 绝对位置,换机器就断链。全部改成相对路径后,库不再依赖 MT5 的 Include 固定结构。 第三方 fxsaber 的 MultiTester 单文件也从外部依赖挪进库内 Utils 文件夹,避免克隆后少文件。下面这段替换已提交仓库,直接对照改你的 .mqh 即可。

MQL5 / C++
class="macro">#include <antekov/Advisor/Optimization/Optimizer.mqh>
class="macro">#include "../Optimization/Optimizer.mqh"
class="macro">#include <antekov/Advisor/Database/Database.mqh>
class="macro">#include <fxsaber/MultiTester/MTTester.mqh> class=class="str">"cmt">// [MQL5官方文档]
class="macro">#include "../Database/Database.mqh"
class="macro">#include "../Utils/MTTester.mqh" class=class="str">"cmt">// [MQL5官方文档]
把品种扫描交给小布盯盘
这些跨品种连续蜡烛的统计与诊断,小布盯盘的 AIGC 已内置,打开对应品种页即可看到分布概览,你只需专注该把阈值卡在哪一档。

常见问题

分离后库部分可独立迭代复用于多个 EA 项目,项目部分只承载具体品种的组装逻辑,降低耦合也方便沿多个方向并行开发。
可以,小布盯盘的品种页已内置该类价格行为扫描,支持多周期查看,省去自己写脚本逐一统计的重复劳动。
组合总数随区间扩大呈乘法增长,有效组合被稀释,单轮优化耗时上升且过拟合概率可能走高,最好先用统计摸清合理上下限。
用非交易项目验证 Advisor 库的工程化能力,能低成本暴露架构决策的问题,避免直接在复杂策略上试错拖慢进度。