OnCalculate

この関数は、Calculateイベントが発生して価格の変化が処理されるときに、指標で呼び出されます。この関数の型は 2 つあります。1つの指標内では1つだけ使用できます。

データ配列に基づく計算

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[]配列または入力系列のサイズ第2の関数タイプでは、パラメータ値は、それが開始されたチャート上の棒の数に対応します。

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]  バーのスプレッド値の配列

戻り値

次に関数が呼び出されるときにprev_calculatedパラメータとして渡されるint 型の値

注意事項

OnCalculate()関数がゼロに等しい場合、クライアント端末のデータウィンドウには指標値が表示されません。

OnCalculate()関数の最後の呼び出し以降に価格データが変更された場合(より長期間の履歴が読み込まれているか、履歴のギャップが埋められている場合)、 prev_calculated入力パラメータは、端末自身によってゼロに設定されます。

time[]open[]high[]low[]close[]tick_volume[]volume[]spread[]配列で索引付けの方向を定義するには、ArrayGetAsSeries()関数を呼び出します。デフォルトに依存しないためには、作業する配列でArraySetAsSeries()関数を呼び出します。

最初の関数タイプを使用する場合、指標を起動するときに必要な時系列または指標がパラメータタブのprice[]配列としてユーザによって選択されます。そのためには "Apply to"(適用)フィールドのドロップダウンリストに必要な項目を指定する必要があります。

カスタム指標値を他のMQL5プログラムから取得するにはiCustom()関数が使用されます。これは、後の操作のために指標ハンドルを返します。また、必要なprice [] 配列または他の指標ハンドルを指定することも出来ます。このパラメータは、カスタム指標の入力変数のリストに最後に送信されるべきです。

OnCalculate()の戻り値とprev_calculated の2番目の入力パラメータとの関係はここで指摘される必要があります。関数が呼び出されたとき、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[]配列サイズ
              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);
 }

参照

ArrayGetAsSeriesArraySetAsSeriesiCustomEvent handling functionsProgram runningClient terminal eventsAccess to timeseries and indicators