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

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

MQL5におけるOnDeinitは、EA(エキスパートアドバイザー)、インジケーター、またはスクリプトがチャートから削除されたり、設定が変更されたりする際に自動的に呼び出される「終了時イベントハンドラ」です。

実務開発において、初心者が最もつまずきやすいのが「後片付け」の放置です。例えば、EAがチャート上に描画したボタンやラベル、あるいは計算用のテンポラリファイルなどをそのままにしておくと、次にEAを起動した際や、別のインジケーターを入れた際に表示が重なったり、メモリリークのような予期せぬ挙動を引き起こしたりします。

OnDeinitを活用する最大のメリットは、プログラムの「状態の保存」と「クリーンアップ」です。
オブジェクトの削除: チャートを元の綺麗な状態に戻す。
データの保存: 取引統計や変数の値をファイルやグローバル変数に書き出し、次回起動時に引き継ぐ。
リソースの解放: オープンしたままのファイルハンドルを閉じる。

プロのクオンツエンジニアは、OnDeinitを「単なる終了処理」ではなく、「次のトレードサイクルへの橋渡し」として極めて重要視します。

2. 構文と戻り値

OnDeinit関数の構造は非常にシンプルです。戻り値はなく、終了の理由を示す引数を一つ受け取ります。

void OnDeinit(const int reason)
{
   // ここに終了処理を記述
}

パラメーター

  • reason (const int):
    プログラムが終了した理由を示す「初期化解除理由コード」です。MQL5には、なぜ終了したのかを判別するための定数が用意されています。
  • REASON_PROGRAM: EAが手動で削除された
  • REASON_PARAMETERS: パラメーターが変更された
  • REASON_CHARTCHANGE: 通貨ペアや時間足が変更された
  • REASON_CHARTCLOSE: チャート自体が閉じられた

戻り値

  • void: 戻り値はありません。

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

以下は、EAの実行中にチャートへラベルを表示し、終了時にその理由をログに出力しながらラベルを綺麗に削除する、実戦的なサンプルコードです。

//+------------------------------------------------------------------+
//|                                              SampleOnDeinit.mq5  |
//|                                  Copyright 2024, Quant Engineer  |
//+------------------------------------------------------------------+
#property strict

//--- グローバル変数
string labelName = "TradeStatusLabel";

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // チャート上にステータス表示用のラベルを作成
   ObjectCreate(0, labelName, OBJ_LABEL, 0, 0, 0);
   ObjectSetString(0, labelName, OBJPROP_TEXT, "EA稼働中...");
   ObjectSetInteger(0, labelName, OBJPROP_XDISTANCE, 20);
   ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, 20);

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // 1. チャート上のオブジェクトを削除(クリーンアップ)
   if(ObjectFind(0, labelName) >= 0)
   {
      ObjectDelete(0, labelName);
      Print("オブジェクトを削除しました。");
   }

   // 2. 終了理由をスイッチ文で判定し、ログに残す
   string reasonText;
   switch(reason)
   {
      case REASON_PROGRAM:      reasonText = "ユーザーによってEAが削除されました。"; break;
      case REASON_PARAMETERS:   reasonText = "パラメーターが変更されました。"; break;
      case REASON_CHARTCHANGE:  reasonText = "時間足または通貨ペアが変更されました。"; break;
      case REASON_CHARTCLOSE:   reasonText = "チャートが閉じられました。"; break;
      case REASON_RECOMPILE:    reasonText = "プログラムが再コンパイルされました。"; break;
      case REASON_REMOVE:       reasonText = "スクリプトがチャートから削除されました。"; break;
      default:                  reasonText = "その他の理由で終了しました。"; break;
   }

   Print("Deinit完了。理由: ", reasonText);

   // ここに「現在の収益をファイルに保存する」などの処理を追加することもあります
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // トレードロジック(今回は省略)
}

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

① 実行時間制限(2.5秒の壁)

OnDeinitには実行時間の制限があります。通常、2.5秒以内に処理を終えなければなりません。この時間を超えると、MetaTrader 5(MT5)によって強制終了されます。膨大な計算や重いループ処理、応答の遅い外部サーバーへのWebRequestなどをここに記述するのは避けましょう。

② グローバル変数の寿命

OnDeinitが呼ばれるタイミングは、新しい設定でOnInitが呼ばれる直前です。例えば時間足を変更した場合、OnDeinit(REASON_CHARTCHANGE)が走った直後に、新しい環境でOnInitが走ります。この流れを意識して、変数の初期化順序に注意してください。

③ オブジェクト削除漏れ

OnDeinitでオブジェクトを削除するコードを書かないと、EAを入れ替えるたびに古いグラフィックオブジェクトがチャートに残り続け、MT5の動作が非常に重くなる原因になります。

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

アルゴリズムトレードにおいて、ロジックの優位性と同じくらい重要なのが「実行環境の低レイテンシ(低遅延)」です。多くの開発者が自宅のPCでEAを稼働させようとしますが、これは技術的な観点から非常にリスクが高い行為です。家庭用インターネット回線は、プロバイダーを経由する際のホップ数が多く、ブローカーのサーバーに注文が届くまでに致命的なタイムラグ(ミリ秒単位の遅延)が発生します。

この遅延は、バックテストでは現れない「スリッページ」を誘発し、本来得られるはずの利益を削り取ります。極限まで約定スピードを高め、スリッページによる損失を最小限に抑えるには、ブローカーのデータセンターに近い場所に設置された自動売買専用のVPS(仮想専用サーバー)の利用が不可欠です。24時間365日、安定した電源と超高速ネットワーク環境下で運用することこそが、プロのクオンツとして生き残るための最低条件と言えます。

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

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

コメント

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