【MQL5】CopyIndicatorBuffer関数について

MQL5リファレンス
スポンサーリンク
スポンサーリンク

CopyIndicatorBuffer関数の働き・役割

CopyIndicatorBuffer関数は、指定された指標(インジケータバッファのデータをベクトルにコピーするために使用されます。この関数を使うと、過去のインジケータ値を指定した数だけ取り出して分析や表示に利用できます。例えば、MACDRSIといったインジケータの過去のデータを取得し、それをEAエキスパートアドバイザー)やスクリプト内で利用することができます。

CopyIndicatorBuffer関数には、データを取得する方法に応じて3つのオプションがあります。
1つ目はデータの初期位置と要素数を指定する方法、2つ目は開始日付と要素数で指定する方法、3つ目は開始日付と終了日付で指定する方法です。このように、過去のデータを取得する条件を柔軟に設定できるため、さまざまな分析や計算に役立ちます。

バッファとは

バッファ(データを一時的に保存する領域)は、指標の計算結果を一時的に保管するメモリ領域です。インジケータによって生成された値が保存され、過去のデータも含めて再利用できるようになっています。

ベクトルとは

ベクトルは、データを格納する配列の一種で、必要に応じてデータの追加や削除ができる構造です。この関数では、インジケータのデータがベクトルにコピーされ、一番古いデータがベクトルの先頭に配置されます。ベクトルに保存することで、データを時間順に並べて扱いやすくなり、分析や計算を効率よく行うことができます。

CopyIndicatorBuffer関数は、データがサーバからダウンロード中でまだ準備ができていない場合や、指定した条件に合わないデータが存在しない場合には、エラーとしてfalseを返します。

CopyIndicatorBuffer関数の引数について

CopyIndicatorBuffer関数には、3つの異なる使い方(書式)があり、それぞれ異なる方法でデータの取得範囲を指定します。以下に、各書式ごとに引数の役割を詳しく説明します。

初期位置と必要な要素数による書式

bool  vector::CopyIndicatorBuffer(
  long     indicator_handle,    // 指標ハンドル
  ulong   buffer_index,        // 指標バッファ番号
  ulong   start_pos,            // 複製開始位置
  ulong   count                // 複製する要素の数
  );

この書式では、データを取得したい位置とその要素数を指定します。

indicator_handle
指標(インジケータ)を指定するための番号ハンドルを指定します。このハンドルは、インジケータを計算する関数から返され、特定のインジケータを指定するために使います。

buffer_index
インジケータが持っているデータのグループ(バッファ)の番号です。インジケータによっては複数のバッファを持つ場合があり、どのバッファからデータを取得するかをこの番号で指定します。

start_pos
データの取得を開始する位置を指定します。0は現在のデータを意味し、1なら1つ前のデータ、2なら2つ前のデータといったように、古いデータの位置を決めます。

count
取得したいデータの個数です。start_posで指定した位置から、いくつのデータをコピーするかをここで指定します。

開始日付と必要な要素数による書式

bool  vector::CopyIndicatorBuffer(
  long     indicator_handle,    // 指標ハンドル
  ulong   buffer_index,        // 指標バッファ番号
  datetime  start_time,          // 複製開始日
  ulong   count                 // 複製する要素の数
  );

この書式では、データの取得を開始する日付と要素数を指定します。

indicator_handle
インジケータの識別番号で、特定のインジケータハンドルを指定します。このハンドル指定により、目的のインジケータからデータを取得できるようになります。

buffer_index
インジケータのデータが入っているバッファの番号です。複数のデータグループを持つインジケータがあるため、この番号でどのデータを取得するかを決めます。

start_time
データの取得を開始する日付です。この日付に最も近い時点のデータを取得し、以降のデータも合わせてコピーします。

count
取得するデータの数です。start_timeで指定した日付から順に、指定した数だけのデータをコピーします。

開始日付と終了日付による書式

bool  vector::CopyIndicatorBuffer(
  long     indicator_handle,    // 指標ハンドル
  ulong   buffer_index,        // 指標バッファ番号
  datetime  start_time,          // 複製開始日
  datetime  stop_time             // 複製終了日
  );

この書式では、データの取得を開始する日付と終了する日付を指定します。

indicator_handle
取得したいインジケータを指定するためのハンドルを指定します。インジケータの計算関数から返される値を使い、どのインジケータからデータを取得するかを指定します。

buffer_index
取得するインジケータデータが入っているバッファの番号です。インジケータが複数のバッファを持つ場合、この番号で指定したバッファからデータを取得します。

start_time
データの取得を開始する日付です。この日付に近い時点から、データのコピーを始めます。

stop_time
データの取得を終了する日付です。この日付に最も近いデータまでコピーを行います。

CopyIndicatorBuffer関数の戻り値について

CopyIndicatorBuffer関数戻り値は、指定されたインジケータデータのコピーが成功したかどうかを示します。この関数は、コピーが正常に行われた場合はtrueを返し、何らかのエラーが発生した場合はfalseを返します。

例えば、サーバからのデータダウンロードが未完了である場合や、指定したバッファに適切なデータがない場合には、falseが返されます。また、開始位置や指定した日付にデータが存在しないといった理由でも、falseが返される可能性があります。

この戻り値は、データ取得の成否を確認するために役立ちます。たとえば、取得が成功した場合にデータを処理し、失敗した場合には処理を中止したり再試行したりすることが可能です。

CopyIndicatorBuffer関数を使う際の注意点

複製されたデータは、新しいデータから過去のデータに向かって並んでいるため、コピーの開始位置が0である場合は、現在のデータが一番初めに配置されます。そのため、データの順序を意識して利用することが重要です。

未知のデータ量をコピーする場合は、ベクトルのサイズを事前に設定せずに宣言します。CopyIndicatorBuffer関数は、コピーしたデータ量に応じてベクトルのサイズを自動的に調整します。ベクトルのサイズを事前に指定してしまうと、メモリが再割り当てされ、無駄が生じる可能性があります。

必要なデータ量だけコピーする場合には、コピーする先のベクトルをあらかじめ宣言して、必要なサイズを設定しておくことが推奨されます。これにより、無駄なメモリの再割り当てが避けられ、処理が効率的になります。

インジケータのデータがまだサーバからダウンロードされていない場合や、必要なデータがまだ準備できていない場合、関数はすぐにfalseを返します。サーバからデータがダウンロードされるまで時間がかかる場合があるため、この関数を呼び出すときには、データがそろっているかを確認してから利用することが重要です。

CopyIndicatorBuffer関数を使ったサンプルコード

CopyIndicatorBuffer関数については、公式リファレンスにサンプルコードがありません。

自分で下記のようなコードを書いてみたのですが、実行してみると、ハンドル取得後のコピーが旨く行っていないようです。

現在鋭意調査中です(どなたか、使い方知っている人いたら教えてください)

→Xで教えて頂き、以下のような形に変更したところ、値が取得できるようになりました。教えて頂き感謝です。

// OnStart関数はスクリプト実行時に最初に呼び出される関数です
void OnStart()
{
    // MACDインジケータを使って、インジケータハンドルを取得します
    // MACDインジケータの設定として短期期間を12、長期期間を26、シグナル期間を9に設定
    int macd_handle = iMACD(_Symbol, PERIOD_H1, 12, 26, 9,PRICE_CLOSE);

    // インジケータハンドルが正しく取得できなかった場合、エラーメッセージを出力し終了します
    if(macd_handle == INVALID_HANDLE)
    {
        Print("インジケータハンドルの取得に失敗しました。");
        return;
    }

    // データを格納するためのベクトルを宣言します(MACDメインライン用)
    vector macd_main_data;

    // 過去10本分のMACDメインラインデータを取得します
    // データ取得が失敗した場合、エラーメッセージを出力して終了します
    if(!macd_main_data.CopyIndicatorBuffer(macd_handle, 0, 0, 10))
    {
        Print("データの取得に失敗しました。");
        return;
    }

    // コピーされたMACDデータを出力します(過去のデータから現在のデータへ順に出力)
    for(int i = 0; i <(int)macd_main_data.Size(); i++)
    {
        // ArraySize関数はベクトルのサイズ(要素数)を返します
        // 各データ要素の値をエキスパートログに表示
        Print("MACD メインラインデータ[", i, "] = ", macd_main_data[i]);
    }

    // インジケータハンドルを解放します
    // 解放しないとメモリが消費されたままになるため、不要になったら解放が推奨されます
    IndicatorRelease(macd_handle);
}

サンプルコードの解説

1. OnStart関数の開始

OnStart関数スクリプトが実行されるときに最初に呼び出される関数です。この関数内に記述されたコードが順番に実行されます。

2. iMACD関数でインジケータハンドルを取得

iMACD関数を使って、MACDインジケータハンドル識別子)を取得します。このハンドルは、後でインジケータのデータを参照するために必要です。

  • 引数
  • _Symbol:現在のチャートの通貨ペア(例:EURUSD)。
  • PERIOD_H1:時間枠(ここでは1時間足)。
  • 12, 26, 9:MACDの短期、長期、およびシグナルラインの期間。
  • PRICE_CLOSE:終値に基づいてMACDを計算します。

ハンドルの取得に成功すると、macd_handleという変数ハンドルが格納されます。

3. ベクトルmacd_main_dataの宣言

vectorクラスを使って、macd_main_dataという名前のベクトルを宣言します。このベクトルには、取得したMACDのメインラインデータが格納されます。

4. CopyIndicatorBufferでデータを取得

CopyIndicatorBuffer関数を使用して、MACDインジケータのメインラインデータをベクトルにコピーします。

  • 引数
  • macd_handle:先ほど取得したインジケータハンドル
  • 0:MACDメインラインを指定するバッファ番号。
  • 0:コピーの開始位置(最新のバー)。
  • 10:コピーするバーの数(最新から10本分)。

CopyIndicatorBuffer関数戻り値がfalseの場合、データ取得に失敗したことを示します。その場合は、エラーメッセージを出力してreturn処理を終了します。

5. データをエキスパートログに出力

データ取得が成功した場合、取得したデータをforループで1つずつエキスパートログに出力します。

  • ループの条件
  • iはループカウンタで、macd_main_data.Size()を使ってベクトルのサイズを取得し、そのサイズ分ループします。
  • 出力内容
    Print関数を使い、各データのインデックスと値をログに表示します。

6. IndicatorReleaseでハンドルを解放

IndicatorRelease関数を使い、macd_handleで取得したインジケータハンドルを解放します。これにより、不要になったハンドルを解放してシステムリソースを節約します。

実行結果の例

例えば、MACDメインラインデータが以下のような値の場合、次のようなログが出力されます。

MACD メインラインデータ[0] = 0.0032
MACD メインラインデータ[1] = 0.0028
MACD メインラインデータ[2] = 0.0025
...
MACD メインラインデータ[9] = 0.0011

タイトルとURLをコピーしました