检查计算得出柱线的数量:BarsCalculated

当我们通过调用iCustom或本章后续将介绍的其他函数创建第三方指标时,指标需要一定时间进行计算。我们知道,指标数据就绪状态的主要衡量标准是已计算柱线数量,这一数值由指标的OnCalculate函数返回。通过指标句柄,我们可以获取这一数值。

int BarsCalculated(int handle)

该函数返回由handle指定的指标中计算数据的柱线数量。如果发生错误,我们将收到 -1。

当数据尚未计算时,结果为 0。后续需将此数值与时间序列的大小进行比较(例如,如果调用指标在自身 OnCalculate函数上下文校验 BarsCalculated,可对比 rates_total),以分析指标对新柱线的处理情况。

UseWPR2.mq5指标中,我们将尝试通过在输入参数更改 WPR 周期来创建 IndWPR

input int WPRPeriod = 0;

其默认值为 0,这是一个无效值。我们有意设计这种情况,为的就是演示异常处理情况。回顾 IndWPR.mq5的源代码,OnInitOnCalculate 函数中均包含校验。

// IndWPR.mq5
void OnInit()
{
   if(WPRPeriod < 1)
   {
      Alert(StringFormat("Incorrect Period value (%d). Should be 1 or larger",
         WPRPeriod));
   }
   ...
}
   
int OnCalculate(ON_CALCULATE_STD_FULL_PARAM_LIST)
{
   if(rates_total < WPRPeriod || WPRPeriod < 1return 0;
   ...
}

因此,当周期为零时,我们应收到错误消息,且BarsCalculated应始终返回 0。当输入正周期后,辅助指标应开始正常计算(考虑到 WPR 计算的简易性,几乎会立即完成),此时 BarsCalculated将返回柱线总数。

现在我们来展示 UseWPR2.mq5中创建指标句柄的源代码:

// UseWPR2.mq5
int handle// handle to global variable
   
int OnInit()
{
   // passing name and parameter
   handle = PRTF(iCustom(_Symbol_Period"IndWPR"WPRPeriod));
   // next check is useless here because you have to wait,
   // when the indicator is loaded, run and calculate
   // (here it is for demonstration purposes only)
   PRTF(BarsCalculated(handle));
   // successful initialization depends on the descriptor
   return handle == INVALID_HANDLE ? INIT_FAILED : INIT_SUCCEEDED;
}

OnCalculate中,我们仅记录 BarsCalculatedrates_total 值。

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &data[])
{
   // wait until the slave indicator is calculated on all bars
   if(PRTF(BarsCalculated(handle)) != PRTF(rates_total))
   {
      return prev_calculated;
   }
   
   // ... here is usually further work using handle
   
   return rates_total;
}

编译并运行UseWPR2,先将参数设为 0,再设为有效值(如 21)。下面是周期为零时的日志记录:

iCustom(_Symbol,_Period,IndWPR,WPRPeriod)=10 / ok
BarsCalculated(handle)=-1 / INDICATOR_DATA_NOT_FOUND(4806)
Alert: Incorrect Period value (0). Should be 1 or larger
BarsCalculated(handle)=0 / ok
rates_total=20000 / ok
...

在句柄创建后立即检验,由于数据尚不可用,会显示 INDICATOR_DATA_NOT_FOUND(4806) 错误,且结果BarsCalculated为 -1。随后会出现输入参数错误的通知,证实IndWPR指标已成功加载并启动。在后续日志段中,我们将收到 BarsCalculated值为 0

为使指标正常计算,我们将输入正确的输入参数。此时,BarsCalculated等于 rates_total

iCustom(_Symbol,_Period,IndWPR,WPRPeriod)=10 / ok
BarsCalculated(handle)=-1 / INDICATOR_DATA_NOT_FOUND(4806)
BarsCalculated(handle)=20000 / ok
rates_total=20000 / ok
...

在掌握从属指标就绪状态的检验方法后,我们可以开始读取其数据。让我们在接下来的示例 UseWPR3.mq5中实践这一点,在该示例中我们将学习 CopyBuffer 函数的使用。