【MQL5】CopyClose関数の使い方と自動売買実装コード

1. CopyClose関数の概要と実務での活用法

MQL5におけるCopyCloseは、指定した通貨ペアや時間足の「終値(Close)」データを配列に取得するための非常に重要な関数です。MQL4ではiClose()という関数で1本ずつのデータを取得していましたが、MQL5ではCopyCloseを使用して、必要な本数分をまとめて配列へコピーする手法が標準となりました。

実務レベルの開発において、この関数は以下のような場面で多用されます。
* テクニカル指標の自作: 移動平均線(MA)やRSIなどのロジックを計算する際。
* 確定足の判定: 「前の足の終値が〇〇を上回ったらエントリー」という条件分岐。
* マルチタイムフレーム(MTF)分析: 5分足のEAを動かしながら、1時間足や日足の終値を参照してトレンドを判断する場合。

初心者が特につまずきやすいのは、「データの時系列順序」「データの準備状況」です。配列にコピーされたデータが「古い順」なのか「新しい順」なのかを正しく制御しないと、バックテストと実運用で結果が乖離する原因になります。

2. 構文と戻り値

CopyCloseにはいくつかの呼び出し方(オーバーロード)がありますが、最も一般的で使いやすい「開始位置と個数を指定する方法」を解説します。

構文

int  CopyClose(
   string           symbol_name,       // 通貨ペア(NULLで現在のチャート)
   ENUM_TIMEFRAMES  timeframe,         // 時間足(PERIOD_CURRENTで現在の時間足)
   int              start_pos,         // コピー開始位置(0が最新の足)
   int              count,             // コピーする個数
   double           close_array[]      // コピー先の配列(double型)
);

戻り値

  • 成功時: コピーされた要素の数(int型)を返します。
  • 失敗時: -1 を返します。

実務では、戻り値が -1 でないか、または count で指定した数と一致しているかをチェックすることで、データの取得ミスによる誤作動を防ぐのが鉄則です。

3. 具体的な使い方・実践サンプルコード

以下のコードは、最新の確定足(1本前の足)とその前の足(2本前の足)の終値を取得し、簡単な価格比較を行うEAのスケルトンです。

//+------------------------------------------------------------------+
//|                                              CopyClose_Sample.mq5|
//+------------------------------------------------------------------+
void OnTick()
{
    // 終値を格納するための動的配列
    double closePrices[];

    // 配列を時系列順(インデックス0が最新)に設定
    // これを行わないと、配列[0]が最も古いデータになってしまいます
    ArraySetAsSeries(closePrices, true);

    // データのコピー(最新の足[0]から3本分取得)
    // 戻り値には実際にコピーされた個数が入る
    int copied = CopyClose(_Symbol, _Period, 0, 3, closePrices);

    // エラーチェック:3本分のデータが正しく取得できたか確認
    if(copied < 3)
    {
        Print("データの取得に失敗しました。エラーコード: ", GetLastError());
        return;
    }

    // 各足の終値を取得(ArraySetAsSeriesにより直感的なインデックス操作が可能)
    double currentClose = closePrices[0]; // 現在動いている足の終値
    double lastClose    = closePrices[1]; // 1本前に確定した足の終値
    double prevClose    = closePrices[2]; // 2本前に確定した足の終値

    // ロジック例:1本前の足がその前の足より高値で終わった場合
    if(lastClose > prevClose)
    {
        Print("上昇トレンドの兆し: 1本前(", lastClose, ") > 2本前(", prevClose, ")");
        // ここにエントリー処理などを記述
    }
}

4. 使用上の注意点とよくあるエラー

  1. ArraySetAsSeries(true) の忘れ
    デフォルトの配列は、古いデータがインデックス0、新しいデータが大きなインデックスになります。チャートの右側(最新)を0として扱いたい場合は、必ず ArraySetAsSeries でフラグを立てる必要があります。これを忘れると、インデックス[1]を参照したつもりが「大昔の価格」を参照してしまうミスが起こります。

  2. 動的配列の使用
    CopyClose に渡す配列は、サイズを指定しない動的配列(double closePrices[];)として宣言してください。関数側が自動でリサイズしてくれます。

  3. ヒストリーデータの未ロード
    EAを起動した直後や、普段使っていない時間足を指定した場合、MT5のターミナルにデータが届いておらず、CopyClose が失敗することがあります。特にマルチタイムフレーム分析を行う際は、データの準備ができるまでループや待機処理を入れるなどの工夫が必要です。

  4. バーの数不足
    count に10000を指定しても、チャート上に500本しかデータがなければ、戻り値は500になります。常に「戻り値(取得できた数)」を確認する癖をつけましょう。

5. 【重要】自動売買における約定スピードと環境の罠

プロのクオンツエンジニアの視点から断言しますが、CopyClose でどんなに完璧なロジックを組んだとしても、実行環境が「自宅PC」であれば、その優位性はネットワーク遅延(レイテンシ)によって容易に打ち消されます。家庭用インターネット回線は数多くのノードを経由するため、数ミリ秒〜数十ミリ秒の遅延がランダムに発生します。この遅延は、急変時のスリッページや約定拒否を招き、バックテストでは利益が出ていたロジックを実運用で赤字に変えてしまうほど致命的です。

機関投資家やプロのアルゴリズムトレーダーは、取引サーバーとの物理的な距離が極限まで近い専用のVPS(仮想専用サーバー)を利用するのが常識です。サーバー近接環境であれば、ネットワークのホップ数を最小限に抑え、ミリ秒単位での超高速な注文執行が可能になります。自動売買を「趣味」ではなく「投資」として成立させるのであれば、24時間安定稼働し、かつ極小のレイテンシを担保できる専用VPSの導入は、手法の開発以前にクリアすべき最低条件と言えます。

💡 この記事の内容を実運用で活かすには?

この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント

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