時系列と指標データへのアクセス

これらの関数は時系列と指標の操作に使用されます。時系列は、索引付けが後ろから前へ(最新のデータから古いデータへ)されている点で通常の配列とは異なります。コピー関数は値を受け取る配列の必要なサイズを割り当てるように設計されているので、時系列の値と指標データのコピーには動的配列の使用のみが推奨されます。

この規則には重要な例外があります。時系列と指標の値が、例えばエキスパートアドバイザーでの OnTick()や指標での OnCalculate() の呼び出しの度に頻繁に複製される場合には動的配列でのメモリ操作には時間がかかりテストと最適化に影響が出るので、静的配列が使用されるべきです。

時系列と指標値にアクセスする関数を使用する場合は、索引付けの方向が考慮されるべきです。これは配列、バッファ及び時系列における索引付けの方向 セクションで説明されています。

指標及び時系列データへのアクセスはリクエストされたデータが準備されているかどうかに関係なく実装されています(いわゆる非同期アクセス)。これは、カスタム指標の計算に非常に重要なので、データが存在しない場合は Copy...() 型の関数が即時にエラーを返します。しかし、エキスパートアドバイザーやスクリプトからのアクセス時には、複数のデータを受信するための試みが、指標値を算出するために必要な時系列をダウンロードするために必要な時間を提供する休止をはさんで行われます。

データアクセスの整理セクションは MetaTrader 5 クライアント端末での価格データの受信、格納及びリクエストの詳細を含みます。

時系列及び通常の配列での索引付けの方向

配列内の価格データへのアクセスはデータの終わりから行われることは歴史的に認められています。物理的には新しいデータは常に配列の最後に書かれていますが、配列のインデックスは常にゼロに等しいです。時系列配列のインデックス 0 は、この時間軸内の未完成の時間間隔に対応するバー、すなわち、現在足のデータを表します。

時間軸とは、単一の価格バーが形成されている期間です。事前定義された標準時間軸は 21 あります。

関数

アクション

SeriesInfoInteger

履歴データの状態情報を返します。

Bars

指定された銘柄と期間の履歴内のバーの数を返します。

BarsCalculated

指標バッファで計算されたデータの数、またはエラー(データがまだ計算されていません。)の場合 -1 を返します。

IndicatorCreate

MqlParam 型パラメータの配列によって作成された指定されたテクニカル指標へのハンドルを返します。

IndicatorParameters

指定されたハンドルに基づいて、指標の入力パラメータの数、値と型を返します。

IndicatorRelease

指標ハンドルを削除し、誰によっても使用されていない場合は指標の計算ブロックを解放します。

CopyBuffer

指定された指標の指定されたバッファデータを配列に取得します。

CopyRates

指定された銘柄と期間の Rates 構造体の履歴データを配列に取得します。

CopySeries

MqlRates構造体から、指定された銘柄期間と指定された量の同期済み時系列を取得します。

CopyTime

指定された銘柄と期間のオープン時間の履歴データを配列に取得します。

CopyOpen

指定された銘柄と期間のバー始値の履歴データを配列に取得します。

CopyHigh

指定された銘柄と期間のバー高値の履歴データを配列に取得します。

CopyLow

指定された銘柄と期間のバー安値の履歴データを配列に取得します。

CopyClose

配列に指定された銘柄と期間のバー終値の履歴データを取得します。

CopyTickVolume

指定された銘柄と期間のティックボリュームの履歴データを配列に取得します。

CopyRealVolume

指定された銘柄と期間の取引高の履歴データを配列に取得します。

CopySpread

指定された銘柄と期間のスプレッドの履歴データを配列に取得します。

CopyTicks

現在の作業セッションので端末に蓄積されたティックを配列に取得します。

CopyTicksRange

この関数は指定された期間内のティックをMqlTick形式で ticks_arrayで受け取ります。

iBars

該当する銘柄と期間の履歴内のバーの数を返します。

iBarShift

この関数は、指定された時刻に対応するバーのインデックスを返します。

iClose

対応するチャートのバー( 'shift'パラメータで示される)の終値を返します。

iHigh

対応するチャートのバー( 'shift'パラメータで示される)の高値を返します。

iHighest

