MQL4が書ける人向け、標準ライブラリーを使ったMQL5プログラミング、注文編

　この記事ではMT4からMT5へ移行を考えている開発者に向けて、MT5で注文を出すプログラムの書き方の一つの例を紹介しています。MQL5で通常使われる__専用構造体を使った注文方法__ではなく、これまでMQL4だけを書いてきたプログラマーにとっては比較的にわかりやすい方法かなと思う__標準ライブラリーを使った注文方法__を解説します。

##MQL4とMQL5の注文の出し方の違い

MQL4で注文を出す書き方は
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/8b43e529-ad07-2cdf-2a37-ef6fc3052d5f.png)

対してMQL5で注文を出す書き方は
※今回は覚える必要はありません

```.c
   MqlTradeRequest Request;
   MqlTradeResult Result;
   
   ZeroMemory(Request);
   ZeroMemory(Result);

   Request.action = TRADE_ACTION_DEAL;                   // 取引の種類
   Request.magic = Magic;                                // マジックナンバー
   Request.symbol = _Symbol;                             // 通貨ペア
   Request.volume = Lots;                                // ロット数
   Request.type = ORDER_TYPE_BUY;                        // 注文タイプ
   Request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK); // 価格
   Request.sl = 0;                                       // sl
   Request.tp = 0;                                       // tp
   Request.deviation = Slippage;                         // スリッページ
   Request.comment = NULL;                               // コメント
   Request.type_filling = OrderTypeFilling;              // 注文実行の種類
   
   OrderSend(Request,Result);

```

　MQL5の方が細かい設定ができたり慣れると便利ですが、MQL4に慣れている人にとっては、使いづらさを感じる仕様になっているようにも思います。

###MQL5で標準ライブラリーを使った注文の出し方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/d62c549a-533d-0523-e2d5-d49b34ee1538.png)
　このように標準ライブラリーを使用するとMQL4に近い感覚で注文コードを書くことができます。

　それでは詳しく注文を出す手順を確認していきましょう。

　今回はMT5に__標準ライブラリー__として用意されている__CTrade__というクラスを呼び出して注文を出すプログラムを書いていきます。__CTrade__にはMQL4に近いタイプの注文関数が多く用意されています。

　まずクラスを呼ぶために__CTrade__が書かれたファイル__Trade.mqh__を__#include__で読み込みます。

```.c
 #include <Trade\Trade.mqh>
```
　次に通常のクラスの使い方と同じく、クラス名を指定してオブジェクトを生成します。オブジェクト名は任意でOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/77344d74-f765-01f4-80e0-43708d0fb802.png)

　これで__『オブジェクト名.関数』__という形で__CTrade__内のメンバ関数を使えるようになるわけですが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/6259e59f-786d-9b9c-0d64-872841ed8220.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/49efa521-b445-8436-88a5-2a3d46897411.png)
　MQL4の注文関数と比較するとMQL5の__CTrade__関数にはマジックナンバーとスリッページを指定する引数がないです。__CTrade__の仕様でマジックナンバーとスリッページはプログラム内で一度だけ設定すれば、その後の注文すべてに適応することになっています。

　マジックナンバーやスリッページは注文ごとに値を変更することは基本的にしないのでこの方が便利ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/8128f79f-8b7e-7e4e-da56-05cfa6e48480.png)

 次に決済するための関数について
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/3a311e2e-0674-02e4-fb3f-9394e18f01b4.png)
　決済は主にこの関数を使います。1ポジションしか持たないEAであれば、ポジションチケットを指定する代わりに通貨ペアを書くだけでOKです。

　分割決済する場合は
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/0aea5af8-229f-c9c5-2d90-f05b188f4aa1.png)
　こっちの関数を使います。

###実際に動作させてみる
　今回は動作確認のため
「EAを起動させるとすぐに買いポジションを持って、ローソク終値が確定すると決済する」
というプログラムを書いています。

```.c
#include <Trade\Trade.mqh>

sinput ulong  Magic = 12345;  // マジックナンバー
sinput ulong  Slippage = 20;  // スリッページ
sinput double Lots = 0.1;     // ロット数

CTrade ExtTrade; // オブジェクト生成

int OnInit()
  {
   // EAの初期設定
   ExtTrade.SetExpertMagicNumber(Magic);    // マジックナンバーの設定
   ExtTrade.SetDeviationInPoints(Slippage); // スリッページの設定
   
   // 新規注文
   ExtTrade.PositionOpen(_Symbol,ORDER_TYPE_BUY,Lots,SymbolInfoDouble(_Symbol,SYMBOL_ASK),0,0,NULL);
   
   return(INIT_SUCCEEDED);
  }
    
void OnTick()
  {
   // ローソク終値が確定したら決済
   static datetime time = iTime(_Symbol,PERIOD_CURRENT,0);
   
   if(time != iTime(_Symbol,PERIOD_CURRENT,0))
      ExtTrade.PositionClose(_Symbol,Slippage);
  }

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/9da5d612-7a03-c7fc-e0b1-3090be21cf09.png)
　正しく動作しました。

###MQL5の仕様の注意点
　MQL4の__OrderSend関数__は戻り値が__チケット番号__でしたが、MQL5の注文関数の戻り値は注文が成功したときにtrue、失敗したときにfalseとなります。

　MT5ではMT4でいう__チケット番号__が
1. オーダーチケット
2. ディールチケット
3. ポジションチケット

この3つに該当します。MT5から__ディール__というものが追加されたことによるためですが、それぞれどう違うのかというと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/79965390-0414-0e1a-99ff-f5649c210177.png)
　端末から送信された注文はまだ約定するかどうかわからない状態で、実際は価格が少しずれたり、分割して約定したりすることもあるので、ここを厳密にするため__ディール__というものが新たに追加されています。

 上で動作させたEAで
1. オーダーチケット
2. ディールチケット
3. ポジションチケット
がそれぞれどうなっていたかを確認してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/ac73bd61-a7e9-aab9-69ad-8bc97729c7b2.png)
　新規注文のオーダーチケットとポジションチケットは同じで、他はすべて別々の番号が割り振られています。ポジションチケットを取得する方法はいろいろありますが、__CTrade__では直近の注文のオーダーチケットを取得する関数が用意されているので、ポジションチケットが必要な場合は、それを利用するのもいいかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/f7751968-df42-1d21-91f6-af1604aa5c9c.png)


　最後に__CTrade__の公式のリファレンスサイトのURLを貼っておきます。この記事で紹介したもの以外にもたくさん関数が用意されているので使う人には必須のサイトです。

https://www.mql5.com/ja/docs/standardlibrary/tradeclasses/ctrade
 
***
続きの記事はこちら↓

https://qiita.com/aisaki180507/items/7f56e90a4ca9ac48aa10