1. CopyBuffer関数の概要と実務での活用法
MQL5でのインジケーター開発やEA(エキスパートアドバイザー)開発において、最も頻繁に使用し、かつ初心者が最初につまずきやすいのがこのCopyBuffer関数です。
MQL4ではiMA()やiRSI()といった関数を呼ぶだけで直接値を取得できましたが、MQL5では設計思想が大きく異なります。MQL5ではまずインジケーターの「ハンドル(識別番号)」を取得し、そのハンドルを介して「インジケーターの計算結果(バッファ)を配列にコピーする」という2ステップの工程が必要になります。
実務レベルでは、この関数を使いこなすことで、自作インジケーターの値だけでなく、MT5標準搭載の高度な指標データを高速に取得し、売買ロジックに組み込むことが可能になります。特にマルチタイムフレーム(MTF)分析を行う際、異なる時間足のデータを安全かつ効率的に取得するために不可欠な関数です。
2. 構文と戻り値
CopyBuffer関数の基本的な構文は以下の通りです。
int CopyBuffer(
int indicator_handle, // インジケーターハンドル
int buffer_num, // インジケーターのバッファ番号 (0から始まる)
int start_pos, // コピー開始位置
int count, // コピーするデータ個数
double buffer_array[] // コピー先の配列
);
パラメーターの解説
- indicator_handle:
iMA()やiCustom()などの関数で事前に作成したハンドルの整数値。 - buffer_num: 取得したいデータのインデックス。例えば移動平均線なら通常は「0」、ボリンジャーバンドならメインが「0」、上線が「1」、下線が「2」といった形です。
- start_pos: どのバーからコピーを開始するか。現在のバー(最新)は「0」です。
- count: 何個分のデータを取得するか。直近1本分なら「1」を指定します。
- buffer_array[]: 取得した数値を格納するための
double型の動的配列。
戻り値
- 成功した場合:コピーされた要素の数(countで指定した数)。
- 失敗した場合:-1。失敗の理由は
GetLastError()で詳細を確認できます。
3. 具体的な使い方・実践サンプルコード
以下は、単純移動平均線(SMA)の値を直近3本分取得し、配列に格納してデバッグ出力するEAのサンプルコードです。
//--- インジケーターのハンドルを格納する変数
int handleSMA;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// 期間20、シフト0、SMA、適用価格は終値のハンドルを作成
handleSMA = iMA(_Symbol, _Period, 20, 0, MODE_SMA, PRICE_CLOSE);
// ハンドルの作成に失敗した場合の処理
if(handleSMA == INVALID_HANDLE)
{
Print("ハンドル作成失敗。エラーコード:", GetLastError());
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// データを格納するための動的配列
double smaValues[];
// 配列を時系列順(インデックス0が最新)に設定
ArraySetAsSeries(smaValues, true);
// CopyBufferを使ってデータを配列にコピー(最新から3本分)
int copied = CopyBuffer(handleSMA, 0, 0, 3, smaValues);
// コピーに成功したかチェック
if(copied > 0)
{
// smaValues[0] が現在の足のSMA、[1]が1本前の足のSMA
PrintFormat("最新SMA: %.5f, 1本前SMA: %.5f", smaValues[0], smaValues[1]);
// ゴールデンクロスの判定などに利用可能
if(smaValues[1] < iClose(_Symbol, _Period, 1) && smaValues[0] > iClose(_Symbol, _Period, 0))
{
// 上抜け判定などのロジックへ
}
}
else
{
Print("データのコピーに失敗。エラーコード:", GetLastError());
}
}
4. 使用上の注意点とよくあるエラー
- ArraySetAsSeriesの忘れ:
MQL5のデフォルトでは、配列のインデックス0は「最も古いデータ」を指します。チャートの感覚(0が最新)で扱うには、必ずArraySetAsSeries(array, true)を呼び出す必要があります。 - ハンドルの作成場所:
iMA()などのハンドル取得関数をOnTick()内で毎回呼ぶのはNGです。非常に重い処理になり、PCのメモリを圧迫します。必ずOnInit()で一度だけ作成し、変数に保存しておきましょう。 - データ未準備エラー(4806):
インジケーターの計算が追いついていない場合や、ヒストリカルデータが読み込まれていない場合、-1を返しエラーコード4806が発生します。ループ内で再試行するか、エラー時は計算をスキップする堅牢なコードが求められます。 - バッファ番号の取り違え:
カスタムインジケーターを使用する場合、ソースコード内のSetIndexBufferを確認し、どの番号にどのデータが割り当てられているか正確に把握する必要があります。
5. 【重要】自動売買における約定スピードと環境の罠
アルゴリズムトレードにおいて、ロジックの正しさと同じ、あるいはそれ以上に重要なのが「実行環境の品質」です。多くの初心者が自宅のPCでMT5を稼働させますが、これはプロの視点から見ると極めてリスクの高い行為です。家庭用のインターネット回線はパケットロスが発生しやすく、ブローカーのサーバーとの通信遅延(レイテンシ)は、数ミリ秒の遅れとなって現れます。相場の急変時、このわずかな遅れが「注文を出した瞬間に価格が滑る(スリッページ)」を引き起こし、期待収益を大幅に削り取ります。
さらに、OSの自動アップデートによる再起動や、停電、ルーターのフリーズなど、物理的な障害は24時間稼働が前提のシステムトレードにおいて致命的な損失を招きかねません。約定スピードを極限まで高め、物理的なリスクを排除するためには、ブローカーのデータセンターに近い場所に位置する専用のVPS(仮想専用サーバー)の利用が不可欠です。低遅延なネットワーク環境を確保することは、アルゴリズムトレーダーにとって「勝つための最低条件」であると認識してください。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント