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

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

OnTick関数は、MQL5でEA(エキスパートアドバイザー)を開発する際、最も頻繁に使用される「心臓部」となるイベントハンドラです。証券会社のサーバーから新しい価格データ(ティック)が届くたびに、ターミナルによって自動的に呼び出されます。

実務レベルの開発において、OnTickは単に「価格が動いたら動く場所」以上の意味を持ちます。エントリー・エグジットの判定、トレイリングストップの更新、ポジションの監視など、動的なロジックはすべてここに集約されます。

しかし、初心者が最もつまずきやすいのが「ティックごとの処理負荷」と「重複注文」です。1秒間に数回発生することもあるティックすべてに対して重い計算を走らせると、PCの動作が重くなり、約定の遅延を招きます。また、「1本のローソク足で1回だけ取引したい」場合に適切なガードを入れないと、同じローソク足の中で何度も注文を出してしまうといったバグが発生しがちです。プロの開発者は、OnTick内で「今、本当に処理が必要なタイミングか?」を最初に判定するロジックを組み込むのが通例です。

2. 構文と戻り値

OnTick関数の構造は非常にシンプルです。引数はなく、戻り値もありません。

void OnTick()
{
   // ここにティックごとの処理を記述する
}
  • : void(戻り値なし)
  • パラメーター: なし
  • 実行タイミング: 該当する通貨ペアの新しいティックを受信したとき

※注意:OnTickはEAでのみ動作します。カスタムインジケーターではOnCalculateを使用するため、混同しないようにしましょう。

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

以下は、移動平均線(SMA)を使ったシンプルな押し目買いのサンプルです。「新しいローソク足が確定したタイミングで1回だけ判定する」という、実戦で必須のテクニックを盛り込んでいます。

//+------------------------------------------------------------------+
//|                                              SimpleMaExpert.mq5  |
//|                                  Copyright 2023, Quant Engineer  |
//+------------------------------------------------------------------+
#property strict
#include <Trade\Trade.mqh>

// 入力パラメーター
input int      MA_Period = 20;          // 移動平均の期間
CTrade         trade;                   // 取引クラスのインスタンス

// グローバル変数
datetime       last_bar_time;           // 最後に処理したローソク足の時間

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    // --- 1. 新しいローソク足が形成されたかチェック ---
    // ティックごとに判定すると過剰取引になるため、足の変わり目のみ実行
    datetime current_bar_time = iTime(_Symbol, _Period, 0);
    if(current_bar_time == last_bar_time) return; // 同じ足なら何もしない
    last_bar_time = current_bar_time;             // 時間を更新

    // --- 2. 指標データの取得 ---
    double ma_buffer[];
    int handle = iMA(_Symbol, _Period, MA_Period, 0, MODE_SMA, PRICE_CLOSE);

    ArraySetAsSeries(ma_buffer, true);
    if(CopyBuffer(handle, 0, 0, 2, ma_buffer) < 2) return; // データ取得失敗時は抜ける

    double last_close = iClose(_Symbol, _Period, 1); // 1本前の終値
    double current_ma = ma_buffer[1];                // 1本前のMA

    // --- 3. 売買ロジック ---
    // 終値がMAを上抜けていたら買い(ポジションがない場合のみ)
    if(last_close > current_ma && PositionsTotal() == 0)
    {
        double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
        trade.Buy(0.1, _Symbol, ask, 0, 0, "OnTick_Sample");
        Print("買い注文を送信しました: ", ask);
    }
}

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

  1. 市場閉鎖時の挙動: 土日など市場が閉まっている間はティックが発生しないため、OnTickは一切実行されません。週末にロジックのテストをしたい場合は、ストラテジーテスターを活用する必要があります。
  2. 処理の重さ(レイテンシ): OnTickの中で複雑なループ処理や、大量の過去データの解析を行うと、次のティック受信までに処理が終わらず、最新の価格を取りこぼす(スリッページの原因になる)可能性があります。
  3. 複数通貨ペアの監視: OnTickはそのEAをセットした通貨ペアのティックにのみ反応します。他通貨ペアの動きをトリガーにする場合は、自通貨のティックが動いたタイミングで他通貨の価格を参照する等の工夫が必要です。
  4. 計算ミス: 5桁表示の業者と4桁表示の業者で、1ポイントの重みが変わります。_Point_Digitsを適切に使用して、価格計算に汎用性を持たせましょう。

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

アルゴリズムトレードにおいて、ロジックの正確さと同じくらい重要なのが「実行環境」です。多くの初心者は自宅のPCでEAを稼働させようとしますが、これはプロの視点から見ると非常にリスクの高い行為です。一般の家庭用回線では、証券会社のサーバーとの間に数十〜数百ミリ秒の「ネットワーク遅延(レイテンシ)」が発生します。相場が激しく動く局面では、このわずかな遅れが数ピップスのスリッページを招き、期待収益を根こそぎ奪っていきます。

極限まで約定スピードを高め、優位性を確保するためには、証券会社のデータセンターに近い場所に設置された「専用のVPS(仮想専用サーバー)」の利用が不可欠です。24時間安定して稼働し、物理的な距離による遅延を最小限に抑えることで、初めてOnTickによる高速判定がその真価を発揮します。プロのクオンツが自宅PCで本番運用をしないのは、それが技術的な敗北に直結することを知っているからです。

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

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

コメント

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