利用指数平滑法进行时间序列预测(基础篇)
「用指数平滑在MT5里做行情推演」
指数平滑(Exponential Smoothing)把历史价格按衰减权重叠加,越近的K线影响越大,适合捕捉外汇与贵金属的短时趋势漂移。在MT5里不需要自己造轮子,内置时序函数就能直接跑。 以简单一次指数平滑为例,递推式为 S_t = α·P_t + (1-α)·S_{t-1},α取0.3时,对EURUSD的M5收盘价做平滑,滞后大约2~3根K线,但能滤掉大部分随机噪声。外汇与贵金属杠杆高、跳空频繁,平滑值只作概率倾向参考,不是方向保证。 下面这段MQL5演示了最基础的单次平滑计算,复制进脚本即可在「数据窗口」看到逐根S值:
class="type">class="kw">double alpha = class="num">0.3; class="type">class="kw">double S = class="num">0; class="type">bool first = true; for(class="type">int i = Bars-class="num">1; i >= class="num">0; i--) { class="type">class="kw">double price = Close[i]; if(first) { S = price; first = false; } else { S = alpha * price + (class="num">1 - alpha) * S; } class=class="str">"cmt">// 此处可 Print(S) 观察逐根平滑值 }
◍ 外推预测与指数平滑的落点
市面上能叫出名字的时序预测法,大多只啃价格序列的过去值,本质就是技术分析的延伸。它们走外推路线:在某一固定延迟上认出序列特征,再把这条特征推过边界;默认未来和过去、现在同构。稍复杂一点的外推会去追特征自身的变动动态,但实盘里用得少。 名气最大的外推模型是 ARIMA(自回归求和移动平均),火起来是因为 Box 和 Jenkins 把求和集成模型做透了。不过早在这之前,Holt 和 Brown 就搞出了指数平滑模型。实测里指数平滑给出的结果,经常和 ARIMA 差不离——不奇怪,它本就是 ARIMA 的一个特例,本文涉及的每个指数平滑变体都能在 ARIMA 里找到对等物。 真要做一次像样的预测,流程长得很:缺值离群值处理、趋势与周期识别、平稳性检验、取对数或差分预处理、选模型、定参数、出预测、估精度、拆误差,不对就换模型重跑。参数拟合和出数值其实只占整件事的一小截。 这篇只盯指数平滑,且直接用没做预处理的货币报价当试验序列。外汇和贵金属波动剧烈、杠杆风险高,未清洗序列跑出来的东西只能当概率参考。文章不试图回答预测全流程的所有问题,只讲清楚模型研究必需的那部分。
外推预测靠的是过程稳定性
外推法的内核其实很直白:它默认所研究过程的未来发展和过去、现在基本一致,也就是依赖过程的稳定性。从预测角度看,平稳过程最理想,但现实里不存在——任何实际过程在演进中都会变,预期、方差、分布随时间都会出现明显差异。 不过变化极慢的过程,在有限观测窗口内其特性漂移可以忽略,就能近似当平稳处理。这里“极慢”的尺度是相对于你手上的样本长度而言的。 可用的观测区间越短,越容易误判整个过程稳定;但如果你只关心紧接着的短期状态,砍掉部分样本反而可能提升预测精度。因为过程若已变异,长窗口估出来的参数只是区间内某种平均值,和窗口末端真实状态脱节。 预测区间拉得越长,序列特性变异对误差的放大越强。所以只能把自己限制在短期预测里——提前 1 个、2 个或几个时间步,而不是经济学里“小于一年”那种短期。指数平滑和 ARIMA 一样,底层都赌稳定性;后文为省事统一假设参数缓慢可忽略地变,但你实盘调模型时,研究窗口别无脑缩短:太短会直接牺牲参数估计精度,得在“变异误差”和“样本不足误差”之间找折中。
「不规则采样给序列分析挖的坑」
本文用到的测试序列来自 M1、M5、M30、H1 四个周期,覆盖 EURRUR、EURUSD、USDJPY、XAUUSD 四品种,每个保存文件固定存了 1100 个 open 值,最新值对应文件创建时刻。这些文件都由 HistoryToCSV.mq5 脚本从终端历史导出,未做任何预处理。 直接拿原始报价喂给算法,第一个雷就是采样区间不规整。比如 EURRUR_H1 一天只有 12~13 根柱,而 XAUUSD 周五的柱数比别的交易日少一根。对依赖统一量化时间间隔的时序模型来说,这种缺口型样本基本不可用。 周末报价整段缺失也值得警惕。周六若发生地缘冲突、政府更迭或自然灾害,其对全球资产的冲击并不比工作日小,但外汇盘面静止,造成周线收口处频繁跳空。要不要外推补全周末值做技术分析,目前没有定论,至少判断周期或季节性分量时,似乎没有任何现成序列更合适。 除了缺口,还有更隐蔽的污染:生成报价时,某些固定时间点被塞进了不属于它的 open/close,它们其实对应订单号触发时刻,而真实成交可能很久才来一笔。叠加变量点差与采样率根本不满足采样定理,终端里看到的报价离“干净时间序列”差得很远。外汇与贵金属本身高杠杆高风险,这类数据缺陷会放大误判概率,动手回测前先想清楚怎么洗数据。
◍ 从 SES 到带趋势项的单参数平滑
先拆最朴素的加法过程:X(t)=L(t)+r(t),L(t) 是想要的级别,r(t) 是零均值噪声。对 X 做平均能压低方差,所以只要平滑够狠,r(t) 虽不能根除,也会被削弱到能拎出 L(t)。 简单指数平滑(SES)用 S(t)=αX(t)+(1-α)S(t-1) 控制强度。α=0 时新数据完全无效,序列被压成水平线;α=1 时毫无平滑,L(t) 不失真但噪声全留。两者冲突,α 必须按预测目标来选,而不是只看画图顺眼。 把 SES 当一步预测器用时,t 时刻对 t+1 的预测就是上一步的 S(t)。优化准则是全样本一步预测误差平方和最小,谁最小 α 就最优。在 USDJPY M1 某片段上扫 α,图 1 的最小值模糊落在 α≈0.8;但多数片段是误差平方和随 α 往 1 跌——说明纯水平模型跟不上报价,级别 L(t) 变得太快或藏着趋势。 往模型里加趋势项:X(t)=L(t)+T(t)+r(t),T(t) 为线性趋势。对序列做两次同 α 平滑可得回归系数 a1、a2,m 步预测为 a1+a2·m。这叫带线性增长的单参数模型。 图 2 给了一段从水平突变成线性的过程:SES 明显滞后且差距越拉越大;单参数趋势模型会努力追上,α 高时几乎贴住输入。同一 USDJPY 片段下,趋势模型最优 α 降到约 0.4(图 3),比 SES 的 0.8 低一截,证明趋势项吸收了一部分变动。 MT5 里 EMA、DEMA 是这类公式的平滑版而非预测版。DEMA 只输出对应 a1 的项,不算 a2,且用周期 n 反推 α:α=0.8 约对应 n=2,α=0.4 约对应 n=4。开 MT5 把 USDJPY M1 调出 EMA(2) 与 EMA(4),对照 DEMA 看滞后差异,比读公式直观。
时间零点处的初始值怎么定
指数平滑法里当前值是靠前一个值递推出来的,所以时间零点那个 S 或 S1、S2 根本没有现成值可用,必须单独算出来。 如果历史数据够长,比如 MT5 里常见的长周期报价,初始值就算估得不准,曲线一般也能在到达当前点前自我修正。经验上大致需要 10 到 200 个周期(有时更多),具体看平滑系数大小。 粗略给个初始值、再在目标周期前多跑 200-300 个周期通常就够用;但样本只有 100 个值时,难度明显上升。文献里有不少建议:简单平滑可把初始值设为序列首个元素,或取前三四项均值来压随机离群;线性增长模型则常假设初始级别等于首元素、趋势斜率为零。 不过谁都没法保证早期阶段没有显著误差,尤其当平滑系数低、需要很多周期才稳的时候。 为压住短序列上的初始值偏差,可以搜一组让预测误差最小的初始值——遍历小幅增量的组合挑最优。这本质是多变量函数最小化,直接穷举太费算,实际多用专用优化算法缩范围,后面讲预测时再展开。