【MQL5パラダイス 第7回】インジケーターと会話しよう!移動平均線の値を読み込んでトレンドを判定~MQL5入門
みなさん、こんにちは!パイナップルです。
前回の第6回では、EAの心臓部である「OnTick(オンティック)」について学びました。価格がピクッと動くたびにプログラムが実行される仕組みを知り、いよいよ24時間働く自動売買ロボットの土台ができあがりましたね。
しかし、今の私たちのEAは「現在の価格」を見ることしかできません。実際のトレードでは、過去の価格の平均からトレンドを読み解く「移動平均線(MA)」や、買われすぎ・売られすぎを判断する「RSI」といったインジケーターを使って、相場の状況を分析しますよね。
そこで今回は、いよいよ「プログラムの中でインジケーターの値を読み込む方法」について解説します。 EAにインジケーターという「新しい目」を持たせることで、単なる価格の監視員から、相場を分析する優秀なトレーダーへと一気に進化します。
少し新しい概念が登場しますが、ゆっくり分かりやすく解説していきますので、コーヒーを片手にリラックスして読み進めてくださいね。
MQL5のインジケーターは「レストランの予約制」
過去にMT4(MQL4)でプログラムを作ったことがある方は、ここで少し戸惑うかもしれません。MT4では、インジケーターの値が欲しいときに「今すぐ移動平均線の値を教えて!」と直接関数を書けば、すぐに値が返ってきました。
しかし、MQL5では少し勝手が違います。MQL5におけるインジケーターの取得は、「レストランの予約制」のような2段階のステップを踏むルールになっているのです。
なぜそんな面倒なことをするのでしょうか? それは、「スピードと軽さ」を実現するためです。
毎回のTick(価格変動)のたびに、ゼロからインジケーターの計算をやり直していては、パソコンの頭脳がパンクしてしまいます。
そこでMQL5では、最初に「このインジケーターを使いますよ」と宣言(予約)して計算専用のルートを作っておき、あとは値が更新されるたびに、そのルートから「最新の結果だけを受け取る」という非常に効率的な仕組みを採用しているのです。
この仕組みのおかげで、MQL5のバックテストはMT4に比べて劇的に速くなっています。まさに「パラダイス」な開発環境の秘密がここにあるのですね。
2つのステップを覚えよう
- 予約する(ハンドルの取得) 最初に「期間14の移動平均線を使います」とMT5に伝え、予約チケット(ハンドル)をもらいます。
- 値を受け取る(バッファのコピー) 価格が動くたびに、その予約チケットを見せて「最新の数値をちょうだい」とお願いし、用意しておいた箱に値を入れてもらいます。
新しい枠組み「OnInit」で予約を済ませよう
レストランの予約は、食事の直前ではなく事前に済ませておく必要がありますよね。
プログラムでも同じで、毎回の価格変動(OnTick)の中で予約をしていては遅すぎます。EAをチャートにセットした瞬間に、1回だけ予約を済ませておきたいところです。
そこで登場するのが、OnInit(オンイニット)という枠組みです。
(Initは、Initialization=初期化の略です)
MetaEditorで新しくEAのファイルを作成すると、実は OnTick の上に、この OnInit というブロックが最初から用意されています。
ここには「EAがチャートにセットされた時に、最初だけ1回実行したい準備作業」を書きます。インジケーターの予約には、まさにうってつけの場所ですね。
複数のデータを入れる「箱の列(配列)」を用意しよう
もう一つだけ、準備するものがあります。 インジケーターの値は「現在のローソク足の値」「1つ前のローソク足の値」「2つ前の……」と、過去に向かって複数のデータが存在しますよね。
これを受け取るためには、第3回で学んだような「1つしかデータが入らない変数の箱」では足りません。複数の箱がズラッと横に並んだ「箱の列(配列:はいれつ)」を用意する必要があります。
MQL5では、変数の名前の後に [](四角いカッコ)をつけるだけで、この「箱の列」を作ることができます。
double ma_values[];
このように書くことで、「移動平均線の値をたくさん受け取るための、小数の箱の列」が準備できました。
実際にインジケーターを読み込むプログラムを書いてみよう
少し説明が長くなりましたが、百聞は一見に如かず。実際のコードを見てみましょう。 今回は、現在の価格が「期間14の単純移動平均線(SMA)」よりも上にあるか、下にあるかを判定して出力するEAを作ります。
以下のコードを記述してみてください。
//+------------------------------------------------------------------+
//| My_MA_Cross.mq5 |
//+------------------------------------------------------------------+
// 1. 全体で使う「箱」と「箱の列」を準備する
int ma_handle; // 予約チケット(ハンドル)を入れる整数の箱
double ma_values[]; // MAの数値を受け取る箱の列(配列)
//+------------------------------------------------------------------+
//| EAがチャートに入った時の準備作業(1回だけ実行) |
//+------------------------------------------------------------------+
int OnInit()
{
// 2. 移動平均線(期間14のSMA)の予約チケットを取得
ma_handle = iMA(_Symbol, PERIOD_CURRENT, 14, 0, MODE_SMA, PRICE_CLOSE);
// 3. 箱の列を「新しい順(右から左)」に並び替えるおまじない
ArraySetAsSeries(ma_values, true);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 価格が動くたびに呼ばれる心臓部 |
//+------------------------------------------------------------------+
void OnTick()
{
// 4. チケットを使って、最新のMAの値を3つ(現在、1つ前、2つ前)受け取る
if(CopyBuffer(ma_handle, 0, 0, 3, ma_values) <= 0) return;
// 5. 現在の価格(Bid)を取得
double current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
// 6. 現在の価格とMA(ma_values[0]が最新の値)を比較する
if(current_price > ma_values[0])
{
Print("現在の価格(", current_price, ")は、MA(", ma_values[0], ")より上です。強気!");
}
else if(current_price < ma_values[0])
{
Print("現在の価格(", current_price, ")は、MA(", ma_values[0], ")より下です。弱気!");
}
}
サンプルコードの読み解き方
いかがでしょうか?ステップごとに見ていくと、それほど難しくないはずです。
- 手順2:予約チケットの取得(iMA関数)
iMAという関数を使って予約をしています。カッコの中には「通貨ペア、時間足、期間(14)、表示移動、計算方法(SMA)、適用価格(終値)」という、私たちが普段チャートにMAを入れる時と同じ設定項目を順番に入れています。 - 手順3:配列のおまじない(ArraySetAsSeries)
これはMQL5特有の非常に大事な「おまじない」です。
通常、プログラムの配列は古いデータから順に入ってしまいます。しかし、私たちが欲しいのは「最新のデータ」ですよね。この
ArraySetAsSeriesにtrueをセットすることで、箱の並び順が逆転し、「ma_values[0]が一番新しい現在の足」「ma_values[1]が1つ前の足」という、直感的に分かりやすい順番になってくれるのです。 - 手順4:値の受け取り(CopyBuffer)
OnTickの中で、CopyBufferという関数を使ってデータを受け取っています。 「予約チケット(ma_handle)を使って、一番新しいところ(0)から、3個分のデータを、ma_valuesという箱の列に入れてください」というお願いをしています。
あとは、前々回学んだ if文 の出番です。
最新の価格(current_price)と、最新の移動平均線の値(ma_values[0])を比較して、強気か弱気かをプリントさせています。
コンパイルしてチャートにセットし、エキスパートタブのログを見てみてください。価格が動くたびに、MAの値と現在の価格を比較して、健気に相場を実況中継してくれるはずです!
シンプルだからこそ「見極め」が効く
インジケーターをプログラムで取得できるようになると、多くの人が「移動平均線と、RSIと、MACDと、ボリンジャーバンドを組み合わせて……」と、たくさんの指標を一度に使いたくなります。
気持ちは痛いほど分かります。私も昔は、チャートがインジケーターで埋め尽くされて、肝心のローソク足が見えなくなるようなEAを作っては悦に入っていました(笑)。
しかし、指標を増やせば増やすほど、条件は厳しくなり、エントリーの回数は極端に減っていきます。そして「過去10年間で、全ての条件が完璧に揃った奇跡のタイミング」だけを拾い上げるような、ガチガチに過剰最適化(カーブフィッティング)されたEAが出来上がってしまうのです。
未来の相場は、過去と全く同じ波形を描くことはありません。 シンプルで堅牢なトレードを目指すのであれば、まずは「移動平均線1本」のシンプルなトレンドフォローから始めてみることを強くお勧めします。
今回プログラムに組み込んだ「価格がMAの上にあるか、下にあるか」というシンプルな事実は、相場における最も強力な事実(トレンド)の一つです。複雑な計算式をこねくり回すよりも、こうした王道の見極めを大切にすることが、長く生き残るシステムの土台となると私は考えます。
まずは1つのインジケーターの声に、じっくりと耳を傾けてみてくださいね。
おわりに
今回は、OnInit と CopyBuffer という仕組みを使って、移動平均線の値を取得し、相場のトレンドを判定する方法を学びました。
現在価格の取得、if文による条件判定、そしてインジケーターによる分析。 これらが揃った今、あなたのEAの「頭脳」はすでに一人前のトレーダーと同じ機能を持っています。
足りないものはあと一つだけ。そう、「実際に注文を出す(エントリーする)」というアクションです!
次回は、私たちが作ったEAに、ついにMT5の注文ボタンを押させます。 MQL5で注文を出すのは難しいと言われることもありますが、ご安心ください。初心者でも安全かつ簡単に注文が出せる「CTrade」という強力な助っ人の使い方を、分かりやすく解説します。
あなたが作ったプログラムが、自分の意志でポジションを持つ。その感動の瞬間はもう目の前です!
それでは、次回の「MQL5パラダイス」でまたお会いできるのを楽しみにしています。 あなたのEAの分析が、素晴らしいトレンドを捉えますように。パイナップルでした!
よろしいですか?