首页 / 交易学院 / 小布知识库 / 指标加速的 3 种方法:以线性回归为例的算法优化
指标加速的 3 种方法:以线性回归为例的算法优化

指标加速的 3 种方法:以线性回归为例的算法优化

MQL5 编程 难度 · 进阶 2013 10 分钟阅读
指标优化线性回归算法加速MQL5性能

指标算得慢,实盘就卡、回测就久。本文用“线性回归指标”当样板,演示三种纯算法层面的加速法——不砍历史深度、不开多核,只改算法本身。线性回归在每根柱用最近 N 根价格拟合一条直线 y=a·x+b,取末端函数值 lrvalue。标准写法要在每根柱循环 N 次算四个累加和(Sx、Sy、Sxx、Sxy),N 越大越慢。三种优化正是冲着这四个累加和去的。

一、基准:标准线性回归怎么算

标准实现里,每根柱都从头累加:Sx=Σx、Sy=Σy、Sxx=Σx²、Sxy=Σxy,再代入公式求 a、b。代码简单但复杂度与回归长度 N 成正比——N=2000 时每根柱要循环 2000 次,百万根K线下来就是几十亿次运算。

for(int x=1; x<=LRPeriod; x++){ double y=price[bar-LRPeriod+x];
  Sx+=x; Sy+=y; Sxx+=x*x; Sxy+=x*y; }
double a=(LRPeriod*Sxy-Sx*Sy)/(LRPeriod*Sxx-Sx*Sx);
double b=(Sy-a*Sx)/LRPeriod; lrvalue=a*LRPeriod+b;

二、方法一:移动总和(Moving Totals)

相邻两根柱的累加和有大量重叠:第 0 根的总和,与第 1 根相比,只是“少了一根过期柱、多了一根新柱”。所以只需取上一根的总和,减旧加新,两次算术运算即可。关键是把四个中间和存进 INDICATOR_CALCULATIONS 类型的缓存(不上图),下一根直接读缓存递推。

// 用 INDICATOR_CALCULATIONS 缓存存中间和
SetIndexBuffer(1, ExtBufSx, INDICATOR_CALCULATIONS);
SetIndexBuffer(2, ExtBufSy, INDICATOR_CALCULATIONS);
// 下一根:旧值出、新值入
Sy = ExtBufSy[prevbar] - price[bar-LRPeriod] + price[bar];
Sxy = ExtBufSxy[prevbar] - ExtBufSy[prevbar] + price[bar]*LRPeriod;
无论 N 是 20 还是 200000,每根柱都只做“减旧加新”两次运算,耗时几乎不随回归长度变化。实测比标准法快几百倍。

三、方法二:简化(Simplification)

回归公式里的 Σy 其实就是简单移动平均(SMA),Σx·y 是线性加权移动平均(LWMA)。既然客户端内置 iMA 已经极快,不如直接调用 iMA(MODE_SMA) 和 iMA(MODE_LWMA),把回归值化简成一个极简式:lrvalue = 3·LWMA − 2·SMA。代码量骤减,速度还由内置指标兜底。

h_SMA = iMA(NULL,0,LRPeriod,0,MODE_SMA,PRICE_CLOSE);
h_LWMA= iMA(NULL,0,LRPeriod,0,MODE_LWMA,PRICE_CLOSE);
CopyBuffer(h_LWMA,0,rates_total-bar,1,LWMA);
CopyBuffer(h_SMA, 0,rates_total-bar,1,SMA);
lrvalue = 3*LWMA[0] - 2*SMA[0];
优先把等式化简到 iMA/iMACD 等内置指标:它们由开发商深度优化,比你自己写的循环更可靠更快。

四、方法三:近似(Approximation)

调试或粗优化阶段,精度没那么重要。把回归区间切成前后两半,各算均价,连成一条直线外推到最后一根柱。运算量远少于完整回归,形状却和真回归很接近(文中红/绿/蓝三线对比,近似线贴近回归线)。日常策略先用“轻”指标跑通逻辑,再用“重”指标精修参数。

int HalfPeriod=(int)MathRound(LRPeriod/2);
double s1=0,s2=0;
for(int i=0;i<HalfPeriod;i++) s1+=price[bar-i]; s1/=HalfPeriod;
for(int i=HalfPeriod;i<LRPeriod;i++) s2+=price[bar-i]; s2/=(LRPeriod-HalfPeriod);
double k=(s1-s2)/(LRPeriod/2);
lrvalue = s1 + k*(HalfPeriod-1)/2;

五、速度实测:400 万根K线对比

作者在 M1、最大历史深度(400 万+ 根)上测:20 柱与 2000 柱各跑一遍。结论——三种方法都至少快 2 倍;N 拉到 2000 时,移动总和与简化法比标准法快几百倍,且耗时几乎不随 N 变。移动总和综合最快。这意味着你优化策略参数的速度能快百倍,等于更早把钱赚到手。

代价提示:移动总和要加 4 个辅助缓存,内存换速度(见《通过辅助指标减少内存消耗》)。要速度还是要内存,按实盘机器定。

六、三法怎么选:一张清单

三种法不是互斥,按场景挑主导:① 要极致速度且机器内存宽裕 → 移动总和,它是实测最快且与回归长度无关;② 想代码最短、又信赖开发商优化 → 简化法,直接调内置 iMA;③ 仅调试/粗优化阶段 → 近似法,先跑通逻辑再换重指标精修。实战常组合:用近似法快速圈参数区,用移动总和法上实盘。

反例:给一个本来只循环 20 根的轻指标硬上移动总和,反而因多 4 个缓存拖内存,得不偿失。先量后改。

七、小结

指标加速不必砍历史、不必堆核,算法层面就有三把刀:移动总和(缓存递推,与 N 无关)、简化(化简到内置 iMA)、近似(粗算先跑通)。线性回归只是样板,思路可套到任意“每根柱重算滑动聚合”的指标。把这三法接进你的指标,回测与实盘都能快一个数量级。

常见问题

用算法层面的优化,本文三种都有效且不减历史深度:① 移动总和——把滑动聚合的中间和缓存起来,每根柱只减旧加新(2 次运算,耗时与回归长度无关);② 简化——把公式化简到内置 iMA 等;③ 近似——调试期用粗算代替精算。
相邻K线的累加和大量重叠,只需取上一根的总和减去过期值、加上新值,不再循环 N 次。把四个中间和存进 INDICATOR_CALCULATIONS 缓存递推,无论 N=20 还是 200000,每根柱都只做两次运算,所以耗时几乎不随回归长度增长。
回归里的 Σy 就是 SMA、Σx·y 就是 LWMA,直接调用客户端内置 iMA(MODE_SMA) 和 iMA(MODE_LWMA),回归值化简为 lrvalue = 3·LWMA − 2·SMA。代码更短、速度由开发商深度优化的内置指标兜底。
近似法(把区间切两半取均值外推)精度低于完整回归,适合调试和粗优化阶段快速验证逻辑、圈定参数有效区;逻辑跑通后再换“重”指标精修。若回测显示近似已足够,也可直接上实盘。