【徹底解説】バイナリーオプションに使えるサインツールの作り方(MT5&MQL5)

サインツールの作り方 バイナリーオプション関連記事

バイナリーオプションの攻略で使える「3連続陽線サインツール」の作り方を徹底解説!初心者でも安心のMQL5コードを完全公開。

MetaTrader5への設定手順も画像付きで詳しく説明しています。自作インジケーターで取引チャンスを見逃さず、攻略に役立てましょう!

「陽線が3本」のサインツールのコードを紹介

「陽線が3本続いたタイミング」でサインを表示


//+------------------------------------------------------------------+
//| 3連続陽線でサインを出すバージョン      |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

#property indicator_label1 "Buy Signal"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2

double BuySignalBuffer[];
datetime LastAlertBarTime = 0;

int OnInit()
{
    SetIndexBuffer(0, BuySignalBuffer, INDICATOR_DATA);
    PlotIndexSetInteger(0, PLOT_ARROW, 233);
    return (INIT_SUCCEEDED);
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
    if (rates_total < 4) // 3連続陽線なので最低4本必要
        return 0;

    int start = MathMax(prev_calculated - 1, 3);

    if (prev_calculated == 0)
    {
        ArrayInitialize(BuySignalBuffer, EMPTY_VALUE);
    }

    for (int i = start; i <= rates_total - 2; i++)
    {
        bool isBullish1 = (close[i] > open[i]);        // 3本目(今確定したバー)
        bool isBullish2 = (close[i - 1] > open[i - 1]); // 2本目
        bool isBullish3 = (close[i - 2] > open[i - 2]); // 1本目
        bool isBullish4 = (close[i - 3] > open[i - 3]); // 4本目(4連続チェック用)

        // ★「ちょうど3連続の時のみ」サインを出す → 4本目が陽線ならスルー
        if (isBullish1 && isBullish2 && isBullish3 && !isBullish4)
        {
            BuySignalBuffer[i] = low[i] - (Point() * 10);

            if (i == rates_total - 2 && LastAlertBarTime != time[i])
            {
                string msg = StringFormat("【アラート】3連続陽線!確定足: %s", TimeToString(time[i], TIME_DATE | TIME_MINUTES));
                Alert(msg);
                PlaySound("alert.wav");

                LastAlertBarTime = time[i];
            }
        }
        else
        {
            BuySignalBuffer[i] = EMPTY_VALUE;
        }
    }

    return rates_total;
}

MetaTraderにサインツールのコードを貼り付け動かしてみよう

実際にサインツールを
動かしてみよう

MT5のMetaTraderを使って実際にサインを表示させるまでの流れを紹介します。

MT5でサインコードを起動する設定1

まずはMT5を起動させ「ツール」より「MetaQuotes 言語エディタ」を選択します。

MT5でサインコードを起動する設定2

MetaTraderが開きます。

MetaTraderの「ファイル」より「新しいファイル」を選択します。

MT5でサインコードを起動する設定3

「MQLウィザード:ファイル」が表示されるので「カスタムインディケータ」を選択して「次へ」ボタンをクリックします。

MT5でサインコードを起動する設定4

ファイル名(名前)を入力します。

デフォルトでは「Indicators¥」と表示されています。ファイルの位置になりますので、「Indicators¥」はそのままで、「Indicators¥ファイル名」とします。

今回はyousen3にしています。

名前を入力後「次へ」ボタンをクリックします。

MT5でサインコードを起動する設定5

次に表示される画面はそのまま「次へ」をクリックします。

MT5でサインコードを起動する設定6

次に表示される画面はそのまま「完了」ボタンをクリックします。

MT5でサインコードを起動する設定7

デフォルトのテンプレートが表示されます。

MT5でサインコードを起動する設定8

デフォルトのテンプレートの中身を消します。

MT5でサインコードを起動する設定9

3連続陽線でサインを出すコードをコピーして貼り付けます。

MT5でサインコードを起動する設定10

画面上部にある「コンパイル」ボタンをクリックします。

MT5でサインコードを起動する設定11

ツールボックス内でエラーが表示されない事を確認します。

MT5でサインコードを起動する設定12

