This script is designed as a market analysis tool that measures the "strength" or "durability" of price levels. Instead of simply looking at where the price is moving now, it calculates how long the market has avoided hitting specific historical highs and lows.
Here is a breakdown of the logic in non-technical terms:
Core Functionality
The tool tracks two main values: the time elapsed since the market last broke above a previous high, and the time elapsed since it last broke below a previous low. It represents these durations as a histogram on your chart.
Essentially, if a price level has not been breached for a long time, it is considered "strong." The longer the period of stability without a breakout, the higher the indicator value will be.
Key Filtering Mechanisms
To ensure that only high-quality, meaningful data is shown to the user, the script employs three specific types of logic:
1. Perspective Filter (Retrospective Horizon) The script won't show signals for very recent price action if it hasn't had enough time to "mature." You can set a minimum timeframe (the retrospective horizon); the indicator will only begin to display values once the price has stayed within its bounds for longer than this specified period.
2. Significance Filter This logic ensures that the signals displayed are not just minor fluctuations. It checks how far the current level "reaches" into the past compared to the last recorded significant point. Only signals that demonstrate a substantial shift in depth (rather than a tiny, insignificant movement) are allowed to appear on the chart.
3. Signal Processing The script can be configured to either show every single breach of a high or low or to use a stricter "significant signal" logic. When the latter is active, it looks for a specific momentum—it only records a new significant point if the change in time/distance exceeds a user-defined threshold. This helps filter out "noise" and focuses on major structural shifts in the market.
User Notifications and Display
- Real-time Alerts: The script is programmed to watch live price action. If a price breaks a high or low that hasn't been touched for a significant amount of time, it will trigger an automated alert notification.
- Alert Limiting: To prevent the system from spamming notifications, it is designed to only send one alert per direction (High or Low) per bar. It resets these alerts automatically when a new candle forms on the chart.
- Visual Feedback: The tool displays a live comment on the screen showing the total count of significant signals formed for the specific symbol and timeframe you are currently viewing.
//+------------------------------------------------------------------+
//| ipulsar_v3.mq4 |
//| Copyright 2012, 2015 Òàðàáàíîâ À.Â. |
//| alextar@bk.ru |
//+------------------------------------------------------------------+
/* iPulsar Îòîáðàæàåò êîëè÷åñòâî ïåðèîäîâ ðàçìåðîì Scale(ïî óìîë÷àíèþ - äíåé),
íà ïðîòÿæåíèè êîòîðûõ íå áûëè ïðîáèòû òåêóùèå çíà÷åíèÿ High è Low.
Óñëîâíî, õàðàêòåðèçóåò "ñèëó" òåñòèðóåìûõ óðîâíåé.
Èñïîëüçóåìûå ôèëüòðû:
1. Ôèëüòð óðîâíÿ ãîðèçîíòà ðåòðîñïåêòèâû, LevelFilter . Ïðè ãîðèçîíòå,
ìåíüøåì çàäàííîãî ÷èñëà ïåðèîäîâ Scale, çíà÷åíèå èíäèêàòîðà íå îòîáðàæàåòñÿ.
2. Ôèëüòð çíà÷èìîñòè ñèãíàëà (çíà÷åíèÿ èíäèêàòîðà),SignalFilter .
Îòîáðàæàþòñÿ òîëüêî òå çíà÷åíèÿ èíäèêàòîðà, êîòîðûå "çàãëÿäûâàþò"
â ïðîøëîå íå ìåíåå, ÷åì íà çàäàííîå ÷èñëî áàðîâ ãëóáæå, ÷åì ïðåäûäóùåå
îòîáðàæåííîå çíà÷åíèå. */
#property copyright "Copyright 2012, 2015 Òàðàáàíîâ À.Â."
#property link "alextar@bk.ru"
#property strict
#property indicator_separate_window // Àòðèáóòû èíäèêàòîðà
#property indicator_buffers 2
#property indicator_color1 Magenta // Àòðèáóòû áóôåðîâ
#property indicator_width1 2
#property indicator_color2 Teal
#property indicator_width2 2
#define Version "iPulsar_v3" // Êîíñòàíòû
#define Zero 0.00000001
bool IsHighReported, // Ôëàãè ñðàáàòûâàíèÿ àëåðòîâ
IsLowReported;
int Hval,Lval, // Ïðåäûäóùèå çíà÷åíèÿ
Signals; // Êîëè÷åñòâî ñôîðìèðîâàííûõ ñèãíàëîâ
datetime HT,LT, // Âðåìÿ ïðåäûäóùèõ çíà÷åíèé
BarTime; // Âðåìÿ íà÷àëà òåêóùåãî áàðà
double HP[],LP[], // Áóôåðû
Periods; // ×èñëî áàðîâ â åäèíèöå øêàëû
//--- Âíåøíèå ïåðåìåííûå:
extern bool SetSignalFilter=true; // Ôèëüòðîâàòü ñèãíàë?
extern double LevelFilter =5, // Ãîðèçîíò ðåòðîñïåêòèâû, Scales
SignalFilter =0; // Çíà÷èìîñòü ñèãíàëà, Bars/Scales ïðè<0
extern int Scale =1440, // Ìèíèìàëüíûé èíòåðâàë ñèãíàëîâ
ScaleDigits=0;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int init()
{
IndicatorShortName(Version); // Àòðèáóòû èíäèêàòîðà
IndicatorDigits(ScaleDigits);
SetIndexLabel(0,"High"); // Àòðèáóòû áóôåðîâ
SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexBuffer(0,HP);
SetIndexLabel(1,"Low");
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexBuffer(1,LP);
if(Scale<0) Scale=-Scale; // Êîíòðîëü âíåøíèõ ïåðåìåííûõ
if(Scale==0) Scale=Period();
if(ScaleDigits<0) ScaleDigits=-ScaleDigits;
if(ScaleDigits>Digits()) ScaleDigits=Digits();
Periods=Scale/Period(); // Èíèöèàëèçàöèÿ ãëîáàëüíûõ ïåðåìåííûõ
IsHighReported=false;
IsLowReported =false;
HT =0;
LT =0;
BarTime=0;
Hval =0;
Lval =0;
Signals=0;
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
double H,L,HB,LB,dSF,
dLF=LevelFilter*Periods+0.5;
bool HD,LD;
int LF=(int)dLF, // Ãîðèçîíò ðåòðîñïåêòèâû, Bars
SF, // Çíà÷èìîñòü ñèãíàëà, Bars
i,k,Hbar,Lbar,History=Bars-1;
if(SignalFilter>-Zero) dSF=SignalFilter+0.5;
else dSF=-SignalFilter*Periods+0.5;
SF=(int)dSF;
if( HT > 0 ) Hbar=iBarShift(NULL,0,HT);
if( LT > 0 ) Lbar=iBarShift(NULL,0,LT);
int j=History-IndicatorCounted(); // Ðàññìàòðèâàåìûå áàðû
while(j>=0)
{
H=High[j];
L=Low[j];
HD=false; // Ôëàãè îáíàðóæåíèÿ ïðîáîåâ
LD=false;
HB=0; // ×èñëî áàðîâ äî ïðîáîÿ High
LB=0; // ×èñëî áàðîâ äî ïðîáîÿ Low
i=j;
//--- Ïîèñê ïðîáîåâ
while(i<History)
{
if(HD && LD) break; // Ïðîáîè íàéäåíû
i++;
k=i-j-1; // Òåêóùàÿ ãëóáèíà ïîèñêà
if(!HD && High[i]-H>Zero)
{
HD=true; // Ïðîáîé High
//--- Ôèëüòðàöèÿ óðîâíÿ
if(k-LF>-Zero)
{
if(!SetSignalFilter)
{
HB=k;
Signals++;
}
else HB=Signal(j,k,SF,Hbar,Hval,HT,Lbar,Lval,LT);
}
}
if(!LD && L-Low[i]>Zero)
{
LD=true; // Ïðîáîé Low
//--- Ôèëüòðàöèÿ óðîâíÿ
if(k-LF>-Zero)
{
if(!SetSignalFilter)
{
LB=k;
Signals++;
}
else LB=Signal(j,k,SF,Lbar,Lval,LT,Hbar,Hval,HT);
}
}
}
//--- Êîíòðîëü îáíàðóæåíèÿ ïðîáîåâ
if(!SetSignalFilter)
{
if(!HD)
{
HB=History-j-2;
Signals++;
}
if(!LD)
{
LB=History-j-2;
Signals++;
}
}
//--- Ïðèâåäåíèå ê çàäàííîé øêàëå è îòîáðàæåíèå:
HP[j]= NormalizeDouble(HB/Periods,ScaleDigits);
LP[j]=-NormalizeDouble(LB/Periods,ScaleDigits);
if(!j) // Òîëüêî â ðåàëüíîì âðåìåíè
{
if(IsNewBar())
{ // Òîëüêî íà ïåðâîì òèêå áàðà
IsHighReported=false;
IsLowReported =false;
Comment(Version,": ñôîðìèðîâàíî ",Signals," ñèãíàëîâ äëÿ ",Symbol(),", ",Period());
}
//--- Íå áîëåå, ÷åì ïî îäíîìó àëåðòó äëÿ êàæäîãî íàïðàâëåíèÿ çà áàð:
if(!IsHighReported && HP[j]>Zero)
{
IsHighReported=true;
Alert(Symbol(),", ",Period(),": ïðîáèò ìàêñèìóì çà ",DoubleToStr(HP[j],ScaleDigits),"*",Scale);
}
if(!IsLowReported && LP[j]<-Zero)
{
IsLowReported=true;
Alert(Symbol(),", ",Period(),": ïðîáèò ìèíèìóì çà ",DoubleToStr(-LP[j],ScaleDigits),"*",Scale);
}
}
j--;
}
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double Signal(int Bar1, // Òåêóùèé áàð
int Val1, // Òåêóùåå çíà÷åíèå, Bars
int F, // Çíà÷èìîñòü ñèãíàëà, Bars
int& Bar0, // Ïðåäûäóùèé áàð
int& Val0, // Ïðåäûäóùåå çíà÷åíèå, Bars
datetime& T, // Ïðåäûäóùåå âðåìÿ
int& contrBar, // Ïðåäûäóùèé îïïîçèòíûé áàð
int& contrVal, // Ïðåäûäóùåå îïïîçèòíîå çíà÷åíèå
datetime &contrT) // Ïðåäûäóùåå îïïîçèòíîå âðåìÿ
{
double S=0; // Çíà÷åíèå òåêóùåãî ñèãíàëà
int I=Val1-Val0-Bar0+Bar1; // Ïðåîáëàäàíèå òåêóùåãî ñèãíàëà
if(I>= F) // Åñòü ïðåîáëàäàþùèé ñèãíàë
{
Signals++;
S=Val1; // Çàïîìíèòü ïàðàìåòðû ñèãíàëà
Bar0 =Bar1;
Val0 =Val1;
T =Time[Bar1];
if(Bar1<contrBar)
{
contrBar=0; // Çàáûòü ïðåäûäóùèé îïïîçèòíûé ñèãíàë
contrVal=0;
contrT =0;
}
}
return(S);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsNewBar() // Ðåãèñòðàöèÿ íîâîãî áàðà
{
bool NewBar=false; // Íîâîãî áàðà íåò
if(BarTime!=Time[0])
{
BarTime=Time[0]; // Òåïåðü âðåìÿ òàêîå
NewBar =true; // Ïîéìàëñÿ íîâûé áàð
}
return(NewBar);
}
//+------------------------------------------------------------------+
Comments