自身の備忘録も兼ねて、RSIを用いたサインツールのソースコードをここに残します。
具体的な実装内容は下記の通り。
- RSIの値が30未満または70越えの時、矢印サインとアラートを鳴らす
- サインが出た後、次足での勝敗結果に応じてマル・バツ印を表示
- リペイント(終値が確定した過去足のサイン変更)は無し
- 勝率を集計し画面上に表示する
RSIの値を使ったサインツールですが、当然このまま使うだけでは何の役にも立たないので、コピペ後自由にロジックを書き換えて使用することをオススメします。
目次
コピペOK!RSIサインツールのソースコード
※コードブロック右上の「Copy」をクリックすることで、一括コピーすることができます。
//+------------------------------------------------------------------+
//| origintool.mq4 |
//| Copyright 2020, MetaQuotes Software Corp. |
//| |
//+------------------------------------------------------------------+
#property copyright "オリジナルインジケーター" //インジケータータイトル
#property link "" //参考リンク設定
#property version "1.00" //バージョン情報
#property strict //パラメーターの日本語表示
#property indicator_chart_window //メインチャートへの表示
//インジケーターで何本のラインや矢印を使うか
#property indicator_buffers 4
//ラインのカラー設定
#property indicator_color1 clrBlue
#property indicator_color2 clrRed
#property indicator_color3 clrYellow
#property indicator_color4 clrYellow
//ラインの太さ
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 2
#property indicator_width4 2
//バッファーの宣言(サインを格納する配列)
double Buffer_0[], Buffer_1[], Buffer_2[], Buffer_3[];
//+------------------------------------------------------------------+
//| 初期化関数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
//使用するバッファ数
IndicatorBuffers(4);
//用意したインジケーターバッファに、どの変数と対応させるかの設定
SetIndexBuffer(0, Buffer_0);
SetIndexBuffer(1, Buffer_1);
SetIndexBuffer(2, Buffer_2);
SetIndexBuffer(3, Buffer_3);
//インジケーターをラインにする設定(ラインの場合「DRAW_LINE」)
SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID);
SetIndexStyle(1, DRAW_ARROW, STYLE_SOLID);
SetIndexStyle(2, DRAW_ARROW, STYLE_SOLID);
SetIndexStyle(3, DRAW_ARROW, STYLE_SOLID);
//サインの種類
SetIndexArrow(0, 233);
SetIndexArrow(1, 234);
SetIndexArrow(2, 161);
SetIndexArrow(3, 251);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| インジケーター削除時に一度だけ実行 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//オブジェクトを全て削除
ObjectsDeleteAll();
}
//+------------------------------------------------------------------+
//| 変数定義 |
//+------------------------------------------------------------------+
extern int maxBars = 2000; //対象本数範囲
extern int totalCnt = 0; //合計判定回数
extern int winCnt = 0; //合計勝利回数
extern int loseCnt = 0; //合計敗北回数
extern double endPrise = 0; //終値格納用変数
extern bool isJudge = false; //次足判定制御用
extern bool upEntryFlag = false; //勝利判定フラグ
extern bool downEntryFlag = false; //敗北判定フラグ
extern int cognitoBars = 0; //認識済みのローソク足
//+------------------------------------------------------------------+
//| 1ティック毎に実行 |
//+------------------------------------------------------------------+
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[])
{
//---
//過去チャートを見てサインを表示させた後、最新足のみ更新していく
//Bars・・・表示されているローソク足の本数 / IndicatorCounted・・・計算済み(変化していない)ローソク足の本数
int limit = Bars - IndicatorCounted() - 1;
//引数2つの内、小さい方の値を返す
limit = MathMin(limit, maxBars);
//チャート更新時の勝率計算バグを防ぐ処理
if(limit == Bars - 1) {
totalCnt = 0;
winCnt = 0;
loseCnt = 0;
}
//チャートを集計
for(int i = limit; i >= 0; i--) {
//RSIの値を取得 iRSI(通貨ペア,時間軸,期間,価格,シフト)
double RSI = iRSI(NULL,0,14,0,i);
double prevRSI = iRSI(NULL,0,14,0,i+1);
//現在足の集計
if(i == 0) {
//ティックが動く毎にサインを初期化
Buffer_0[i] = EMPTY_VALUE;
Buffer_1[i] = EMPTY_VALUE;
//RSIが30未満の時
if(RSI < 30) {
//上矢印を安値の1pips下に出す。(1*Point=0.1pips)
Buffer_0[i] = iLow(NULL,0,i)-10*Point;
//新しくサインが出た時のみアラートを鳴らす
if(cognitoBars < Bars){
Alert(Symbol()+" M"+Period()+" High Sign");
cognitoBars = Bars;
}
}
//RSIが70超えの時
if(RSI > 70) {
//下矢印を高値の1pips上に出す。(1*Point=0.1pips)
Buffer_1[i] = iHigh(NULL,0,i)+10*Point;
//新しくサインが出た時のみアラートを鳴らす
if(cognitoBars < Bars){
Alert(Symbol()+" M"+Period()+" LOW Sign");
cognitoBars = Bars;
}
}
}//現在足の集計
//過去足の集計
if(i > 1){
//RSIが30未満の時
if(RSI < 30) {
//上矢印を安値の1pips下に出す。(1*Point=0.1pips)
Buffer_0[i] = iLow(NULL,0,i)-10*Point;
//エントリー確定時フラグを立てる
upEntryFlag = true;
//エントリー確定時の終値を格納
endPrise = iClose(NULL,0,i); }
//RSIが70超えの時
if(RSI > 70) {
//下矢印を高値の1pips上に出す。(1*Point=0.1pips)
Buffer_1[i] = iHigh(NULL,0,i)+10*Point;
//エントリー確定時フラグを立てる
downEntryFlag = true;
//エントリー確定時の終値を格納
endPrise = iClose(NULL,0,i);
}
}//過去足の集計
//勝敗判定
if(upEntryFlag) {
//isJudgeがfalseの場合、一回処理を飛ばす(次足で判定サインを出したい為)
if(isJudge) {
//前足の終値よりも次足の終値の方が大きかった場合
if(endPrise < iClose(NULL,0,i)) {
//丸印を安値の1pips下に出す。(1*Point=0.1pips)
Buffer_2[i] = iLow(NULL,0,i)-10*Point;
upEntryFlag = false;
winCnt++;
} else {
//バツ印を安値の1pips下に出す。(1*Point=0.1pips)
Buffer_3[i] = iLow(NULL,0,i)-10*Point;
upEntryFlag = false;
loseCnt++;
}
isJudge = false;
} else {
isJudge = true;
}
}
if(downEntryFlag) {
//isJudgeがfalseの場合、一回処理を飛ばす(次足で判定サインを出したい為)
if(isJudge) {
//前足の終値よりも次足の終値の方が小さかった場合
if(endPrise > iClose(NULL,0,i)) {
//丸印を高値の1pips上に出す。(1*Point=0.1pips)
Buffer_2[i] = iHigh(NULL,0,i)+10*Point;
downEntryFlag = false;
winCnt++;
} else {
//バツ印を高値の1pips上に出す。(1*Point=0.1pips)
Buffer_3[i] = iHigh(NULL,0,i)+10*Point;
downEntryFlag = false;
loseCnt++;
}
isJudge = false;
} else {
isJudge = true;
}
}
}//チャートを集計(for文終了)
//勝率表示オブジェクトを作成&更新
CreateRateView();
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| 勝率表示オブジェクトを作成 |
//+------------------------------------------------------------------+
void CreateRateView()
{
//勝率オブジェクト作成
ObjectCreate("obj_judgeMonitor",OBJ_LABEL,0,0,0);
ObjectSet("obj_judgeMonitor",OBJPROP_CORNER,CORNER_LEFT_UPPER);
ObjectSet("obj_judgeMonitor",OBJPROP_XDISTANCE,10);
ObjectSet("obj_judgeMonitor",OBJPROP_YDISTANCE,20);
//勝率計算
totalCnt = winCnt + loseCnt;
double rate = MathRound((double)winCnt/totalCnt*100);
ObjectSetText("obj_judgeMonitor", "判定:"+(string)totalCnt+" 勝ち:"+(string)winCnt+" 勝率:"+(string)rate+"%", 11, "メイリオ", clrWhite);
}
//+------------------------------------------------------------------+