技術辞典

MQL5 OnInitの役割と初期化失敗の確認

EAファンクラブ

MQL5でEAやインジケーターを作る時、最初に確認したいイベント関数がOnInitです。

OnInitは、EAやインジケーターをチャートへセットした時、inputを変更した時、時間足を変更した時、再コンパイル後などに呼ばれる初期化処理です。

EAが起動しない、チャートにセットしても動かない、インジケーターハンドルが作れない、設定値が不正で止まる、といった問題は、OnInit内の初期化処理やログを確認すると原因を追いやすくなります。

このページでは、MQL5のOnInitの役割、INIT_SUCCEEDED / INIT_FAILED、input validation、indicator handle生成失敗、初期化ログ、EAが起動しない時の確認手順を整理します。

なお、このページはMQL5開発における技術確認を目的とした内容です。売買判断、推奨エントリー、推奨ロット、利益保証、損失回避保証を行うものではありません。

OnInitとは何か

OnInitは、MQL5プログラムの初期化処理を行うイベント関数です。

EAの場合、OnInitでは、input値の確認、インジケーターハンドルの生成、銘柄仕様の取得、タイマー設定、内部状態の初期化、ログ出力などを行います。

処理OnInitで確認する理由
input validationロット、期間、閾値、ON/OFF設定などが不正なまま動かないようにするため
indicator handle生成iMA、iATR、iRSI、iCustomなどのハンドル作成に失敗していないか確認するため
銘柄仕様の取得point、digits、volume step、stop levelなどを確認するため
内部状態の初期化前回状態や未初期化値を混ぜずに起動するため
タイマー設定OnTimerを使うEAで、初期化時にEventSetTimerを設定するため
初期化ログEA名、バージョン、銘柄、時間足、設定状態をExpertsログに残すため

OnInitは、EAが実際の判定や注文処理に入る前の準備段階です。ここで必要な確認を行っておくと、EAが静かに壊れる状態を避けやすくなります。

OnInitが呼ばれるタイミング

OnInitは、チャートへEAやインジケーターをセットした時だけではなく、再初期化が必要なタイミングでも呼ばれます。

タイミング確認したいこと
チャートへセットした時初回起動ログ、input値、handle生成、銘柄仕様
inputを変更した時変更後の設定値で再初期化できるか
時間足を変更した時時間足依存のhandleや状態を作り直せるか
銘柄を変更した時銘柄仕様、point、digits、volume step、取引条件
再コンパイルした時最新コードとして初期化ログが出るか
アカウントを変更した時口座情報、権限、認証、リスク設定の再確認

初期化ログには、symbol、period、account、EA version、input概要、handle生成結果を残しておくと、再初期化時の差分を確認しやすくなります。

int OnInitを使う理由

OnInitには、戻り値なしのvoid型と、戻り値ありのint型があります。

EA開発では、初期化成功・失敗を明確に返せるint OnInitを使う方が、ログ確認や不具合調査に向いています。

int OnInit()
{
   Print("[INIT_START] EA initialization started");

   if(!ValidateInputs())
   {
      Print("[INIT_FAILED] reason=input_validation_failed");
      return INIT_PARAMETERS_INCORRECT;
   }

   if(!CreateIndicatorHandles())
   {
      Print("[INIT_FAILED] reason=indicator_handle_create_failed");
      return INIT_FAILED;
   }

   Print("[INIT_OK] EA initialization succeeded");
   return INIT_SUCCEEDED;
}

初期化に失敗した時は、どの理由で失敗したのかをログに残してから、INIT_FAILEDやINIT_PARAMETERS_INCORRECTを返します。

INIT_SUCCEEDED / INIT_FAILED / INIT_PARAMETERS_INCORRECTの使い分け

OnInitの戻り値は、初期化結果を明確にするために使います。

戻り値意味使う場面
INIT_SUCCEEDED初期化成功input、handle、銘柄仕様、必要な初期化が完了した時
INIT_FAILED初期化失敗必要なindicator handleが作れない、必須ファイルがない、致命的な初期化失敗がある時
INIT_PARAMETERS_INCORRECTinputパラメータ不正期間、ロット、閾値、モード指定など、設定値が仕様上不正な時

どの戻り値を使う場合でも、戻す前に理由付きログを出してください。戻り値だけでは、あとから原因を追いにくくなります。

OnInitで確認すべき項目

OnInitでは、EAが動き始める前に必要な前提を確認します。

すべてをOnInitへ詰め込む必要はありませんが、起動後に必ず必要になるものは、初期化時に確認しておくと安全です。

