//+------------------------------------------------------------------+ //| indicator.mq5 | //| Copyright 2024, Issam Kadhi | //| https://www.upwork.com/freelancers/issamk31 | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Issam Kadhi" #property link "https://www.upwork.com/freelancers/issamk31" #property version "1.00" #property indicator_chart_window #property indicator_buffers 0 #property indicator_plots 0 struct array{int x1; double y1; int x2; double y2; int breaks;}; input int length_ = 5;//Swings Period int length=MathMax(2,length_); input int breaks_ = 1;//Maximum Breaks int breaks=MathMax(1,breaks_); input int maxDuration = 1000;//Breaker Maximum Duration input color bullCss = clrGreen;//Bullish MS input color bullBreakCss = clrGreen;//Breaker input color bearCss = clrRed;//Bearish MS input color bearBreakCss = clrRed;//Breaker input color clrg=clrGreen;//demand box color input color clrr=clrRed;//supply box color input color clrt=clrBlack;//text color input color clrl=clrFireBrick;//label color input int mincnt=4;//minimum number of consecutive bars input bool ea=true;//enable alerts input bool sa=true;//Strategy alerts input bool el=false;//enable labels to indicate the zones that were broken input bool extend = false;//Extend Boxes And Delete Broken Ones //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping //--- return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { ObjectsDeleteAll(0,prefix); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ double pivotlow(int period1, int period2, int i) { if(i<=period2)return 0; int pos=iLowest(_Symbol,PERIOD_CURRENT,MODE_LOW,period1+period2+1,i-period2); return pos==i?INT_MAX:iLow(_Symbol,PERIOD_CURRENT,pos); } double pivothigh(int period1, int period2, int i) { if(i<=period2)return INT_MAX;//Print(i); int pos=iHighest(_Symbol,PERIOD_CURRENT,MODE_HIGH,period1+period2+1,i-period2);//Print(pos); return pos==i?0:iHigh(_Symbol,PERIOD_CURRENT,pos); } string prefix="MSI-"; int count=0; datetime lastTimeGreen=TimeCurrent(); void lineGreen(int x2, double y2, color couleur, int os) { int i,pos=iBarShift(_Symbol,PERIOD_CURRENT,lastTimeGreen); for(i=x2-1;i>=pos;i--) if(y2<=MathMax(iOpen(_Symbol,PERIOD_CURRENT,i),iClose(_Symbol,PERIOD_CURRENT,i)) &&y2>=MathMin(iOpen(_Symbol,PERIOD_CURRENT,i),iClose(_Symbol,PERIOD_CURRENT,i))) break; if(i<pos)return; lastTimeGreen=iTime(_Symbol,PERIOD_CURRENT,x2); string name=prefix+IntegerToString(x2); if(ObjectFind(0,name)<0) ObjectCreate(0,name,OBJ_TREND,0,0,0); ObjectSetDouble(0,name,OBJPROP_PRICE,0,y2); ObjectSetDouble(0,name,OBJPROP_PRICE,1,y2); ObjectSetInteger(0,name,OBJPROP_TIME,0,iTime(_Symbol,PERIOD_CURRENT,i)); ObjectSetInteger(0,name,OBJPROP_TIME,1,iTime(_Symbol,PERIOD_CURRENT,x2)); ObjectSetInteger(0,name,OBJPROP_RAY,false); ObjectSetInteger(0,name,OBJPROP_COLOR,couleur); ObjectSetInteger(0,name,OBJPROP_WIDTH,5); labelGreen((x2+i)/2, y2, os == -1 ? "MSS" : "MSB", couleur); ChartRedraw(); } datetime lastTimeRed=TimeCurrent(); void lineRed(int x2, double y2, color couleur, int os) { int i,pos=iBarShift(_Symbol,PERIOD_CURRENT,lastTimeRed); for(i=x2-1;i>=pos;i--) if(y2<=MathMax(iOpen(_Symbol,PERIOD_CURRENT,i),iClose(_Symbol,PERIOD_CURRENT,i)) &&y2>=MathMin(iOpen(_Symbol,PERIOD_CURRENT,i),iClose(_Symbol,PERIOD_CURRENT,i))) break; if(i<pos)return; lastTimeRed=iTime(_Symbol,PERIOD_CURRENT,x2); string name=prefix+IntegerToString(x2); if(ObjectFind(0,name)<0) ObjectCreate(0,name,OBJ_TREND,0,0,0); ObjectSetDouble(0,name,OBJPROP_PRICE,0,y2); ObjectSetDouble(0,name,OBJPROP_PRICE,1,y2); ObjectSetInteger(0,name,OBJPROP_TIME,0,iTime(_Symbol,PERIOD_CURRENT,i)); ObjectSetInteger(0,name,OBJPROP_TIME,1,iTime(_Symbol,PERIOD_CURRENT,x2)); ObjectSetInteger(0,name,OBJPROP_RAY,false); ObjectSetInteger(0,name,OBJPROP_COLOR,couleur); ObjectSetInteger(0,name,OBJPROP_WIDTH,5); labelRed((x2+i)/2, y2, os == -1 ? "MSS" : "MSB", couleur); ChartRedraw(); } void labelRed(int x1, double y1, string text, color couleur) { string name=prefix+IntegerToString(x1)+"RED"; if(ObjectFind(0,name)<0) ObjectCreate(0,name,OBJ_LABEL,0,0,0); int x,y; ChartTimePriceToXY(0,0,iTime(_Symbol,PERIOD_CURRENT,x1),y1,x,y); ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y); ObjectSetInteger(0,name,OBJPROP_COLOR,couleur); ObjectSetInteger(0,name,OBJPROP_FONTSIZE,10); ObjectSetInteger(0,name,OBJPROP_WIDTH,5); ChartRedraw(); } void box(int x,double y, int x2, double y2, color couleur,string text, color textColor) { string name=prefix+IntegerToString(x)+"BOX"; if(ObjectFind(0,name)<0) ObjectCreate(0,name,OBJ_RECTANGLE,0,0,0); ObjectSetDouble(0,name,OBJPROP_PRICE,0,y); ObjectSetDouble(0,name,OBJPROP_PRICE,1,y2); ObjectSetInteger(0,name,OBJPROP_TIME,0,iTime(_Symbol,PERIOD_CURRENT,x)); ObjectSetInteger(0,name,OBJPROP_TIME,1,iTime(_Symbol,PERIOD_CURRENT,x2)); ObjectSetInteger(0,name,OBJPROP_COLOR,couleur); ObjectSetInteger(0,name,OBJPROP_FILL,true); name=prefix+IntegerToString(x)+"BOXLABEL"; if(ObjectFind(0,name)<0) ObjectCreate(0,name,OBJ_LABEL,0,0,0); int x1,y1; ChartTimePriceToXY(0,0,iTime(_Symbol,PERIOD_CURRENT,x),y,x1,y1); ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x1); ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y1); ObjectSetInteger(0,name,OBJPROP_COLOR,textColor); ObjectSetInteger(0,name,OBJPROP_FONTSIZE,5); ObjectSetInteger(0,name,OBJPROP_WIDTH,5); ObjectSetString(0,name,OBJPROP_TEXT,text); ChartRedraw(); } void labelGreen(int x1, double y1, string text, color couleur) { string name=prefix+IntegerToString(x1)+"GREEN"; if(ObjectFind(0,name)<0) ObjectCreate(0,name,OBJ_LABEL,0,0,0); int x,y; ChartTimePriceToXY(0,0,iTime(_Symbol,PERIOD_CURRENT,x1),y1,x,y); ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y); ObjectSetInteger(0,name,OBJPROP_COLOR,couleur); ObjectSetInteger(0,name,OBJPROP_FONTSIZE,10); ObjectSetInteger(0,name,OBJPROP_WIDTH,5); ChartRedraw(); } datetime bars; 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(bars!=time[rates_total-2])ObjectsDeleteAll(0,prefix); bars=time[rates_total-2]; //ObjectsDeleteAll(0,prefix); ArraySetAsSeries(time,true); lastTimeRed=TimeCurrent(); lastTimeGreen=TimeCurrent(); ArraySetAsSeries(close,true); ArraySetAsSeries(open,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); int os = 0; double ph[]; ArrayResize(ph,rates_total); double pl[]; ArrayResize(pl,rates_total); int phx = 0; int plx = 0; bool phcross = false; bool plcross = false; bool rbroken=false; bool gbroken=false; for(int i=0;i<rates_total-1;i++) { int n = i; ph[i] = pivothigh(length, length, i); if(ph[i] != ph[i+1]) { phx = n+length; phcross = false; } //Test for bullish market structure if(close[i] > ph[i] && !phcross) {//Print(1); lineGreen(n, !ph[i]?high[i]:ph[i], bullCss, os); gbroken=true; phcross = true; os = 1; } //-----------------------------------------------------------------------------{ pl[i] = pivotlow(length, length,i); if(pl[i] != pl[i+1]) { plx = n+length; plcross = false; } //Test for bearish market structure if(close[i] < pl[i] && !plcross) { lineRed(n, pl[i]==INT_MAX?low[i]:pl[i], bearCss, os); rbroken=true; plcross = true; os = -1; } //Iterate trough existing bearish structures and test for breaks } int last=-1; for(int i=rates_total-1;i>=0;i--) { string name2=prefix+IntegerToString(i)+"GREEN"; if(ObjectFind(0,name2)>=0) { if(last==1) ObjectSetString(0,name2,OBJPROP_TEXT,"MSS"); else ObjectSetString(0,name2,OBJPROP_TEXT,"MSB"); last=0; } name2=prefix+IntegerToString(i)+"RED"; if(ObjectFind(0,name2)>=0) { if(last==0) ObjectSetString(0,name2,OBJPROP_TEXT,"MSS"); else ObjectSetString(0,name2,OBJPROP_TEXT,"MSB"); last=1; } } ChartRedraw(); bool bear=false; bool bull=false; int bullcnt=0; int bearcnt=0; double bullh=0; double bulll=0; double bearh=0; double bearl=0; bool gstopper=false; bool rstopper=false; os = 0; ArrayResize(ph,rates_total); ArrayResize(pl,rates_total); phx = 0; plx = 0; phcross = false; plcross = false; rbroken=false; gbroken=false; for(int i=rates_total-2;i>=0;i--) { if(ph[i] != ph[i+1]) phcross = false; //Test for bullish market structure if(close[i] > ph[i] && !phcross) {//Print(1); gbroken=true; phcross = true; } if(pl[i] != pl[i+1]) plcross = false; //Test for bearish market structure if(close[i] < pl[i] && !plcross) { rbroken=true; plcross = true; } bull=close[i]>open[i]?true:false; bear=open[i]>close[i]?true:false; if(!(bull || bear)) { bullcnt=0; bearcnt=0; } if(bull )//and not gstopper { rstopper=false; rbroken=false; if(bullcnt==0) { bullh=high[i+1]; bulll=low[i+1]; } bullcnt=bullcnt+1; bearcnt=0; } if(bear) { gbroken=false; gstopper=false; if(bearcnt==0) { bearh=high[i+1]; bearl=low[i+1]; } bearcnt=bearcnt+1; bullcnt=0; } if(bullcnt>=mincnt && !gstopper && gbroken) { box(i+bullcnt,bullh,i,bulll,clrg,"DEMAND", clrt); gstopper=true; gbroken=false; } if(bearcnt>=mincnt && !rstopper && rbroken) { box(i+bearcnt,bearh,i,bearl,clrr,"SUPPLY", clrt); rstopper=true; rbroken=false; } } return(rates_total); } //+------------------------------------------------------------------+
You shouldn't use the iOpen/iTime functions in OnCalculate because they will not sequence to the correct bar unless you use iBarShift.
Instead of using iOpen and iTime, use the "time" and "open" buffer which is in the signature of OnCalculate
You can set the buffers to series if you want to make [0] the latest index.
![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
i converted a code from tradingview to mql5, but the drawing is not exactly the same, can you find the bug?
tradingview code:
mql5 code in first comment.
tradingview chart:
mt5 chart: