MQL5参考事件处理OnCalculate 

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事件处理函数程序运行客户端事件访问时间序列和指标