卡尔曼滤波器在外汇均值回归策略中的应用(基础篇)
📘

卡尔曼滤波器在外汇均值回归策略中的应用(基础篇)

第 1/2 篇

「用卡尔曼滤波抓外汇均值回归」

卡尔曼滤波器能把带噪的价格序列实时估出“真实”状态,在 MT5 里适合做均值回归类的动态中枢。对外汇与贵金属而言,这类品种高杠杆、跳空频繁,均值回归只是概率倾向,不等于价格必回。 原文给出的示例发布于 2025 年 11 月 10 日 15:04,截至统计口径有 1072 次查看、6 条讨论,说明该思路在实战圈有一定验证需求。 想在 MT5 自己跑一遍,核心是先建状态方程再用预测—修正两步迭代;下一节会直接给可粘贴的代码与逐行拆解。

◍ 卡尔曼滤波在报价噪声里的真实用途

卡尔曼滤波器本质是一个递归估计算法,核心动作是拿上一刻的状态预测值和当前新到的报价做加权融合,把高频噪声压下去,留下它认为的“真实状态”。对做价格行为的人来说,它比固定窗口的平滑工具更顺手的地方在于:权重会随着数据波动自动调节,不需要你手动改窗口长度。 在外汇和贵金属这种报价抖动极凶的市场里,它常被塞进均值回归类策略——因为价差回归的触发点往往被噪声淹没,滤波后的序列能更早暴露偏离。注意,杠杆品种波动具有高风险,滤波只降低观测误差,不消除方向误判概率。 本篇后续会先拆它的计算步骤与 MT5 实现,再用一个经典外汇均值回归例子跑一遍;最后把卡尔曼滤波和移动平均线放在若干货币对上做统计对比,看两者在噪声环境下的跟踪差异。

把卡尔曼滤波当会自适应的均线用

卡尔曼滤波是1960年提出的最优递归估计器,两步跑:先预测系统下一状态,再用新观测值更新、压低噪声。放到MT5里,你可以把它直接类比成一条会自己调权重的移动平均线——但比MA更狠的是,它按测量可信度实时改比例,而不是固定周期取平均。 在外汇和贵金属这种高杠杆、高波动市场里用,先记一句:它假设价格动态是线性的,突变会滞后,参数没调好反而比EMA还难用,属于高风险玩法。 常见落点有四个:均值回归里拿估计价当入场筛子;配对交易动态估价差调对冲比;趋势跟踪滤短噪抓长趋;波动率自适应估出来管仓位。 过程方差Q和测量方差R决定平滑度。Q高=信价格会变,灵敏但晃;R高=信旧估,平滑但慢。低Q+适中R稳,高Q+低R敏但噪。开MT5把Q从0.001调到0.1,曲线会从迟钝变抖,自己肉眼校一遍最实在。

「把均值回归写成可跑的 EA」

均值回归在半平稳的外汇数据上多年保持正期望,核心假设是价格不会长期停留在极端位。本策略用 100 周期、偏差 2.0 的布林带量化:上根收盘破下轨买、破上轨卖,价格穿中轨即平,同刻只留一个仓位,止损设为市价 1% 以挡肥尾。

  • 分钟框被选中,是因它兼顾信号质量与触发频率。编码次序先写买卖函数,再初始化 magic 与指标句柄,最后在 OnTick 用每根 K 线触发逻辑,避免 tick 级重复开仓。

卡尔曼滤波作为反转确认:价格破下轨且高于滤波估值,才视为超卖企稳;500-EMA 则只用于顺趋势过滤。要换状态过滤器,改最终买卖判定那几行即可。外汇与贵金属杠杆高,回测通过不等于实盘可控,务必先在策略测试器跑图形验证。

MQL5 / C++
class="macro">#include <Trade/Trade.mqh>
CTrade trade;
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Buy Function                                                      |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void executeBuy(class="type">class="kw">string symbol) {
    class="type">class="kw">double ask = SymbolInfoDouble(symbol, SYMBOL_ASK);
    class="type">class="kw">double lots=class="num">0.01;
    class="type">class="kw">double sl = ask*(class="num">1-class="num">0.01);
    trade.Buy(lots,symbol,ask,sl);
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Sell Function                                                     |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void executeSell(class="type">class="kw">string symbol) {    
    class="type">class="kw">double bid = SymbolInfoDouble(symbol, SYMBOL_BID);
    class="type">class="kw">double lots=class="num">0.01;
    class="type">class="kw">double sl = bid*(class="num">1+class="num">0.01);
    trade.Sell(lots,symbol,bid,sl);  
}
input class="type">int Magic = class="num">0;
input class="type">int bbPeriod = class="num">100;
input class="type">class="kw">double d = class="num">2.0;
class="type">int barsTotal = class="num">0;
class="type">int handleMa;
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Initialization                                                    |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit()
{  handleBb = iBands(_Symbol,PERIOD_CURRENT,bbPeriod,class="num">0,d,PRICE_CLOSE);  
   trade.SetExpertMagicNumber(Magic);
   class="kw">return INIT_SUCCEEDED;
}
class="type">int bars = iBars(_Symbol,PERIOD_CURRENT);

if (barsTotal!= bars){
  barsTotal = bars;
class="type">class="kw">double bbLower[], bbUpper[], bbMiddle[];
CopyBuffer(handleBb,UPPER_BAND,class="num">1,class="num">1,bbUpper);
CopyBuffer(handleBb,LOWER_BAND,class="num">1,class="num">1,bbLower);
CopyBuffer(handleBb,class="num">0,class="num">1,class="num">1,bbMiddle);
class="type">bool NotInPosition = true;

常见问题

卡尔曼滤波会根据报价噪声自动调权重,比固定周期的均线更跟手;实盘里能少几次假突破信号,但高频成本要自己算。
把过程噪声调大、观测噪声调小,让滤波更信最新价;先用历史数据看平滑度再上模拟盘。
小布可自动跑卡尔曼滤波诊断并标出偏离带,打开品种页就能看当前偏离和回归概率,不用自己写代码。
以滤波均值加减两倍实时标准差作通道,破通道外沿就止损;外汇贵金属波动大,必须先模拟验证。
新闻跳空让观测噪声瞬间失真,滤波滞后严重;这类时段建议暂停策略或手动锁仓,属高风险窗口。