[MT4で自動売買5]EA(MQL)の構文・よく使う関数を見てみよう

MT4−5

EAファイルはMQL言語で記載しており、基本的な構成について前回ご説明しました😀

基本構造がわかった後は実際に早速プログラムを書いてみましょう❗️

プログラミング言語によってif文やfor文の構文が微妙に違います。
EAで利用する言語はMQLです。MQLでの構文及び、よく使う関数の使い方を記載します🤗

私自身、試行錯誤してなんとかトラリピ風自動売買プログラムを作りました。
ご参考程度にはなりますが、私自身がプログラム作成時に利用したもの+αを記載します。(このページに記載しているものを組み合わせればトラリピ風自動売買プログラムの作成は可能です❗️)

目次

MQLでよく使う構文

命令実行文の行末に「;(セミコロン)」を記載

言語によって一文のとみなす定義が異なります。MQLは命令実行文に行末にセミコロン「;」を記載します。if文やfor文の文末にはセミコロンは不要です。

———
//int型の変数を宣言する
int a;

//変数に値を設定する
a = 12;

//コンソールに文字列(Hello)を表示する命令文
Print(‘Hello!’);

//if/for文等は命令実行文のみセミコロン
if(a > 10){
   Print(a); //aの値を表示
}
———

データ型

プログラミングを行う際には変数を利用します。変数にはどんな値を入れてもいいわけではありません。予め変数に設定して良いものを決めておきます。よく使うデータ型を記載します。

スクロールできます
設定可能な値
int整数値のみ。小数を扱いたいときはdouble。
double浮動小数点。double→intに型変換を行う場合は丸められるので注意が必要
booltrue / false または整数値を設定可能
整数の場合、0:false , 0以外:trueとなる
string文字列を変数に格納する場合に利用。文字列は”(ダブルクォーテーション)で囲む
enum自身で格納する内容を決めれる

どのような感じで利用するのか見てみましょう。

———
//+————————
//.  int
//+————————
//int型の変数を宣言する
int a;

//変数に値を設定する
a = 12;

//+————————
//. double
//+————————
//double型の変数を宣言する
double b;

//変数に値を設定する
b = -123.456;

//+————————
//.  bool
//+————————
//bool型の変数を宣言する
bool c,d;

//変数に値を設定する
c = true;
d = 0;

if(c){
 Print(“TRUE”);  //c=trueなのでTRUEを表示
}else{
 Print(“FALSE”);
}

if(d){
 Print(“TRUE”);
}else{
 Print(“FALSE”);  //d=0(false)なのでFALSEを表示
}

//+————————
//. string
//+————————
//string型の変数を宣言する
string e;

//変数に値を設定する
e = “文字列を変数に設定します”;

//+————————
//. enum
//+————————
//enum型の名前、利用できる値を設定する
enum fruits_list{
   banana,
   strawberry,
   apple
};

//変数を宣言する
fruits_list kudamono;

//変数に値を設定する
kudamono = apple;
———

比較演算子

条件文で利用する比較演算子は以下の通りです。

演算子演算子内容
a == baとbが等しい
a != baとbは等しくない
a > baはbより大きい
a < baはbより小さい
a >= baはbより大きいか等しい
a <= baはbより小さいか等しい
———
//int型の変数を宣言する
int a;

//変数に値を設定する
a = 10;

//比較演算子の使い方
if(a == 10){
   Print(“Good”); //a=10なのでGoodを表示
}else{
   Print(“Bad”)
}
———

if文

if-else文はよく使う条件分岐文です。条件式に合致する(True)する場合の処理、合致しない(False)場合の処理を記載します。条件式が複数ある場合else if文を追加します。

———
int a;

a = 10;

//条件が1つの場合(if-else)
if (a > 8){
   Print(a+3);  //a = 10 なのでこちらの処理に入る。13が表示される。
}else{
   Print(a);
}

