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

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

MQL5におけるCopyTicksは、指定した銘柄のティックデータ(価格の最小変動単位の履歴)を取得するための極めて重要な関数です。MQL4ではティック履歴の取得が困難でしたが、MQL5ではこの関数により、過去のBid、Ask、Last価格、そしてそれらに付随するフラグ(価格が変化したのか、取引が発生したのか等)を構造体配列として一括取得できるようになりました。

実務での活用シーン

実務開発において、CopyTicksは以下のような場面で不可欠です。
* 高精度なテクニカル計算: ローソク足(OHLC)だけでは見えない、スプレッドの急拡大や一瞬の価格の飛びを検知する。
* ティックベースのインジケーター作成: ティックボリュームの推移や、買い注文・売り注文の勢い(Last価格の動き)を可視化する。
* 約定能力の分析: 自身のバックテストやフォワードテストにおいて、どの程度のスリッページが発生し得るかをティック単位で検証する。

初心者がつまずきやすいポイントは、「ティックデータは非常に重い」という点です。1分間に数百〜数千ティック発生することもあるため、安易に大量のデータを毎回呼び出すと、PCのリソースを食いつぶし、プラットフォーム全体の動作を重くする原因になります。


2. 構文と戻り値

CopyTicks関数の基本構文は以下の通りです。

int CopyTicks(
   string           symbol_name,           // 銘柄名
   MqlTick&         ticks_array[],         // データを格納するMqlTick構造体配列
   uint             flags = COPY_TICKS_ALL, // 取得するデータの種類
   ulong            from = 0,              // 開始日時(ミリ秒単位)
   uint             count = 0              // 取得するティック数
);

パラメーター解説

  1. symbol_name: 取得したい通貨ペアなどの銘柄名を指定します。
  2. ticks_array[]: MqlTick型の動的配列を渡します。関数実行後、この配列にデータが格納されます。
  3. flags: 取得する情報の種類を指定します。
    • COPY_TICKS_ALL: 全てのティック情報を取得。
    • COPY_TICKS_INFO: Bid/Askの変化のみ取得。
    • COPY_TICKS_TRADE: 取引(Last/Volume)の変化のみ取得。
  4. from: 取得開始時間を1970年1月1日からの経過ミリ秒数で指定します。0を指定すると、直近のデータからcount分遡ります。
  5. count: 取得したいティックの個数を指定します。

戻り値

  • 成功した場合:配列にコピーされたティックの個数を返します。
  • 失敗した場合:-1を返します。エラーの詳細はGetLastError()で確認します。

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

以下のサンプルコードは、最新の100ティックを取得し、その間の「平均スプレッド」を算出する実用的なEAの一部です。

//+------------------------------------------------------------------+
//|                                              TickAnalyzer_Sample |
//+------------------------------------------------------------------+
void OnTick()
{
    // ティックデータを格納する動的配列
    MqlTick tick_array[];

    // 直近100ティックを取得
    // 第3引数にCOPY_TICKS_ALL、第4引数に0(現在)、第5引数に100を指定
    int copied = CopyTicks(_Symbol, tick_array, COPY_TICKS_ALL, 0, 100);

    // データの取得に失敗した場合はログを出力して終了
    if(copied == -1)
    {
        Print("ティックデータの取得に失敗しました。エラーコード: ", GetLastError());
        return;
    }

    // 取得したティックから平均スプレッドを計算
    double total_spread = 0;
    for(int i = 0; i < copied; i++)
    {
        // Ask - Bid でその瞬間のスプレッドを算出
        double spread = tick_array[i].ask - tick_array[i].bid;
        total_spread += spread;
    }

    double avg_spread = (copied > 0) ? (total_spread / copied) : 0;

    // 小数点以下の桁数を調整して表示
    int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
    Comment("直近100ティックの平均スプレッド: ", DoubleToString(avg_spread, digits));
}

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

  1. メモリ管理の罠: CopyTicksを呼び出すたびに巨大な配列を確保すると、メモリ不足に陥ります。特にOnTick()内で何万ティックも取得する設計は避けてください。必要な分だけを差分取得するのがクオンツの基本です。
  2. 同期の遅延: 初めて特定の銘柄や期間のティックを呼び出す際、ターミナルがサーバーからデータをダウンロードするため、初回呼び出し時に時間がかかったり、0件(空の配列)が返されたりすることがあります。
  3. ミリ秒単位の指定: 第4引数のfromは、通常のdatetime(秒単位)ではなく、ミリ秒単位であることに注意が必要です。
  4. flagsの選択ミス: 注文執行の判定に使うならCOPY_TICKS_TRADEが適切ですが、スプレッド監視ならCOPY_TICKS_INFOの方が効率的です。用途に合わせてフラグを最適化しましょう。

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

ティックデータを秒単位、あるいはミリ秒単位で解析してトレードを行うエンジニアにとって、最大の敵は「ネットワークレイテンシ(遅延)」です。自宅のPC環境から一般的なインターネット回線を通じて注文を出す場合、物理的な距離やプロバイダーの混雑により、数ミリ秒から数百ミリ秒の遅延が必ず発生します。この一瞬の遅れにより、CopyTicksで検知した絶好のエントリータイミングは既に過去のものとなり、結果として意図しない不利な価格での約定(スリッページ)を招きます。

どれほど洗練されたアルゴリズムを組み上げたとしても、実行環境が貧弱であれば、その優位性は全てスリッページによって相殺されてしまいます。プロのクオンツや専業トレーダーにとって、ブローカーのデータセンターに物理的に近い場所にある「専用VPS」の導入はオプションではなく、必須のインフラ投資です。安定した電力、強固なネットワーク、そして極限まで短縮された注文伝達スピードを確保することこそが、システムトレードにおける真の勝敗を分ける境界線となります。

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

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

コメント

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