MQL4でRSIサインツールを作りたい方必見!ChatGPTを活用して、RSIが70以上・30以下でサインを出すインジケーターを簡単に作成・カスタマイズする方法を詳しく解説。コードの意味や修正方法も分かりやすく説明します。
サインツールを使ってFXやバイナリーオプションを攻略しよう!
項目 | 内容 |
---|---|
RSIサインツールの作り方 | ChatGPTを活用してMQL4でサインツールを作成する方法 |
ChatGPTの活用方法 | コード作成・修正の依頼手順やポイント |
RSIサインの条件設定 | RSIが70以上で売り、30以下で買いのサインを出すコード |
コードの解説 | 各コードの役割(プロパティ、バッファ、関数)を詳しく説明 |
修正・カスタマイズ | RSIの反転ポイントでサインを出すように条件を追加 |
MQL4の学習方法 | ChatGPTを使って分からない部分を学習するコツ |
RSIのサインツールの作り方
コードを作ろう
RSIのサインツールを作るなら、ChatGPTの活用をおすすめします。
MQL4やMQL5は解説サイトが少なく、学習できる情報が限られているため、独学が難しいのがデメリットです。
ChatGPTは完璧ではありませんが、使いこなせばかなり便利になります。
このページでは、ChatGPTを使ってRSIのサインツールを作る手順や、コードの意味を詳しく解説しています。
今回はチャットGPTに以下の依頼をしています。
RSIが70以上の時にサインを出す
RSIが30以下の時にサインを出す
チャットGPTを使う際の注意点
作ろう
コードを依頼する時は、完成形からでは無くベースとなるシンプルなコードから依頼しましょう。
シンプルなコードから作った方が学習しやすくなります。
いきなり複雑なコードを作った場合、学習の難易度が上がり挫折しやすくなるので初心者の方は注意が必要です。
RSIが70以上の時と30以下の時にサインが出るコード
チャットGPTでも充分に書ける
実際にチャットGPTに書いて貰ったコードになります。
RSIが70以上の時にサインを出す
RSIが30以下の時にサインを出す
//+------------------------------------------------------------------+
//| RSIシグナルインジケーター |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue
// バッファ定義
double BuySignal[];
double SellSignal[];
// 設定
input int RSI_Period = 14;
input int RSI_Overbought = 70;
input int RSI_Oversold = 30;
//+------------------------------------------------------------------+
//| インジケータの初期化 |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, BuySignal);
SetIndexBuffer(1, SellSignal);
SetIndexStyle(0, DRAW_ARROW);
SetIndexStyle(1, DRAW_ARROW);
SetIndexArrow(0, 233); // 上向き矢印(買い)
SetIndexArrow(1, 234); // 下向き矢印(売り)
IndicatorShortName("RSI Signals");
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 < 1) return 0;
for(int i = prev_calculated; i < rates_total; i++)
{
double rsi = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, i);
// 初期化(サインなしの場合は空)
BuySignal[i] = EMPTY_VALUE;
SellSignal[i] = EMPTY_VALUE;
// RSIが30以下のとき買いサイン
if (rsi <= RSI_Oversold)
{
BuySignal[i] = low[i] - (Point * 5); // ひげの少し下に矢印を表示
}
// RSIが70以上のとき売りサイン
if (rsi >= RSI_Overbought)
{
SellSignal[i] = high[i] + (Point * 5); // ひげの少し上に矢印を表示
}
}
return rates_total;
}
コードを実行するとRSIが70以上の時とRSIが30以下の時にサインが出ている事が分かります。
コードで分からない箇所はすべてチャットGPTに質問する
チャットGPTの強みはプログラムに強い事です。コードで分からない箇所は全て答えてくれます。
例えば以下の内容が分からなったとします。
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue
分からない部分をチャットGPTに貼り付けて以下の様に質問します。
以下の意味を簡潔に表にまとめて
実際に質問した結果、簡潔に表にまとめてくれました。
分からない箇所を潰していくだけでMQL4の知識が増えていきます。
スクールや専門書で学習するのも一つの手ですが、チャットGPTは学習方法として優れていると個人的には思っています。
コードの解説
コードの基礎に関しては関連記事をご確認下さい。関連記事ではインジケーターの設置方法からコードの基礎部分を分かりやすく解説しています。