※MT5を起動します。先ほどMetaTraderで保存したファイルはMT5に反映されています。

MT5のナビゲーターの「指標」の中に「yousen3」がある事を確認します。

「yousen3」をダブルクリックします。

MT5でサインコードを起動する設定13

ポップアップが表示されるので「OK」ボタンをクリックします。

MT5でサインコードを起動する設定14

3連続で陽線の場合サインが出ている事を確認します。

MT5でサインコードを起動する設定15

コードの修正に関しては「yousen3」を右クリックして「変更」を選ぶと、MetaTraderが起動して修正する事が出来ます。

サインツールのコードを徹底解説

コードを
1から10まで徹底解説

サインツールのコードを徹底解説しています。変数や関数、条件式など完全解説していますので、分からない箇所の解説をご確認下さい。

#propertyを解説


#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

#property indicator_label1 "Buy Signal"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2

#propertyは、インジケーターを作るときに、「どこに表示するか」や「色」・「線の形」などを簡単に決める事が出来ます。

#propertyの内容
#property 設定 説明
indicator_chart_window チャートのメイン画面にインジケーターを表示する
indicator_buffers 1 データを入れる箱を1つ使う
indicator_plots 1 チャートに表示するサインやラインは1つ
indicator_label1 "Buy Signal" サインの名前を「Buy Signal」にする
indicator_type1 DRAW_ARROW 矢印を表示する
indicator_color1 clrGreen 矢印の色を緑にする
indicator_style1 STYLE_SOLID 線のスタイルは「実線」にする
indicator_width1 2 矢印や線の太さ(大きさ)を「2」にする
indicator_buffers 1(バッファ)を解説
【重要】
バッファを理解しよう

indicator_buffers 1

indicator_buffers 1 は、「バッファを1つ用意する」という意味になります。

※indicator_buffers 2にするとバッファを2つ用意します。

バッファとは、サインやラインなどを表示するための「データを入れる箱」のようなものです。

MetaTraderはこのバッファを常に監視していて、値が入ると自動的にその位置にサインを表示してくれます。

今回のサインツールでは、チャートに表示するサインが1つだけなので、バッファも1つで十分です。もし、ほかのサインを追加で表示したい場合は、そのサイン用にもう1つバッファを用意する必要があります。

indicator_plots1を解説
MQL5から登場した
indicator_plotsを解説

indicator_plots は、インジケーターがチャートに表示する線や矢印など、「描画する項目の数」を指定する設定です。

MQL5から登場した「宣言」になります。

MQL4では、チャートに線や矢印を表示するとき、「何を何個表示するのか」を最初に決める必要は無く、線の種類や色などをバラバラに設定していました。

MQL4の場合
描画のタイプを設定(SetIndexStyle)、矢印の種類を設定(SetIndexArrow)、バッファの登録(SetIndexBuffer)

SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID, 2, clrGreen);
SetIndexArrow(0, 233); // 矢印の種類
SetIndexBuffer(0, BuySignalBuffer);

このやり方でも良いのですが、設定が増えると「どこに何を表示しているのか」が分かりにくくなってしまいます。

MQL5では、まず最初に indicator_plots を使って、チャートに「何を、いくつ表示するか」を決めてから作り始めます。

そのあとで、「どんな形にするか(矢印や線など)」や「色・太さ」を、順番にわかりやすく設定していくルールになっています。

MQL5の場合

#property indicator_plots 1//まずはindicator_plotsから宣言する

#property indicator_label1 “Buy Signal”
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2

このおかげで、MQL5は「何を・いくつ・どう表示するか」が最初からはっきりしているため、初心者でも作りやすく、あとからコードを見ても理解しやすいのが特徴です。

※indicator_color1の「1」は「1番目の描画設定」 を表しています。indicator_color 1の様にスペースが空くとエラーになるのでご注意下さい。

double BuySignalBuffer[];

double BuySignalBuffer[];

サインを表示するためのデータを入れる配列を宣言しています。

この配列は、あとで SetIndexBuffer() を使って、チャートに表示するためのバッファとして登録します。

datetime LastAlertBarTime = 0;

datetime LastAlertBarTime = 0;

