从零写一个 MQL5 自定义指标:SMA 全解剖
代码结构、#property、OnInit/OnCalculate 与增量计算
很多新手被一整页指标代码吓退。其实任何 MQL5 自定义指标都有最小且固定的骨架:全局声明、OnInit 初始化、OnCalculate 计算。我们拿最有名的简单移动平均线(SMA)当例子,一行一行拆开看。
一、指标代码的三段结构
第一段是全局层面代码:#property 指令、input 输入参数、以及作为指标缓冲区的动态数组。第二段 OnInit 只在指标加载时执行一次,做一次性设置。第三段 OnCalculate 在每笔新报价到来时被调用,负责计算并写入缓冲区。
二、#property 与 input:对外暴露的开关
indicator_buffers / indicator_plots 告诉终端要用几个缓冲区和几幅图;indicator_type1 / indicator_color1 定义第一幅图是线形、什么颜色。input int MAPeriod = 13 是用户可在属性窗口改的平均周期;input int MAShift = 0 是水平平移(柱数)。
三、指标缓冲区:动态数组 + SetIndexBuffer
double ExtLineBuffer[] 声明为全局动态数组,它在 OnInit 里通过 SetIndexBuffer(0, ExtLineBuffer, INDICATOR_DATA) 被绑定为第 0 号指标缓冲区;再用 PlotIndexSetInteger 设置平移(PLOT_SHIFT)和绘图起点(PLOT_DRAW_BEGIN = MAPeriod),前 MAPeriod-1 根柱子没东西可平均,不画。
四、OnCalculate:每笔报价都跑一次的计算核心
OnCalculate 的入参由终端传入且为 const:rates_total(可用柱数)、prev_calculated(上次已算柱数)、begin(首柱索引)、price[](计算用价格数组)。柱的索引从 0 开始、0 是最旧的那根,缓冲区和价格数组同序递增。
五、增量计算:别每次都从头算
if(prev_calculated == 0) 算全部柱子,否则只算新出现的柱子(first = prev_calculated - 1)。主循环从左往右累加 MAPeriod 根收盘价求平均,写回 ExtLineBuffer[bar],最后 return rates_total。这样每来一根新 K 线只补算最新的,效率最高。
小结
- 指标 = 全局声明 + OnInit + OnCalculate 三段
- #property 定义缓冲区/绘图/颜色,末尾无分号
- 动态数组经 SetIndexBuffer 绑定为指标缓冲区
- OnCalculate 每笔报价跑一次,柱索引 0 为最旧
- 用 prev_calculated 做增量计算,避免重复劳动
- 先编译成 .ex5,指标才能挂上图表