技術講座

MQL5イベント処理完全ガイド|OnTimer・OnTradeTransaction・OnChartEventの使い分け

EAファンクラブ

MQL5のEAやインジケーターは、決められたイベントに応じて処理が呼び出されます。代表的なものに、起動時の OnInit、終了時の OnDeinit、新しいティックを受け取る OnTick、一定間隔で処理する OnTimer、取引サーバー側の取引変化を受ける OnTradeTransaction、チャート上のクリックや変更を受ける OnChartEvent があります。

イベント処理を理解すると、EAやインジケーターの処理を整理しやすくなります。特に、すべてを OnTick に詰め込むのではなく、外部制御、認証、通知、UIクリック、取引結果確認、ログ出力、パネル更新などを適切なイベントへ分けると、検証・保守・問い合わせ対応がしやすくなります。

この記事では、MQL5のイベント処理を、EA開発・インジケーター開発・パネルUI・外部連携・ログ確認の実務視点で整理します。売買判断、推奨ロット、特定銘柄、運用成績に関する助言は扱いません。あくまで、MQL5プログラムを安定して設計・確認するための技術講座です。

この記事で扱う範囲

この記事では、MQL5イベント関数の基本的な役割と、実務上の使い分けを扱います。対象は、EA、インジケーター、パネルEA、外部連携EA、通知機能付きツール、長時間稼働する補助ツールです。

主に扱うイベント関数

イベント関数主な用途この記事での重点
OnInit起動時の初期化初期設定、ハンドル作成、timer開始、self-check
OnDeinit終了時の後処理timer停止、軽量cleanup、終了理由の確認
OnTickEAで新しいtickを受ける価格変化に連動する処理、過負荷回避
OnTimer一定間隔の処理外部制御、認証、通知、UIメンテナンス
OnTradeTransaction取引トランザクションの確認注文結果、約定、決済、履歴確認の入口
OnChartEventチャート操作やObjectクリックボタン、パネル、表示切替、チャート変更
OnCalculateインジケーター計算EAのOnTickとの違い

この記事で深く扱わないこと

この記事では、個別の売買ロジック、ロット計算、注文戦略、損益改善手法は扱いません。また、外部API通信そのものの詳細、JSON組み立て、WebRequest許可設定、Google Apps Script側の実装、Discord Webhookの実URLなども扱いません。

イベント関数をどのように分けるか、どのイベントで何を確認するか、どのログを残すか、問い合わせ前にどの情報を整理すべきかに絞って解説します。

MQL5イベント処理の全体像

MQL5では、プログラム側が任意のタイミングで常に動き続けるのではなく、ターミナルから届くイベントに応じて関数が呼び出されます。EAであれば新しいtick、timer、取引イベント、チャートイベントなどを受け取り、インジケーターであれば価格データの再計算やチャートイベントを受け取ります。

重要なのは、イベントごとに向いている処理が違うことです。価格変化に連動する処理は OnTick、一定間隔の監視は OnTimer、取引結果の追跡は OnTradeTransaction、ボタン操作は OnChartEvent、インジケーター計算は OnCalculate というように責務を分けます。

イベント関数比較表

イベント主な対象呼ばれる契機向いている処理注意点
OnInitEA / インジケータープログラム起動時初期化、入力値確認、ハンドル作成失敗時の扱いを明確にする
OnDeinitEA / インジケーター終了・再初期化時timer停止、handle解放、軽量終了処理重いObject走査や広範囲削除は避ける
OnTick主にEA新しいtick受信時価格変化に依存する評価すべての処理を詰め込まない
OnTimerEA / インジケーター設定した周期定期監視、外部制御、軽量メンテナンスtimer開始と停止を管理する
OnTradeTransactionEA取引トランザクション発生時注文・約定・決済結果の追跡処理を重くしすぎない
OnChartEventEA / インジケータークリック、キー操作、チャート変更ボタン、UI、パネル操作Object名と表示文字を混同しない
OnCalculateインジケーター価格データ計算時インジケーター値の計算EAのOnTickとは役割が違う