アラートの連続発生を防ぐために使われます。

int OnInit()を解説

int OnInit()で動作に
必要な処理を設定

int OnInit() は、インジケーターやEAをチャートにセットしたときに最初に1回だけ実行される関数です。

具体的には、サインを表示するためのデータを入れる箱(バッファ)を用意したり、サインの色や形、大きさを決めたりします。

操作 意味
SetIndexBuffer(0, BuySignalBuffer, INDICATOR_DATA); インディケーターが使用するデータを格納する場所(バッファ)を設定します。これにより、インディケーターが描画に使うデータが格納されます。例えば、BuySignalBufferという配列にデータを保存します。
PlotIndexSetInteger(0, PLOT_ARROW, 233); インディケーターの描画設定を行います。ここでは「233」というコードで矢印を表示する設定をしています。これにより、インディケーターがチャートに矢印を表示します。
return (INIT_SUCCEEDED); 初期化が成功したことを返すためのコードです。この行が実行されることで、インディケーターが正しく準備できたことが示されます。

この中で特に重要になるの「SetIndexBuffer(0, BuySignalBuffer, INDICATOR_DATA);」です。MQL5初心者の方は、SetIndexBuffe()をしっかり理解しておきましょう。

SetIndexBuffe()の引数はSetIndexBuffer(int index, double &buffer[], int type);になります。

引数名 説明
int index 使用するインディケーターのバッファ番号(0から始まる番号)。
double &buffer[] データを格納する配列(バッファ)。インディケーターが表示するデータを格納します。
int type バッファのタイプ。通常、インディケーターのデータを格納するためにINDICATOR_DATAを指定します。

SetIndexBuffer()でBuySignalBuffer[]を登録すると、その配列BuySignalBuffer[]がバッファとして扱われるようになります。

バッファはMetaTraderが常に監視しており、BuySignalBuffer[]に新しい値が入ると、自動的にサインが出されます。

int OnCalculate()を解説

OnCalculate()で
ローソク足の情報が分かる

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])

OnCalculateは、MQL5でインディケーターを作成する際に使用される、インディケーターの主要な計算関数です。インディケーターがチャート上で表示されるたびに、データを更新し、描画するための計算を行います。

OnCalculateは10個の引数が入っており意味は以下の様になっています。

引数名 説明
int rates_total チャートに表示されているバー(ローソク足)の総数。
int prev_calculated 前回計算されたバーの数。最初の計算では0、その後は前回の計算結果を引き継いで計算を行います。
datetime &time[] 各バーの時間情報が格納された配列。
double &open[] 各バーの始値が格納された配列。
double &high[] 各バーの高値が格納された配列。
double &low[] 各バーの安値が格納された配列。
double &close[] 各バーの終値が格納された配列。
long &tick_volume[] 各バーのティックボリューム(価格変動回数)が格納された配列。
long &volume[] 各バーの実際の取引量が格納された配列。
int &spread[] 各バーのスプレッド(買いと売りの価格差)が格納された配列。

MQL5はOnCalculateの引数を順番で見ていますので、表示されているコードと同じ順番で使いましょう。

計算処理を解説

if (rates_total < 4)

if (rates_total < 4) // 3連続陽線なので最低4本必要
return 0;

rates_totalは、現在チャートに表示されているローソク足(バー)の数を示しています。

今回の計算には最低でも4本のローソク足が必要です。もし4本未満の状態で計算を始めると、データが足りなくなりエラーが発生する可能性があります。

そのため、表示されているローソク足が4本未満の場合、計算を開始せずに処理を中断します。

int start = MathMax(prev_calculated - 1, 3);

int start = MathMax(prev_calculated - 1, 3);

「prev_calculated」は前回計算されたローソク足(バー)の数になります。

「prev_calculated - 1」は前回の計算結果の1つ前のバーから計算を再開するという意味になります。これにより、前回計算した場所から次に進めるようになります。

MathMax()は引数の2つの値のうち、大きい方を返す関数であることを意味します。具体的には、prev_calculated - 1(前回の計算での1つ前のバー)と「3」(3本目のバー) のうち、大きい方を選んでいます。

このコードにより、計算は前回の計算が終わった場所の次から始まるか、最低でも3本目のバーから計算が始まるようになります。

例えば、前回計算が2本目のバーで終わった場合、prev_calculated - 1は1になりますが、3と比べると3の方が大きいので、計算は3本目のバーから始まります。

もし前回計算が4本目のバーで終わった場合、prev_calculated - 1は3となり、3本目のバーから計算を再開します。

このようにすることで、計算をする場所が前回計算した場所の次から始まるか、最低でも3本目のバーから計算を始めるようにしています。

if (prev_calculated == 0)

if (prev_calculated == 0)
{
ArrayInitialize(BuySignalBuffer, EMPTY_VALUE);
}

このコードは、インディケーターが初めて計算を行うときに、BuySignalBuffer 配列を空の状態に初期化する処理です。

空の状態にすることで、配列に不要な値や古いデータが残らないようにします。これにより、インディケーターが正しいデータを使って計算できるようになります。

これがないと、BuySignalBuffer 配列に不要な値や古いデータが残り、計算結果が不正確になる可能性があります。

ArrayInitialize()の引数は以下の様になります。


ArrayInitialize(BuySignalBuffer, EMPTY_VALUE);

引数 説明
引数①: 配列 初期化する配列の名前。配列の要素すべてを指定した値で初期化します。例えば、BuySignalBufferなど。
引数②: 初期値 配列の各要素に設定する値。指定された値。(EMPTY_VALUE=初期化されていない状態)
for (int i = start; i <= rates_total - 2; i++)

 for (int i = start; i <= rates_total - 2; i++)
    {
        bool isBullish1 = (close[i] > open[i]);        // 3本目(今確定したバー)
        bool isBullish2 = (close[i - 1] > open[i - 1]); // 2本目
        bool isBullish3 = (close[i - 2] > open[i - 2]); // 1本目
        bool isBullish4 = (close[i - 3] > open[i - 3]); // 4本目(4連続チェック用)

        // ★「ちょうど3連続の時のみ」サインを出す → 4本目が陽線ならスルー
        if (isBullish1 && isBullish2 && isBullish3 && !isBullish4)
        {
            BuySignalBuffer[i] = low[i] - (Point() * 10);

            if (i == rates_total - 2 && LastAlertBarTime != time[i])
            {
                string msg = StringFormat("【アラート】3連続陽線!確定足: %s", TimeToString(time[i], TIME_DATE | TIME_MINUTES));
                Alert(msg);
                PlaySound("alert.wav");

                LastAlertBarTime = time[i];
            }
        }
        else
        {
            BuySignalBuffer[i] = EMPTY_VALUE;
        }
    }

for (int i = start; i <= rates_total - 2; i++)

for (int i = start; i <= rates_total - 2; i++)

上記式は、startからrates_total - 2までのローソク足(バー)を順番に処理するループです。

startは、MathMax(prev_calculated - 1, 3)によって設定され、最初の計算時には最低でも3本目のローソク足から計算が始まります。

初回の計算では、prev_calculatedが0なので、prev_calculated-1は-1になります。その為、MathMax(-1, 3)が適用され、startは3に設定されます。

つまり、3本目のローソク足から計算が始まります。

rates_totalは表示されているローソク足の総数を表し、rates_total-2はローソク足の総数から2を引いた位置を意味します。

例えば、ローソク足が100本の場合、rates_total-2は98本目となり、3本目から98本目までが処理されます。

※-2にする理由

例えば、ローソク足が100本ある場合、「rates_total - 2」という計算によって、98本目までを処理対象とします。

その理由は、一番新しいローソク足(0番目の足)は、まだ値動きの途中で確定していないからです。この「未確定の足」を計算に含めると、後で値が変わってしまう可能性があり、正しい分析やインジケーターの計算ができなくなります。

さらに、「rates_total - 1」も計算から除外することがあります。

これは、インジケーターによっては、最後の1本もまだ安定しないと考え、安全のために計算範囲を「rates_total - 2」までに設定しているからです。

「rates_total - 1」のバーは、確定直後またはまだ完全に処理されていないタイミングだと、データが変動することがあります。これは、ティックごとの更新とバーの確定処理が完全に同期していないために起こる現象です。

