348 lines
12 KiB
MQL5
348 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);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|