責務分離で考える

イベント処理では、どのイベントに何を書くかを先に決めます。処理をイベント単位で分けるだけでなく、signal、execution、risk、exit、auth、external control、notification、UI、loggingという責務でも分けます。

責務主に使うイベント補足
初期化OnInit入力値確認、ハンドル作成、timer開始
価格依存処理OnTick新tickで必要な軽量評価
定期監視OnTimer外部制御、認証、UIメンテナンス
取引結果確認OnTradeTransaction注文結果、約定、決済、履歴更新
UI操作OnChartEventボタン、入力欄、表示切替
インジ計算OnCalculateバッファ更新、表示値計算
終了処理OnDeinittimer停止、軽量cleanup

OnInitの役割

OnInit は、EAやインジケーターの起動時に呼ばれる初期化関数です。ここでは、入力値の確認、indicator handleの作成、Object prefixの初期化、Timer開始、初期ログ、self-checkなどを行います。

OnInitは「起動できる状態か」を確認する場所です。設定不備がある場合は、静かに動かし続けるのではなく、何が不足しているかをログやステータスで確認できるようにします。

OnInitに向いている処理

処理目的確認ログ例
input確認無効な設定を早期検出するINIT/CHECK: input=OK
symbol情報取得digits、point、volume step等を確認するINIT/SYMBOL: symbol=…
indicator handle作成MA、ATR等の参照準備INIT/HANDLE: ma=OK
EventSetTimerOnTimerを使う準備INIT/TIMER: sec=1
Object prefix初期化UIやライン名の衝突回避INIT/OBJECT: prefix=…
外部連携準備確認URLやtokenを直接出さず準備状態だけ確認INIT/EXT: configured=Y/N
初期SNAP問い合わせ時の初期状態確認INIT/SUMMARY: status=OK

OnInitの最小例

int OnInit()
{
   Print("INIT: version=1.00 status=START");

   if(!ValidateInputs())
   {
      Print("INIT: status=FAILED reason=INVALID_INPUT");
      return INIT_FAILED;
   }

   EventSetTimer(1);

   Print("INIT: status=OK timer=1sec");
   return INIT_SUCCEEDED;
}

この例では、入力値確認に失敗した場合に INIT_FAILED を返します。実務では、どの項目が不正だったか、どの機能だけ停止したかをログで分けると確認しやすくなります。

OnDeinitの役割

OnDeinit は、EAやインジケーターが終了する時、時間足変更や設定変更などで再初期化される時に呼ばれる終了処理です。timer停止、handle解放、Comment解除、必要最小限のObject整理などを行います。

OnDeinitで重要なのは、見た目の完全cleanupよりも、異常終了しないことを優先する点です。大量のObject走査や広範囲削除をOnDeinitに詰め込むと、チャート状態や環境によって不安定化する場合があります。

OnDeinitで行う処理と避けたい処理

分類処理例方針
行うEventKillTimerOnTimerを使った場合は停止する
行うIndicatorRelease作成したhandleを解放する
行うComment(“”)コメント表示を消す
必要時のみ自EAの一時Object削除prefixと用途を限定する
避ける全Object走査他EAや手動Objectを巻き込む可能性がある
避ける大量削除ループ終了処理が重くなりやすい
避けるtrade系処理終了時に予期しない操作を避ける

OnDeinitの最小例

void OnDeinit(const int reason)
{
   EventKillTimer();
   Comment("");

   Print("DEINIT: reason=", reason, " status=OK");
}

実際には、reasonの内容に応じてログを分けると確認しやすくなります。ただし、終了時に重い処理を行うより、次回起動時のstartup auditで残存Objectを検出・分類する方が安定する場合があります。

OnTickの役割

OnTick は、EAで新しいtickを受け取った時に呼ばれます。価格変化に連動する処理を行う入口です。EAの中心処理として使われることが多い一方で、すべての処理をOnTickへ集めると重くなりやすくなります。

