時系列やインジケータを操作する為の関数です。
時系列は通常のデータ配列と異なり順序が逆になります。
時系列配列の要素は、配列の末尾(最新のデータから古いデータに向かって)からインデックスが作成されます。
時系列値とインジケータデータをコピーする場合、
動的配列のみ使用する事をお勧めします。
コピー関数は値を受け取る為に必要な配列サイズを動的に割り当てるように設計されています。
但し、このルールには例外があります。
時系列およびインジケータ値を頻繁にコピーする必要がある場合、
例えば、EAの
OnTick()関数の呼び出しや、カスタムインジケータの
OnCalculate()関数の呼び出しです。
この場合は静的配列を使用する必要があります。
動的配列のメモリ割り当て処理は時間がかかる為、テストや最適化にかかる時間に影響します。
時系列とインジケータ値にアクセスする関数を使用する時、インデックス方向を考慮する必要があります。
これは
"バッファ・時系列配列のインデックス方向"に記載されています。
インジケータと時系列データへのアクセスは、
非同期アクセス(要求したデータの準備がされていなくてもアクセスします)です。
これはカスタムインジケータの計算において非常に重要です。
データが無い場合、CopyXXXX()関数は直ぐにエラーを返せません。
ただし、スクリプトやEAからアクセスする時は、
データ受信を数回試み、僅かに休止(指標値を計算する為に必要な時系列データのダウンロードする時間を提供)します。
データを他チャート(
通貨ペアまたは
時間軸が異なる)から要求する場合、
対応する他チャートが開かれていない可能性があります。
その場合、必要なデータはサーバーから取得しなければなりません。
このケースでは、
エラーコード4066(ERR_HISTORY_WILL_UPDATED:要求されたヒストリーデータが更新中)が発生します。
データアクセス編成では、メタトレーダー4クライアントターミナルの価格データ受信と格納の詳細について説明します。
配列の価格データへのアクセスはデータの末尾から行われます。
物理的には新しいデータは常に配列の最後に書かれますが、
配列のインデックスは常に0に等しくなります。
時系列配列のインデックス=0は、現在バーのデータを表します。
これは現在の時間軸の未完成のバー(終値が確定していない現在のバー)に対応します。
時間軸にはいくつか定義済みの標準的な時間軸があります。
ArraySetAsSeries()関数を使用する事で、
時系列配列のような配列アクセスが可能になります。
ただし、インデックス方向の変更のみで、配列要素は物理的に同じ順序で格納されている事を忘れてはいけません。
以下は、この事実を実証する為のサンプルソースです。
サンプルソース:
void OnInit() {
int copied;
int size;
datetime TimeAsSeries[];
ArraySetAsSeries(TimeAsSeries, true);
ResetLastError();
copied = CopyTime(Symbol(),PERIOD_H1,0,5,TimeAsSeries);
if( copied <= 0 ) {
Print("オープン時間のコピー失敗。ヒストリカルデータが無い可能性があります。");
return;
}
Print("現在の時間(サーバー時間) =",TimeCurrent());
Print("配列サイズ(TimeAsSeries) =",ArraySize(TimeAsSeries));
Print("\n");
Print("時系列配列のようなアクセス設定");
size = ArraySize(TimeAsSeries);
for(int i=0; i < size ;i++) {
printf( "TimeAsSeries[%d] = %s",i, TimeToStr(TimeAsSeries[i]) );
}
datetime ArrayNotSeries[];
ArraySetAsSeries(ArrayNotSeries,false);
ResetLastError();
copied = CopyTime(Symbol(),PERIOD_H1,0,5,ArrayNotSeries);
if( copied <= 0 ) {
Print("オープン時間のコピー失敗。ヒストリカルデータが無い可能性があります。");
return;
}
Print("\n");
Print("通常配列アクセス設定");
size = ArraySize(ArrayNotSeries);
for(int i = size-1; i >= 0 ;i--) {
printf( "ArrayNotSeries[%d] = %s",i, TimeToStr(ArrayNotSeries[i]) );
}
}
結果:
現在の時間(サーバー時間) =2015.04.29 14:14:12
配列サイズ(TimeAsSeries) =5
時系列配列のようなアクセス設定
TimeAsSeries[0] = 2015.04.29 14:00
TimeAsSeries[1] = 2015.04.29 13:00
TimeAsSeries[2] = 2015.04.29 12:00
TimeAsSeries[3] = 2015.04.29 11:00
TimeAsSeries[4] = 2015.04.29 10:00
通常配列アクセス設定
ArrayNotSeries[4] = 2015.04.29 14:00
ArrayNotSeries[3] = 2015.04.29 13:00
ArrayNotSeries[2] = 2015.04.29 12:00
ArrayNotSeries[1] = 2015.04.29 11:00
ArrayNotSeries[0] = 2015.04.29 10:00
TimeAsSeries配列の出力結果から分かる様に、インデックス増加でオープン時間が減少します。
インデックスの方向は現在から過去に向かっています。
ArrayNotSeries配列は逆に、インデックス増加につれてオープン時間が増加します。
インデックスの方向は過去から現在に向かっています。