確認項目確認内容失敗時の扱い
EA versionどの版が起動しているかログへ出力する
symbol / period対象銘柄と時間足想定外なら警告または停止
input値期間、ロット、閾値、ON/OFF、Magic Numberなど不正ならINIT_PARAMETERS_INCORRECT
indicator handleiMA、iATR、iRSI、iCustomなど必須handle失敗ならINIT_FAILED
symbol specpoint、digits、volume step、stop levelなど取得失敗なら停止または該当機能OFF
外部連携設定WebRequest、URL、通知ON/OFFなど売買本体と分けて警告または外部連携OFF
Object / UI状態パネル、ラベル、過去Objectの扱い広範囲削除ではなくstartup auditで確認
ログ設定詳細ログ、簡易ログ、BT用ログ過剰ログにならないように初期化する

特にEAが動かない原因を調査する場合は、OnInitの最初と最後にログを出し、途中のチェックごとにOK / NGを分けると確認しやすくなります。

input validationの例

input validationでは、ユーザーが指定した設定値がEAの前提を壊していないかを確認します。

例えば、期間が0以下、ロットが0以下、最大ポジション数が0、しきい値が範囲外といった状態では、EAを動かしても正常な判定になりません。

input double InpLots = 0.10;
input int    InpMAPeriod = 20;
input int    InpMaxPositions = 1;

bool ValidateInputs()
{
   bool ok = true;

   if(InpLots <= 0.0)
   {
      PrintFormat("[INIT_INPUT_NG] name=InpLots value=%.2f reason=must_be_positive", InpLots);
      ok = false;
   }

   if(InpMAPeriod <= 1)
   {
      PrintFormat("[INIT_INPUT_NG] name=InpMAPeriod value=%d reason=period_too_small", InpMAPeriod);
      ok = false;
   }

   if(InpMaxPositions <= 0)
   {
      PrintFormat("[INIT_INPUT_NG] name=InpMaxPositions value=%d reason=must_be_positive", InpMaxPositions);
      ok = false;
   }

   if(ok)
   {
      PrintFormat("[INIT_INPUT_OK] lots=%.2f ma_period=%d max_positions=%d",
                  InpLots,
                  InpMAPeriod,
                  InpMaxPositions);
   }

   return ok;
}

input validationでは、「推奨値から外れている」状態と「実行不能な不正値」を分けてください。推奨値外は警告、実行不能な不正値は初期化失敗として扱うと確認しやすくなります。

indicator handle生成失敗を確認する

EAでインジケーター値を使う場合、OnInitでindicator handleを生成することが多くあります。

iMA、iATR、iRSI、iCustomなどがINVALID_HANDLEを返している場合、CopyBufferで値を取得できません。必須handleの生成に失敗した場合は、OnInitで止める設計が安全です。

int g_ma_handle = INVALID_HANDLE;
int g_atr_handle = INVALID_HANDLE;

bool CreateIndicatorHandles()
{
   ResetLastError();

   g_ma_handle = iMA(_Symbol, PERIOD_CURRENT, InpMAPeriod, 0, MODE_EMA, PRICE_CLOSE);

   if(g_ma_handle == INVALID_HANDLE)
   {
      PrintFormat("[INIT_HANDLE_NG] name=MA symbol=%s period=%d ma_period=%d last_error=%d",
                  _Symbol,
                  PERIOD_CURRENT,
                  InpMAPeriod,
                  GetLastError());
      return false;
   }

   ResetLastError();

   g_atr_handle = iATR(_Symbol, PERIOD_CURRENT, 14);

   if(g_atr_handle == INVALID_HANDLE)
   {
      PrintFormat("[INIT_HANDLE_NG] name=ATR symbol=%s period=%d atr_period=%d last_error=%d",
                  _Symbol,
                  PERIOD_CURRENT,
                  14,
                  GetLastError());
      return false;
   }

   PrintFormat("[INIT_HANDLE_OK] ma_handle=%d atr_handle=%d",
               g_ma_handle,
               g_atr_handle);

   return true;
}

handle生成失敗時は、どのインジケーター、どの銘柄、どの時間足、どの期間設定で失敗したのかをログに残してください。

銘柄仕様の初期確認

EAが注文処理やリスク管理を行う場合は、OnInitで銘柄仕様を確認しておくと、後続処理のエラーを減らせます。

point、digits、最小ロット、最大ロット、volume step、stop levelなどは、発注前チェックやログ確認で使う基本情報です。

bool PrintSymbolSpecOnInit()
{
   double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
   int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
   double volume_min = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double volume_max = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double volume_step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   long stops_level = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);

   if(point <= 0.0 || volume_min <= 0.0 || volume_step <= 0.0)
   {
      PrintFormat("[INIT_SYMBOL_SPEC_NG] symbol=%s point=%.8f volume_min=%.2f volume_step=%.2f",
                  _Symbol,
                  point,
                  volume_min,
                  volume_step);
      return false;
   }

   PrintFormat("[INIT_SYMBOL_SPEC_OK] symbol=%s digits=%d point=%.8f vol_min=%.2f vol_max=%.2f vol_step=%.2f stops_level=%d",
               _Symbol,
               digits,
               point,
               volume_min,
               volume_max,
               volume_step,
               (int)stops_level);

   return true;
}

銘柄仕様のログは、GOLD / XAUUSD、CFD、suffix付き銘柄、ブローカー差がある環境で特に役立ちます。

初期化ログの設計

OnInitのログは、EAが起動したかどうかを確認する最初の証跡です。

ログが少なすぎると原因を追えず、多すぎると通常運用で確認しづらくなります。初期化ログでは、最低限の項目を固定形式で出すことが重要です。

ログ名意味出力する内容
INIT_START初期化開始EA名、version、symbol、period、account種別
INIT_INPUT_OKinput確認OK主要inputの要約
INIT_INPUT_NGinput確認NG項目名、値、理由
INIT_HANDLE_OKhandle生成OKhandle名、handle番号
INIT_HANDLE_NGhandle生成NGhandle名、symbol、period、last_error
INIT_SYMBOL_SPEC_OK銘柄仕様確認OKpoint、digits、volume step、stop level
INIT_FAILED初期化失敗停止理由、return code、確認箇所
INIT_OK初期化成功EAが稼働準備完了したこと

ログ名を固定しておくと、問い合わせ時やバックテスト時に、どの段階まで初期化できたかを確認しやすくなります。

EAが起動しない時の確認手順

EAが起動しない場合は、OnInitだけでなく、MT5側の設定、コンパイル状態、チャート設定、Expertsログ、Journalログも確認します。

順番確認内容確認場所
1コンパイルエラーがないかMetaEditor
2EAがチャートへセットされているかMT5チャート
3OnInitのINIT_STARTログが出ているかExpertsログ
4INIT_FAILEDやINIT_INPUT_NGが出ていないかExpertsログ
5indicator handle生成に失敗していないかExpertsログ
6自動売買許可やDLL / WebRequest設定が原因ではないかMT5設定、Journalログ
7銘柄・時間足・口座条件が想定と合っているかチャート、Expertsログ
8再セット、時間足変更、input変更後も同じかExpertsログ、Journalログ

EAがチャートにセットされているのに動かない場合は、まずOnInitの開始ログが出ているかを確認してください。INIT_STARTすら出ていない場合は、EAの設置、コンパイル、ファイル配置、MT5側設定を先に確認します。

初期化失敗時のログ例

初期化失敗時は、最後に失敗理由をまとめたログを出すと確認しやすくなります。

[INIT_START] name=SampleEA version=1.000 symbol=GOLD period=15
[INIT_INPUT_OK] lots=0.10 ma_period=20 max_positions=1
[INIT_SYMBOL_SPEC_OK] symbol=GOLD digits=2 point=0.01000000 vol_min=0.01 vol_max=50.00 vol_step=0.01 stops_level=50
[INIT_HANDLE_NG] name=MA symbol=GOLD period=15 ma_period=20 last_error=4802
[INIT_FAILED] reason=indicator_handle_create_failed return=INIT_FAILED

この形式でログを残しておくと、EAが起動しない原因が、input不正なのか、銘柄仕様なのか、handle生成失敗なのかを分けて確認できます。

OnInitに入れすぎない方がよい処理

OnInitは初期化処理ですが、すべての処理をOnInitへ入れるべきではありません。

重い通信処理、長いファイル走査、広範囲のチャートObject削除、tickごとに変わる判定、注文処理などは、責務を分けて扱います。

OnInitに入れすぎない処理理由代替
重いWebRequest初期化が遅くなり、失敗時の切り分けが難しいOnTimerで状態確認、失敗時は外部連携だけOFF
広範囲のObject削除他EAや手動Objectを消す事故につながるprefix管理、startup audit、必要範囲だけ更新
注文処理初期化と売買実行の責務が混ざるOnTickや専用execution処理へ分離
長い最適化処理チャートセット時やBT開始時に重くなる必要最小限の初期化に留める
毎tick必要な判定初期化時の一度だけでは意味がないOnTick、OnTimer、専用関数で実行

OnInitは、EAが動く前提を整える場所です。売買ロジック、決済処理、通知処理、外部連携処理は、初期化と混同しないように分けてください。

OnDeinitとの関係

OnInitで作成したリソースは、必要に応じてOnDeinitで解放します。

ただし、OnDeinitで広範囲のObject削除や重い処理を行うと、時間足変更やEA削除時の不安定要因になることがあります。indicator handleの解放、タイマー解除、必要最小限の終了ログに留める設計が安全です。

void OnDeinit(const int reason)
{
   PrintFormat("[DEINIT] reason=%d", reason);

   if(g_ma_handle != INVALID_HANDLE)
   {
      IndicatorRelease(g_ma_handle);
      g_ma_handle = INVALID_HANDLE;
   }

   if(g_atr_handle != INVALID_HANDLE)
   {
      IndicatorRelease(g_atr_handle);
      g_atr_handle = INVALID_HANDLE;
   }

   EventKillTimer();
}