OnTickに向いているのは、価格変化に依存する軽量な確認、現在価格の取得、必要な評価関数の呼び出し、状態変化の検出などです。外部通信、UI全再構築、重いObject走査、長いログ出力は、OnTimerや別helperへ分けることを検討します。

OnTickに置く処理・置かない処理

処理OnTick向きか理由代替先
最新価格の取得向いているtickごとに変わるため
新バー判定向いている軽量でEA制御に使いやすい
signal評価呼び出し条件付きで向いている軽量化・新バー限定が必要Evaluate helper
外部制御取得通常は不向き通信遅延や負荷が出る可能性OnTimer
認証状態の定期確認通常は不向きtick頻度に依存させる必要が薄いOnTimer
通知送信通常は不向きtransport処理を本体評価と分けたいnotification queue / OnTimer
UI全再構築不向きちらつき・描画負荷の原因になるOnChartEvent / OnTimer
全Object走査不向き長時間稼働で重くなりやすいOnTimer / startup audit
大量ログ不向きStrategy Testerや実運用でログ過多になる状態変化時ログ / summary

OnTickを軽く保つ基本形

void OnTick()
{
   UpdateMarketSnapshot();

   if(IsNewBar())
   {
      EvaluateSignalOnNewBar();
   }

   ManageRuntimeStateLight();
}

OnTickでは、処理本体を長く書かず、役割ごとのhelperを呼び出す形にすると確認しやすくなります。実際のEAでは、signal、execution、risk、exit、external controlを分け、ログ上でもどこで止まったか追えるようにします。

OnTimerの役割

OnTimer は、EventSetTimer などで設定した周期に応じて呼ばれるイベント処理です。tickが少ない時間帯でも一定間隔で処理できるため、外部制御、認証確認、通知キュー処理、UIメンテナンス、Object欠損チェック、定期ログに向いています。

OnTimerを使う場合は、OnInitでtimerを開始し、OnDeinitで必ず停止します。timerを使う目的、周期、処理内容、失敗時の扱いを明確にしておくと、長時間稼働時の確認がしやすくなります。

OnTimer利用例表

用途OnTimerに向いている理由確認ログ例
外部制御取得tick頻度に依存しないTIMER/EXTCTRL: state=OK
認証状態確認定期確認しやすいTIMER/AUTH: status=OK
通知キュー処理本体判定とtransportを分けられるTIMER/NOTIFY: sent=1 fail=0
UIメンテナンス毎tick再描画を避けられるTIMER/UI: update=DIFF
Object監査低頻度で十分な場合が多いTIMER/OBJECT: count=…
状態summary一定間隔で現状を記録できるTIMER/SUMMARY: mode=…
長時間稼働監視heartbeat的に状態確認できるTIMER/HEARTBEAT: alive=Y

OnTimerの最小例

int OnInit()
{
   EventSetTimer(5);
   Print("INIT: timer=5sec");
   return INIT_SUCCEEDED;
}

void OnTimer()
{
   RefreshExternalStateIfNeeded();
   ProcessNotificationQueue();
   UpdatePanelIfChanged();
}

void OnDeinit(const int reason)
{
   EventKillTimer();
}

この例では、外部状態確認、通知処理、パネル更新をOnTimer側へ分けています。実務では、それぞれの処理にthrottle、失敗時reason、last-good状態、ログ抑制を持たせると確認しやすくなります。

OnTradeTransactionの役割

OnTradeTransaction は、EAで取引トランザクションが発生した時に呼ばれるイベント処理です。注文リクエストの結果、約定、注文更新、決済、履歴反映など、取引関連の変化を確認する入口になります。

OnTradeTransactionは、取引処理の結果確認やログ追跡に役立ちます。ただし、ここに重い処理を詰め込むのではなく、受け取った内容を分類し、必要な状態更新やログ記録へ渡す設計が扱いやすくなります。

OnTradeTransactionで確認する項目

