彗星尾算法(CTA)(基础篇)
📘

彗星尾算法(CTA)(基础篇)

第 1/2 篇

「彗星尾算法在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。外汇与贵金属参数优化属高风险场景,该过程仅提供解空间探索可能,不保证实盘收益。 下面这段是结构与原类声明,逐行对应上文字段含义。

MQL5 / 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 用历史数据做交叉验证。

MQL5 / C++
    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
};

常见问题

它把候选参数当成解空间里的粒子群,用历史价格回测打分迭代收敛,比固定均线更适配非平稳行情,但需警惕过拟合。
至少留粒子位置、速度、适应度缓存和迭代代数,外层套一个优化器接口即可在品种页直接调用。
可以,小布盯盘的 AIGC 已内置该算法的诊断与寻优流程,打开对应品种页即可一键跑解空间搜索。
实盘前建议先设 30~50 个粒子、迭代 80 代内,MT5 单品种回测通常几分钟内出结果,贵金属高风险需分批验证。
是,解空间随行情漂移,概率上 3~6 个月需重寻优一次,别把某次结果当长期圣杯。