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

　この記事ではMT4からMT5へ移行を考えている開発者に向けて、MT5でインジケータの数値を呼び出すプログラムの書き方の一つの例を紹介しています。

前回の記事(注文編)はこちら↓

https://qiita.com/aisaki180507/items/756ec8a47b494e97fb42

##MQL5のインジケータを呼び出すルール
　最初に標準ライブラリーを使わない通常の書き方の例を見せます。MQL5ではプログラム内でインジケータの値を呼び出すには__指標ハンドル__を取得する必要がありますが、この__指標ハンドル__がMQL4にはないものなので混乱を招くのだと思います。

MAの値を呼び出して10個表示させるプログラム

```.c
int MA_handle;
double MA[];

int OnInit()
  {
   MA_handle = iMA(_Symbol,PERIOD_CURRENT, 20, 0,MODE_SMA,PRICE_CLOSE); // ハンドルを取得
   
   ArraySetAsSeries(MA,true); // MA[]を時系列のように索引付け
   
   CopyBuffer(MA_handle,0,0,10,MA); // MA[]に最新データをコピー
   
   for(int i=0; i<ArrayRange(MA,0); i++)
      printf("MA[%d] = %g",i,MA[i]); // 取得したMAの値を出力
   
   return(INIT_SUCCEEDED);
  }
```
動作結果↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/fa24333a-e047-883a-e088-a86fdf004c79.png)

　__今回はこの指標ハンドルを使用しない方法を紹介します。__

###MQL5で標準ライブラリーを使ったインジケータの呼び出し方
　MT5では__見かけ上、指標ハンドルを使わずにインジケータデータを呼び出す__ための標準ライブラリーが用意されています。呼び出すインジケータの種類によって使うクラスが違うので必要に応じて使い分ける必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/d68b79c7-40bb-89e7-6b8a-031ac3c6c762.png)




MT5ではインジケータが
__1. トレンド系
2. オシレーター
3. ボリューム系
4. ビル・ウィリアムス系__

に分かれており、どれを呼びたいかによって__#include__で読み込むファイルが違います。

```.c
#include <Indicators\Trend.mqh>         // トレンド系
#include <Indicators\Oscilators.mqh>    // オシレーター
#include <Indicators\Volumes.mqh>       // ボリューム系
#include <Indicators\BillWilliams.mqh>  // ビルウィリアムズ系
```
　今回はMAを例にして進めます。MAを使う場合は__CiMA__というクラスを呼び出す必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/4eedbd14-199d-4614-5849-303fef785902.png)

　次にMAの初期設定をします。これはプログラム内で一度だけでOKです。MQL4のように毎回インジケータの設定値を引数にしなくてもいいわけです。通常は__OnInit関数__の中に記述します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/95eef09e-0e7d-4ff5-a0f0-6809e8f62405.png)

　これで呼び出す準備はできましたが、呼び出す前に最新のデータに更新させるように癖付けましょう。

```.c
 ExpMA.Refresh(); // 最新データに更新
```
　あとは__オブジェクト名.Main(呼び出したい番号)__とすればOKです。

###実際に動作させてみる
```.c
#include <Indicators\Trend.mqh>         // トレンド系

int MA_handle;
double MA[];

CiMA ExpMA;         // MAオブジェクト

int OnInit()
  {
   ExpMA.Create(_Symbol,PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE); // MAの初期設定
   
   ExpMA.Refresh(); // 最新データに更新
   
   for(int i=0; i<10; i++)
      printf("MA[%d] = %g", i, ExpMA.Main(i) ); // 取得したMAの値を出力
   
   return(INIT_SUCCEEDED);
  }
```
動作確認↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/78f0cc42-0f37-a783-4b75-0c3b330ebee7.png)
正しく動作しました。

　ここまでの使い方をまとめると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/a5885e96-6f86-4181-3801-f0b9b7375276.png)






###ゴールデンクロスで買うEAを作ってみる
　前回の注文を出すプログラムと組み合わせて__「MAとローソク足がゴールデンクロスすれば買い。デッドクロスすれば決済するEA」__を作ってみます。

