Dr. Tradelove 或我如何不再担忧并创建一个自训练 EA 交易·综合运用
(3/3)·从单策略参数刷新到多策略自切换,这篇收束前面两篇留下的实盘自适应缺口
多数交易者把EA跑挂后第一反应是手动拉测试器重跑优化,行情早变了几轮。把再优化当成断点重启的苦力活,等于让算法在旧市场里裸奔。本文收尾这一系统思路:让EA自己决定何时重训、用遗传算法挑新参数甚至换策略。
「基因到品种与均线的映射落地」
这段逻辑处在遗传算法训练收尾阶段,负责把染色体里的浮点基因翻译成 MT5 可直接调用的指标句柄与交易品种。注意 GeneCount-1 号基因乘 12 后四舍五入,得到 0~12 的整数索引,再 switch 映射到具体货币对——目前样例里 case 0 和 case 1 都指向 AUDUSD,说明基因空间存在冗余,实盘前最好压缩映射表。 短均线与长均线周期由 Chromosome[1]、Chromosome[2] 乘 MaxMAPeriod 再加 1 得出,MODE_SMA 配 PRICE_OPEN 意味着用开盘价算简单移动平均,避免收盘重绘带来的回测虚高。CopyBuffer 把算好的均线值塞进 ShortBuffer / LongBuffer,供后续信号判断复用。 外汇与贵金属杠杆放大了参数过拟合风险,这套映射在 EURUSD 上回测漂亮,换到 GBPJPY 可能因点值差异直接失效。开 MT5 把 MaxMAPeriod 设成 200,跑一遍 GetTrainResults 看生成的句柄周期是否落在 2~201 之间,就能验证基因边界有没有写漏。
class="type">void GetTrainResults() { class=class="str">"cmt">//--- intermediary between a gene colony and optimised parameters class="type">int z; MAshort=iMA(s,tf,(class="type">int)MathRound(Chromosome[class="num">1]*MaxMAPeriod)+class="num">1,class="num">0,MODE_SMA,PRICE_OPEN); MAlong =iMA(s,tf,(class="type">int)MathRound(Chromosome[class="num">2]*MaxMAPeriod)+class="num">1,class="num">0,MODE_SMA,PRICE_OPEN); CopyBuffer(MAshort,class="num">0,from,count,ShortBuffer); CopyBuffer(MAlong ,class="num">0,from,count,LongBuffer); class=class="str">"cmt">//--- save the best pair z=(class="type">int)MathRound(Chromosome[GeneCount-class="num">1]*class="num">12); class="kw">switch(z) { case class="num">0: {s="AUDUSD"; class="kw">break;}; case class="num">1: {s="AUDUSD"; class="kw">break;}; case class="num">2: {s="EURAUD"; class="kw">break;}; case class="num">3: {s="EURCHF"; class="kw">break;}; case class="num">4: {s="EURGBP"; class="kw">break;}; case class="num">5: {s="EURJPY"; class="kw">break;}; case class="num">6: {s="EURUSD"; class="kw">break;}; case class="num">7: {s="GBPCHF"; class="kw">break;}; case class="num">8: {s="GBPJPY"; class="kw">break;}; case class="num">9: {s="GBPUSD"; class="kw">break;}; }
遗传算法怎么挑交易品种
在 EA 的染色体编码里,最后一个基因位常被用来决定跑哪一品种。上面这段把 10/11/12 硬编码成美系直盘,默认回退 EURUSD,属于最省事的写法。 但更灵活的做法是交给市场本身:用 SymbolsTotal(true) 拿到当前可见交易品种总数,再让基因里的浮点值乘以(总数-1)后四舍五入,直接映射成 SymbolName(z,true) 返回的字符串。这样遗传算法每代进化时,可能自动在几十个外汇或贵金属符号里换目标,不用你手动改 case。 外汇与贵金属杠杆高、点差跳变频繁,这种自动选品种逻辑回测好看,实盘仍可能因为流动性断层吃滑点。开 MT5 把这段贴进 OnTester 或遗传层,打印 z 和 s,先确认映射没越界再上信号。
case class="num">10: {s="USDCAD"; class="kw">break;} case class="num">11: {s="USDCHF"; class="kw">break;} case class="num">12: {s="USDJPY"; class="kw">break;} class="kw">default: {s="EURUSD"; class="kw">break;} } class=class="str">"cmt">//--- saving the best optimal F optF=Chromosome[GeneCount]; class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//--- GA is selecting a pair z=(class="type">int)MathRound(Colony[GeneCount-class="num">1][chromos]*(SymbolsTotal(true)-class="num">1)); s=SymbolName(z,true);
◍ 自适应训练与遗传优化的本质分野
做自训练 EA 并不难,难在想清楚往里喂什么逻辑——点子才是核心,工程实现只是技术活。悲观者问“这东西真有用吗”,答案是有用,但别指望它是万能圣杯;乐观者则容易高估它的边界。 拿移动平均线 EA 做对照最直观:自适应训练系统里,均线周期在编译前就得定死,只能在有限的预设方案里挑;遗传优化 EA 编译前不做任何决定,周期由 GA 在运行中选,能覆盖的情形只受你判断力约束。 虚拟交易的频率也两样。自适应系统是逐根 K 线(柱到柱)跑虚拟单;遗传优化 EA 很少这么干,一般只在触发再优化条件时才动。 性能瓶颈也得正视。策略、参数、标的数量一多,自适应系统对算力的吞噬会很明显,这可能成为它实盘落地的硬限制。外汇与贵金属波动剧烈、杠杆高风险极大,任何自训练方案都只是概率工具,不是确定性答案。
「记住这一条就够了」
上面那张 2010.01.01–2011.09.30 的 EURUSD 日线回测单,没碰任何优化:443 笔成交、总净利润 -9 094.49,获利系数只有 0.76,最大市值亏损干到 93.53%。神经网络裸跑两年,账户从 1 万美金缩到不到一千,这不是模型不行,是市场换了脸它没换脑。 三种再优化片段里,AUDUSD 在 2010 年 6 月下旬连吃几根小亏后,7 月 1 日一根 -249.60 的卖单直接把余额砸到 1 649.46;GBPCHF 那组也是隔日对冲来回磨损。外汇和贵金属杠杆放大下,这种无再训练的自适应 EA 实盘爆仓概率偏高,开 MT5 把 annexample.mq5 拖进去跑同一段历史就能复现。 真要做家庭作业,就别只调 trainDD、maxDD 那几个数——在系统库里挑出当下最贴行情的那套逻辑,比死磕参数有用。市场一变,旧权重就是负资产。