MT4でクリックした3点を順につなぐラインを描画するには?イベント処理と状態管理の基本

外国為替、FX

MetaTrader 4(MT4)で独自の描画ツールを作成しようとすると、イベントの扱いと状態の保持が難しく感じられるかもしれません。とくに「チャート上の3点を順にクリックして、それを結ぶラインを描きたい」という操作を実現するには、チャートイベントの正しい使い方とプログラムの状態管理がカギとなります。

MT4のチャートイベント処理の基本

MT4でマウスクリックやカーソル移動を扱うには、OnChartEvent()関数が必要です。この関数では、イベントの種類(id)とクリックされた座標がlparamdparamに格納されて渡されます。ただし、注意点は「関数が呼ばれるたびに変数が初期化される」ことです。

そのため、clickや座標の値は、グローバル変数として定義しなければ次のクリック時に保持されません。これが「クリックが1回分しか記録できない」原因の一つです。

3点を記録してラインを描くための基本的な流れ

3つのクリック点を記録し、それを結ぶには、以下のようなフローが必要です。

  • グローバル変数でクリック回数と座標を保持
  • 3点取得後、ChartXYToTimePriceで時間と価格を取得
  • ObjectCreate()でラインを描画

以下はそのための基本コードです。

int click = 0;int x1, y1, x2, y2, x3, y3;datetime t1, t2, t3;double p1, p2, p3;int OnInit(){ ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true); return(INIT_SUCCEEDED);}void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam){ if(id == CHARTEVENT_CLICK) { int x = (int)lparam; int y = (int)dparam; int win = 0; if(click == 0) { x1 = x; y1 = y; click++; } else if(click == 1) { x2 = x; y2 = y; click++; } else if(click == 2) { x3 = x; y3 = y; ChartXYToTimePrice(0, x1, y1, win, t1, p1); ChartXYToTimePrice(0, x2, y2, win, t2, p2); ChartXYToTimePrice(0, x3, y3, win, t3, p3); ObjectCreate(0, "line1", OBJ_TREND, 0, t1, p1, t2, p2); ObjectCreate(0, "line2", OBJ_TREND, 0, t2, p2, t3, p3); click = 0; } }}

上記コードでは、クリックごとに座標を保存し、3回目でラインを2本描きます。

状態を維持するための注意点

ローカル変数ではなく、グローバル変数を使うことが、クリック情報を維持するポイントです。また、オブジェクト名(例:「line1」「line2」)は毎回上書きされないように、タイムスタンプやユニークな文字列を付けて管理するのも有効です。

また、描画後にclick0に戻すのを忘れずに。これを忘れると次の描画に支障が出ます。

応用:より複雑なラインやフィボナッチ描画も可能

上記の方法はシンプルなライン描画に適していますが、応用すればトライアングルやチャネルライン、フィボナッチリトレースメントなど、より複雑な描画も可能です。

例えば、3点目を使ってOBJ_TRIANGLEを描くことや、斜めのフィボナッチを独自実装するなど、MT4の描画APIは多彩な表現をサポートしています。

まとめ:MT4でのイベント処理は「状態管理」がカギ

MT4でチャートに対してクリックイベントを処理し、3点をつないで描画するためには、「グローバル変数の利用」および「イベント処理の構造の理解」が重要です。

失敗の多くは、イベントが呼ばれるたびに変数が初期化されてしまうことに起因します。そのため、コード構造をしっかり組み立てておくことが成功のカギとなります。

外国為替、FX
最後までご覧頂きありがとうございました!もしよろしければシェアして頂けると幸いです。
最後までご覧頂きありがとうございました!もしよろしければシェアして頂けると幸いです。
riekiをフォローする

コメント

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