確認対象確認する理由ログ例
transaction typeどの種類の取引変化かを分類するTRADE_TX: type=…
symbol対象銘柄を確認するsymbol=…
order注文IDを確認するorder=…
deal約定IDを確認するdeal=…
positionポジションIDを確認するposition=…
requestEAが送ったリクエストとの関係を見るrequest_action=…
resultretcodeや結果を確認するretcode=…
time発生時刻を記録するserver_time=…

OnTradeTransactionの最小例

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
{
   Print("TRADE_TX: type=", trans.type,
         " order=", trans.order,
         " deal=", trans.deal,
         " symbol=", trans.symbol,
         " retcode=", result.retcode);
}

この例は、取引トランザクションの概要をログに出すだけの最小例です。実務では、必要に応じてorder、deal、position、symbol、magic、reason、retcodeなどを分類し、注文結果、決済結果、履歴更新の確認に使います。

OnTradeTransactionを使う時の注意

OnTradeTransactionは、取引関連の変化を詳細に追いやすい一方で、複数段階のtransactionが発生する場合があります。1回の注文操作に対して、注文追加、約定、履歴追加など複数のイベントが関係することがあります。

そのため、「OnTradeTransactionが呼ばれたら必ず最終状態」と決めつけず、必要に応じて現在のポジション、注文、履歴を再確認します。ログでは、transaction単体の情報と、再取得した現在状態を分けて記録すると追跡しやすくなります。

OnChartEventの役割

OnChartEvent は、チャート上のクリック、オブジェクトクリック、キー入力、チャート変更などを受け取るイベント処理です。パネルUI、ボタン、HELP、SNAP、表示切替、設定編集などで重要です。

ボタンUIでは、CHARTEVENT_OBJECT_CLICK を確認し、sparam に入るObject名を使って、どのボタンが押されたかを判断します。表示文字ではなく、内部Object名で判定することが重要です。

OnChartEventで受ける代表的なイベント

イベント例主な用途確認ポイント
CHARTEVENT_OBJECT_CLICKボタン押下sparamのObject名
CHARTEVENT_CHART_CHANGEチャートサイズ・時間足変更等パネル再配置要求
キー入力系イベントショートカット操作誤操作防止、対象限定
Object変更系イベントObject移動や編集手動変更を許可するか
マウス関連イベント高度なUI操作必要時のみ有効化

OnChartEventの最小例

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   if(id == CHARTEVENT_OBJECT_CLICK)
   {
      if(sparam == "EAF_BTN_HELP")
      {
         ToggleHelpPanel();
         return;
      }

      if(sparam == "EAF_BTN_SNAP")
      {
         PrintRuntimeSnapshot();
         return;
      }
   }

   if(id == CHARTEVENT_CHART_CHANGE)
   {
      g_relayout_required = true;
      return;
   }
}

この例では、ボタンを押した時の処理と、チャート変更時の再配置要求を分けています。OnChartEvent内で重い再構築を直接行うのではなく、フラグを立ててOnTimer側で軽く処理する構成にすると安定しやすくなります。

OnCalculateとの違い

OnCalculate は、主にカスタムインジケーターで使う計算イベントです。価格データやインジケーターバッファを更新するための関数であり、EAの OnTick とは役割が異なります。

インジケーターでは、表示値やバッファを計算する処理をOnCalculateに置きます。一方で、ボタン操作やチャート変更はOnChartEvent、定期処理はOnTimerへ分けられます。

EAとインジケーターのイベント差

項目EAインジケーター
価格変化の主処理OnTickOnCalculate
初期化OnInitOnInit
終了処理OnDeinitOnDeinit
定期処理OnTimerOnTimer
チャート操作OnChartEventOnChartEvent
取引transactionOnTradeTransaction通常は対象外
注文・決済EA側の責務通常は表示・計算中心

インジケーターをEAへ流用する場合、OnCalculateに入っていた計算処理をそのままOnTickへ移すのではなく、データ取得、評価、表示、ログを分けて設計し直します。

重い処理をOnTickに置かない理由

