彗星尾算法(CTA)(基础篇)
「彗星尾算法在MT5里的定位」
彗星尾算法(CTA)是一类偏趋势跟踪的量化思路,在 MetaTrader 5 环境下常被封装成自定义指标或 EA 来跑。它核心是用近期价格轨迹的“拖尾”形态来判断惯性是否还在。 原文示例里,Andrey Dik 在 2024 年 11 月 22 日 10:50 发布了该算法的公开示例,截至记录时显示 1,143 次查看、0 条评论。这个冷清的数据点说明:纯算法类文章在中文交易圈外其实关注度有限,但代码本身可直连 MT5 验证。 对读者来说,开 MT5 把这类 CTA 示例加载到 EURUSD 的 H1 图,先观察拖尾信号在震荡段的假突破频率,比直接上实盘更有用。外汇与贵金属杠杆高,任何算法信号都只是概率倾向,不是方向保证。
◍ 把彗星尾当成解空间里的粒子群
彗星接近太阳时,表面冰体直接升华成气体,轨道普遍是高偏心率椭圆,周期跨度能从几年拉到上百万年。太阳风与辐射压把彗发里的尘埃和气体吹离彗核,尾长有时能拉到数千万公里,气体被电离后还会自发光。 在 CTA 里,解空间里的每个候选解被映射为一颗彗星尾粒子:彗核本身是当前最优解,尾部粒子是围绕它的派生解。这样算法不必全局盲搜,而是借尾粒子分布去嗅解空间局部结构。 外汇与贵金属参数寻优中套这套隐喻,本质是高风险实验——历史拟合出的尾长权重,换周期可能立刻失效,只能当概率参考。
把彗星尾算法落进MT5类结构
彗星尾算法(CTA)在 MT5 里不需要另起一套框架,直接复用智能体基类 C_AO 就能跑。核心思路是用 S_AO_Agent 结构同时描述彗星核与尾部粒子:c[] 存解空间坐标,f 存适应度,评估质量时只认 f。 C_AO_CTA 类继承 C_AO,构造函数把默认参数写死:种群 50、彗星 5 颗、尾长系数 0.2、移位系数区间 0.5~0.9、尺寸系数区间 0.1~1.5。这些数直接决定搜索的「细挖」与「广撒」比例,调 tailLengthKo 从 0.2 往小改,彗星离最优解越近时尾部越收缩,局部精炼概率会上升。 Init() 先调 StandardInit 建范围,再按 cometsNumb 扩 comets 数组;tailLength 和 maxSpaceDistance 按坐标维数扩,随后算每维空间最大距离与尾长,partNumber = 50/5 = 10,即每颗彗星尾部挂 10 个粒子。 Moving() 里 epochNow 自增后,若 revision 为假就用高斯分布在 tailLength 范围内绕核撒粒子;为真则按 coefTail、coefSize 更新位置。u.RNDprobab()<0.6 走高斯扰动,否则取两颗随机彗星核坐标做线性组合——这一步是算法跳出局部最优的主要杠杆。 Revision() 先扫全种群刷新 cB(已知最优),再逐彗星在自身粒子里找最佳并更新 comets[i].c。外汇与贵金属参数优化属高风险场景,该过程仅提供解空间探索可能,不保证实盘收益。 下面这段是结构与原类声明,逐行对应上文字段含义。
class="kw">struct S_AO_Agent { class="type">class="kw">double c []; class=class="str">"cmt">//coordinates class="type">class="kw">double f; class=class="str">"cmt">//fitness }; class C_AO_CTA : class="kw">public C_AO { class="kw">public: ~C_AO_CTA() { } C_AO_CTA() { ao_name = "CTA"; ao_desc = "Comet Tail Algorithm"; ao_link = "[MQL5官方文档] popSize = class="num">50; class=class="str">"cmt">//population size cometsNumb = class="num">5; class=class="str">"cmt">//number of comets tailLengthKo = class="num">0.2; class=class="str">"cmt">//tail length coefficient maxShiftCoef = class="num">0.9; minShiftCoef = class="num">0.5; maxSizeCoef = class="num">0.1; minSizeCoef = class="num">1.5; ArrayResize(params, class="num">7); } };
「把彗星群参数塞进优化器」
这段结构把彗星算法(Comet Algorithm)的 7 个核心参数通过 params 数组对外暴露,MT5 策略测试器就能直接把它们当可优化变量跑。popSize 控制种群规模,cometsNumb 决定彗星数量,其余 5 个 Coef 都是空间缩放与位移的边界系数。 SetParams() 负责把 params[0]~params[6] 的 val 回写到类成员变量,类型转换上 popSize 和 cometsNumb 强转成 int,其余 double 原样赋值。你在 EA 里改一个外部输入,不用动算法主体就能生效。 Init() 的签名暴露了搜索框架:rangeMinP / rangeMaxP / rangeStepP 三个数组定义每维的最小、最大和步长,epochsP 默认 0 表示不限制迭代轮次。comets[] 是 S_AO_Agent 类型的代理数组,私有段里的 tailLength[] 和 maxSpaceDistance[] 才是真正驱动粒子运动的运行时缓存。 外汇与贵金属市场高波动、高杠杆,这类群体智能优化仅用于离线参数搜索,实盘前务必在 MT5 用历史数据做交叉验证。
params [class="num">0].name = "popSize"; params [class="num">0].val = popSize; params [class="num">1].name = "cometsNumb"; params [class="num">1].val = cometsNumb; params [class="num">2].name = "tailLengthKo"; params [class="num">2].val = tailLengthKo; params [class="num">3].name = "maxShiftCoef"; params [class="num">3].val = maxShiftCoef; params [class="num">4].name = "minShiftCoef"; params [class="num">4].val = minShiftCoef; params [class="num">5].name = "maxSizeCoef"; params [class="num">5].val = maxSizeCoef; params [class="num">6].name = "minSizeCoef"; params [class="num">6].val = minSizeCoef; } class="type">void SetParams() { popSize = (class="type">int)params [class="num">0].val; cometsNumb = (class="type">int)params [class="num">1].val; tailLengthKo = params [class="num">2].val; maxShiftCoef = params [class="num">3].val; minShiftCoef = params [class="num">4].val; maxSizeCoef = params [class="num">5].val; minSizeCoef = params [class="num">6].val; } class="type">bool Init(class="kw">const class="type">class="kw">double &rangeMinP [], class=class="str">"cmt">//minimum search range class="kw">const class="type">class="kw">double &rangeMaxP [], class=class="str">"cmt">//maximum search range class="kw">const class="type">class="kw">double &rangeStepP [], class=class="str">"cmt">//step search class="kw">const class="type">int epochsP = class="num">0); class=class="str">"cmt">//number of epochs class="type">void Moving(); class="type">void Revision(); class="type">void Injection(class="kw">const class="type">int popPos, class="kw">const class="type">int coordPos, class="kw">const class="type">class="kw">double value); class=class="str">"cmt">//---------------------------------------------------------------------------- class="type">int cometsNumb; class=class="str">"cmt">//number of comets class="type">class="kw">double tailLengthKo; class=class="str">"cmt">//tail length coefficient class="type">class="kw">double maxShiftCoef; class=class="str">"cmt">//maximum shift coefficient class="type">class="kw">double minShiftCoef; class=class="str">"cmt">//minimum shift coefficient class="type">class="kw">double maxSizeCoef; class=class="str">"cmt">//maximum size coefficient class="type">class="kw">double minSizeCoef; class=class="str">"cmt">//minimum size coefficient S_AO_Agent comets []; class="kw">private: class=class="str">"cmt">//------------------------------------------------------------------- class="type">int epochs; class="type">int epochNow; class="type">class="kw">double tailLength []; class="type">class="kw">double maxSpaceDistance []; class=class="str">"cmt">//maximum distance in space class="type">int partNumber; class=class="str">"cmt">//number of particles };