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

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

MQL5のCopyTime関数は、特定の通貨ペアや時間足における「ローソク足の開始時間(datetime型)」を取得し、配列に格納するための非常に重要な関数です。

実務レベルの開発において、この関数は主に以下の2つの用途で多用されます。

  1. 新しいローソク足(確定足)の発生検知
    「新しい足が形成された瞬間にエントリーする」といったロジックを組む際、直前のバーの開始時間と現在の開始時間を比較するために必須となります。
  2. マルチタイムフレーム(MTF)分析
    例えば、15分足のEAを稼働させながら、1時間足や日足の開始時間を参照してトレンドの方向性を確認する場合などに使用します。

初心者の方は「iTime関数を使えばいいのでは?」と思いがちですが、MQL5ではCopyTimeのように「必要な要素数をまとめて配列にコピーする」手法が推奨されています。これは、ループ処理内での呼び出し回数を減らし、バックテストや最適化の実行速度を劇的に向上させるためです。

2. 構文と戻り値

CopyTime関数には、取得方法の違いにより3つのオーバーロード(引数のパターン)が存在しますが、実務で最も使われる「開始位置と個数を指定する形式」を中心に解説します。

基本構文

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

戻り値

  • 成功時:コピーされた要素の数(int型)を返します。
  • 失敗時:-1 を返します。データが準備できていない場合や、指定した範囲が履歴データ外の場合に発生します。

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

以下は、最も実用的な「新しいローソク足の確定を検知して処理を行う」EAのテンプレートです。

//+------------------------------------------------------------------+
//|                                              NewBarDetector.mq5  |
//+------------------------------------------------------------------+
#property strict

// 直前のバーの開始時間を保持するグローバル変数
datetime prev_time = 0;

void OnTick()
{
   // 最新の1本分の開始時間を格納する配列
   datetime time_buffer[];

   // 配列を時系列(最新がインデックス0)に設定
   ArraySetAsSeries(time_buffer, true);

   // 最新のバー(インデックス0)から1本分だけ取得
   if(CopyTime(_Symbol, _Period, 0, 1, time_buffer) > 0)
   {
      datetime current_bar_time = time_buffer[0];

      // 前回の保存時間と比較し、異なれば「新しい足」と判断
      if(current_bar_time != prev_time)
      {
         Print("新しい足が発生しました: ", TimeToString(current_bar_time));

         // --- ここにエントリーやインジケーター計算のロジックを記述 ---

         // 現在の時間を次回の比較用に保存
         prev_time = current_bar_time;
      }
   }
   else
   {
      // データの取得に失敗した場合のエラー処理
      Print("データの取得に失敗しました。エラーコード: ", GetLastError());
   }
}

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

開発時につまずきやすいポイントを整理しました。

  • 動的配列の宣言とサイズ設定
    コピー先の配列(例:time_buffer[])は、必ず動的配列として宣言してください。CopyTimeは実行時に自動的に配列サイズをリサイズしてくれますが、固定長配列(例:datetime time_buffer[10])を指定すると、取得件数が合わない場合にエラーとなります。
  • データの未同期(ERR_HISTORY_NOT_FOUND)
    MT5の起動直後や、初めて別の時間足を呼び出す際、履歴データがサーバーからダウンロードされていないと-1を返します。実戦用EAでは、戻り値が-1の場合に「データ準備中」として処理をスキップするエラーハンドリングが必須です。
  • ArraySetAsSeriesの有無
    MQL5のデフォルトでは、配列のインデックス0は「最も古いデータ」を指します。MT4と同じ感覚で「0番目=最新の足」として扱いたい場合は、必ずArraySetAsSeries(array, true)を実行してください。

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

アルゴリズム取引において、CopyTimeでいかに正確なシグナルを検知したとしても、その後の「注文実行スピード」が遅ければ全てが無意味になります。一般的な家庭用インターネット回線やPC環境では、プロバイダー経由の複雑な経路によるネットワーク遅延(レイテンシ)が避けられず、ミリ秒単位の不利な約定(スリッページ)を招きます。これは特に、ボラティリティが高い局面でのトレンドフォローやスキャルピングにおいて、致命的な損失要因となります。

このリスクを排除し、ロジック通りのパフォーマンスを発揮させるためには、ブローカーの取引サーバーに物理的に近いデータセンターに設置された「専用VPS」の導入が不可欠です。低遅延なネットワーク環境でEAを24時間稼働させることは、もはや単なる利便性の追求ではなく、クオンツエンジニアとして市場を生き抜くための最低限のインフラ投資と言えます。自宅PCでの運用によるネットワークの瞬断やWindowsアップデートによる再起動リスクを考慮すれば、VPSの利用は最も合理的かつ安価なリスク管理手法なのです。

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

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

コメント

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