OnTickは、相場のtickを受けるたびに呼ばれます。tickが多い環境では、短時間に何度も呼ばれます。ここに外部通信、全Object走査、大量ログ、全パネル再作成、履歴全件走査などを入れると、処理が重くなりやすくなります。

OnTickは「価格変化に関係する軽量処理の入口」と考え、重い処理はOnTimer、OnTradeTransaction、OnChartEvent、helper関数、queue処理へ分けます。

OnTick過負荷の典型例

典型例起きやすい問題整理方針
毎tickで外部制御を取得通信遅延、ログ過多OnTimerで周期管理
毎tickで全Object再作成ちらつき、描画負荷差分更新、OnTimer再配置
毎tickで履歴全走査長期間稼働で重くなる必要時だけ範囲限定
毎tickで詳細ログ出力ログ確認が困難状態変化時のみ出力
OnTickに長い分岐を直書き保守性低下責務別helperへ分離
通知送信を直接実行transport失敗が本体処理に混ざる通知queueへ分離

状態変化時だけログを出す

OnTickで毎回同じログを出すと、確認したい情報が埋もれます。状態が変わった時だけ出す、一定秒数ごとにsummaryだけ出す、詳細ログはdebug inputで切り替えるといった設計が有効です。

void PrintStateWhenChanged(const string new_state)
{
   static string last_state = "";

   if(new_state != last_state)
   {
      Print("STATE_CHANGE: from=", last_state, " to=", new_state);
      last_state = new_state;
   }
}

このような仕組みにすると、OnTickで確認していても、ログ量を抑えながら状態遷移を追えます。

外部制御や認証をOnTimerへ分離する考え方

外部制御、認証、稼働許可、通知先設定、管理用ステータス取得などは、tickごとに確認する必要がない場合が多くあります。これらをOnTimerに分けると、価格変化処理と外部確認処理を分離できます。

外部制御を扱う場合は、実URL、APIキー、認証トークンなどの実値をログや画面に出さないようにします。ログには、取得成否、状態、reason、最終取得時刻、stale判定など、確認に必要な情報だけを出します。

外部制御をOnTimerへ分ける例

項目OnTimerで確認する内容OnTick側で使う内容
認証状態認証OK / NG / stale / fetch error新規処理を許可するか
外部稼働制御ON / OFF / emergency / invalid処理候補を止めるか
時間制御現在時間帯の許可状態新規処理のgate
通知設定通知ON/OFF、送信先種別通知queueへ積むか
設定バージョンconfig_version、updated_at古い設定を使っていないか
最終成功状態last-good snapshot取得失敗時の扱いを判断

fail-safe理由を分ける

外部制御では、取得失敗、認証NG、設定不正、古い設定、緊急停止などを同じ理由にしないことが重要です。理由を分けると、問い合わせ時にどこで止まったか確認しやすくなります。

enum ExtState
{
   EXT_OK,
   EXT_FETCH_ERROR,
   EXT_INVALID_BODY,
   EXT_STALE,
   EXT_DISABLED
};

この例では、外部状態をenumで分けています。実際のログでは、raw URLやtokenではなく、分類済みの状態だけを出します。

通知処理の分離

通知処理は、signal評価や注文結果確認とは別の責務です。通知が成功したかどうかと、EA内部の判定や取引結果は混同しないようにします。

通知処理をOnTickへ直接書くと、transport失敗、通信遅延、payload生成失敗などが本体処理と混ざりやすくなります。実務では、通知したいイベントをqueueへ積み、OnTimerで送信処理を行う構成が扱いやすい場合があります。

通知処理の責務分離

責務内容主な場所
通知イベント生成何を通知対象にするか決めるOnTick / OnTradeTransaction / OnChartEvent
payload作成送信用の本文を作るnotification helper
送信実行transport処理OnTimer / notifier helper
送信結果確認成功・失敗・status code確認notification logger
再送制御必要に応じた再試行queue manager
ログ通知成否を記録NOTIFY/SEND、NOTIFY/FAIL