//条件が2つ以上ある場合(else ifを使う場合)
if(a > 10){
   Print(a+3);   //a=10なのでこちらの処理には入らない
}else if(a > 5){
   Print(a+2);   //a=10なのでこちらの処理に入る。12が表示される。
}else{
   Print(a+1);
}

//if文の中にさらにif文が入れることも可能
if(a > 5){
   if(a > 11){
     Print(a);    //a=10なのでこちらの処理には入らない
   }else{
     Print(a+1);  //a=10なのでこちらの処理に入る。11が表示される。
   }
}
———

for文

配列に入れた値を元に計算するなど、値を少しずつ変えて繰り返し処理したいときにfor文を利用すると便利です。

———
int i ;

i = 0;

//10回の繰り返し処理。0から9まで表示される
for(i;i<10;i++){
  Print(i);
}

//上記変数iは前もって宣言する必要はなく、以下でも同じ結果となる。
for(int i=0;i<10,i++){
  Print(i);
}

//ループの途中で抜けたいときにはbreakを利用できます。
//下記の場合、7まで表示された後、ループ処理は終了(break)します
for(int i=0;i<10,i++){
  Print(i);
  if(i==7){
    break;
  }
}
———

while文

for文と利用用途は変わりません。while文の条件がTrueの間、ループ処理となります。for文同様、break処理を追加して特定条件でループ処理を抜けることが可能です。

———
int i ;

//10回の繰り返し処理。0から9まで表示される
i=10;
while(i<10){
  Print(i);
  i++;  //変数iのカウントアップを記載忘れると無限ループになるので注意❗️
}
———

トラリピ風EA作成で使用した関数

EAで利用可能な関数は山ほどあるのでほぼ理解できていませんが、以下の取引関数を組み合わせることで私自身はトラリピ風EA作成ができました。

OrdersHistoryTotal

OrdersHistoryTotal はMT4ソフトのターミナルにロードされた決済済み注文数を返却してくれます。int型で整数値を返します。この関数には引数はありません。

———
//OrdersHistroyTotal

int i=0;
i = OrdersHistroyTotal(); //決済済み注文数を変数iにセット
———

OrderTotal

注文中及び、保留中の合計値を返します。int型の整数値で、この関数には引数の設定はありません。

———
//OrdersTotal

int i=0;
i = OrdersTotal(); //注文中・保留中の合計値を変数iにセット
———

OrderSelect

OrderSelectはよく利用する関数の1つです。指定した注文の注文詳細情報を取得します。OrderSelect自体はbool型です。引数は3つあります。

スクロールできます
引数設定内容
indexindex番号を指定します。
下記select=SELECT_BY_TICKETの場合はチケット番号。
select以下のいずれを選択。 
 ・SELECT_BY_POS : 注文プールのインデックスをindexに指定
 ・SELECT_BY_TICKET : チケット番号をindexに指定
poolselect=SELECT_BY_POSの場合に使用する。
 ・MODE_TRADES : 取引プール(エントリー中の注文、保留中の注文)
 ・MODE_HISTORY : 履歴プール(決済済み注文・キャンセルした注文)
———
//OrdersSelect

int i=0;
bool x;

i = OrdersHistroyTotal(); //決済済み注文数を変数iにセット

if(i>0){
  //履歴プールのインデックス0の注文情報を取得
  x = OrderSelect( 0 , SELECT_BY_POS , MODE_HISTORY);

  if(x){
    //x=trueの場合、さまざまな注文情報を取得できる
    Print(“チケット番号:”,OrderTicket() );
    Print(“注文価格:”,OrderOpenPrice());
  }else{
    //x=falseの場合、注文情報を取得できなかった原因をエラーコードから探る
    int errcd = 0;
    errcd =GetLastError();

    Print(“エラーコード:”,errcd);

  }
}else{
  Print(“決済履歴なし”);
}
———

上記コードにも記載した通り、OrderSelect=trueの場合、以下の情報を取得できる。

