チャートをダブルクリックした際の処理

チャートをダブルクリックした際の処理

サムネ
おはようございます。 fx-onエンジニアの岩淵です。 最近チャートをダブルクリックした際に処理を実行したいなと思ったのですが、 そういえばダブルクリックなんてイベント見覚えないなとなりました。 CHARTEVENT_CLICKでシングルクリックは取得できるのですが、 CHARTEVENT_DOUBLE_CLICKみたいなのは無いみたいですね。 そこで試しにMQL4でダブルクリックの判定を実装してみました。

準備

まずグローバル変数を3つほど用意します。
bool is_click = false;
ulong click_time = 0;
int dclick_msec = 500;
is_clickは今回の肝になるフラッグです。 こいつの状態を操作してダブルクリックかシングルクリックかを判定します。 click_timeは1回目のクリックが発生した際の時間を保持するための変数です。 この変数の時間から一定時間経過したらis_clickを操作します。 dclick_msecは1回目のクリックと2回目のクリックの間の猶予時間をミリ秒単位で設定する変数です。 この変数の数値を弄ればダブルクリックの間隔が調整できるよう作っていきます。

OnChartEventの実装

1.イベントのidを確認してCHARTEVENT_CLICKの場合に処理を書いていきます。
if(id == CHARTEVENT_CLICK){
   // ここに処理を書いていきます
}
2.is_clickがfalseの場合はis_clickをtrueに変更してclick_timeに現在の時間を記録する。
if(id == CHARTEVENT_CLICK){
   if(is_click ==false){
      is_click = true;
      click_time = GetMicrosecondCount();
   }
}
3.is_clickがtrue(ダブルクリック時)の場合、is_clickをfalseに戻してダブルクリック時の処理を実行する。
if(id == CHARTEVENT_CLICK){
   if(is_click ==false){
      is_click = true;
      click_time = GetMicrosecondCount();
   }
   else{
      is_click = false;
      // ダブルクリック時の処理
      // .........
   }
}
OnChartEvent側の実装はこれで完了です。

OnTimerの実装

OnChartEventの処理だけですとダブルクリックというよりは2回クリックで処理発生になってしまいます。 OnTimerを使って一定時間でis_clickをfalseに戻す処理を加えてダブルクリックっぽくしていきます。 1.OnInit内でEventSetMillisecondTimer、OnDeinit内でEventKillTimerを呼び出す。
int OnInit(){
   EventSetMillisecondTimer(100);
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason){
   EventKillTimer();
}
今回は短い間隔で判定をおこないたいので、EventSetTimerではなくEventSetMillisecondTimerを使用してミリ秒単位で指定しています。 サンプルのコードだと100ミリ秒なので0.1秒毎に処理が発生してくれます。 2.OnTimer内で時間を判定し、1回目のクリックから一定時間経過していればis_clickをfalseに戻す。
void OnTimer(){
   if(is_click == true){
      if(GetMicrosecondCount() > click_time + dclick_msec){
         is_click = false;
      }
   }
}
以上で実装は完了です。

サンプル

ダブルクリック時に「hoge」とアラートするインジケーターのサンプルコードです。
#property version   "1.00"
#property strict
#property indicator_chart_window

bool   is_click    = false;
ulong  click_time  = 0;
int    dclick_msec = 500;

int OnInit(){
   Comment("ダブルクリックしてね");
   EventSetMillisecondTimer(dclick_msec);
   return(INIT_SUCCEEDED);
}

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

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam){
  
   if(id == CHARTEVENT_CLICK){
      if(is_click ==false){
         is_click = true;
         click_time = GetMicrosecondCount();
      }
      else{
         is_click = false;
         Alert("hoge");
      }
   }
}

void OnTimer(){
   if(is_click == true){
      if(GetMicrosecondCount() > click_time + dclick_msec){
         is_click = false;
      }
   }
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {

   return(rates_total);
}
間隔が0.5秒なので気合入れてダブルクリックしてみてください。

まとめ

今回はダブルクリックの判定を実装してしました。 いつもの如く、使用する場面は非常に限られます。 私が作りたいものはこれで問題なかったのですが、シングルクリックも組み合わせるとなるとこの処理だとちょっと物足りないですね。
商号 株式会社ゴゴジャン
金融商品取引業の登録番号 関東財務局長(金商)第1960号
加入協会 一般社団法人 日本投資顧問業協会
商号 株式会社ゴゴジャン
金融商品取引業の登録番号
関東財務局長(金商)第1960号
加入協会 一般社団法人
日本投資顧問業協会
金融庁日本投資顧問業協会証券・金融商品あっせん相談センター証券取引等監視委員会

Copyright © 2025 GogoJungle Inc. All Rights Reserved.