通知ログには、Webhook URL、APIキー、認証トークン、個人情報、口座番号などの実値を入れないようにします。対象種別、イベント種別、送信成否、理由だけを残す方針が安全です。

UIクリック処理の分離

パネルEAや表示付きインジケーターでは、ボタン操作を OnChartEvent で受けます。ただし、クリックイベントの中に重い処理や全再構築を入れると、UIが重くなったり、表示崩れの原因になる場合があります。

クリックイベントでは、どのボタンが押されたかを判定し、runtime stateや要求フラグを更新する程度に留めます。重い処理、再配置、外部通信、通知送信などは、OnTimerや専用helperへ渡します。

UIクリック処理の分離表

操作OnChartEventで行うこと後続処理
HELPHELP表示フラグを切り替えるパネル差分更新
SNAPSNAP要求を立てるログ出力helper
APPLYedit buffer検証要求を立てるvalidation、applied value反映
CANCELedit bufferを戻す要求UI表示更新
RESET初期値復帰要求確認ログ、表示更新
表示切替view modeを変更OnTimerで再配置
チャート変更relayout_requiredを立てる軽量再配置

Object名で判定する

ボタンの表示文字は後から変わる可能性があります。クリック判定では、表示文字ではなくObject名を使います。Object名にはprefixと役割を含め、他EAや手動Objectと衝突しないようにします。

bool IsPanelButton(const string name)
{
   return (StringFind(name, "EAF_PANEL_") == 0);
}

このようにprefixで判定すると、自EAのパネルObjectだけを処理対象にしやすくなります。

イベント間で状態を共有する方法

OnTick、OnTimer、OnTradeTransaction、OnChartEventは別々のイベントですが、同じEA内のruntime stateを共有できます。ただし、どのイベントがどの状態を更新するかを決めておかないと、状態の上書きや表示と実状態のズレが起きやすくなります。

状態共有で分けるべきもの

状態主に更新するイベント確認ポイント
Market snapshotOnTick価格、spread、bar time
External stateOnTimer認証、外部制御、stale判定
Trade stateOnTradeTransaction / OnTick注文結果、ポジション状態
UI stateOnChartEvent / OnTimer表示モード、ボタン、HELP
Applied configOnChartEvent後のvalidationAPPLY済み設定
Edit bufferUI入力操作未適用値と確定値を分ける
Log state各イベント前回ログとの差分を管理

runtime構造体でまとめる例

struct RuntimeState
{
   string mode;
   string ext_state;
   string last_reason;
   datetime last_tick_time;
   datetime last_timer_time;
   bool relayout_required;
};

RuntimeState g_rt;

状態を構造体にまとめると、SNAPログやパネル表示でも同じ情報を使いやすくなります。ただし、表示用文字列と判定用enumやboolを混同しないようにします。

ログ設計とデバッグ

イベント処理を分けても、ログが整理されていなければ不具合の切り分けは難しくなります。ログでは、どのイベントで、何を確認し、どの状態に変わったかを短く記録します。

ログを増やすほど確認しやすくなるとは限りません。同じログが大量に出続けると、重要な変化が見えにくくなります。イベント別にログ名を分け、状態変化時ログ、定期summary、詳細debugを分けて設計します。

イベント別ログ表

イベントログ名例記録する内容
OnInitINIT/SUMMARYversion、symbol、timeframe、timer、設定確認
OnDeinitDEINIT/SUMMARYreason、timer停止、終了状態
OnTickTICK/STATE新バー、spread、軽量状態変化
OnTimerTIMER/SUMMARY外部制御、認証、通知queue、UI更新
OnTradeTransactionTRADE_TXtype、order、deal、retcode、symbol
OnChartEventCHART_EVENTevent id、Object名、操作種別
OnCalculateCALC/SUMMARYrates_total、prev_calculated、計算状態
共通SNAP現在状態のまとめ

SNAPログに入れると確認しやすい項目

