通过辅助指标减少内存消耗:复合指标的内存陷阱与优化
复合指标(自己内部又调用多个辅助指标的指标)是 MT5 里最常见的“内存杀手”。最典型的是 MACD:它内部要用两个 EMA,内存和算力是单一 EMA 的 3 倍以上。一旦你把多时间框架、多货币、多辅助指标叠起来,客户端吃几个 G 内存都不是新闻。本文给出两条“不换机器也能救”的瘦身路径。
一、复合指标为何吃内存
指标的每个输出都对应一块“缓存”(buffer),而每块缓存由客户端按整段历史预分配。一个 Ichimoku 含 5 块缓存,一个 Price_Channel 含 3 块。当你的主指标在 5 个时间框架(H4/H1/M15/M5/M1)上各调一个 Ichimoku + 一个 Price_Channel,辅助指标就有 10 个,缓存数 = (5+3)×5 = 40,加上主指标自己 1 块,共 41 块。
二、作者造的 Trender 指标:5 周期共振
为了演示问题,作者写了一个叫 Trender 的复合指标:在 H4/H1/M15/M5/M1 五个周期上,各用 Ichimoku(Tenkan>Kijun 判上升)和 Price_Channel(价在中线上方判上升)取信号,5 周期同向共振才给总信号。它共挂 10 个辅助指标,正是内存炸弹的本尊。
ENUM_TIMEFRAMES TF[5]={PERIOD_H4,PERIOD_H1,PERIOD_M15,PERIOD_M5,PERIOD_M1};
int h_Ichimoku[5], h_Channel[5];
// OnInit 中为每个周期创建辅助指标副本
for(int itf=0; itf<5; itf++){
h_Ichimoku[itf]=iCustom(Symbol(),TF[itf],"TestSlaveIndicators\\Ichimoku",9,26,52);
h_Channel[itf]=iCustom(Symbol(),TF[itf],"TestSlaveIndicators\\Price_Channel",22);
}
三、两类解法:减柱 or 减缓存
作者把内存想成一块矩形面积:宽 = 指标依据的K线数,高 = 缓存数量。面积太大,就砍宽或砍高。砍宽(减少 Max bars in chart)人人会、不用写代码;砍高(减缓存)才是程序员的真功夫,也是本文重点。
四、「Need」法:砍掉辅助指标用不到的缓存
如果辅助指标里有些缓存主指标根本不读,就把它改掉。比如 Price_Channel 有 3 块缓存,Trender 只读中间那块。把 indicator_buffers 从 3 改 1、删掉另两块数组、把引用它们的代码改成中间变量的计算结果——编译器会直接报出所有“未声明标识符”行,逐个改完即可。
// 改前 #property indicator_buffers 3 // 改后 #property indicator_buffers 1 // 删除用不到的两块 // double ExtHighBuffer[]; double ExtLowBuffer[]; double ExtMiddBuffer[];
五、「Aggregate」法:在辅助指标里先聚合成单缓存
如果主指标只是读取辅助指标的多个缓存再做聚合(比如比较 Tenkan 与 Kijun 得一个信号),那就把聚合下推到辅助指标内部,让它只吐一块“信号缓存”。以 Ichimoku 为例:主指标原本读 0、1 两块缓存判断大小,改成辅助指标内部聚合成一块 ExtSignalBuffer,主指标一句 CopyBuffer(...,0,...) 就拿到结果。
// 主指标旧写法:读两块再比 CopyBuffer(h_Ichimoku[itf],0,Time,1,bufTenkan); CopyBuffer(h_Ichimoku[itf],1,Time,1,bufKijun); if(Tenkan>Kijun) Signal++; // 新写法:辅助指标已聚合成 1 块信号 CopyBuffer(h_Ichimoku[itf],0,Time,1,bufSignal); Signal += bufSignal[0];
配合「Need」法,Ichimoku 的 5 块缓存最终也只剩 1 块。两种手法可以叠加,瘦身效果最大。
六、实操清单与收益
- 先列清单:主指标到底读了辅助指标的哪些缓存?没读的立刻砍(Need 法)
- 只读多块又做聚合的,把聚合下推到辅助指标(Aggregate 法)
- 非可视的辅助指标可一并删掉外观属性(indicator_type/plot),不报错
- 改完用 OnCalculate 里的“未声明标识符”报错快速定位残留引用
- 多周期×多货币的组合,每个维度都能省出成倍缓存,务必逐层瘦身
七、小结
复合指标的内存爆炸,根子在“辅助指标被完整实例化、而主指标只用其中一角”。两条解法——Need(删掉用不到的缓存)和 Aggregate(把聚合下推到辅助指标内部)——都是从源码层面减缓存,比“加内存条”更治本。把 Trender 这类 41 块缓存的指标按本文改完,能成倍回内存,多货币多周期实盘也更稳。