bool isBullish1 = (close[i] > open[i]);

bool isBullish1 = (close[i] > open[i]);        // 3本目(今確定したバー)
bool isBullish2 = (close[i - 1] > open[i - 1]); // 2本目
bool isBullish3 = (close[i - 2] > open[i - 2]); // 1本目
bool isBullish4 = (close[i - 3] > open[i - 3]); // 4本目(4連続チェック用)

たとえば、i = 3 の場合は…

インデックス 表すバー コメントの解釈 実際のローソク足
i 3 3本目 4本前のバー
i - 1 2 2本目 3本前のバー
i - 2 1 1本目 2本前のバー
i - 3 0 4本目 最新のバー(未確定) ←基本は使わない

このコードは、4本のローソク足が全て陽線かどうかを確認するためのものです。各行で、close[i](終値)がopen[i](始値)より大きければ陽線(上昇)と判定し、4本のローソク足について陽線かどうかを判断しています。

isBullish1: 今確定したバーが陽線かどうか
isBullish2: 1つ前のバーが陽線かどうか
isBullish3: 2つ前のバーが陽線かどうか
isBullish4: 4つ前のバーが陽線かどうか

boolは、論理型(ブール型)と呼ばれるデータ型で真(true)または偽(false)の2つの値だけを取ります。

bool isBullish = (close[i] > open[i]); // 終値が始値より大きければtrue、そうでなければfalse

if (isBullish1 && isBullish2 && isBullish3 && !isBullish4)

 if (isBullish1 && isBullish2 && isBullish3 && !isBullish4)

このif文では、&&(論理AND演算子)を使って、すべての条件がtrueであるかを確認しています。

&&(論理AND演算子)は、両方の条件がtrueである時だけ、全体がtrueになる演算子です。例えば、A && B の場合、AもBもtrueでないと、結果はtrueになりません。

BuySignalBuffer[i] = low[i] - (Point() * 10);

BuySignalBuffer[i] = low[i] - (Point() * 10);

if (isBullish1 && isBullish2 && isBullish3 && !isBullish4)で全てがtrueの時にバッファ(BuySignalBuffer[i] )に値を入れます。

BuySignalBuffer[i] には、i番目のバーの安値から最小価格変動幅(Point())の10倍を引いた値が格納され、その位置にサインが表示されます。

アラートの処理

if (i == rates_total - 2 && LastAlertBarTime != time[i])
{
string msg = StringFormat("【アラート】3連続陽線!確定足: %s", TimeToString(time[i], TIME_DATE | TIME_MINUTES));
Alert(msg);
PlaySound("alert.wav");

LastAlertBarTime = time[i];
}

このコードは、チャート上で「3本連続の陽線」が確定したタイミングで、トレーダーに知らせるアラート機能です。

仕組みとしては、最後から2本目(1つ前の確定したローソク足)をチェックし、「今回アラートを出す対象のバーの時間」と「前回アラートを出した時間」が異なっているかを確認しています。

もし違っていれば、それは新しいシグナルだと判断し、画面にアラートを表示して音を鳴らします。

また、同じバーでアラートが何度も鳴らないように、「このバーではもうアラートを出した」という情報を記録しています。これにより、アラートは新しいバーが確定してから、次の条件がそろったときにだけ発動するようになっています。

処理内容 説明
if (i == rates_total - 2 && LastAlertBarTime != time[i]) 最後から2番目の確定バーで、かつ前回アラートを出した時間と違う場合に実行する。重複アラートを防ぐ。
string msg = StringFormat("【アラート】3連続陽線!確定足: %s", TimeToString(time[i], TIME_DATE | TIME_MINUTES)); アラート用のメッセージを作成する。3連続陽線が発生した確定足の日時をわかりやすく表示するための文字列。
Alert(msg); 作成したメッセージを画面に表示し、ポップアップ通知を出す。
PlaySound("alert.wav"); 指定したアラート音(alert.wav)を再生し、音で知らせる。
LastAlertBarTime = time[i]; アラートを出したバーの時間を記録し、同じバーでアラートが重複して鳴らないようにする。

コメント

タイトルとURLをコピーしました