項目理由注意点
version対象ファイルを確認するファイル名と一致させる
symbol / timeframe再現条件を確認するブローカー差も記録する
timer状態OnTimerが動いているか確認する周期も記録する
external state外部制御の状態を確認するURLやtokenは出さない
last event直近のイベントを確認するOnTick / OnTimer / OnChartEventなど
last reason停止・見送り理由を確認する短いreasonにする
object countUI過多や残存確認に使う必要な範囲だけ数える
last error異常の追跡に使う発生時刻も残す

イベント設計でよくある不具合と確認方法

イベント処理の不具合は、コンパイルエラーだけでは判断できません。動いているように見えても、OnTimerが止まっている、OnChartEventが届いていない、OnTradeTransactionのログが多すぎる、OnTickに処理が集中している、といったケースがあります。

症状主な原因確認するログ整理方針
OnTimerが動いていないEventSetTimer未実行、EventKillTimer後に再開していないINIT/TIMER、TIMER/SUMMARYOnInitとOnDeinitを確認
ボタンが反応しないObject名不一致、背景Objectが前面、イベント未処理CHART_EVENTsparamとZORDERを確認
ログが多すぎるOnTickで毎回詳細ログTICK/STATE状態変化時ログにする
通知が本体処理を巻き込む通知transportをOnTickに直書きNOTIFY/FAILqueueとOnTimerへ分離
取引結果が追えないOnTradeTransactionログ不足TRADE_TXorder、deal、retcodeを記録
終了時に不安定OnDeinitで重いcleanupDEINIT/SUMMARY軽量終了処理へ寄せる
再セット後に古いObjectが混ざるprefixやstartup audit不足OBJECT_AUDIT残存Objectを分類する

開発依頼前に整理すること

イベント処理が絡むEAやインジケーターの開発を依頼する場合は、どのイベントで何をしたいかを整理しておくと、仕様化が進めやすくなります。特に、外部連携、通知、パネルUI、長時間稼働、取引結果ログを含む場合は、イベント設計が重要です。

依頼前整理表

整理項目確認する内容補足
対象種別EA / インジケーター / パネルEA / スクリプト使えるイベントが変わる
価格依存処理tickごとか、新バーごとかOnTick設計に関係
定期処理何秒ごとに何を確認するかOnTimer設計に関係
取引結果確認注文・約定・決済をどう記録するかOnTradeTransactionに関係
UI操作ボタン、入力欄、HELP、SNAPの有無OnChartEventに関係
外部連携認証、外部制御、通知、記録URLやtokenの扱いに注意
ログINIT、TIMER、TRADE_TX、SNAPの有無問い合わせ前確認に重要
終了時処理Objectを消すか、残すかOnDeinit方針に関係
再現資料Expertsログ、Journalログ、スクリーンショット発生時刻も記録する

問い合わせ時は、EA名、バージョン、setファイル、対象銘柄、時間足、発生時刻、Expertsログ、Journalログ、スクリーンショットを整理してください。イベント処理の不具合では、どのイベントのログが出ているか、どのイベントのログが出ていないかも重要な確認材料になります。

次に読む技術講座

この講座とあわせて確認すると、MT5・MQL5開発、検証、不具合調査の流れを整理しやすくなります。

No講座確認できること
LEARN-019MQL5チャートオブジェクト・パネルUI完全ガイドチャートObject・パネルUIを確認する
LEARN-018MQL5 WebRequest・JSON・外部API実装完全ガイドWebRequestや通知をOnTimerへ分ける考え方を確認する
LEARN-021MQL5マルチシンボル・マルチタイムフレーム完全ガイド複数銘柄データ取得のタイミングを確認する
LEARN-022MQL5長時間稼働・安定化完全ガイドOnTimer・OnDeinit・長時間稼働を確認する
LEARN-014MQL5デバッグ・ログファースト開発完全ガイドイベント別ログ設計を確認する

次に確認するページ

技術講座を確認した後、導入・商品確認・開発相談・不具合報告へ進む場合は、以下のページも確認してください。

