开发多币种 EA 交易(第 18 部分):考虑远期的自动化组选择·综合运用
🧩

开发多币种 EA 交易(第 18 部分):考虑远期的自动化组选择·综合运用

(3/3)·三个月样本不足以评判平稳行情,靠远期行为自动挑组才是收口关键

实战向 第 3/3 篇
把优化结果直接按历史最佳塞进一组,常在远期出现协同崩坏。多数人忽略单独实例在样本外区间的行为一致性,分组只看主区间等于闭眼过弯。外汇贵金属高杠杆下,这种盲区可能放大回撤概率。

◍ 用欧氏距离重排样本内与样本外通过

原先的筛选思路是把主期间(2018–2022)和远期(2023)的各项指标比值凑近 1,再累加偏离度 SumDiff,配合回撤缩放系数 Scale 算 Res = Scale / SumDiff 降序排。但比值里一旦出现极端远离 1 的项,会不合理地拉低总距离估计,所以更稳的做法是:把每组通过在特征空间里看成向量,用最小最大缩放后直接算主期间与远期的欧氏距离。 实操落在 EURGBP H1 的第二阶段优化任务上,任务 id_task = 10,passes 表里该任务记录超过 22,000 条。先按相同 pass 编号把 is_forward=0(样本内)和 is_forward=1(样本外)的两行拼成一对,加 I_ / O_ 前缀,行数正好减半,说明样本内与样本外一一对应。 取 custom_ontester、equity_dd_relative、profit_factor 三个参数做最小最大缩放(值压到 0–1),建临时表 t0;再从 t0 自连接出 t1,只留两边缩放后利润因子都为正的行,结果比 t0 少约三分之一。最后在 t1 里算每对 I_ 与 O_ 向量的欧氏距离并升序排,排最前的 I_id_pass 就是两段结果最接近的那次通过。 这个距离最小的通过 ID,和主期间单纯高利润的最佳通过 ID 并不重合。意味着若只按样本内利润挑参数,样本外表现可能偏离;用欧氏距离挑出的集,更可能在两个时段都站得住。外汇与贵金属测试高风险, distances 小只代表历史吻合度高,不代表未来概率占优,建议直接开 MT5 优化库跑下面 SQL 验证。

MQL5 / C++
-- Request class="num">1
SELECT *
  FROM passes p0
WHERE p0.id_task = class="num">10;
-- Request class="num">2
SELECT p0.id_pass AS I_id_pass,
       p0.is_forward AS I_is_forward,
       p0.custom_ontester AS I_custom_ontester,
       p1.id_pass AS O_id_pass,
       p1.is_forward AS O_is_forward,
       p1.custom_ontester AS O_custom_ontester
  FROM passes p0
       JOIN
       passes p1 ON p0.pass = p1.pass AND
                    p0.is_forward = class="num">0 AND
                    p1.is_forward = class="num">1
WHERE p0.id_task = class="num">10 AND p1.id_task = class="num">10
CREATE TABLE ... AS SELECT ... ;
-- Request class="num">3
DROP TABLE IF EXISTS t0;
CREATE TABLE t0 AS
SELECT id_pass,
       pass,
       is_forward,
       custom_ontester,
       (custom_ontester - MIN(custom_ontester) OVER() ) / (MAX(custom_ontester) OVER() - MIN(custom_ontester) OVER() ) AS s_custom_ontester,
       equity_dd_relative,
       (equity_dd_relative - MIN(equity_dd_relative) OVER() ) / (MAX(equity_dd_relative) OVER() - MIN(equity_dd_relative) OVER() ) AS s_equity_dd_relative,
       profit_factor,
       (profit_factor - MIN(profit_factor) OVER() ) / (MAX(profit_factor) OVER() - MIN(profit_factor) OVER() ) AS s_profit_factor
  FROM passes
WHERE id_task=class="num">10;
SELECT * FROM t0;
-- Request class="num">4
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 AS
SELECT p0.id_pass AS I_id_pass,
       p0.is_forward AS I_is_forward,
       ROUND(p0.s_custom_ontester, class="num">4) AS I_custom_ontester,
       ROUND(p0.s_equity_dd_relative, class="num">4) AS I_equity_dd_relative,
       ROUND(p0.s_profit_factor, class="num">4) AS I_profit_factor,
       p1.id_pass AS O_id_pass,
       p1.is_forward AS O_is_forward,
       ROUND(p1.s_custom_ontester, class="num">4) AS O_custom_ontester,
       ROUND(p1.s_equity_dd_relative, class="num">4) AS O_equity_dd_relative,
       ROUND(p1.s_profit_factor, class="num">4) AS O_profit_factor
  FROM t0 p0
       JOIN
       t0 p1 ON p0.pass = p1.pass AND
                    p0.is_forward = class="num">0 AND
                    p1.is_forward = class="num">1 AND

「用 SQL 给优化结果排个距离序」