対応するチャート上で見つかった最大値のインデックスを返します(現在のバーとの相対的なシフト)。

iLow

対応するチャートのバー( 'shift'パラメータで示される)の安値を返します。

iLowest

該当するチャート上で見つかった最小値のインデックスを返します(現在のバーとの相対的なシフト)。

iOpen

対応するチャートのバー( 'shift'パラメータで示される)の始値を返します。

iTime

対応するチャートのバー( 'shift'パラメータで示される)の時間を返します。

iTickVolume

対応するチャートのバー( 'shift'パラメータで示される)のティックボリュームを返します。

iRealVolume

対応するチャートのバー( 'shift'パラメータで示される)の実ボリュームを返します。

iVolume

対応するチャートのバー( 'shift'パラメータで示される)のティックボリュームを返します。

iSpread

対応するチャートのバー( 'shift'パラメータで示される)のスプレッドを返します。

ArraySetAsSeries()関数を使用して配列要素のアクセスを時系列風に設定することは可能ですが、配列要素は物理的には同じ向きで格納されていて、索引付けの方向だけが変わることを忘れてはいけません。この事実を実証するための例を実行してみましょう。

  datetime TimeAsSeries[];
//--- 時系列風に配列アクセスを設定する
  ArraySetAsSeries(TimeAsSeries,true);
  ResetLastError();
  int copied=CopyTime(NULL,0,0,10,TimeAsSeries);
  if(copied<=0)
    {
    Print("The copy operation of the open time values for last 10 bars has failed");
    return;
    }
  Print("TimeCurrent =",TimeCurrent());
  Print("ArraySize(Time) =",ArraySize(TimeAsSeries));
  int size=ArraySize(TimeAsSeries);
  for(int i=0;i<size;i++)
    {
    Print("TimeAsSeries["+i+"] =",TimeAsSeries[i]);
    }
 
  datetime ArrayNotSeries[];
  ArraySetAsSeries(ArrayNotSeries,false);
  ResetLastError();
  copied=CopyTime(NULL,0,0,10,ArrayNotSeries);
  if(copied<=0)
    {
    Print("The copy operation of the open time values for last 10 bars has failed");
    return;
    }  
  size=ArraySize(ArrayNotSeries);
  for(int i=size-1;i>=0;i--)
    {
    Print("ArrayNotSeries["+i+"] =",ArrayNotSeries[i]);
    }

結果としてこのような出力が得られます。

TimeCurrent = 2009.06.11 14:16:23
ArraySize(Time) = 10
TimeAsSeries[0] = 2009.06.11 14:00:00
TimeAsSeries[1] = 2009.06.11 13:00:00
TimeAsSeries[2] = 2009.06.11 12:00:00
TimeAsSeries[3] = 2009.06.11 11:00:00
TimeAsSeries[4] = 2009.06.11 10:00:00
TimeAsSeries[5] = 2009.06.11 09:00:00
TimeAsSeries[6] = 2009.06.11 08:00:00
TimeAsSeries[7] = 2009.06.11 07:00:00
TimeAsSeries[8] = 2009.06.11 06:00:00
TimeAsSeries[9] = 2009.06.11 05:00:00
 
ArrayNotSeries[9] = 2009.06.11 14:00:00
ArrayNotSeries[8] = 2009.06.11 13:00:00
ArrayNotSeries[7] = 2009.06.11 12:00:00
ArrayNotSeries[6] = 2009.06.11 11:00:00
ArrayNotSeries[5] = 2009.06.11 10:00:00
ArrayNotSeries[4] = 2009.06.11 09:00:00
ArrayNotSeries[3] = 2009.06.11 08:00:00
ArrayNotSeries[2] = 2009.06.11 07:00:00
ArrayNotSeries[1] = 2009.06.11 06:00:00
ArrayNotSeries[0] = 2009.06.11 05:00:00

出力からわかるように、TimeAsSeries 配列のインデックスが増加するにつれてインデックスの time 値が減少します。つまり、現在から過去に存在から移動するわけです。ArrayNotSeries 通常配列では結果が異なります。インデックスが大きくなるにつれて、過去から現在までの移動が行われます。

参照

ArrayIsDynamicArrayGetAsSeriesArraySetAsSeriesArrayIsSeries