⚡
指标加速的 3 种方法:以线性回归为例的算法优化
指标优化线性回归算法加速MQL5性能
为什么指标要计算快
指标的快速计算是实盘关键任务。我们不做历史深度妥协、也不强开多核,而是直接优化算法本身——这通常更简单且收益稳定。
基础指标:线性回归
线性回归在每根 K 线拟合一条线,显示该线在此根的函数值。设 x 为柱序号、y 为价格,系数 a、b 由以下求和式决定(N 为回归窗口):
// 线性回归系数:避免每根都从 0 求和
double Sx=0,Sy=0,Sxx=0,Sxy=0;
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;
方法一:递推/增量更新
窗口右移一根时,只需减去最左一根的累加项、加上最新一根,不必重新遍历整个窗口。Sx、Sxx 是固定公式可闭式更新,Sy、Sxy 用差量维护。
- Sx、Sxx 仅依赖窗口长度,可预计算常量。
- Sy(t) = Sy(t-1) - price_out + price_in。
- Sxy(t) = Sxy(t-1) - Σx·price_out + Σx·price_in。
方法二:缓存中间量
把 Sx、Sxx、以及 x 序列的乘积表在 Init 阶段算一次存数组,OnCalculate 每根只做加减与一次除法,彻底消除内层循环。
方法三:减少类型转换与分支
在热点循环里避免 string 拼接、避免反复调用 iCustom;用静态数组而非每次 ArrayResize;把 const 引用传给子函数减少拷贝。
✦ 先 profiling 再优化
用 Print(GetTickCount()) 包住热点段定位瓶颈,别凭直觉优化——多数指标 80% 时间花在 20% 的代码上。
小结
线性回归的三板斧——增量更新、缓存中间量、削减类型开销——适用于绝大多数滑动窗口类指标(MA、布林、回归通道)。算法优化零副作用,应作为指标编写的默认习惯。
常见问题
增量更新(递推)收益最大且零副作用:窗口右移时只加减最左/最新一根的累加项,不重遍历。
算法级优化(递推、缓存、削减类型开销)不砍历史深度也不开多线程,精度完全不变。
用 GetTickCount() 包住热点段打印耗时做 profiling,别凭直觉优化。