この記事ではMT4からMT5へ移行を考えている開発者に向けて、MT5でインジケータの数値を呼び出すプログラムの書き方の一つの例を紹介しています。
前回の記事(注文編)はこちら↓
##MQL5のインジケータを呼び出すルール
最初に標準ライブラリーを使わない通常の書き方の例を見せます。MQL5ではプログラム内でインジケータの値を呼び出すには__指標ハンドル__を取得する必要がありますが、この__指標ハンドル__がMQL4にはないものなので混乱を招くのだと思います。
MAの値を呼び出して10個表示させるプログラム
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);
}
今回はこの指標ハンドルを使用しない方法を紹介します。
###MQL5で標準ライブラリーを使ったインジケータの呼び出し方
MT5では__見かけ上、指標ハンドルを使わずにインジケータデータを呼び出す__ための標準ライブラリーが用意されています。呼び出すインジケータの種類によって使うクラスが違うので必要に応じて使い分ける必要があります。
MT5ではインジケータが
1. トレンド系
2. オシレーター
3. ボリューム系
4. ビル・ウィリアムス系
に分かれており、どれを呼びたいかによって__#include__で読み込むファイルが違います。
#include <Indicators\Trend.mqh> // トレンド系
#include <Indicators\Oscilators.mqh> // オシレーター
#include <Indicators\Volumes.mqh> // ボリューム系
#include <Indicators\BillWilliams.mqh> // ビルウィリアムズ系
今回はMAを例にして進めます。MAを使う場合は__CiMA__というクラスを呼び出す必要があります。
次にMAの初期設定をします。これはプログラム内で一度だけでOKです。MQL4のように毎回インジケータの設定値を引数にしなくてもいいわけです。通常は__OnInit関数__の中に記述します。
これで呼び出す準備はできましたが、呼び出す前に最新のデータに更新させるように癖付けましょう。
ExpMA.Refresh(); // 最新データに更新
あとは__オブジェクト名.Main(呼び出したい番号)__とすればOKです。
###実際に動作させてみる
#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);
}
###ゴールデンクロスで買うEAを作ってみる
前回の注文を出すプログラムと組み合わせて__「MAとローソク足がゴールデンクロスすれば買い。デッドクロスすれば決済するEA」__を作ってみます。
#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);
}
正しく動作しました。
###2種類のインジケータを使うEAを作ってみる
使うインジケータの種類が増えても、やり方は同じです。今回は__「ローソク足終値がMAより上に位置しているときにRSIが30以下になったら買う。RSIが70以上になったら決済するEA」__を作ってみます。
#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;
}
}
正しく動作しました。
最後にMQL5の公式リファレンスサイト(標準ライブラリー、インジケータのページ)のURLを貼っておきます。この記事で紹介したもの以外にもたくさん関数が用意されているので使う人には必須のサイトです。