こんにちは、潤奈です( ゚Д゚)!
前回の記事でMQL5の開発環境が整ったら、次はいよいよMQL5プログラムの骨組みとなる「3大イベントハンドラ(関数)」について学んでいきましょう!
「EAの自作を始めてみたけれど、チャートに変なテキストやラインが残り続けて消えない…」
「時間足を変更したらEAの表示が一瞬消えてチラつく…」
「MQL4で書いたコードをMQL5に書き直したら、最初の関数の書き方からエラーが出る…」
と悩んでいませんか?
これらは、EAプログラミングの骨組みである「OnInit, OnTick, OnDeinit」の役割分担や、MQL4とMQL5の仕様の違いを正しく理解していないことが原因です。
今回は、MQL5でEAを作る上で絶対に欠かせないこの3大基本関数の役割と、MQL4からMQL5へ移行する際に「絶対に間違えてはいけない違い」について分かりやすく解説します!
1. MQL5プログラムのライフサイクル(実行順序)
EAがチャートにセットされてから外されるまで、プログラムは特定のタイミングで決まった関数を自動的に呼び出します。これを「ライフサイクル」と呼びます。
graph TD
A[EAをチャートにセット_起動] --> B[OnInit_初期設定とチェック]
B --> C{初期設定は成功?}
C -->|Yes| D[OnTick_メイン処理]
C -->|No| F[OnDeinit_クリーンアップ]
D --> E[EAをチャートから取り外し_終了]
E --> F
F --> G[EAの完全停止]
- 起動時(初期化): EAがチャートにロードされた際、
OnInit()が1回だけ実行されます。 - 価格変動時(メイン処理): チャートの価格が動く(最新のティックを受信する)たびに、
OnTick()が繰り返し実行されます。 - 終了時(後片付け): EAがチャートから取り外されたり、設定が変更されたりした際、
OnDeinit()が1回だけ実行されます。
2. 3大関数の役割とMQL4との違い
ここからは、それぞれの関数の具体的な役割と、MQL4とMQL5の書き方の違いをコード例を交えて解説します。
① OnInit():初期設定とパラメータのチェック
OnInit は、EAが動き始める前に「準備運動(ウォームアップ)」をする場所です。
- 主な役割:
- ユーザーが入力したパラメータ(ロット数やスプレッド制限など)が正常な範囲かチェックする
- チャート上に情報パネル(ボタンやテキストなどのオブジェクト)を初期描画する
- テクニカル指標(インジケーター)の初期化やハンドルの取得
⚠️ MQL4(旧形式)との違い
昔のMQL4の古いコード形式では、戻り値のない void init() が使われていましたが、現在のMQL4やMQL5では戻り値が int 型 に厳密に制限されています。
初期化の結果を整数で返す必要があり、それによってEAの動作をコントロールします。
INIT_SUCCEEDED(0): 初期化成功。そのままOnTickの監視に移ります。INIT_PARAMETERS_INCORRECT: パラメーター設定がおかしい等の理由で初期化失敗。EAの起動を即座に中断し、チャートからEAを自動で取り外します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// MQL5でのOnInitの書き方 int OnInit() { // パラメーターチェックの例 if(MaxSpread <= 0) { Alert("エラー: スプレッド設定値が不正です。"); return(INIT_PARAMETERS_INCORRECT); // 起動を中止して自動取り外し } Print("EAの初期化が成功しました!"); return(INIT_SUCCEEDED); // 正常起動 } |
② OnTick():取引判断とポジションの監視
OnTick は、EAの「頭脳であり心臓部(メインロジック)」です。
- 主な役割:
- 最新のテクニカル指標の計算(移動平均線やRSIなど)
- エントリー(注文)や決済のシグナル判定
- トレーリングストップなどの保有ポジション制御
⚠️ MQL4(旧形式)との違い
昔のMQL4の古い形式では start() 関数が使われていましたが、現在のMQL4やMQL5では OnTick() に移行・統一されました。
さらに大きな違いは、価格データ(Ask / Bid)やローソク足データの取得方法です。
MQL4では Ask や Bid と書くだけで現在の価格が取得できましたが、MQL5ではより正確なデータを取得するために、関数を使って安全にデータを取得する必要があります。
|
1 2 3 4 5 6 7 8 9 |
// MQL5でのOnTickの書き方 void OnTick() { // 現在のAsk/Bid価格を取得する(MQL5では関数を用いて安全に取得します) double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK); double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID); // ここにエントリーや決済の処理を記述します } |
③ OnDeinit():チャート上の「ゴミ掃除」
OnDeinit は、EAが仕事を終えた後に「後片付け(クリーンアップ)」をする場所です。
- 主な役割:
OnInitやOnTickで描画したオブジェクト(ボタン、ラベル、矢印ラインなど)をチャートから消す- プログラムが確保したメモリやリソースの解放
⚠️ MQL4とMQL5の違い
関数の書き方はほぼ同じですが、MQL5ではEAが取り外された「理由コード(DeinitReason)」がより整理されています。この理由は引数である const int reason に自動で渡されます。
REASON_REMOVE(1): EAがチャートから手動で取り外されたときREASON_RECOMPILE(2): コードを変更してメタエディタで再コンパイルされたときREASON_CHARTCHANGE(5): チャートの時間足や通貨ペアが変更されたとき
|
1 2 3 4 5 6 7 8 9 |
// MQL5でのOnDeinitの書き方 void OnDeinit(const int reason) { // 作成したオブジェクトを一括削除する // "MyEA_" というプレフィックス(接頭辞)で始まるオブジェクトのみ削除 ObjectsDeleteAll(0, "MyEA_"); Print("EAが取り外されました。理由コード: ", reason); } |
「手動で引いたライン」を消さないための超重要ポイント!
ObjectsDeleteAll(0)とだけ書くと、EAが描画したオブジェクトだけでなく、あなたが手動でチャート上に分析のために引いた水平線やトレンドラインまですべて消えてしまいます。
これを防ぐために、EAでオブジェクトを作る際は必ず名前にMyEA_lineなどの特定の接頭辞を付け、削除時はObjectsDeleteAll(0, "MyEA_")のように接頭辞を指定して消すようにしましょう。
3. 応用テクニック:時間足変更時の「チラつき」を防ぐ
OnDeinit は、チャートの時間足(例: 1時間足から15分足)を切り替えた際にも実行されます。
このとき、ただ単にオブジェクトを全部消してしまうと、切り替えるたびに画面の情報パネルが一瞬消えて再描画される「チラつき」が発生します。
これを防ぐために、引数の reason を使って「時間足変更の時はオブジェクトを削除しない」という賢い制御が可能です。
|
1 2 3 4 5 6 7 8 9 |
void OnDeinit(const int reason) { // 時間足変更(REASON_CHARTCHANGE)以外の理由で取り外された場合のみ、オブジェクトを消す if(reason != REASON_CHARTCHANGE) { ObjectsDeleteAll(0, "MyEA_"); Print("オブジェクトを完全にクリーンアップしました。"); } } |
この少しの工夫で、時間足を切り替えてもEAのUI表示が消えず、非常に滑らかでプロっぽい仕上がりになります!
チラつき防止を使う場合の注意点
時間足変更時にオブジェクトを残す場合、新しい時間足のOnInit()が再度実行されます。
もしOnInit()側でオブジェクトを作る際に「すでに存在するかどうか」のチェックや上書き対応をしていないと、オブジェクト作成エラーが発生したり、バグの原因になります。OnInit()側でオブジェクトを生成するコードには、「すでに同名のオブジェクトが存在する場合は作成をスキップし、プロパティの更新(上書き)のみ行う」ような処理を入れておきましょう!
4. まとめ&次のステップ
今回はMQL5プログラミングの基礎である、3大イベントハンドラについて解説しました。
OnInit: 起動時に1回実行。MQL5では戻り値は厳密にint型。OnTick: ティック毎に繰り返し実行。価格やローソク足は取得関数を使用。OnDeinit: 終了時に1回実行。理由コードreasonに応じた処理やオブジェクトのゴミ残し防止が重要。
基本構造が理解できたら、次は実際に自動で新規注文を出す方法(MQL5ならではの標準ライブラリ CTrade の使い方)を学んでいきましょう!
分からない部分やエラーが出る箇所があれば、YouTubeのコメント欄やXでお気軽にメッセージをくださいね!


コメント