ZZ SR TL Indicator_v2
Download scriptThis script is designed to automatically identify and display key Support and Resistance (S/R) levels on your trading charts. It acts as a visual aid, highlighting historical price zones where the market has shown significant turning points, helping traders anticipate potential areas of supply and demand.
Core Logic and Functionality
Multi-Timeframe Analysis The tool is capable of analyzing data from specific timeframes (such as 15-minute, 1-hour, or daily charts). Depending on the timeframe you select in the settings, the script adjusts its behavior to ensure the levels displayed are relevant to your current trading perspective.
Dynamic Level Detection Rather than simply drawing lines at random points, the logic follows a systematic process to find "significant" price peaks and valleys:
- Peak and Valley Identification: The script scans back through recent price history to find local highs and lows.
- Filtering Noise: It uses specific parameters—Depth, Deviation, and Backstep—to filter out minor price fluctuations. This ensures that only meaningful price "walls" are captured, preventing your chart from becoming cluttered with insignificant data.
- Conflict Resolution: The logic includes a "final cutting" process. If multiple high or low points are detected in close proximity, the script evaluates which is more dominant. It essentially "cleans" the data to ensure that only the strongest, most prominent support and resistance levels remain visible.
Visual Management and Cleanup To maintain a professional and clean workspace, the script manages the objects on your chart automatically:
- Automatic Drawing: Once significant levels are identified, the script draws them as trend lines extending into the future.
- Smart Updates: It identifies which levels are still relevant and removes outdated or redundant lines that no longer meet the detection criteria.
- Cleanup on Exit: If you choose to enable this feature, the script will automatically remove its drawn objects from the chart when you close it, leaving your workspace exactly as you found it.
Summary for the User
In simple terms, this tool does the "heavy lifting" of scanning through historical price history to find where the market has historically struggled to break through or fall below. It then paints those levels on your screen as clear visual cues, allowing you to focus on making trading decisions rather than manually searching for price boundaries.
//+------------------------------------------------------------------+
//| SUPRESMultiFrame.mq4 |
//| |
//| RD |
//+------------------------------------------------------------------+
#property copyright "RD"
#property link "marynarz15@wp.pl"
#property indicator_chart_window
#define MaxObject 1000
//---- indicator parameters
extern int TimeFrame=15;
extern int BarsMax=144;
extern int ExtDepth=12;
extern int ExtDeviation=1;
extern int ExtBackstep=5;
bool DeleteObjectsOnExit=true;
color LineColor1=Red;
color LineColor5=Red;
color LineColor15=Red;
color LineColor30=Red;
color LineColor60=Red;
color LineColor240=Orange;
color LineColor1440=Red;
color LineColor10080=Red;
//-----------------------
double ExtMapBuffer[];
double ExtMapBuffer2[];
int SUPRESCount=0;
int linewidth;
string NamePattern;
color LineColor;
//+------------------------------------------------------------------+
//| Delete objects |
//+------------------------------------------------------------------+
int DeleteSupRes()
{
int ObjectCount=ObjectsTotal();
string names[MaxObject];
for(int i=0; i<ObjectCount;i++)
names[i]=ObjectName(i);
for(i=0; i<ObjectCount;i++)
{
string objname=names[i];
objname=StringSubstr(objname,0,StringLen(NamePattern));
if (objname!=NamePattern || ObjectType(names[i])!=OBJ_TREND)
names[i]="";
}
for(i=0; i<ObjectCount;i++)
{
if (names[i]!="")
{
ObjectDelete(names[i]);}
}
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
IndicatorBuffers(2);
SetIndexBuffer(0,ExtMapBuffer);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexEmptyValue(0,0.0);
ArraySetAsSeries(ExtMapBuffer,true);
ArraySetAsSeries(ExtMapBuffer2,true);
switch(TimeFrame)
{
case 1: linewidth=1; LineColor=LineColor1; break;
case 5: linewidth=1; LineColor=LineColor5; break;
case 15: linewidth=1; LineColor=LineColor15; break;
case 30: linewidth=1; LineColor=LineColor30; break;
case 60: linewidth=1; LineColor=LineColor60; break;
case 240: linewidth=1; LineColor=LineColor240; break;
case 1440: linewidth=1; LineColor=LineColor1440; break;
case 10080: linewidth=1; LineColor=LineColor10080; break;
default: linewidth=1; TimeFrame=Period(); break;
}
NamePattern=DoubleToStr(TimeFrame,0)+" SUPRES ";
if (BarsMax<55) BarsMax=55;
//----
DeleteSupRes();
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
if (DeleteObjectsOnExit) DeleteSupRes();
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
int shift, back,lasthighpos,lastlowpos;
double val,res;
double curlow,curhigh,lasthigh,lastlow;
string objectname;
//----
if(BarsMax==0) {BarsMax=Bars/2;}// return(0);
for(shift=iBars(NULL,TimeFrame)-ExtDepth; shift>=0; shift--)
{
val=iLow(NULL,TimeFrame,Lowest(NULL,TimeFrame,MODE_LOW,ExtDepth,shift));
if(val==lastlow) val=0.0;
else
{
lastlow=val;
if((iLow(NULL,TimeFrame,shift)-val)>(ExtDeviation*Point)) val=0.0;
else
{
for(back=1; back<=ExtBackstep; back++)
{
res=ExtMapBuffer[shift+back];
if((res!=0)&&(res>val)) ExtMapBuffer[shift+back]=0.0;
}
}
}
ExtMapBuffer[shift]=val;
//--- high
val=iHigh(NULL,TimeFrame,Highest(NULL,TimeFrame,MODE_HIGH,ExtDepth,shift));
if(val==lasthigh) val=0.0;
else
{
lasthigh=val;
if((val-iHigh(NULL,TimeFrame,shift))>(ExtDeviation*Point)) val=0.0;
else
{
for(back=1; back<=ExtBackstep; back++)
{
res=ExtMapBuffer2[shift+back];
if((res!=0)&&(res<val)) ExtMapBuffer2[shift+back]=0.0;
}
}
}
ExtMapBuffer2[shift]=val;
}
// final cutting
lasthigh=-1; lasthighpos=-1;
lastlow=-1; lastlowpos=-1;
//----
for(shift=iBars(NULL,TimeFrame)-ExtDepth; shift>=0; shift--)
{
curlow=ExtMapBuffer[shift];
curhigh=ExtMapBuffer2[shift];
if((curlow==0)&&(curhigh==0)) continue;
//---
if(curhigh!=0)
{
if(lasthigh>0)
{
if(lasthigh<curhigh) ExtMapBuffer2[lasthighpos]=0;
else ExtMapBuffer2[shift]=0;
}
//---
if(lasthigh<curhigh || lasthigh<0)
{
lasthigh=curhigh;
lasthighpos=shift;
}
lastlow=-1;
}
//----
if(curlow!=0)
{
if(lastlow>0)
{
if(lastlow>curlow) ExtMapBuffer[lastlowpos]=0;
else ExtMapBuffer[shift]=0;
}
//---
if((curlow<lastlow)||(lastlow<0))
{
lastlow=curlow;
lastlowpos=shift;
}
lasthigh=-1;
}
}
for(shift=iBars(NULL,TimeFrame)-1; shift>=0; shift--)
{
if(shift>=iBars(NULL,TimeFrame)-ExtDepth) ExtMapBuffer[shift]=0.0;
else
{
res=ExtMapBuffer2[shift];
if(res!=0.0) ExtMapBuffer[shift]=res;
}
}
//----
int count=0;
double TempBufferPrice[MaxObject];
int TempBufferBar[MaxObject];
string ObjectNames[MaxObject];
//----
for(shift=BarsMax; shift>0; shift--)
if (ExtMapBuffer[shift]>0)
{
count++;
TempBufferPrice[count-1]=ExtMapBuffer[shift];
TempBufferBar[count-1]=shift;
}
for(int i=0; i<count; i++)
ObjectNames[i]=/*TimeFrame+"m S/R("+i+")"+DoubleToStr(TempBufferPrice[i],Digits)+" "+*/
TimeToStr(iTime(NULL,TimeFrame,TempBufferBar[i]),TIME_DATE|TIME_MINUTES);
//----
int ObjectForDeleteCount=0;
string ObjectsForDelete[MaxObject];
for(i=0; i<ObjectsTotal(); i++)
{
objectname=ObjectName(i);
if (StringSubstr(objectname,0,StringLen(NamePattern))==NamePattern)
{
ObjectForDeleteCount++;
ObjectsForDelete[ObjectForDeleteCount-1]=objectname;
}
}
for(i=0; i<count-2; i++)
{
objectname=ObjectNames[i];
for(int j=0; j<ObjectForDeleteCount; j++)
if(ObjectsForDelete[j]==objectname)
{
ObjectsForDelete[j]="";
break;
}
}
for(j=0; j<ObjectForDeleteCount; j++)
if (ObjectsForDelete[j]!="")
{
ObjectDelete(ObjectsForDelete[j]);
}
//----
for(i=0; i<count; i++)
{
if (ObjectFind(ObjectNames[i])==-1)
{
ObjectCreate(ObjectNames[i],OBJ_TREND,0,iTime(NULL,TimeFrame,TempBufferBar[i]),TempBufferPrice[i],
iTime(NULL,TimeFrame,TempBufferBar[i])+10080*60,TempBufferPrice[i]);
ObjectSet(ObjectNames[i],OBJPROP_WIDTH,linewidth);
ObjectSet(ObjectNames[i],OBJPROP_COLOR,LineColor);
ObjectSet(ObjectNames[i],OBJPROP_RAY,True);
ObjectSetText(ObjectNames[i],ObjectNames[i]/*+" "+DoubleToStr(TempBufferPrice[i],Digits),8,"Courier",LightSteelBlue*/);
}
}
}
//+------------------------------------------------------------------+
Comments