ページ確認できること
技術講座一覧MT5・MQL5・EA開発に関する技術講座を順番に確認できます。
導入ガイドEA、インジケーター、補助ツールを導入する前の確認事項を整理できます。
商品一覧EAファンクラブで扱う補助ツール、インジケーター、コピーEAなどを確認できます。
開発代行ページEA、インジケーター、補助ツールの新規作成・改修相談を確認できます。
不具合報告・サポート依頼ログ、スクリーンショット、再現手順を整理して相談する場合に確認できます。

よくある質問

OnTickだけでEAを作ってもよいですか?

小さなEAであればOnTick中心でも構成できます。ただし、外部制御、認証、通知、パネルUI、取引結果ログ、長時間稼働を含む場合は、OnTimer、OnTradeTransaction、OnChartEventへ責務を分けた方が確認しやすくなります。

OnTimerは何に使いますか?

定期監視、外部制御取得、認証確認、通知queue処理、UIメンテナンス、Object欠損チェック、heartbeatログなどに使います。tickが少ない時間帯でも一定間隔で処理できる点が特徴です。

OnTradeTransactionは必須ですか?

すべてのEAで必須ではありません。ただし、注文結果、約定、決済、履歴反映、retcode、order、dealを詳しく追いたい場合は有効です。取引関連のログを整理したいEAでは検討対象になります。

OnChartEventはインジケーターでも使えますか?

はい。チャート上のボタン、Objectクリック、チャート変更などを受ける用途で、EAでもインジケーターでも使えます。パネルUIや表示切替がある場合に重要です。

外部連携をOnTimerに分ける理由は何ですか?

外部連携は、tickごとに実行する必要がない場合が多く、通信遅延や失敗も起こり得ます。OnTimerへ分けると、価格変化処理と外部状態確認を分離でき、ログや失敗理由も整理しやすくなります。

イベント間で変数を共有してもよいですか?

共有できます。ただし、どのイベントがどの状態を更新するかを決めておく必要があります。Market snapshot、external state、trade state、UI state、edit buffer、applied valueを分けると確認しやすくなります。

OnDeinitで重い処理をしてよいですか?

基本的には避けます。OnDeinitではtimer停止、Comment解除、handle解放などの軽量処理を優先します。Objectの広範囲削除や重いcleanupは、対象を限定するか、次回起動時のstartup auditで確認する方が安定する場合があります。

ログはイベントごとに分けるべきですか?

分けた方が確認しやすくなります。INIT、TIMER、TICK、TRADE_TX、CHART_EVENT、DEINIT、SNAPのように分類すると、どのイベントで問題が起きたか追跡しやすくなります。

OnTimerを使うと重くなりますか?

OnTimer自体が問題というより、OnTimer内で何をどれだけ行うかが重要です。短い周期で重い処理を繰り返すと負荷になります。周期、処理量、ログ量、Object更新量を制御してください。

OnTradeTransactionだけで現在ポジションを完全に判断できますか?

OnTradeTransactionは取引変化を追う入口として有効ですが、必要に応じて現在の注文、ポジション、履歴を再取得して確認します。transaction単体の情報と現在状態を分けてログに残すと確認しやすくなります。

まとめ

MQL5のイベント処理では、OnTickにすべてを詰め込むのではなく、処理の性質に応じてイベントを分けることが重要です。価格変化に依存する処理はOnTick、定期監視はOnTimer、取引結果確認はOnTradeTransaction、UI操作はOnChartEvent、インジケーター計算はOnCalculateへ分けます。

イベントごとの責務を分けると、ログ確認、再現条件整理、長時間稼働確認、パネルUIの安定化、外部制御の切り分けがしやすくなります。特に、外部連携や通知を扱う場合は、実URL、APIキー、認証トークン、口座番号などの実値をログや本文に出さず、状態分類とreasonで追跡できる設計にします。

学習内容を確認しても整理が難しい場合は、EA名、バージョン、setファイル、Expertsログ、Journalログ、発生時刻、スクリーンショットを整理したうえで相談してください。

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