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

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

MT5(MetaTrader 5)における開発で、ローソク足(OHLC)データだけでは不可能な精密な分析を行うために必須となるのが「ティックデータ」の取得です。CopyTicksRange関数は、指定した期間内(開始時刻から終了時刻まで)のティックデータを一括で取得するための関数です。

実務での活用シーン:
* スプレッドの動的解析: 特定の時間帯や経済指標発表時にスプレッドがどう拡大したかをミリ秒単位で分析する。
* 独自のティックチャート作成: 100ティックごとにバーを作る「ティック足」インジケーターの開発。
* 約定能力の検証: 自身のEA(エキスパートアドバイザー)が指示した価格と、実際に市場で提示されていた価格の乖離(スリッページ)を後から照合する。

多くの開発者が最初につまずくポイントは、「ミリ秒(ms)単位の指定」「データ量の膨大さ」です。通常のdatetime型(秒単位)ではなくlong型のミリ秒で指定する必要があるため、計算ミスにより「データが1件も取れない」という事態が頻発します。また、数日分のティックは数万〜数十万件に及ぶため、メモリ管理を意識したコード設計が求められます。

2. 構文と戻り値

CopyTicksRange関数の基本的な構文は以下の通りです。

int  CopyTicksRange(
   string           symbol_name,      // 通貨ペア名
   MqlTick&         ticks_array[],    // データを格納する配列
   uint             flags,            // 取得データの種類
   ulong            from_msc,         // 開始時刻(ミリ秒)
   ulong            to_msc=0          // 終了時刻(ミリ秒)
   );

パラメーターの解説

  1. symbol_name: “USDJPY”などの銘柄名。Symbol()_Symbolを指定することが一般的です。
  2. ticks_array[]: MqlTick構造体の動的配列を渡します。関数実行後にここにデータが格納されます。
  3. flags: 取得する情報の種類を指定します。
    • COPY_TICKS_ALL: 全てのティック(価格変更、スプレッド変更など全て)。
    • COPY_TICKS_INFO: Bid/Askの変化のみ。
    • COPY_TICKS_TRADE: 約定(Last価格)の変化のみ。
  4. from_msc: 取得開始時間をミリ秒単位で指定。
  5. to_msc: 取得終了時間をミリ秒単位で指定。0を指定すると「現在まで」となります。

戻り値

  • 成功した場合:取得できたティックの個数を返します。
  • 失敗した場合:-1を返します。詳細なエラーはGetLastError()で確認します。

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

以下は、過去1時間のティックデータを取得し、その間の最大スプレッドと平均スプレッドを算出する実用的なサンプルコードです。

void OnStart()
{
   MqlTick tick_array[]; // データを格納する配列

   // 1. 取得範囲の設定(現在から1時間前まで)
   // TimeCurrent()は秒単位なので、1000倍してミリ秒に変換する
   ulong to_msc = TimeCurrent() * 1000;
   ulong from_msc = to_msc - (1 * 60 * 60 * 1000); // 1時間前

   // 2. ティックデータの取得
   // symbol: 現在のチャート銘柄, flags: 全てのティック情報を取得
   int copied = CopyTicksRange(_Symbol, tick_array, COPY_TICKS_ALL, from_msc, to_msc);

   if(copied > 0)
   {
      PrintFormat("%d 件のティックを取得しました。", copied);

      double max_spread = 0;
      double spread_sum = 0;

      for(int i = 0; i < copied; i++)
      {
         // 各ティックのスプレッドを計算(Ask - Bid)
         double current_spread = tick_array[i].ask - tick_array[i].bid;

         spread_sum += current_spread;
         if(current_spread > max_spread) max_spread = current_spread;
      }

      double avg_spread = spread_sum / copied;
      double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);

      // 結果をログ出力(ポイント換算)
      PrintFormat("最大スプレッド: %.1f points", max_spread / point);
      PrintFormat("平均スプレッド: %.1f points", avg_spread / point);
   }
   else
   {
      Print("ティックデータの取得に失敗しました。エラーコード:", GetLastError());
   }
}

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

  1. ミリ秒単位の計算ミス
    MQL5のdatetime型は1970年からの「秒数」です。CopyTicksRangeで使うには必ず1000倍してulong型にする必要があります。これを忘れると、1970年付近のデータを参照しにいこうとしてデータが空になります。
  2. 配列のオーバーフローとメモリ消費
    数週間分などの広範囲を一度に取得しようとすると、配列が巨大になり、ターミナルやPCの動作が著しく重くなる(またはクラッシュする)ことがあります。数万件を超える場合は、期間を分割してループ処理で取得するなどの工夫が必要です。
  3. 「0」件の戻り値
    エラーではないものの、指定した範囲にティックが存在しない(土日や市場休止時間など)場合は戻り値が0になります。必ずif(copied > 0)のチェックを入れてから配列にアクセスしてください。
  4. 初回実行時の同期遅延
    MT5サーバーからデータをダウンロードする必要がある場合、初回実行時は即座にデータが返ってこないことがあります。数回リトライするか、Waitを入れる処理が必要になるケースがあります。

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

アルゴリズムトレードにおいて、CopyTicksRangeで高度な分析ロジックを組んだとしても、その実行環境が「自宅のPC」であれば、その努力は水の泡になる危険性があります。FXの世界では1ミリ秒の遅延が、本来得られるはずだった利益をスリッページという形で奪い去ります。一般家庭のネットワーク回線は、プロバイダや宅内ルーターを経由することで数十〜数百ミリ秒のレイテンシ(遅延)が発生しており、これはHFT(高周波取引)に近いシストレにおいては致命的な欠陥です。

プロのクオンツエンジニアが共通して推奨するのは、証券会社のサーバーに物理的に近いデータセンターに設置された「専用VPS(仮想専用サーバー)」の利用です。VPSを利用することで、ネットワーク遅延を1ミリ秒以下に抑え、PCの電源落ちやフリーズという物理リスクも排除できます。極限まで約定スピードを高めることこそが、戦略の優位性(エッジ)を守るための唯一のインフラ投資と言えるでしょう。

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

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

コメント

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