window_rep/SRChannel.mq5

670 lines
22 KiB
MQL5
Raw Permalink Normal View History

2025-10-09 17:59:05 +03:00
//+------------------------------------------------------------------+
//| highs_lows.mq5 |
//| Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "AHMAD KAZBAR"
#property link "https://ahmedkzbar.web.app/"
#property version "1.6"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots 1
#property indicator_label1 "zigzag"
#include <Arrays/ArrayObj.mqh>
#include <draw.mqh>
#include <Tclass.mqh>
#include <gamma_level_panel.mqh>
input int Depth = 5 ; // Period
input int AtrPeriod= 200 ; // ATR Period
input double AtrFactor = 1.5 ; // Calculation between level On basis of ATR
input int lookback_htf = 12; // Calculate % of candles chart
input int history = 50; // History (Number of levels)
input bool candle_HeikenAshi = true; // Candle Type
input group "******* Style *******"
input bool show_break_lines = true ; // Show break lines
input group "******* High & Resitance Color *******"
input ColorList High_color = RedColor; // High Color
input ColorList Resitance_color = LightPinkColor; // Resitance Color
input group "******* Low & Support Color *******"
input ColorList Low_color = LightBlueColor; // Low Color
input ColorList Support_color = LightGreenColor; // Support Color
double ExtTRBuffer[],ExtATRBuffer[];
double ExtZigzag[];
double ExtTRBuffer_htf[],ExtATRBuffer_htf[];
double ExtRSI[];
double ExtRSIBuffer[];
double ExtPosBuffer[];
double ExtNegBuffer[];
color PH,PL,SC,RC;
CArrayObj prevResitance;
CArrayObj prevSupport;
CArrayObj lows;
CArrayObj highs;
string prefix;
datetime previousTimeCurrent = 0;
string btn1 ="btn1",btn2 = "btn2",btn3 ="btn3",btn4="btn4",btn5="btn5",btn6="btn6",btn7="btn7";
bool show_Resitance = false,show_Support = false,show_prevSupport =true,show_prevResitance = true,show_Break_levels = false;
bool show_Resitance_htf = true,show_Support_htf = true,show_prevSupport_htf = true,show_prevResitance_htf = true,show_htf_levels = false,show_levels = true;
datetime lastBarTime = 0;
datetime lastBarTimeDraw = 0;
int start_index;
double last_high,last_low,last_high_poi,last_low_poi;
int last_high_pos,last_low_pos;
datetime last_high_time,last_low_time;
CGmmaPanel gammaPanel;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CLevel : public CObject
{
public:
double c;
double o;
double h;
double l;
datetime t;
int i;
bool is_peak ;
string type;
int rsiValue;
CLevel(double _c,double _o,double _h,double _l,datetime _t,int _i,string _type,bool _peak,int _rsiValue = 0)
{
c = _c;
o = _o;
h = _h;
l = _l;
t= _t;
i = _i;
type = _type;
is_peak = _peak;
rsiValue = _rsiValue;
}
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
gammaPanel.ChartEvent(id,lparam,dparam,sparam);
if(id == CHARTEVENT_OBJECT_CLICK) // Check if an object (button) was clicked
{
if(sparam == btn1) // Check if it's our button
{
if(show_Resitance)
{
ObjectSetString(0, btn1, OBJPROP_TEXT, "Show Pivot High");
ObjectsDeleteAll(0,prefix+"Resitance");
}
else
{
ObjectSetString(0,btn1, OBJPROP_TEXT, "Hide Pivot High");
drawHighPivot();
}
show_Resitance = !show_Resitance;
}
if(sparam == btn2) // Check if it's our button
{
if(show_Support)
{
ObjectSetString(0, btn2, OBJPROP_TEXT, "Show Pivot Low");
ObjectsDeleteAll(0,prefix+"Support");
}
else
{
ObjectSetString(0,btn2, OBJPROP_TEXT, "Hide Pivot Low");
drawLowPivot();
}
show_Support = !show_Support;
}
/// END BTN2
if(sparam == btn3)
{
Print(prevSupport.Total());
if(show_prevSupport)
{
ObjectSetString(0, btn3, OBJPROP_TEXT, "Show Support Levels");
ObjectsDeleteAll(0,prefix+"prevSupport");
}
else
{
ObjectSetString(0, btn3, OBJPROP_TEXT, "Hide Support Levels");
drawSupport();
}
show_prevSupport = !show_prevSupport;
}
if(sparam == btn4)
{
Print(prevResitance.Total());
if(show_prevResitance)
{
ObjectSetString(0, btn4, OBJPROP_TEXT, "Show Resitance Levels");
ObjectsDeleteAll(0,prefix+"prevResitance");
}
else
{
ObjectSetString(0, btn4, OBJPROP_TEXT, "Hide Resitance Levels");
drawResitance();
}
show_prevResitance = !show_prevResitance;
}
}
ChartRedraw(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0,ExtZigzag,INDICATOR_DATA);
SetIndexBuffer(1,ExtATRBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(2,ExtTRBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(3,ExtRSIBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(4,ExtPosBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(5,ExtNegBuffer,INDICATOR_CALCULATIONS);
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
StringConcatenate(prefix,"SRChannel","\n");
previousTimeCurrent = iTime(_Symbol, PERIOD_CURRENT, 1);
start_index=0;
if(lookback_htf > 90)
{
Alert("Calculate % of candles chart number must be less than 90.");
return(INIT_FAILED);
}
PH = GetColor(High_color);
PL = GetColor(Low_color);
SC = GetColor(Support_color);
RC = GetColor(Resitance_color);
btn1 = "PANEL\n"+btn1;
btn2 = "PANEL\n"+btn2;
btn3 = "PANEL\n"+btn3;
btn4 = "PANEL\n"+btn4;
btn5 = "PANEL\n"+btn5;
gammaPanel.Oninit();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnDeinit(const int reson)
{
ObjectsDeleteAll(0,"SRChannel");
ObjectsDeleteAll(0,"PANEL");
ClearChart();
gammaPanel.Destroy(reson);
}
//+------------------------------------------------------------------+
//| 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[])
{
if(prev_calculated==0)
{
if(start_index == 0)
start_index= rates_total - (rates_total * 95 / 100) - Depth*2;
}
else
{
start_index=prev_calculated-1;
}
datetime currentBarTime = time[rates_total - 1];
static bool chart_is_load = false;
ATR(rates_total,AtrPeriod+1,prev_calculated,high,low,close,open);
RSI(rates_total,prev_calculated,close);
for(int i = start_index; i < rates_total-1 ; i++)
{
//----START FIND HIGH AND LOW---//
FindHigh_Low(i,time,open,high,low,close,chart_is_load);
//----END FIND HIGH AND LOW---//
CheckMarketStructure(i,time,close,open,low,high,chart_is_load);
}
if(currentBarTime != lastBarTime)
{
lastBarTime = currentBarTime;
chart_is_load = true;
}
if(currentBarTime > lastBarTimeDraw)
{
drawLTFLevels();
lastBarTimeDraw = currentBarTime+11*PeriodSeconds();
}
return(rates_total);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void ClearChart()
{
clearList(prevResitance);
clearList(prevSupport);
clearList(highs);
clearList(lows);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void clearList(CArrayObj &list)
{
for(int i = 0 ; i < list.Total()-1;i++)
{
CLevel* level = list.At(i);
ObjectDelete(0,level.type);
delete level;
}
list.Clear();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void FindHigh_Low(int i,const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],bool chart_is_load)
{
int idx = i - Depth;
if(isHigh(i,high,Depth))
{
if(IsValueFarEnough(high[idx],highs,ExtATRBuffer[idx]))
{
int pivot_id = idx;
CLevel* level = new CLevel(close[pivot_id],open[pivot_id],high[pivot_id],low[pivot_id],time[pivot_id],pivot_id,prefix+"Resitance"+"\n"+DoubleToString(close[pivot_id],_Digits),true,(int)ExtRSIBuffer[pivot_id]);
AddToLimitedArray(highs,level,chart_is_load);
last_high = high[idx];
last_high_pos = idx;
if(chart_is_load && show_Resitance)
DrawRect(level.type,level.h,level.o,level.t,lastBarTime+12*PeriodSeconds(),PH,STYLE_DASHDOT,true,2,1);
}
}
if(isLow(i,low,Depth))
{
if(IsValueFarEnough(low[idx],lows,ExtATRBuffer[idx]))
{
int pivot_id = idx;
CLevel* level = new CLevel(close[pivot_id],open[pivot_id],high[pivot_id],low[pivot_id],time[pivot_id],pivot_id,prefix+"Support"+"\n"+DoubleToString(close[pivot_id],_Digits),false,(int)ExtRSIBuffer[pivot_id]);
AddToLimitedArray(lows,level,chart_is_load);
last_low = low[idx];
last_low_pos = idx;
if(chart_is_load && show_Support)
DrawRect(level.type,level.l,level.o,level.t,lastBarTime+12*PeriodSeconds(),PL,STYLE_DASHDOT,true,2,1);
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CheckMarketStructure(int i,const datetime &time[],const double &close[],const double &open[],const double &low[],const double &high[],bool drawsIsLoaded)
{
for(int j = highs.Total()-1 ; j >= 0 ; j--)
{
CLevel* level = highs.At(j);
double break_price = close[i] ;
double to_break_price = level.h;
if(break_price > to_break_price && time[i] > level.t)
{
if(drawsIsLoaded)
ObjectDelete(0,level.type);
string name = prefix+"break_high"+"\n"+DoubleToString(level.l,_Digits)+IntegerToString(level.i);
//DrawHorizontalLine(name,to_break_price,to_break_price,level.t,time[i],clrDarkRed,STYLE_SOLID,1);
CLevel* level2 = new CLevel(close[i],open[i],high[i],low[i],level.t,i,prefix+"prevSupport"+"\n"+DoubleToString(i,_Digits),false,level.rsiValue);
prevSupport.Insert(level2,0);
double ots = (level2.h + level2.l) / 2.0;
color myColor = RGBToColor(255 * (100 - level.rsiValue / 70.0),255,255 * (100 -level.rsiValue / 70.0));
if(drawsIsLoaded && show_prevSupport)
{
DrawRect(level2.type,low[i],high[i],level2.t,lastBarTime+12*PeriodSeconds(),SC,STYLE_DASHDOT,true,2,1);
}
last_high_poi = ots;;
highs.Delete(j);
last_high = 0.0;
}
}
for(int j = lows.Total()-1 ; j >= 0 ; j--)
{
CLevel* level = lows.At(j);
double break_price = close[i] ;
double to_break_price= level.l;
if(break_price < to_break_price && time[i] > level.t)
{
if(drawsIsLoaded)
ObjectDelete(0,level.type);
string name = prefix+"break_low"+"\n"+DoubleToString(level.l,_Digits)+IntegerToString(level.i);
//DrawHorizontalLine(name,to_break_price,to_break_price,level.t,time[i],clrDarkRed,STYLE_SOLID,1);
double new_poi = (level.h + level.l) / 2;
CLevel* level2 = new CLevel(close[i],open[i],high[i],low[i],i,prefix+"prevResitance"+"\n"+IntegerToString(i),true,level.rsiValue);
prevResitance.Insert(level2,0);
double ots = (level2.h + level2.l) / 2.0;
color myColor = RGBToColor(255,255 * (level.rsiValue / 70.0),255 * (level.rsiValue / 70.0));
if(drawsIsLoaded && show_prevResitance)
{
DrawRect(level2.type,high[i],low[i],level2.t,lastBarTime+12*PeriodSeconds(),RC,STYLE_DASHDOT,true,2,1);
}
last_low_poi = (level2.h + level2.l) / 2;
lows.Delete(j);
last_low = 0.0;
}
}
for(int j = prevResitance.Total()-1 ; j >=0 ; j--)
{
CLevel* level = prevResitance.At(j);
if(close[i] > level.h && time[i] > level.t)
{
if(drawsIsLoaded)
{
ObjectDelete(0,level.type);
}
prevResitance.Delete(j);
}
}
for(int j = prevSupport.Total()-1 ; j >= 0 ; j--)
{
CLevel* level = prevSupport.At(j);
if(close[i] < level.l && time[i] > level.t)
{
if(drawsIsLoaded)
{
ObjectDelete(0,level.type);
}
prevSupport.Delete(j);
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void drawLTFLevels()
{
if(show_Resitance)
{
drawHighPivot();
}
if(show_Support)
{
drawLowPivot();
}
if(show_prevResitance)
{
drawResitance();
}
if(show_prevSupport)
{
drawSupport();
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void ATR(int rates_total,int ExtPeriodATR,int prev_calculated,const double &_H[],const double &_L[],const double &_C[],const double &_O[])
{
if(rates_total<=ExtPeriodATR)
return;
int i,start;
//--- preliminary calculations
if(prev_calculated==0)
{
ExtTRBuffer[0]=0.0;
ExtATRBuffer[0]=0.0;
//--- filling out the array of True Range values for each period
for(i=1; i<rates_total ; i++)
ExtTRBuffer[i]=MathMax(_H[i],_C[i-1])-MathMin(_L[i],_C[i-1]);
//--- first AtrPeriod values of the indicator are not calculated
double firstValue=0.0;
for(i=1; i<=ExtPeriodATR; i++)
{
ExtATRBuffer[i]=0.0;
firstValue+=ExtTRBuffer[i];
}
//--- calculating the first value of the indicator
firstValue/=ExtPeriodATR;
ExtATRBuffer[ExtPeriodATR]=firstValue;
start=ExtPeriodATR+1;
}
else
start=prev_calculated-1;
//--- the main loop of calculations
for(i=start; i<rates_total-1 ; i++)
{
ExtTRBuffer[i]=MathMax(_H[i],_C[i-1])-MathMin(_L[i],_C[i-1]);
ExtATRBuffer[i]=ExtATRBuffer[i-1]+(ExtTRBuffer[i]-ExtTRBuffer[i-ExtPeriodATR])/ExtPeriodATR;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void RSI(int rates_total,int prev_calculated,const double &_C[])
{
int pos=prev_calculated-1;
if(pos<=14)
{
double sum_pos=0.0;
double sum_neg=0.0;
//--- first RSIPeriod values of the indicator are not calculated
ExtRSIBuffer[0]=0.0;
ExtPosBuffer[0]=0.0;
ExtNegBuffer[0]=0.0;
for(int i=1; i<=14; i++)
{
ExtRSIBuffer[i]=0.0;
ExtPosBuffer[i]=0.0;
ExtNegBuffer[i]=0.0;
double diff=_C[i]-_C[i-1];
sum_pos+=(diff>0?diff:0);
sum_neg+=(diff<0?-diff:0);
}
//--- calculate first visible value
ExtPosBuffer[14]=sum_pos/14;
ExtNegBuffer[14]=sum_neg/14;
if(ExtNegBuffer[14]!=0.0)
ExtRSIBuffer[14]=100.0-(100.0/(1.0+ExtPosBuffer[14]/ExtNegBuffer[14]));
else
{
if(ExtPosBuffer[14]!=0.0)
ExtRSIBuffer[14]=100.0;
else
ExtRSIBuffer[14]=50.0;
}
//--- prepare the position value for main calculation
pos=14+1;
}
//--- the main loop of calculations
for(int i=pos; i<rates_total && !IsStopped(); i++)
{
double diff=_C[i]-_C[i-1];
ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(14-1)+(diff>0.0?diff:0.0))/14;
ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(14-1)+(diff<0.0?-diff:0.0))/14;
if(ExtNegBuffer[i]!=0.0)
ExtRSIBuffer[i]=100.0-100.0/(1+ExtPosBuffer[i]/ExtNegBuffer[i]);
else
{
if(ExtPosBuffer[i]!=0.0)
ExtRSIBuffer[i]=100.0;
else
ExtRSIBuffer[i]=50.0;
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsValueFarEnough(double NeWvalue,CArrayObj &list,double A)
{
if(list.Total()==0)
return true;
for(int i=list.Total()-1;i>=0;i--)
{
CLevel* level = list.At(i);
double val = level.is_peak ? level.h : level.l;
double dis = MathAbs(NeWvalue - val);
if(dis <= (A))
{
return false;
break;
}
}
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void drawSupport()
{
for(int i = 0 ; i <= prevSupport.Total()-1 ; i++)
{
CLevel* level = prevSupport.At(i);
color myColor = RGBToColor((level.rsiValue * 255.0) /30,255,(level.rsiValue * 255.0)/30);
DrawRect(level.type,level.h,level.l,level.t,lastBarTime+12*PeriodSeconds(),myColor,STYLE_DASHDOT,true,2,1);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void drawResitance()
{
for(int i = 0 ; i <= prevResitance.Total()-1 ; i ++)
{
CLevel* level = prevResitance.At(i);
color myColor = RGBToColor(255,255 * (level.rsiValue / 30.0),255 * (level.rsiValue / 30.0));
DrawRect(level.type,level.h,level.l,level.t,lastBarTime+12*PeriodSeconds(),myColor,STYLE_DASHDOT,true,2,1);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void drawHighPivot()
{
for(int i = highs.Total()-1 ; i >= 0 ; i --)
{
CLevel* level = highs.At(i);
DrawRect(level.type,level.h,level.l,level.t,lastBarTime+12*PeriodSeconds(),PH,STYLE_DASHDOT,true,2,1);
//DrawHorizontalLine(level.type+"C",level.c,level.c,level.t,iTime(_Symbol,PERIOD_CURRENT,0)+1*PeriodSeconds(),clrGreen,STYLE_SOLID,2);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void drawLowPivot()
{
for(int i = lows.Total()-1 ; i >=0 ; i --)
{
CLevel* level = lows.At(i);
DrawRect(level.type,level.h,level.l,level.t,lastBarTime+12*PeriodSeconds(),PL,STYLE_DASHDOT,true,2,1);
//DrawHorizontalLine(level.type+"C",level.c,level.c,level.t,iTime(_Symbol,PERIOD_CURRENT,0)+1*PeriodSeconds(),clrGreen,STYLE_SOLID,2);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void AddToLimitedArray(CArrayObj &list,CObject *newElement,bool chart_is_load)
{
list.Add(newElement);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
color RGBToColor(double aR,double aG,double aB)
{
int int_r=(int)MathRound(aR);
int int_g=(int)MathRound(aG);
int int_b=(int)MathRound(aB);
int Color=0;
Color=int_b;
Color<<=8;
Color|=int_g;
Color<<=8;
Color|=int_r;
return((color)Color);
}
//+------------------------------------------------------------------+
// Get R component
double GetR(color aColor)
{
return(aColor&0xff);
}
// Get G component
double GetG(color aColor)
{
return((aColor>>8)&0xff);
}
// Get B component
double GetB(color aColor)
{
return((aColor>>16)&0xff);
}
//+------------------------------------------------------------------+