【MT4のプログラミングをやってみる】3本のRCIを利用したサインツールを作成

 

まえがき

こんにちは、こんばんは、脱初心者トレーダーさつま芋です。

 

ちょっと調べたり考えたりすれば分かるような盲点情報などをシェアしたいと思います。

 

 

HTのMQL習得 Step5 3本のRCIを利用したサインツールを作成

今回は次の動画をタイプしてみました。

 

www.youtube.com

 

コード

//+------------------------------------------------------------------+
//| 3RCI_Sign.mq4 |
//| HT FX |
//| http://htfx.blog.fc2.com/ |
//+------------------------------------------------------------------+
#property copyright "HT FX"
#property link "http://htfx.blog.fc2.com/"
#property description "Copyright (C) 2020 HT FX All Rights Reserved.\n"
#property description "http://htfx.blog.fc2.com/\n"
#property description "htfxjp@gmail.com"
#property version "1.00"
#property strict
#property indicator_separate_window
#property indicator_maximum 1
#property indicator_minimum -1
#property indicator_buffers 3
#property indicator_plots 3
#property indicator_color1 clrWhite
#property indicator_color2 clrYellow
#property indicator_color3 clrRed
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 1
#property indicator_style1 STYLE_SOLID
#property indicator_style2 STYLE_SOLID
#property indicator_style3 STYLE_SOLID

//+------------------------------------------------------------------+
//| Input parameters |
//+------------------------------------------------------------------+
input int BARS = 500; // 計算バー本数
input int PERIOD_S = 10; // 短期
input int PERIOD_M = 20; // 中期
input int PERIOD_L = 50; // 長期

//--- indicator buff
double RCI0, RCI1, RCI2;

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
IndicatorSetInteger(INDICATOR_DIGITS, 6);
SetIndexStyle(0, DRAW_LINE);
SetIndexStyle(1, DRAW_LINE);
SetIndexStyle(2, DRAW_LINE);
SetIndexBuffer(0, RCI0, INDICATOR_DATA);
SetIndexBuffer(1, RCI1, INDICATOR_DATA);
SetIndexBuffer(2, RCI2, INDICATOR_DATA);
SetIndexLabel(0, "RCI(" + (string)PERIOD_S + ")");
SetIndexLabel(1, "RCI(" + (string)PERIOD_M + ")");
SetIndexLabel(2, "RCI(" + (string)PERIOD_L + ")");
string name = "RCI(" + (string)PERIOD_S + "," +(string)PERIOD_M + "," + (string)PERIOD_L + ")";
IndicatorSetString(INDICATOR_SHORTNAME, name);

return 0;
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, "3RCI_Sign");
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars = IndicatorCounted();
//---- check for possible errors
if(counted_bars < 0)
return -1;
//---- last counted bar will be recounted
if(counted_bars > 0)
counted_bars--;

int limit = MathMin(Bars - 1, BARS);
// if (limit < 1) limit = 1;

ObjectsDeleteAll(0, "3RCI_Sign");

for(int i = limit; i >= 0; i--)
{
RCI0[i] = iRCI(NULL, 0, PERIOD_S, i);
RCI1[i] = iRCI(NULL, 0, PERIOD_M, i);
RCI2[i] = iRCI(NULL, 0, PERIOD_L, i);

bool upNow = RCI0[i] > RCI1[i] && RCI1[i] > RCI2[i];
bool upPre = RCI0[i+1] > RCI1[i+1] && RCI1[i+1] > RCI2[i+1];
bool dnNow = RCI0[i] < RCI1[i] && RCI1[i] < RCI2[i];
bool dnPre = RCI0[i+1] < RCI1[i+1] && RCI1[i+1] < RCI2[i+1];

if(upNow && !upPre)
{
string name = "3RCI_Sign" +(string)i;
ObjectCreate(0, name, OBJ_ARROW, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_TIME, 0, Time[i]);
ObjectSetDouble(0, name, OBJPROP_PRICE, 0, Low[i]);
ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_TOP);
ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
ObjectSetInteger(0, name, OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, name, OBJPROP_ARROWCODE, 233);
}
if(dnNow && !dnPre)
{
string name = "3RCI_Sign" +(string)i;
ObjectCreate(0, name, OBJ_ARROW, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_TIME, 0, Time[i]);
ObjectSetDouble(0, name, OBJPROP_PRICE, 0, High[i]);
ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_BOTTOM);
ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
ObjectSetInteger(0, name, OBJPROP_COLOR, clrDodgerBlue);
ObjectSetInteger(0, name, OBJPROP_ARROWCODE, 234);
}

}