OnInitで何を作り、OnDeinitで何を解放するのかを分けておくと、時間足変更、再セット、EA削除時の挙動を確認しやすくなります。

OnInit初期化とあわせて確認したい安定化ポイント

OnInitで初期化失敗が起きる場合は、EA全体の初期化処理だけでなく、インジケーターハンドル、CopyBuffer、長時間稼働時のリソース管理もあわせて確認すると原因を切り分けやすくなります。

確認したい内容関連ページ確認ポイント
CopyBuffer取得不良MQL5 CopyBufferで値が取れない原因と確認ポイントhandle生成、BarsCalculated、buffer番号、EMPTY_VALUE、GetLastErrorを確認します。
インジケーターハンドル管理MQL5 CopyBufferとインジケーターハンドル管理を実コードで解説OnInitでのhandle作成、CopyBuffer安全取得、IndicatorReleaseの流れを確認します。
長時間稼働時の安定化MQL5長時間稼働・安定化完全ガイドメモリ、ハンドル、ログ、Object管理を長時間稼働前提で整理します。

関連ページ

OnInitの確認は、EAのイベント構造、ログ確認、EAが動かない時の確認、MQL5開発入門と合わせて確認すると整理しやすくなります。

関連ページ確認できること
MQL5 EAの基本イベント構造を実コードで解説OnInit、OnTick、OnDeinitの責務分離とEAイベント構造
EAが動かない時に見る基本用語自動売買、認証、スプレッド、ログ確認などの基本用語
MQL5開発入門MetaEditor、EA、インジケーター、イベント関数、コンパイルエラーの基本
MQL5デバッグ・ログファースト開発完全ガイドPrint、Expertsログ、再現条件、ログ設計の基本
MT5のログ確認方法|Experts・Journalの見方ExpertsログとJournalログの確認方法
MQL5 EAのObject lifecycleを実コードで解説OnDeinit、Object cleanup、startup audit、終了時処理の考え方

イベント処理全体を確認する場合

OnInitは、EAやインジケーターの起動時に、input確認、初期化、indicator handle生成、timer設定、初期ログ出力などを行うためのイベント関数です。イベント処理全体の役割分担を確認したい場合は、親記事もあわせて確認してください。

確認したいこと確認するページ主な確認内容
MQL5イベント処理の全体を確認したいMQL5イベント処理完全ガイドOnInit、OnTick、OnTimer、OnTradeTransaction、OnChartEventの使い分け
OnInitで設定したTimer処理を確認したいMQL5 OnTimerの使い方EventSetTimer、EventKillTimer、外部連携、通知、状態監視、ログ抑制

OnInitで初期化に失敗した場合は、単に起動できない状態として扱わず、input値、銘柄仕様、indicator handle、Timer設定、WebRequest許可、初期化ログを分けて確認してください。

開発依頼前に整理したい情報

OnInitの初期化失敗やEA起動不具合を相談する場合は、次の情報を整理しておくと確認が進めやすくなります。

整理する情報確認内容
対象EA名EA名、ファイル名、バージョン、mq5 / ex5の有無
発生タイミングチャートセット時、input変更時、時間足変更時、再コンパイル後など
ExpertsログINIT_START、INIT_INPUT_NG、INIT_HANDLE_NG、INIT_FAILEDなど
JournalログMT5側の読み込み、エラー、許可設定、端末状態
input設定setファイル、変更した項目、初期値との差分
対象銘柄・時間足GOLD / XAUUSD、USDJPY、M15、H1など
外部連携有無WebRequest、Discord通知、Google Sheets、認証など
再現手順どの操作をすると初期化失敗になるか

EAの初期化失敗や起動不具合を相談する場合は、エラー行だけではなく、OnInit開始から失敗までのExpertsログをまとめて確認してください。

MT4/MT5の開発・改修相談はこちら

まとめ

OnInitは、EAやインジケーターが動き始める前に、input、indicator handle、銘柄仕様、内部状態、ログ設定などを初期化する重要なイベント関数です。

EAが起動しない、チャートへセットしても動かない、CopyBufferで値が取れない、設定変更後に止まるといった問題は、OnInitのログを確認すると原因を追いやすくなります。

OnInitでは、成功時にINIT_SUCCEEDED、設定不正時にINIT_PARAMETERS_INCORRECT、致命的な初期化失敗時にINIT_FAILEDを返し、必ず理由付きログを残してください。

初期化処理と売買判定、注文処理、終了処理を分けておくと、EAの導入確認、不具合調査、バックテスト、実運用前確認が進めやすくなります。

ABOUT ME
記事URLをコピーしました