PR

【MQL4&MQL5】マクロ定義を使用した自動売買のボタン操作方法【dll使用】

オリジナル関数

この記事では、MT4・MT5の自動売買ボタンにマクロを使用して、プログラムする方法を解説します。変数や関数などの基本的な知識がある人向けの内容です。


You
You

聞いたことが無いワードがたくさんあります!
むずかしそう。。。

WAN
WAN

普段使わないし、知らなくてもそんなに困らないから裏技だと思って!
オタク向けの知識かな(‘ω’)

MT4・MT5の自動売買ボタンを操作(制御)するには

ターミナルウインドウの中にあるボタンの一つで、これをクリックすると、自動売買のオンオフを切り替えることができます。

MT4では「自動売買」、MT5では「アルゴリズム取引」と表示されています。

これらのボタンを、普通は手動でクリックしますが、特定のシナリオにおいて、プログラム制御したい場合があります。

しかし、そこで問題点があります。。。

MQL言語で自動売買ボタンをプログラム制御することはできない → dll を使用する

MQL言語には、自動売買ボタンを操作する関数はありません。
なので、user32.dllの必要な関数をインポートして、自動売買ボタンを操作できるようにします。

#import "user32.dll"
   long GetAncestor(long hwnd, uint flags);
   int PostMessageW(long wnd, uint Msg, long param, long param);
#import

自動売買ボタンを操作するコードはこちらです。

PostMessageW(GetAncestor(ChartGetInteger(ChartID(), CHART_WINDOW_HANDLE), 2), 0x0111, TRADE_BUTTON, 0);

これらの一つ一つの関数につきましては今回は割愛します。

説明が欲しい場合は、ChatGPTなどで調べてください。

WAN
WAN

ヲタクのWANでもわからない事の方がおおいです笑

ChatGPTとのやり取り
You
You

#import “user32.dll”

long GetAncestor(long hwnd, uint flags);

int PostMessageW(long wnd, uint Msg, long param, long param);

#import

 

PostMessageW(GetAncestor(ChartGetInteger(ChartID(), CHART_WINDOW_HANDLE), 2), 0x0111, TRADE_BUTTON, 0);

 

MQL5の自動売買ボタンを押す関数です。 この関数の説明をできるだけ詳しくお願いします

ChatGPT
ChatGPT
  1. #import "user32.dll"
    • Windowsの基本的な機能を提供するuser32.dllをインポートします。
  2. long GetAncestor(long hwnd, uint flags);
    • GetAncestor関数を宣言します。これはウィンドウの祖先を取得するために使います。
  3. int PostMessageW(long wnd, uint Msg, long param, long param);
    • PostMessageW関数を宣言します。これはウィンドウにメッセージを送るために使います。
  4. PostMessageW(GetAncestor(ChartGetInteger(ChartID(), CHART_WINDOW_HANDLE), 2), 0x0111, TRADE_BUTTON, 0);
    • 現在のチャートのウィンドウハンドルを取得し(ChartGetIntegerを使用)、その祖先ウィンドウをGetAncestorで取得します。
    • PostMessageWを使用して、取得したウィンドウに対してメッセージを送信します。
    • 0x0111はメッセージタイプで、ここではコマンドメッセージを意味します。
    • TRADE_BUTTONは操作したいボタンの識別子です。
    • 最後の0はこのコマンドに関連する追加の情報を提供する引数ですが、ここでは使用しません。

このコードは、特定の自動売買ボタンをプログラム的に”クリック”するために使用されます。

条件付きコンパイルとは?(MQL4とMQL5の両方で使える)

特定の状況に合わせて、プログラムの動作を変えたいときに使用します。