return 0;
}

//+------------------------------------------------------------------+
//| RCI function by HT |
//+------------------------------------------------------------------+
double iRCI(string symbol, ENUM_TIMEFRAMES timeframe, int period, int index)
{
int data;
ArrayResize(data, period);
double dig = MathPow(10, SymbolInfoInteger(symbol, SYMBOL_DIGITS));
for(int i = 0; i < period; i++)
data[i] = int(iClose(symbol, timeframe, i + index) * dig); // 終値を整数化して格納

double rank;
int tie
;
ArrayResize(rank, period);
ArrayResize(tie, period);
ArrayInitialize(rank, 0);
ArrayInitialize(tie, 0);
for(int i = 0; i < period; i++)
{
for(int j = 0; j < period; j++)
{
if(i == j)
continue;
if(data[i] <= data[j])
rank[i]++; // 順位積算
if(data[i] == data[j])
tie[i]++; // 同値カウント
}
}

double d = 0;
for(int i = 0; i < period; i++)
{
if(tie[i] > 0)
rank[i] -= tie[i] / 2.0; // 同値順位調整
d += MathPow(rank[i] - i, 2); // (順位-順番)の2乗を積算
}

return(1 - 6 * d / (period * (period * period - 1))); // スピアマンの順位相関係数
}

//+------------------------------------------------------------------+
//| RCI function (オリジナルRCIを模擬したバージョン) by HT |
//+------------------------------------------------------------------+
/*double iRCI(string symbol, ENUM_TIMEFRAMES timeframe, int period, int index)
{
int data;
double TrueRanks
;
ArrayResize(data, period);
ArrayResize(TrueRanks, period);

double dig = MathPow(10, SymbolInfoInteger(symbol, SYMBOL_DIGITS));
for(int i = 0; i < period; i++) {
data[i] = int(iClose(symbol, timeframe, i + index) * dig); // 終値を整数化して格納
TrueRanks[i] = i + 1;
}

int sort;
ArrayResize(sort, period);
ArrayCopy(sort, data);
ArraySort(sort, WHOLE_ARRAY, 0, MODE_DESCEND); // 降順で並べ替え MT4バージョン
// ArraySort(sort); // 昇順で並べ替え MT5バージョン
// ArrayReverse(sort); // 順番を反転 MT5バージョン

for(int i = 0; i < period - 1; i++) {
if(sort[i] != sort[i + 1]) continue; // 同値でなければスルー
int k = i + 1;
int count = 1;
double average = k;
while(k < period) {
if(sort[k] == sort[i]) {
count++;
average += k + 1; // 同値だった順位を積算
k++;
}
else break;
}
average = average / count; // 順位の平均化
for(int j = i; j < k; j++) TrueRanks[j] = average; // 平均化した順位に置き換え
i = k; // ←ココがミスっていますが、オリジナルに合わせてそのままにしてます
}

double rank;
ArrayResize(rank, period);
for(int i = 0; i < period; i++) {
int n = 0;
while(n < period) {
if(data[i] == sort[n]) {
rank[i] = TrueRanks[n]; // 終値に相当する順位値を格納
break;
}
n++;
}
}

double d = 0;
for(int i = 0; i < period; i++) {
d += MathPow(rank[i] - i - 1, 2); // (順位-順番)の2乗を積算
}

return(1 - 6 * d / (period * (period * period - 1))); // スピアマンの順位相関係数
}*/

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

 

 

あとがき

コンパイル&実行した画像は次の状態でした。

 

f:id:satsumaim0:20200709165248p:plain


ちょこちょことタイピングしているのですが、SetIndexLabelなど分からないことに少しづつ気づけるようになってきました。

 

以上、さつま芋でした。