SRL/SandR.mq5
super.admin 780e90f361 convert
2025-05-30 16:25:54 +02:00

347 lines
12 KiB
MQL5

//+------------------------------------------------------------------+
//| SandR.mq5 |
//| BP |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "BP"
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 10
#property indicator_plots 10
//--- plot R1
#property indicator_label1 "R1"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- plot S1
#property indicator_label2 "S1"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrBlue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
//--- plot R2
#property indicator_label3 "R2"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrRed
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//--- plot S2
#property indicator_label4 "S2"
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrBlue
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
//--- plot R3
#property indicator_label5 "R3"
#property indicator_type5 DRAW_ARROW
#property indicator_color5 clrRed
#property indicator_style5 STYLE_SOLID
#property indicator_width5 1
//--- plot S3
#property indicator_label6 "S3"
#property indicator_type6 DRAW_ARROW
#property indicator_color6 clrBlue
#property indicator_style6 STYLE_SOLID
#property indicator_width6 1
//--- plot R4
#property indicator_label7 "R4"
#property indicator_type7 DRAW_ARROW
#property indicator_color7 clrRed
#property indicator_style7 STYLE_SOLID
#property indicator_width7 1
//--- plot S4
#property indicator_label8 "S4"
#property indicator_type8 DRAW_ARROW
#property indicator_color8 clrBlue
#property indicator_style8 STYLE_SOLID
#property indicator_width8 1
//--- plot R5
#property indicator_label9 "R5"
#property indicator_type9 DRAW_ARROW
#property indicator_color9 clrRed
#property indicator_style9 STYLE_SOLID
#property indicator_width9 1
//--- plot S5
#property indicator_label10 "S5"
#property indicator_type10 DRAW_ARROW
#property indicator_color10 clrBlue
#property indicator_style10 STYLE_SOLID
#property indicator_width10 1
//--- input parameters
input int SRnumber=2; //Number of line (max 5)
input int BarNumber=50; //Number of bars to analyse high and low
input int HistBarNumber=200; //Number of bars to create the score
input double Tolerence=30; //Tolerence in detection of cluster
input int ScoreMinMax = 2; //Bonus for high or low
input int ScoreReverse = 100; //Bonus for reversal bars
input int CrossingPenalty = -100; //Penalty for crossing
input int ScoreLimit = -10000;
input int DrawBar = 2000;
//--- indicator buffers
double R1Buffer[];
double R2Buffer[];
double R3Buffer[];
double R4Buffer[];
double R5Buffer[];
double S1Buffer[];
double S2Buffer[];
double S3Buffer[];
double S4Buffer[];
double S5Buffer[];
//-- global variables
double lastOpen;
int sr_number;
int rCount;
int sCount;
double tol;
double rScore[];
double rValue[];
double sScore[];
double sValue[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,R1Buffer,INDICATOR_DATA);
SetIndexBuffer(1,S1Buffer,INDICATOR_DATA);
SetIndexBuffer(2,R2Buffer,INDICATOR_DATA);
SetIndexBuffer(3,S2Buffer,INDICATOR_DATA);
SetIndexBuffer(4,R3Buffer,INDICATOR_DATA);
SetIndexBuffer(5,S3Buffer,INDICATOR_DATA);
SetIndexBuffer(6,R4Buffer,INDICATOR_DATA);
SetIndexBuffer(7,S4Buffer,INDICATOR_DATA);
SetIndexBuffer(8,R5Buffer,INDICATOR_DATA);
SetIndexBuffer(9,S5Buffer,INDICATOR_DATA);
lastOpen = 0;
if(SRnumber>5){
sr_number = 5;
}
else{
sr_number = SRnumber;
}
ArrayFree(rScore);
ArrayFree(rValue);
ArrayFree(sScore);
ArrayFree(sValue);
rCount = 0;
sCount = 0;
//PrintFormat("Hello");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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[])
{
//---
//--- check for rates count
if(rates_total<HistBarNumber){
return(0);
}
int pos;
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,rates_total-DrawBar);
pos=prev_calculated-1;
if(pos < rates_total - DrawBar){
pos = rates_total - DrawBar;
}
if(pos < HistBarNumber){
pos = HistBarNumber+1;
}
for(int t=pos; t < rates_total; t++){
//ArraySetAsSeries(open,true);
//ArraySetAsSeries(close,true);
//ArraySetAsSeries(low,true);
//ArraySetAsSeries(high,true);
if(lastOpen == open[t]){
continue;
}
double min = 1000000;
double max = 0;
//if(lastOpen != open[0] && HistBarNumber<rates_total){
ArrayFree(rScore);
ArrayFree(rValue);
ArrayFree(sScore);
ArrayFree(sValue);
rCount = 0;
sCount = 0;
//set the tolerence
for(int i=t-BarNumber; i> t; i++){
if(high[i]>max){
max = high[i];
}
if(low[i]<min){
min = low[i];
}
}
tol = (max-min)/Tolerence;
for(int i= t-2; i > t - BarNumber; i--){
rCount++;
sCount++;
ArrayResize(rScore,rCount);
ArrayResize(rValue,rCount);
ArrayResize(sScore,sCount);
ArrayResize(sValue,sCount);
rScore[rCount-1]=0;
sScore[sCount-1]=0;
rValue[rCount-1]=high[i];
sValue[sCount-1]=low[i];
for(int j= t-2; j > t- HistBarNumber; j--){
if(i!=j){
//test high of bar[i] against all other high
if(high[j]<high[i]+tol && high[j]>high[i]-tol){
rScore[rCount-1] = rScore[rCount-1]+ScoreMinMax;
if(high[i]>rValue[rCount-1]){
rValue[rCount-1]=high[i];
}
}
//test high of bar[i] against close of bar that are going up and followed by a bar going down
else if(open[i]<close[i] && open[i-1]>close[i-1] && close[i]<high[j]+tol && close[i]>high[j]-tol){
rScore[rCount-1] = rScore[rCount-1]+ScoreReverse;
if(close[i]>rValue[rCount-1]){
rValue[rCount-1]=close[i];
}
}
//test low of bar[i] against all other low
if(low[j]<low[i]+tol && low[j]>low[i]-tol){
sScore[sCount-1] = sScore[sCount-1]+ScoreMinMax;
if(low[i]<sValue[sCount-1]){
sValue[sCount-1]=low[i];
}
}
//test low of bar[i] against close of bar that are going down and followed by a bar going up
else if(open[i]>close[i] && open[i-1]<close[i-1] && close[i]<low[j]+tol && close[i]>low[j]-tol){
sScore[sCount-1] = sScore[sCount-1]+ScoreReverse;
if(close[i]<sValue[sCount-1]){
sValue[rCount-1]=close[i];
}
}
}
}
}
//decrease the score if resistance had been crossed
for(int i=0; i<rCount; i++){
for(int j=t; j>t-BarNumber; j--){
if(rValue[i]>open[j] && rValue[i]<close[j]){
rScore[i] = rScore[i]+CrossingPenalty;
}
}
}
//decrease the score if support had been crossed
for(int i=0; i<sCount; i++){
for(int j=t; j>t-BarNumber; j--){
if(sValue[i]<open[j] && sValue[i]>close[j]){
sScore[i] = sScore[i]+CrossingPenalty;
}
}
}
for(int va=0; va<2; va++){
for(int i = 0; i<sCount; i++){
for(int j=i+1; j<sCount; j++){
if(sValue[j] < sValue[i]+tol && sValue[j] > sValue[i]-tol && sScore[i]!=-100000 && sScore[j]!=-100000){
if(sScore[j]>sScore[i]){
sScore[j]= sScore[j]+sScore[i];
sScore[i] = -100000;
if(sValue[j]>sValue[i]){
sValue[j] = sValue[i];
}
}
else if(sScore[i]!=-100000 && sScore[j]!=-100000){
sScore[i] = sScore[i]+sScore[j];
sScore[j] = -100000;
if(sValue[i]>sValue[j]){
sValue[i] = sValue[j];
}
}
}
}
//PrintFormat(i+", S Score:"+sScore[i]+", Price: "+sValue[i]);
}
for(int i = 0; i<rCount; i++){
for(int j=i+1; j<rCount; j++){
if(rValue[j] < rValue[i]+tol && rValue[j] > rValue[i]-tol && rScore[i]!=-100000 && rScore[j]!=-100000){
if(rScore[j]>rScore[i]){
rScore[j]= rScore[j]+rScore[i];
rScore[i] = -100000;
if(rValue[j] < rValue[i]){
rValue[j] = rValue[i];
}
}
else if(rScore[i]!=-100000 && rScore[j]!=-100000){
rScore[i] = rScore[i]+rScore[j];
rScore[j] = -100000;
if(rValue[i] < rValue[j]){
rValue[i] = rValue[j];
}
}
}
}
//PrintFormat(i+", R Score:"+rScore[i]+", Price: "+rValue[i]);
}
}
double S[5];
double R[5];
//PrintFormat(ArraySize(clusterScores));
ArrayFill(S,0,5,0);
ArrayFill(R,0,5,0);
for(int i=0; i<sr_number; i++){
if(ArrayMaximum(sScore) > ScoreLimit){
S[i]= sValue[ArrayMaximum(sScore)];
}
else{
S[i]= 0;
}
//PrintFormat("S"+(i+1)+": "+S[i]+", score: "+sScore[ArrayMaximum(sScore)]);
sScore[ArrayMaximum(sScore)] = -100000;
if(ArrayMaximum(rScore) > ScoreLimit){
R[i]= rValue[ArrayMaximum(rScore)];
}
else{
R[i]= 0;
}
//PrintFormat("R"+(i+1)+": "+R[i]+", score: "+rScore[ArrayMaximum(rScore)]);
rScore[ArrayMaximum(rScore)] = -100000;
}
lastOpen = open[t];
S1Buffer[t] = S[0];
S2Buffer[t] = S[1];
S3Buffer[t] = S[2];
S4Buffer[t] = S[3];
S5Buffer[t] = S[4];
R1Buffer[t] = R[0];
R2Buffer[t] = R[1];
R3Buffer[t] = R[2];
R4Buffer[t] = R[3];
R5Buffer[t] = R[4];
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+