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

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

MQL5におけるOnChartEventは、チャート上でのユーザー操作やシステムイベントを検知するための「イベントハンドラー」です。通常のEA(エキスパートアドバイザー)が価格の更新(ティック)に反応するのに対し、この関数は「ボタンが押された」「マウスが動いた」「グラフィックオブジェクトが作成された」といった、価格以外の動的な変化をキャッチします。

実務での活用法:
実務開発において、OnChartEventは主に「独自のユーザーインターフェース(UI)」の構築に利用されます。
* トレードパネルの作成: チャート上に「全決済ボタン」や「倍率指定の注文ボタン」を配置し、クリック一つで即座に実行するツール。
* 動的なライン分析: ユーザーが引いた水平線を検知し、その価格にタッチしたら通知を送る、あるいは予約注文を入れる。
* キーボードショートカット: 特定のキー(「S」で売り、「B」で買いなど)に機能を割り当てる。

つまずきやすいポイント:
初心者が陥りやすいのは、OnChartEventが「バックテスト中には動作しない(一部の視覚的テストを除く)」という仕様です。また、マウスの移動など大量に発生するイベントを不用意に監視すると、PCのCPU負荷が急増し、トレードの実行速度(レスポンス)を損なう原因にもなります。


2. 構文と戻り値

OnChartEvent関数は、以下の4つのパラメーターを受け取る定義済み関数です。戻り値はありません(void型)。

void OnChartEvent(
   const int      id,       // イベントID(何が起きたか)
   const long&    lparam,   // long型のイベントパラメータ
   const double&  dparam,   // double型のイベントパラメータ
   const string&  sparam    // string型のイベントパラメータ
);

パラメーターの解説

  1. id: 発生したイベントの種類を示す定数です。例:CHARTEVENT_CLICK(クリック)、CHARTEVENT_OBJECT_CLICK(オブジェクトのクリック)、CHARTEVENT_KEYDOWN(キー入力)など。
  2. lparam: イベントに付随する整数データ。マウスのX座標や、押されたキーのスキャンコードなどが格納されます。
  3. dparam: イベントに付随する実数データ。マウスのY座標などが格納されます。
  4. sparam: イベントに付随する文字列データ。クリックされたオブジェクトの名前などが格納されます。

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

以下は、チャート上に「全決済」ボタンを作成し、それがクリックされた時に動作する実用的なサンプルコードです。

//+------------------------------------------------------------------+
//|                                              SimpleButtonEA.mq5 |
//+------------------------------------------------------------------+
#property strict

// ボタンのオブジェクト名
const string BUTTON_NAME = "CloseAllButton";

//+------------------------------------------------------------------+
//| EAの初期化関数                                                     |
//+------------------------------------------------------------------+
int OnInit()
{
    // チャート上にボタンを作成
    ObjectCreate(0, BUTTON_NAME, OBJ_BUTTON, 0, 0, 0);
    ObjectSetInteger(0, BUTTON_NAME, OBJPROP_XDISTANCE, 100); // 横位置
    ObjectSetInteger(0, BUTTON_NAME, OBJPROP_YDISTANCE, 50);  // 縦位置
    ObjectSetInteger(0, BUTTON_NAME, OBJPROP_XSIZE, 100);     // 幅
    ObjectSetInteger(0, BUTTON_NAME, OBJPROP_YSIZE, 30);      // 高さ
    ObjectSetString(0, BUTTON_NAME, OBJPROP_TEXT, "全決済実行"); // ラベル
    ObjectSetInteger(0, BUTTON_NAME, OBJPROP_COLOR, clrWhite);
    ObjectSetInteger(0, BUTTON_NAME, OBJPROP_BGCOLOR, clrRed); // 背景色(赤)

    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| EAの終了処理                                                      |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // EAを削除する時にボタンも消す
    ObjectDelete(0, BUTTON_NAME);
}

//+------------------------------------------------------------------+
//| チャートイベント・ハンドラ                                          |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
    // イベントIDが「オブジェクトのクリック」であるか確認
    if(id == CHARTEVENT_OBJECT_CLICK)
    {
        // クリックされたオブジェクトの名前が「CloseAllButton」か確認
        if(sparam == BUTTON_NAME)
        {
            Print("全決済ボタンがクリックされました。ロジックを実行します。");

            // ボタンを押し込まれた状態から元に戻す(再クリック可能にする)
            ObjectSetInteger(0, BUTTON_NAME, OBJPROP_STATE, false);

            // ここに全決済の注文処理などを記述します
        }
    }
}

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

  1. イベントの有効化が必要なものがある:
    マウスの移動(CHARTEVENT_MOUSE_MOVE)やグラフィカルオブジェクト作成の変更(CHARTEVENT_OBJECT_CREATE)などを検知するには、ChartSetInteger関数を使って明示的にチャートのプロパティをONにする必要があります。
    cpp
    ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true); // マウス移動を検知可能にする

  2. 大文字・小文字の区別:
    sparamで渡されるオブジェクト名は、MQL5内部で生成された際の大文字・小文字を正確に判定する必要があります。比較時には注意してください。

  3. 計算負荷の蓄積:
    OnChartEvent内で複雑なループ処理や重い計算を行うと、チャートの描画がカクついたり、ボタンの反応が悪くなったりします。重い処理はグローバル変数などを介してOnTickや別のスレッドに渡す設計が理想的です。


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

自動売買プログラム(EA)において、アルゴリズムの優秀さ以上に収益を左右するのが「約定スピード」です。自宅のPC環境でEAを稼働させる場合、家庭用インターネット回線特有のネットワーク遅延(レイテンシ)やプロバイダーによるパケット詰まりが避けられず、プログラムが注文を出してからブローカーのサーバーに届くまでに数十〜数百ミリ秒のロスが発生します。急激な価格変動時には、この僅かな遅れが原因で「スリッページ」が発生し、設計上の期待値を大きく下回る結果を招きます。

極限まで約定速度を高め、プロ水準のトレード環境を構築するためには、ブローカーの取引サーバーと同じデータセンター内、あるいは物理的に極めて近い距離にある専用のVPS(仮想専用サーバー)の利用が不可欠です。物理的な距離を短縮することで、ネットワークの往復時間を最小化(1〜2ミリ秒以下)し、他のトレーダーよりも一瞬早く市場にエントリーすることが可能になります。安定した電源、24時間の稼働保証、そして超低遅延ネットワークというインフラが揃って初めて、あなたのアルゴリズムはその真価を発揮します。

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

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

コメント

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