```.c
#include <Trade\Trade.mqh>
#include <Indicators\Trend.mqh>         // トレンド系

sinput ulong  Magic = 12345;  // マジックナンバー
sinput ulong  Slippage = 20;  // スリッページ
sinput double Lots = 0.1;     // ロット数
input int     MAPeriod = 20;  // MAの期間

CTrade ExtTrade; // 注文オブジェクト
CiMA   ExpMA;    // MAオブジェクト

int OnInit()
  {
   // EAの初期設定
   ExtTrade.SetExpertMagicNumber(Magic);    // マジックナンバーの設定
   ExtTrade.SetDeviationInPoints(Slippage); // スリッページの設定

   ExpMA.Create(_Symbol,PERIOD_CURRENT, MAPeriod, 0, MODE_SMA, PRICE_CLOSE); // MAの初期設定

   return(INIT_SUCCEEDED);
  }

void OnTick()
  {
   // ローソク足が確定したときだけ動作させる
   static datetime time = iTime(_Symbol,PERIOD_CURRENT,0); 
   if(time == iTime(_Symbol,PERIOD_CURRENT,0)) return;
   time = iTime(_Symbol,PERIOD_CURRENT,0);
   
   ExpMA.Refresh(); // 最新データに更新
   
   // 価格がMAを上に抜けて確定したら買い注文
   if( iClose(_Symbol,PERIOD_CURRENT,2) < ExpMA.Main(2) && iClose(_Symbol,PERIOD_CURRENT,1) >= ExpMA.Main(1) )
      ExtTrade.PositionOpen(_Symbol,ORDER_TYPE_BUY,Lots,SymbolInfoDouble(_Symbol,SYMBOL_ASK),0,0,NULL); 

   // 価格がMAを下に抜けて確定したら決済
   if( iClose(_Symbol,PERIOD_CURRENT,1) < ExpMA.Main(1))
      ExtTrade.PositionClose(_Symbol,Slippage);
   
   time = iTime(_Symbol,PERIOD_CURRENT,0);
  }
```
動作確認↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/7a0f9988-a4f7-6b19-691b-e6d6ebab59a3.png)

正しく動作しました。

###2種類のインジケータを使うEAを作ってみる
　使うインジケータの種類が増えても、やり方は同じです。今回は__「ローソク足終値がMAより上に位置しているときにRSIが30以下になったら買う。RSIが70以上になったら決済するEA」__を作ってみます。

```.c
#include <Trade\Trade.mqh>
#include <Indicators\Trend.mqh>         // トレンド系
#include <Indicators\Oscilators.mqh>    // オシレーター

sinput ulong  Magic = 12345;  // マジックナンバー
sinput ulong  Slippage = 20;  // スリッページ
sinput double Lots = 0.1;     // ロット数
input int     MAPeriod = 200; // MAの期間
input int     RSIPeriod = 10; // RSIの期間

CTrade ExtTrade; // 注文オブジェクト
CiMA   ExpMA;    // MAオブジェクト
CiRSI  ExpRSI;   // RSIオブジェクト

int OnInit()
  {
   // EAの初期設定
   ExtTrade.SetExpertMagicNumber(Magic);    // マジックナンバーの設定
   ExtTrade.SetDeviationInPoints(Slippage); // スリッページの設定
   
   ExpMA.Create(_Symbol,PERIOD_CURRENT, MAPeriod, 0, MODE_SMA, PRICE_CLOSE); // MAの初期設定
   ExpRSI.Create(_Symbol,PERIOD_CURRENT, RSIPeriod, PRICE_CLOSE);            // RSIの初期設定
   
   return(INIT_SUCCEEDED);
  }
    
void OnTick()
  {
   // ローソク足が確定したときだけ動作させる
   static datetime time = iTime(_Symbol,PERIOD_CURRENT,0); 
   if(time == iTime(_Symbol,PERIOD_CURRENT,0)) return;
   time = iTime(_Symbol,PERIOD_CURRENT,0);
   
   static bool pos = false; // EAがポジションを持っているかチェックするための変数
   
   // 最新データに更新
   ExpMA.Refresh(); 
   ExpRSI.Refresh(); 
   
   // 価格がMAを上でかつRSIが30以下で確定したら買い注文
   if( pos == false && iClose(_Symbol,PERIOD_CURRENT,1) > ExpMA.Main(1) && ExpRSI.Main(1) <= 30 ){
      ExtTrade.PositionOpen(_Symbol,ORDER_TYPE_BUY,Lots,SymbolInfoDouble(_Symbol,SYMBOL_ASK),0,0,NULL); 
      pos = true;
     }
   
   // RSIが70以上で確定したら決済
   if( pos == true && ExpRSI.Main(1) >= 70 ){
      ExtTrade.PositionClose(_Symbol,Slippage);
      pos = false;
     }
   
  }

```
動作確認↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1882169/ae0a659e-6978-d794-f300-11f0257a3b85.png)

正しく動作しました。


　最後にMQL5の公式リファレンスサイト(標準ライブラリー、インジケータのページ)のURLを貼っておきます。この記事で紹介したもの以外にもたくさん関数が用意されているので使う人には必須のサイトです。

https://www.mql5.com/ja/docs/standardlibrary/technicalindicators