スクロールできます
データ取得の関数返却値の型取得できる情報
OrderClosePrice()double決済価格
OrderCloseTime()datetime決済時刻
OrderMagicNumber()int複数EAを立ち上げるときには設定必須
マジックナンバーが各EAを判別する値となる
OrderLots()double設定ロット数
OrderOpenPrice()double注文価格
OrderStopLoss()double損切値
OrderSymbol()string銘柄名(usdjpyのような値を返却する)
OrderTakeProfit()double利確値
OrderTicket()int注文チケット番号
OrderType()int注文タイプ。注文送信時に設定する値と同値。
0:OP_BUY (買い成行)
1:OP_SELL (売り成行)
2:OP_BUYLIMIT (買い指値)
3:OP_SELLLIMIT(売り指値)
4:OP_BUYSTOP (買い逆指値)
5:OP_SELSTOP (売り逆指値)

OrderSend

注文を行うための関数です。自動売買プログラムでは重要な役割がある関数ですね。戻り値はint型の整数値であり、OrderSendが成功したら、注文時に発行されるチケット番号の値、OrderSendに失敗したら-1が返却されます。OrderSend関数で利用する引数は以下の通りです。

スクロールできます
引数名用途
symbol注文銘柄名
cmd注文タイプ。タイプごとの設定値は以下の通り。
0:OP_BUY (買い成行)
1:OP_SELL (売り成行)
2:OP_BUYLIMIT (買い指値)
3:OP_SELLLIMIT(売り指値)
4:OP_BUYSTOP (買い逆指値)
5:OP_SELSTOP (売り逆指値)
volumeロット数
price注文価格
slippageスリップページ
※各社・銘柄で異なるため、チャートの「仕様」から要確認
stoploss損切りの価格
takeprofit利確の価格
commentコメント
magicマジックナンバー
expiration注文有効期限
arrow_colorチャート表示時の矢印の色。
表示したくない場合は CLR_NONE を設定。
———
//OrderSend

OrderSend(
    Symbol(), //EAを稼働させるチャートの銘柄名をSymbol()関数で取得
    OP_BUYSELL,   // 注文タイプ
    0.01,         // ロット数
    130,          // 注文価格
    5,            // スリップページ
    120,          // 損切り価格
    140,          // 利確価格
    “USDJPY取引”,  //コメント
   12345,        //マジックナンバー
    0,            //有効期限設定しない
    CLR_NONE      //チャートに矢印を表示しない
);
———

おわりに

まだまだ書き足りないことが多いので少しずつパワーアップさせていきます😅

MT4のEAで自動売買を稼働させることに慣れていない方、初めての方はいきなり本番か動作せずに各社が用意しているデモサイトで十分試してくださいね😀慣れてくるとうっかり間違うこともあるかもしれないので、プログラム上に IsDemo() を入れておくことをお勧めします❗️この関数を入れておけば、うっかり本番取引環境で稼働させても誤って取引されることはありませんので。

———
if(IsDemo()){
   //デモ環境の場合
   自信が実装したいプログラムをここに記載する
}else{
  //本番環境の場合
 Print(“本番の取引環境です。デモサイトに切り替えてください”);
}
———

トラリピ風自動売買EAの工夫ポイントの1つとして、自動売買注文の発注リストはファイル出力を行い、ファイル上で管理しています。
MT4での取引履歴上、注文約定したときの価格は持っているため、決済約定時に再度、注文約定時の価格で注文の入れ直しをすることは可能です。
ただ、指値で注文価格を指定していても、注文が約定するときには指値ピッタリで約定することはまず無いです。そのため、何回か注文→決済→注文→決済・・・を繰り返していくと、注文価格が想定価格とかなり乖離することがあります。そのため、注文価格をファイル出力して管理する方針としています。

この方針で問題なく稼働しており、トラリピ風EAが実現できています✌️

ファイル出力のところはまだ書けていませんが近いうちにアップデートします💦

目次