OnCalculate

Calculate事件发生时在指标中调用这个函数,来处理价格数据的变化。有两种函数类型。一个指标内只可以使用其中一种。

基于数据数组的计算

int  OnCalculate(

   const int        rates_total,       // price[]数组大小

   const int        prev_calculated,   // 在前一个调用中处理过的柱形图数量

   const int        begin,             //price[]数组中,有意义数据开始的索引编号

   const double&    price[]            // 计算值数组

   );

基于当前时间周期时间序列的计算

int  OnCalculate(

   const int        rates_total,       // 输入时间序列的大小

   const int        prev_calculated,   // 在前一个调用中处理过的柱形图数量

   const datetime&  time{},            // 时间数组

   const double&    open[],            // 开盘价数组

   const double&    high[],            // 最高价数组

   const double&    low[],             // 最低价数组

   const double&    close[],           // 收盘价数组

   const long&      tick_volume[],     // 报价量数组

   const long&      volume[],          // 真实交易量数组

   const int&       spread[]           // 点差数组

   );

参数

rates_total

[in]  可用于指标计算的price[]数组或输入序列的大小。在第二个函数类型中,当参数值对应于图表中柱形图数量时,启动这种函数类型。

prev_calculated

[in] 包含上一次调用期间OnCalculate()函数的返回值。它的设计旨在跳过自该函数上次启动后没有改变的柱形图。

begin

[in]  price[]数组中,有意义数据开始的索引编号。它允许您跳过缺失或初始数据,因为没有正确的值。

price[]

[in]  计算值数组。其中一个价格时间序列或计算过的指标缓冲区可以作为price[]数组进行传递。为计算而传递的数据类型可以使用_AppliedTo预定义变量来定义。

time{}

[in]  柱形图开盘时间值的数组。

open[]

[in]  开盘价格值的数组。

high[]

[in]  最高价格值的数组。

low[]

[in]  最低价格值的数组。

close[]

[in]  收盘价格值的数组。

tick_volume[]

[in]  报价量值的数组。

volume[]

[in]  交易量值的数组。

spread[]

[in]  柱形图点差值的数组。

返回值

int类型值将在下一次函数调用期间作为prev_calculated参数被传递。

注意

如果OnCalculate()函数等于零,则没有指标值显示在客户的数据窗口中。

如果价格数据在最后一次调用OnCalculate()函数之后发生了变化(已加载更深层历史记录或已填充历史记录空白),那么程序端本身则将prev_calculated输入参数设为零。

若要在time[]open[]high[]low[]close[]tick_volume[]volume[]spread[]数组中定义索引方向,请调用ArrayGetAsSeries()函数。为了不依赖于默认值,请为数组调用ArraySetAsSeries()函数来进行处理。

当使用第一种函数类型时,在启动指标时用户选择必要的时间序列或指标作为“参数”选项卡中的price[]数据。为此,请在“应用于”字段的下拉列表中指定必要的元素。

若要获取其他mql5程序的自定义指标值,则使用iCustom()函数。它返回后续操作的指标句柄。也可以指定所需的price [] 数组或另一个指标的句柄。这个参数应被传递到自定义指标输入变量列表的最后。

有必要使用OnCalculate()函数返回值和prev_calculated第二个输入参数之间的连接。当调用函数时,prev_calculated函数包含了上一次调用期间OnCalculate()函数的返回值。这使得为计算自定义指标而实现资源节约算法成为可能,以避免重复计算自上一次启动该函数以来没有改变的柱形图。

样例指标

//+------------------------------------------------------------------+

//|                                           OnCalculate_Sample.mq5 |

//|                        Copyright 2018, MetaQuotes Software Corp. |

//|                                             https://www.mql5.com |

//+------------------------------------------------------------------+

#property copyright "Copyright 2018, MetaQuotes Software Corp."

#property link      "https://www.mql5.com"

#property version   "1.00"

#property description "Sample Momentum indicator calculation"



//---- 指标设置

#property indicator_separate_window

#property indicator_buffers 1

#property indicator_plots   1

#property indicator_type1   DRAW_LINE

#property indicator_color1  Blue

//---- 输入

input int MomentumPeriod=14; // 计算周期

//---- 指标缓存区

double    MomentumBuffer[];

//--- 存储计算周期的全局变量

int       IntPeriod;

//+------------------------------------------------------------------+

//| 自定义指标初始化函数                                                |

//+------------------------------------------------------------------+

void OnInit()

  {

//--- 检查输入参数

   if(MomentumPeriod<0)

     {

      IntPeriod=14;

      Print("Period parameter has an incorrect value. The following value is to be used for calculations ",IntPeriod);

     }

   else

      IntPeriod=MomentumPeriod;

//---- 缓冲区  

   SetIndexBuffer(0,MomentumBuffer,INDICATOR_DATA);

//---- 显示在“数据窗口”和子窗口的指标名称

   IndicatorSetString(INDICATOR_SHORTNAME,"Momentum"+"("+string(IntPeriod)+")");

//--- 设置柱形图绘制的开始索引

   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,IntPeriod-1);

//--- 将0.0设置为未绘制的空值

   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);

//--- 显示的指标精确性

   IndicatorSetInteger(INDICATOR_DIGITS,2);

  }

//+------------------------------------------------------------------+

//|  动量指标计算                                                      |

//+------------------------------------------------------------------+

int OnCalculate(const int rates_total,     // price[] array size 

                const int prev_calculated, // 之前处理的柱形图的数量

                const int begin,           //重要数据起点 

                const double &price[])     // 值数组处理

  {

//--- 初始持仓计算

   int StartCalcPosition=(IntPeriod-1)+begin;

//---- 如果计算数据不足

   if(rates_total<StartCalcPosition)

      return(0);  // 以零值推出 - 这个指标没有被计算

//--- 正确绘制开始

   if(begin>0)

      PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartCalcPosition+(IntPeriod-1));

//--- 开始计算,定义开始位置

   int pos=prev_calculated-1;

   if(pos<StartCalcPosition)

      pos=begin+IntPeriod;

//--- 主计算循环

   for(int i=pos;i<rates_total && !IsStopped();i++)

      MomentumBuffer[i]=price[i]*100/price[i-IntPeriod];

//--- OnCalculate执行完成。返回后续调用的新prev_calculated值

   return(rates_total);

  }

另见

ArrayGetAsSeriesArraySetAsSeriesiCustom事件处理函数程序运行客户端事件访问时间序列和指标