在 MT5 的本地优化结果表 t1 里,先用过滤条件把两边自定义 OnTester 返回值都大于 0 的场次捞出来,去掉无效样本。 随后用欧氏距离思路,把输入参数与输出指标的差值平方和开根并保留四位小数,作为 dist 字段排序。距离越小,说明这组输入相对于基准输出的偏离越低,倾向用于挑选稳健参数组合。 外汇与贵金属品种波动剧烈,此类距离筛选只降低过拟合概率,不保证实盘收益,请务必在 MT5 策略测试器中做样本外验证。

MQL5 / C++
p0.custom_ontester > class="num">0 AND
p1.custom_ontester > class="num">0;
SELECT * FROM t1;
-- Request class="num">5
SELECT
    ROUND(POW((I_custom_ontester - O_custom_ontester), class="num">2) + POW( (I_equity_dd_relative - O_equity_dd_relative), class="num">2) + POW( (I_profit_factor - O_profit_factor), class="num">2), class="num">4) AS dist,
    *
FROM t1
ORDER BY dist ASC;

样本外年份与前期数据的回撤对照

库里给出两组现成参数:一组标为 Best for dist(IS, OS) (2018-2023),取参数空间距离最小;另一组标为 Best on IS (2018-2022),取 2018–2022 训练期内标准化利润最优。先把两组都丢进 2018–2023 全样本回测,两者最大亏损都锁在 1000 美元以内,但距离最优组年均利润约 1724 美元,利润最优组约 3430 美元,差出接近两倍。 换到没参加优化的 2024 年(截至 10 月),两组都亏,利润最优组亏得少一点,但两段回撤都压在 1000 美元下方。2024 对这个品种不算友好,所以再把镜头拉到优化前的 2015–2017 三年。 这段里回撤突破设定值了:距离最优组大约超 1.5 倍,利润最优组超约 3.5 倍。距离最优组中部没有利润最优组那种深坑,年化差异也不大(857 对 615 美元)。外汇与贵金属属高风险品种,样本外表现仅作概率参考,不能前推未知时段。 未知时间段没法提前算这个值,但前期回撤失控幅度更小,这一版参数更经得起乱纪元。MT5 里把这两组分别加载到同一品种前测 2015–2017,重点看回撤倍数而不是表面利润。

◍ 远期自动选参为何仍卡在半路

把远期检验接进第二阶段优化后,自动化跑通了,但优势依旧没冒出来。这摊活儿比预想宽得多,新冒出的问题还堆在待办里。 一个硬现象是:当远期时段正好落在 EA 表现拉胯的区间,它基本选不出像样的参数组合。换句话说,远期在这类窗口里失灵了。 交易周期拉得很长时,主区间和远期边界各自断开的遍历结果,会和连续遍历差出一大截。这让人怀疑——不是怀疑远期本身,而是怀疑把它当「自动挑出未来更可能复现结果参数」的工具这条路。 目前只用最朴素的距离算法衡量两次遍历结果的分野,把算法搞复杂些或许能救一点。自动挑最优遍历、再塞进多品种多周期套餐的实现还没写,底层 SQL 查询从 EA 调一下就能跑,但因查询肯定还要改,自动化先搁着。 外汇与贵金属历史回测优不等于实盘优,这类研究性质工程请自负风险验证。

「随包文件清单与版本落点」

这套多币种 EA 框架的工程文件都挂在 MQL5/Experts/Article.15683 路径下,一共 35 个模块,从 Advisor.mqh 基类到 VirtualRiskManager.mqh 风险管理类俱全。下载包 MQL.zip 体积 86.02 KB,直接在 MT5 的 MQL5 目录解压就能看到对应 .mqh 和 .mq5。 版本号透露了演进节点:SimpleVolumesExpert.mq5 已到 1.20,是跑多组策略并行实例的主 EA;SimpleVolumesStage1.mq5 停留在 1.17,说明单实例优化阶段改动最少。作者在原讨论里明确回过,第 25 部分才出大致定稿、第 28 部分再完善,所以拿第 18 部分代码单独用会缺后续补丁。 外汇和贵金属市场高杠杆、高波动,这类多组策略框架回测和实盘差异可能很大,导入后先跑策略测试器验证再上模拟盘。想省事可以从 SimpleVolumesExpert.mq5 起步,把 GroupsLibrary.mqh 里的组初始化串改掉就能换策略集。

把远期诊断交给小布盯盘
这些跨区间分组与远期一致性诊断,小布盯盘的 AIGC 已内置,打开对应品种页即可看到各实例的样本外表现,你只需定筛选阈值。

常见问题

独立优化时遗传算法每一步不重复,输入参数组合路径不同,远期与主区间没有一一对应关系,只能改用指定远期启动让参数组合对齐。
它在分离区间挑行为相近的实例,避免主区间过拟合尖峰;组合后平稳性倾向更好,但样本短仍只能看作概率优势。
可以,分别用两种方式选出两组再合并成一个总组,兼顾主区间收益与远期一致性,实盘前需用远期数据回测验证。
能,小布盯盘会对每个策略实例计算主区间与远期的收益偏差,把漂移超阈值的自动标灰,省去手动拉表比对。
预聚类在系列第6部分探讨过,本篇第3篇侧重在自动化框架里把聚类结果接进远期分组流程。