今回はMQL4でコンパイルされたら、(#ifdef __MQL4__)

【このコード】

その他(MQL5)は(#else)

【このコード】

終了(#endif)

といったように、MQL4とMQL5でコードを分けることができます。

WAN
WAN

1つのソースファイルで、MQL4とMQL5どちらも使用したい時に使うよ!

__MQL4____MQL5__アンダースコアは2つの点に注意!

MQL5のドキュメンテーション: 言語基礎 / プリプロセッサ / 条件付きコンパイル( #ifdef、#ifndef、#else、#endif )
条件付きコンパイル( #ifdef、#ifndef、#else、#endif ) - プリプロセッサ - 言語基礎 - MQL5 リファレンス - MetaTrader 5 のためのアルゴリズムの/自動化されたトレーディング言語のリファレン...

条件付きコンパイルの具体例

今回はMT4とMT5で自動売買ボタンの番号が異なります。
これを踏まえて、条件付きコンパイルで TRADE_BUTTON というマクロの値を設定します。

  • MQL4でコンパイル時は「33020
  • MQL5でコンパイル時は「32851
#ifdef __MQL4__
   #define TRADE_BUTTON 33020
#else
   #define TRADE_BUTTON 32851
#endif
WAN
WAN

defineの数値はターミナルのボタン固有のIDで調べるのは非常に難しいので、こういうものということで覚えておこう!

マクロとは?

マクロの作成に、#define を使用しますが、命令文も #define で定義することが可能です。

マクロには、定数のような使い方と、関数のような使い方の二種類の使い方があり、言い換えるとショートカットとも言えます。

マクロを使用する、メリットとデメリット

メリット
  1. 変数のように型が存在しない(常にstringの状態と考えることができる)
  2. 静的配列の宣言時に、配列サイズの指定に使用できる(例.double array[SIZE];このように宣言できる)
デメリット
  1. 書き換えができない(変数でいう、constが付いた定数状態と考えることができる)
  2. グローバル領域でも順番が関係するため、コードの冒頭で記載する必要がある
  3. ソースファイルに新たな要素が加わり、解読性に欠ける

自動売買ボタンをマクロで定義するには

自動売買ボタンの操作をマクロで定義すると以下のようになります。

#define AUTO_TRADE_BUTTON(onoff) \
   if(onoff != TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))\
      PostMessageW(GetAncestor(ChartGetInteger(ChartID(), CHART_WINDOW_HANDLE), 2), 0x0111, TRADE_BUTTON, 0);

マクロで命令を定義する場合、改行の際に「バックスラッシュ(\)」が必要になります。

バックスラッシュはフォントによっては「円マーク」になりますが、
同じ意味ですので気にしないでください。

マクロを使用する上でのポイント3つ

マクロを使用するには、下記の3つを意識しておくと良いです。

  • マクロに引数を設定する場合は、の必要がない
  • マクロ内で使用する引数は、マクロ名の()に記述する
  • if文、for文、変数、関数、インポートした関数も使用できる

まとめ

マクロは使用しなくても、問題なくEAやインジを作成することは可能です。
しかし、開発者として理解していた方が、対応の幅は広がります。
例えば、他の人のコードを解読する必要があるケースで、マクロが使用されていて解読できない可能性があります。

普段使用しなくても、知識として入れておくと良いでしょう(‘ω’)

インジケーターとして使えるコードはこちら(コピペで使用可能)

インジケーターとして導入する場合は、以下のコードを使用することができます。

#property indicator_chart_window
#property indicator_plots 0

#import "user32.dll"
   long GetAncestor(long hwnd, uint flags);
   int PostMessageW(long wnd, uint Msg, long param, long param);
#import

#ifdef __MQL4__
   #define TRADE_BUTTON 33020
#else
   #define TRADE_BUTTON 32851
#endif

#define AUTO_TRADE_BUTTON(onoff) \
   if(onoff != TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))\
      PostMessageW(GetAncestor(ChartGetInteger(ChartID(), CHART_WINDOW_HANDLE), 2), 0x0111, TRADE_BUTTON, 0);

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   AUTO_TRADE_BUTTON(true);//自動売買ボタンをONにする
//---
   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 value of prev_calculated for next call
   return(rates_total);
  }
タイトルとURLをコピーしました