propertyを解説
インジケーターの設定を行う
#property は、MQL4のスクリプトでインジケーターの動作や見た目を設定する命令です。例えば、インジケーターをメインチャートに表示するか、色を何にするか などを決めることができます。
コード | 意味 |
---|---|
#property indicator_chart_window | インジケーターをメインチャート上に表示する設定 |
#property indicator_buffers 2 | 2つのバッファ(買い・売りシグナル)を使用する設定 |
#property indicator_color1 Red | バッファ1(買いシグナル)の色を赤に設定 |
#property indicator_color2 Blue | バッファ2(売りシグナル)の色を青に設定 |
今回はRSIが70以上の時のサインとRSIが30以下の時のサインの2種類が必要なので、バッファを2つ用意します。
ここではインジケーターをメインチャート上に表示する設定やサインの色を設定しています。
バッファの定義を解説
詳しく解説
例えば、RSIのサインを表示するために、「買いサインの位置」や「売りサインの位置」 を保存する箱が必要です。
今回のコードでは、2つのバッファを使っています。
1つ目のバッファ(赤色) → 買いサインの位置を保存
2つ目のバッファ(青色) → 売りサインの位置を保存
バッファに値を入れることで、チャートにサイン(矢印)を表示できるようになります!
コード | 意味 |
---|---|
double BuySignal[]; | 買いシグナル用のバッファ(配列)・買いサインの位置を保存 |
double SellSignal[]; | 売りシグナル用のバッファ(配列)・売りサインの位置を保存 |
まず初めにdouble BuySignal[];を定義します。
この時点でBuySignal[]はただの配列に過ぎません。
次に確認して欲しいのが「SetIndexBuffer(0, BuySignal);」です。
SetIndexBuffer(0, BuySignal);にBuySignal[]が使われています。
SetIndexBuffer(0, BuySignal);を実行すると、BuySignal[]はMetaTraderにバッファとして登録されます。
【重要】MetaTraderは BuySignal[](バッファ)をリアルタイムで監視できるようになります。
そのため、OnCalculate()で BuySignal[]に値が入るたびに、MetaTrader がそれを読み取って描画することができます。
SetIndexBuffer(0, BuySignal);はBuySignal[]をバッファとして登録し、値がリアルタイムで反映されるようにする役割を持ちます。
RSI設定用の変数を解説
変数を用意
RSI用の変数も用意しておきます。
コード | 意味 |
---|---|
input int RSI_Period = 14; | RSIの変動を計算する基準 |
input int RSI_Overbought = 70; | 売りシグナルの基準 |
input int RSI_Oversold = 30; | 買いシグナルの基準 |
後程紹介しますが、変数はiRSI関数で使用します。
OnInit()を解説
初期設定を行う
int OnInit()でインジケーターの初期化(初期設定)を行います。
コード | 意味 |
---|---|
SetIndexBuffer(0, BuySignal); | BuySignal をバッファ0に設定 |
SetIndexBuffer(1, SellSignal); | SellSignal をバッファ1に設定 |
SetIndexStyle(0, DRAW_ARROW); | バッファ0(買いシグナル)を矢印として描画 |
SetIndexStyle(1, DRAW_ARROW); | バッファ1(売りシグナル)を矢印として描画 |
SetIndexArrow(0, 233); | 買いシグナルの矢印を「上向き」に設定 |
SetIndexArrow(1, 234); | 売りシグナルの矢印を「下向き」に設定 |
IndicatorShortName(“RSI Signals”); | インジケーター名を「RSI Signals」に設定。このコードを実行すると、チャートの左上に「RSI Signals」と表示。 |
return(INIT_SUCCEEDED); | 初期化が成功したことを返す |
SetIndexBuffer(0, BuySignal); を実行すると、BuySignal[] はMetaTraderに登録されるバッファになります。バッファになったBuySignal[] に値を入れると、チャートにサインが表示される仕組みです。
OnCalculate()を解説
引数の数を確かめよう
MetaTrader(MT4)は、新しいローソク足ができたり、価格が更新されるたびに OnCalculate() を自動で実行します。
この関数の中で、RSIの計算やサインを表示する処理を行います。
OnCalculate()の中には10個の引数が入っています。
その為、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[])
{
の様に記入します。
しかしチャットGPTにコードを書かせるとOnCalculate()の中身を省略する為、コンパイル時にエラーが発生します。
コンパイル時にOnCalculateでエラーが発生した場合は引数が省略されていないか確かめてみましょう。
引数の意味は以下の様になります。
引数 | 役割 |
---|---|
rates_total | チャート上のローソク足の本数 |
prev_calculated | 前回計算したローソク足の本数 |
time[] | 各ローソク足の時間(タイムスタンプ) |
open[] | 各ローソク足の始値 |
high[] | 各ローソク足の高値 |
low[] | 各ローソク足の安値 |
close[] | 各ローソク足の終値 |
tick_volume[] | 各ローソク足のティック(取引)回数 |
volume[] | 各ローソク足の出来高 |
spread[] | 各ローソク足のスプレッド(買値と売値の差) |
計算処理を解説
ローソク足の本数(rates_total)が1本未満なら計算を中止する処理 です。
if文を簡略しない場合は以下の様になります。
if (rates_total < 1) {
return 0;
}
OnCalculate() で return 0;を実行すると、そこで関数の処理が終了し、それ以降のコードは実行されません。
前回の計算位置 (prev_calculated) から最新のローソク足 (rates_total) までループ処理を行う
部分 | 意味 |
---|---|
int i = prev_calculated; | ループの開始位置(前回の計算済みローソク足の位置) |
i < rates_total; | 最新のローソク足 (rates_total) まで繰り返す |
i++ | 1つずつローソク足を処理 |
略さなかった場合は以下の様になります。
int i = prev_calculated; // ループの開始位置(前回計算済みのインデックス)
while (i < rates_total) { // 最新のローソク足まで繰り返す
// ここに計算処理を書く
i++; // インデックスを1つ進める
}
iRSI関数を解説
RSIの値を取得する
RSIの値を取得するには「iRSI関数」が使われます。
iRSI関数の引数は以下のようになります。
引数 | 役割 | 設定例 |
---|---|---|
symbol | 通貨ペア(NULL で現在のチャート) | NULL |
timeframe | 時間足(0 で現在の時間足) | 0 |
period | RSI の計算期間 | 14 |
applied_price | 計算に使う価格(終値など) | PRICE_CLOSE |
shift | 取得するローソク足の位置(0 なら最新) | i |
今回のコードでは、以下のように各引数が設定されます。
iRSI(
NULL // 現在のチャートの通貨ペア
0 // 現在開いているチャートの時間足
RSI_Period // RSIの計算期間
PRICE_CLOSE // 終値
i // 取得するローソク足の位置
);
double rsi = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, i);
この場合、変数「rsi」には「i番目のローソク足のRSIの値が代入」されます。
コードに条件を継ぎ足す
コードに条件を継ぎ足す
現時点のコードではRSIが70以上もしくは30以下の全てのローソク足に矢印が表示されていますが、ここから好みに合わせてコードの変更を行います。
RSIでサインが欲しいのは基本的に「RSIが70を超えた後、70を下回る時」もしくは「RSIが30を下回った後、30を上回る時」になります。
RSIは逆張りで使う人も多いので、逆張りに適したサインを表示させます。
今回の条件を言葉に変えると「前のRSIが70以上で現在のRSIが70を下回る時」、「前のRSIが30以下で現在のRSIが30を上回る時」になります。
MQL4でコードが書ける方であれば問題ないのですが、プログラミング初心者の方はチャットGPTを活用しましょう。
ここで重要になるのがチャットGPTへの依頼の手順です。
最初に依頼したコードをチャットGPTに読み込ませ、コードを覚えさせます。
その後にチャットGPTに依頼修正を依頼します。
現在のローソク足を基準にして
前のRSIが70以上で現在のRSIが70を下回る時にサインを出す
前のRSIが30以下で現在のRSIが30を上回る時にサインを出す
※RSIの判定がうまくいかない場合は「現在のローソク足を基準にして」と伝えるとうまくいきます。
修正済のコード
//+------------------------------------------------------------------+
//| RSIシグナルインジケーター |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue
// バッファ定義
double BuySignal[];
double SellSignal[];
// 設定
input int RSI_Period = 14;
input int RSI_Overbought = 70;
input int RSI_Oversold = 30;
//+------------------------------------------------------------------+
//| インジケータの初期化 |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, BuySignal);
SetIndexBuffer(1, SellSignal);
SetIndexStyle(0, DRAW_ARROW);
SetIndexStyle(1, DRAW_ARROW);
SetIndexArrow(0, 233); // 上向き矢印(買い)
SetIndexArrow(1, 234); // 下向き矢印(売り)
IndicatorShortName("RSI Signals");
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 < 2) return 0;
for(int i = prev_calculated; i < rates_total; i++)
{
double rsi = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, i);
double prev_rsi = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, i + 1);
// 初期化(サインなしの場合は空)
BuySignal[i] = EMPTY_VALUE;
SellSignal[i] = EMPTY_VALUE;
// RSIが30以下のとき買いサイン
if (prev_rsi <= RSI_Oversold && rsi > RSI_Oversold)
{
BuySignal[i] = low[i] - (Point * 5); // ひげの少し下に矢印を表示
}
// RSIが70以上のとき売りサイン
if (prev_rsi >= RSI_Overbought && rsi < RSI_Overbought)
{
SellSignal[i] = high[i] + (Point * 5); // ひげの少し上に矢印を表示
}
}
return rates_total;
}
動作を確認すると、指定された条件でコードが出ている事が分かります。
コードの修正後、チャットGPTに「変更点を抜き出して」と指定します。
// 前のRSI値を取得
double prev_rsi = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, i + 1);
// RSIが30以下から上抜けたとき買いサイン
if (prev_rsi <= RSI_Oversold && rsi > RSI_Oversold)
{
BuySignal[i] = low[i] - (Point * 5); // ひげの少し下に矢印を表示
}
// RSIが70以上から下抜けたとき売りサイン
if (prev_rsi >= RSI_Overbought && rsi < RSI_Overbought)
{
SellSignal[i] = high[i] + (Point * 5); // ひげの少し上に矢印を表示
}
修正された箇所のみ表示されます。
あとは修正された箇所を学習するだけです。
修正後の計算処理を解説
計算処理を解説
double prev_rsi = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, i + 1);
コードの修正後に追加された「prev_rsi」は前のローソク足のRSI値を表す変数になります。
iRSI()関数で前のRSIデータを抜き出す時「i + 1」と記入します。
前の値が欲しいのに何故「+1」になるのか?
MQL4では、現在のバー(最新の確定済みバー)のインデックスは0 で、過去のバーに向かうほどインデックスが1, 2, 3...と増えていきます。
インデックス | 説明 |
---|---|
0 | 現在のバー(最新の確定済みバー) |
1 | 1本前のバー(直前の確定バー) |
2 | 2本前のバー |
3 | 3本前のバー |
if (prev_rsi <= RSI_Oversold && rsi > RSI_Oversold)の意味は「前のRSIが30以下で、現在のRSIが30を上回ったら買いサインを出す」になります。
&& は 論理AND演算子で、両方の条件が真(true)のときにのみ処理を実行するという意味。
この場合、prev_rsi <= RSI_Oversold(前のRSIが30以下)と rsi > RSI_Oversold(現在のRSIが30を上回る)の両方が条件に当てはまる場合のみにサインが表示されます。
ローソク足の本数 (rates_total) が2本未満の場合、処理を終了する。
インジケーターを計算するには最低でも2本のローソク足が必要です。特にRSIのようなテクニカル指標は、前のバーとの比較が必要なので、1本だけでは計算できません。
この条件を入れることで、エラーを防ぎ、安全にインジケーターを動作させる ことができます。