[MQL]トレンドラインにショートカットを設定する方法2つ

この記事では、MQLでトレンドラインにショートカットキーを割り当てる場合のプログラミング方法を2つ説明します。

標準のショートカットはないの?

残念なことに、MT4にはトレンドラインの描画に標準のショートカットキーは設定されていません。MT4をしばらく使った人ならば誰もがやりたいと思うはずなのでずが、なぜか標準のショートカットが無いのです。

したがって、トレンドラインにショートカットを割り当てるためには、専用のインジケータやまたはスクリプトを作成する必要があります。

以下でその作成方法を説明します。

トレンドラインにショートカットを設定するには

MQLでトレンドラインにショートカットを割り当てる方法には大きくわけて以下の2つがあります。

1.オブジェクトを生成する方法

「指定したキーが押されたらチャートに新規オブジェクト(トレンドライン)を生成する」というコーディングです。処理の概要は、OnChartEvent()ハンドラでキーボード入力とマウスの座標を取得し、objectCreate()でトレンドラインを生成するというものです。

前に記事にした「[MT4]ショートカットキーでラインやフィボナッチを描画するインジケーター」は、この方法でコーディングしました。

2.アイコンボタンを押す方法

「指定したキーが押されたらトンドラインのアイコンボタンを押下する」というコーディングです。実現したいことは、単に「アイコンボタンを押す」というものですが、チャート外の操作になるためWinUser32.mqlを介してウィンドウを操作する必要があります。

次にこれら二つの方法についてそれぞれ具体的にコードを書いてみます。

方法1 オブジェクトを生成する

指定したキー(ここではとします)を押したら、オブジェクト(トレンドライン)を生成するコードの書き方です。大まかな処理の流れは、以下のようになります。

  1. OnChartEvent()ハンドラでユーザー入力を待機
  2. ユーザー入力がならば、トレンドライン生成モードに移行
  3. トレンドライン生成モード中にマウス入力があれば以下処理を行う
  4. マウスがクリックされた座標を始点としてトレンドラインを描画する
  5. マウスがもう一度クリックされた座標を終点としてトレンドラインの描画を完了する

この一連の処理を記載したサンプルコードが下記です。


//+------------------------------------------------------------------+
//|                                            trendline_sample1.mq4 |
//|                                                     minagachi FX |
//|                                            https://minagachi.com |
//+------------------------------------------------------------------+
#property copyright "minagachi FX"
#property link      "https://minagachi.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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);
}
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   // 変数定義
   int KEY = 84; // キーコードT
   string objname = "test";  //トレンドライン名称
   static int objnumber = 1; // オブジェクト番号
   static int step = 0; // 処理のステップ管理

   // キーボード入力時
   if(id == CHARTEVENT_KEYDOWN){
      if(lparam == KEY){
         if(step == 0){
            step = 1;
         }
      }
   }

   // マウスクリック時
   if(id == CHARTEVENT_CLICK){
      if(step > 0){
         // クリック時のXY座標を取得
         int x = (int)lparam;
         int y = (int)dparam;

         // 座標を時間と価格に変換
         datetime time = 0;
         double price = 0;
         int window = 0;
         ChartXYToTimePrice(0, x, y, window, time, price);

         if(step == 1){
            // クリック座標を始点としてトレンドラインを生成
            objname = objname + (string)objnumber;
            ObjectCreate(0, objname, OBJ_TREND, 0, time, price, time + 10000, price);
            step = 2;
         }
         else if(step == 2){
            objname = objname + (string)objnumber;
            // クリック座標をトレンドラインの終点にセット
            ObjectSet(objname, OBJPROP_TIME2, time);
            ObjectSet(objname, OBJPROP_PRICE2, price);
            objnumber++;
            step = 0;
         }
      }
   }
}

ポイント解説

前半は何も処理していないので無視してください。ChartEvent function以降が実際に処理を行っている部分です。ポイントは以下です。

  • 変数定義のKEY = 84はTのキーコードです。(キーコードについてわからなければググってください)
  • キーボード入力がTだったらstep = 1にして次にマウスの入力を待機します。
  • step > 0でマウスがクリックされたら、クリックされたXY座標を取得します。(x座標はlparam、y座標はdparamの値に格納されています。)
  • XY座標をChartXYToTimePrice()関数を使用して時間・価格座標に変換します。
  • step = 1の場合は時間・価格を始点としてトレンドラインを新規生成し、step = 2にします
  • step = 2の場合は時間・価格を終点としてトレンドラインを移動し、生成完了。step = 0

捕捉

上記コードはトレンドラインを引くための最小限のコードです。使用感は非常に悪いです。実際のトレードで快適に使うためには、かなり処理を追記する必要があります。改良版がこれ→「[MT4]ショートカットキーでラインやフィボナッチを描画するインジケーター

方法2 アイコンボタンを押す

指定したキー(ここではとします)を押したら、トレンドラインのアイコンボタンを押すコードの書き方です。大まかな処理の流れは、以下のようになります。

  1. 冒頭でUinUser32.mqhをインクルード
  2. OnChartEvent()ハンドラでユーザー入力を待機
  3. 入力がキーボードのTならば、トレンドライン押下のコマンドを投げる

WinUser32.mqhとは?

WinUser32.mqhはMT4の「データフォルダ¥MQL4¥Include」下に標準で入っているファイルです。このファイルの中を見るとここの話がより理解しやすくなると思います。

この一連の処理を記載したサンプルコードが下記です。


//+------------------------------------------------------------------+
//|                                            trendline_sample2.mq4 |
//|                                                     minagachi FX |
//|                                            https://minagachi.com |
//+------------------------------------------------------------------+
#property copyright "minagachi FX"
#property link      "https://minagachi.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

#include <WinUser32.mqh>   //  WinUser32.mqhをインクルード

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   // DLLの使用を許可するにチェックが入っていない場合は動作しない
   if(!IsDllsAllowed()){
      Alert("DLL use is not allowed. Please allow it.");
   }
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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);
}
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   // 変数定義
   int KEY = 84; // キーコードT
   int CMD_TRENDLINE = 33257; // トレンドライン

   if(id == CHARTEVENT_KEYDOWN){
      if(lparam == KEY){
         int hWnd = GetParent(GetParent(GetParent(WindowHandle(Symbol(),Period()))));
         PostMessageA(hWnd, WM_COMMAND,CMD_TRENDLINE,0);
      }
   }
}

ポイント解説

コードの冒頭部で#include <WinUser32.mqh>でWinUser32.mqhをインクルードしています。WinUser32.mqhをインクルードすることで、Windows APIを介してWindowsの機能にアクセスすることができるようになります。例えばウィンドウの最大化・最小化、終了などです。

int hWnd = GetParent(GetParent(GetParent(WindowHandle(Symbol(),Period()))));は、「チャートハンドルの親の親の親要素」を取得します(Windows APIを使用)。

その要素に対してPostMessageA(hWnd, WM_COMMAND,CMD_TRENDLINE,0);で、トレンドラインのアイコン押下のコマンドを投げます(Windows APIを使用)。

これによって、トレンドラインのアイコンボタンが押す操作を実現しています。

まとめ

MQLでトレンドラインにショートカットを割り当てるには、「キー入力を感知してオブジェクトを生成する」か、「Windows APIを介してアイコンボタンを押す」かのどちらかです。

標準でショートカットが設定されていれば、こんな面倒なことはしなくても良いのですが、、、。とはいえ、このページで書いたような処理はいろいろなインジケーターに応用できるので、使えるようにしておくと便利ですよ。

コメント

この記事へのコメント(0 件)