MQL5 OnInitの役割と初期化失敗の確認
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_INCORRECT | inputパラメータ不正 | 期間、ロット、閾値、モード指定など、設定値が仕様上不正な時 |
どの戻り値を使う場合でも、戻す前に理由付きログを出してください。戻り値だけでは、あとから原因を追いにくくなります。
OnInitで確認すべき項目
OnInitでは、EAが動き始める前に必要な前提を確認します。
すべてをOnInitへ詰め込む必要はありませんが、起動後に必ず必要になるものは、初期化時に確認しておくと安全です。
| 確認項目 | 確認内容 | 失敗時の扱い |
|---|---|---|
| EA version | どの版が起動しているか | ログへ出力する |
| symbol / period | 対象銘柄と時間足 | 想定外なら警告または停止 |
| input値 | 期間、ロット、閾値、ON/OFF、Magic Numberなど | 不正ならINIT_PARAMETERS_INCORRECT |
| indicator handle | iMA、iATR、iRSI、iCustomなど | 必須handle失敗ならINIT_FAILED |
| symbol spec | point、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_OK | input確認OK | 主要inputの要約 |
| INIT_INPUT_NG | input確認NG | 項目名、値、理由 |
| INIT_HANDLE_OK | handle生成OK | handle名、handle番号 |
| INIT_HANDLE_NG | handle生成NG | handle名、symbol、period、last_error |
| INIT_SYMBOL_SPEC_OK | 銘柄仕様確認OK | point、digits、volume step、stop level |
| INIT_FAILED | 初期化失敗 | 停止理由、return code、確認箇所 |
| INIT_OK | 初期化成功 | EAが稼働準備完了したこと |
ログ名を固定しておくと、問い合わせ時やバックテスト時に、どの段階まで初期化できたかを確認しやすくなります。
EAが起動しない時の確認手順
EAが起動しない場合は、OnInitだけでなく、MT5側の設定、コンパイル状態、チャート設定、Expertsログ、Journalログも確認します。
| 順番 | 確認内容 | 確認場所 |
|---|---|---|
| 1 | コンパイルエラーがないか | MetaEditor |
| 2 | EAがチャートへセットされているか | MT5チャート |
| 3 | OnInitのINIT_STARTログが出ているか | Expertsログ |
| 4 | INIT_FAILEDやINIT_INPUT_NGが出ていないか | Expertsログ |
| 5 | indicator 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ログをまとめて確認してください。
まとめ
OnInitは、EAやインジケーターが動き始める前に、input、indicator handle、銘柄仕様、内部状態、ログ設定などを初期化する重要なイベント関数です。
EAが起動しない、チャートへセットしても動かない、CopyBufferで値が取れない、設定変更後に止まるといった問題は、OnInitのログを確認すると原因を追いやすくなります。
OnInitでは、成功時にINIT_SUCCEEDED、設定不正時にINIT_PARAMETERS_INCORRECT、致命的な初期化失敗時にINIT_FAILEDを返し、必ず理由付きログを残してください。
初期化処理と売買判定、注文処理、終了処理を分けておくと、EAの導入確認、不具合調査、バックテスト、実運用前確認が進めやすくなります。
