HL Next Activator Comment
Download scriptThis script is a technical analysis tool designed for the MetaTrader 4 platform. Its primary purpose is to identify specific price action levels based on historical highs and lows across multiple timeframes, helping traders visualize potential support and resistance zones.
Core Logic Overview
The script functions by scanning historical market data to calculate "Average Highs" and "Average Lows." Unlike standard moving averages that might look at every single candle, this tool is designed to be "timeframe aware." It specifically looks for meaningful structural transitions in the market (such as the start of a new day, week, or specific hour) to define the boundaries of its calculations.
How the Logic Works
1. Timeframe Synchronization and Delimiters The script includes internal logic to recognize "delimiters." These are significant time markers based on the chart period you are using (e.g., 5-minute, 1-hour, or Daily charts). It identifies these specific moments to ensure that the high and low prices it captures are relevant to the larger market structure rather than just random noise from individual candles.
2. Dynamic Price Calculation The tool calculates two main values:
- Average High: The highest price reached during a set number of structural periods.
- Average Low: The lowest price reached during those same periods.
It uses a "lookback" mechanism that automatically identifies where these historical periods started and ended, then picks the extreme high or low from those specific zones to create a balanced average.
3. Signal Generation and Visualization Once these averages are established, the script compares the current market closing price against these levels:
- Sell Logic: If the price closes above the calculated "Average High," the script identifies a potential reversal zone and marks a level based on the "Average Low."
- Buy Logic: If the price closes below the calculated "Average Low," the script identifies a potential support zone and marks a level based on the "Average High."
4. Continuity Tracking The script also possesses a "memory" function. If a signal isn't triggered by a price cross, it can carry over the previous value of the activator. This ensures that the visual indicators remain consistent on the chart rather than flickering in and out of existence, providing a smoother visual experience for the user.
Summary for the User
In simple terms, this tool acts as a smart boundary detector. It looks back at past market cycles, finds the highest and lowest points of those cycles, and plots "activator" lines on your current chart. These lines help you see where the market might react when prices push into historical zones of interest.
//+------------------------------------------------------------------+
//| HL Next Activator.mq4 |
//| Rosh |
//| http://fx.winm.ru/book.htm |
//+------------------------------------------------------------------+
#property copyright "Rosh"
#property link "http://fx.winm.ru/book.htm"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- input parameters
extern int ActivatorPeriod=3;
extern int useFullPeriods=1;
//---- buffers
double SellActivator[];
double BuyActivator[];
int first,counterPeriod;
int DelimeterArray[30];
//+------------------------------------------------------------------+
//| Ïîëó÷èì ñëåäóþùèé ïåðèîä |
//+------------------------------------------------------------------+
string GetNextPeriod(int _Period)
{
string nextPeriod="";
//----
switch (_Period)
{
case 5: nextPeriod="H1"; break;
case 15: nextPeriod="H1"; break;
case 30: nextPeriod="H4"; break;
case 60: nextPeriod="H4"; break;
case 240: nextPeriod="D1"; break;
case 1440: nextPeriod="W1"; break;
case 10080: nextPeriod="M"; break;
default: Print("Íåäîïóñòèìûé ïåðèîä!!!");
}
//----
return(nextPeriod);
}
//+------------------------------------------------------------------+
//| Ïðîâåðèì - ðàçäåëèòåëü äèàïàçîíà èëè íåò |
//+------------------------------------------------------------------+
bool isDelimeter(int _Period, int _shift)
{
bool result=false;
//----
switch (_Period)
{
case 5:result=(TimeMinute(Time[_shift])==0); break;
case 15:result=(TimeMinute(Time[_shift])==0); break;
case 30:result=(TimeMinute(Time[_shift])==0)&& MathMod(TimeHour(Time[_shift]),4.0)==0.0; break;
case 60:result=(TimeMinute(Time[_shift])==0)&& MathMod(TimeHour(Time[_shift]),4.0)==0.0;break;
case 240:result=(TimeMinute(Time[_shift])==0)&&(TimeHour(Time[_shift])==0); break;
case 1440:result=(TimeDayOfWeek(Time[_shift])==1)&&(TimeHour(Time[_shift])==0); break;
case 10080:result=(TimeDay(Time[_shift])==1)||((TimeDay(Time[_shift])==2 && TimeDay(Time[_shift+1])!=1))||((TimeDay(Time[_shift])==3 && TimeDay(Time[_shift+1])!=2)); break;
default: Print("Íåäîïóñòèìûé ïåðèîä!!!");
}
//----
return(result);
}
//+------------------------------------------------------------------+
//| Âû÷èñëèòü ñðåäíèé High çà ActivatorPeriod ïåðèîäîâ |
//+------------------------------------------------------------------+
double AverageHigh(int _shift)
{
double AveragePeriodHigh=0.0,tempHigh;
int cnt=_shift;
first=0;
//----
counterPeriod=0;
while (counterPeriod<ActivatorPeriod+useFullPeriods)
{
while (!isDelimeter(Period(),cnt)) cnt++;
if (first==0) first=cnt;
if (_shift==0) Print("AverageHigh Date=",TimeToStr(Time[cnt])," cnt=",cnt," counterPeriod=",counterPeriod);
DelimeterArray[counterPeriod]=cnt;
cnt++;
counterPeriod++;
}
cnt--;
if (_shift==0) Print("AverageHigh Date=",TimeToStr(Time[cnt])," cnt=",cnt);
for (cnt=ActivatorPeriod-1;cnt>0;cnt--)
{
tempHigh=High[Highest(NULL,0,MODE_HIGH,DelimeterArray[cnt]-DelimeterArray[cnt-1],DelimeterArray[cnt-1]+1)];
if (_shift==0) Print("High[",cnt,"]=",tempHigh);
AveragePeriodHigh=AveragePeriodHigh+tempHigh;
}
if (useFullPeriods==1)
{
tempHigh=High[Highest(NULL,0,MODE_HIGH,DelimeterArray[ActivatorPeriod]-DelimeterArray[ActivatorPeriod-1],DelimeterArray[ActivatorPeriod-1]+1)];
if (_shift==0) Print("High[",ActivatorPeriod,"]=",tempHigh);
AveragePeriodHigh=AveragePeriodHigh+tempHigh;
AveragePeriodHigh=AveragePeriodHigh/NormalizeDouble(ActivatorPeriod,0);
}
else
{
tempHigh=High[Highest(NULL,0,MODE_HIGH,DelimeterArray[0]-_shift,_shift)];
if (_shift==0) Print("High[",0,"]=",tempHigh);
AveragePeriodHigh=AveragePeriodHigh+tempHigh;
AveragePeriodHigh=AveragePeriodHigh/NormalizeDouble(ActivatorPeriod,0);
}
if (_shift==0) Print("AveragePeriodHigh[",0,"]=",AveragePeriodHigh);
//----
return(AveragePeriodHigh);
}
//+------------------------------------------------------------------+
//| Âû÷èñëèòü ñðåäíèé Low çà ActivatorPeriod ïåðèîäîâ |
//+------------------------------------------------------------------+
double AverageLow(int _shift)
{
double AveragePeriodLow=0.0,tempLow;
int cnt=_shift;
first=0;
//----
counterPeriod=0;
while (counterPeriod<ActivatorPeriod+useFullPeriods)
{
while (!isDelimeter(Period(),cnt)) cnt++;
if (first==0) first=cnt;
if (_shift==0) Print("AverageLow Date=",TimeToStr(Time[cnt])," cnt=",cnt," counterPeriod=",counterPeriod);
DelimeterArray[counterPeriod]=cnt;
cnt++;
counterPeriod++;
}
cnt--;
if (_shift==0) Print("AverageLow Date=",TimeToStr(Time[cnt])," cnt=",cnt);
for (cnt=ActivatorPeriod-1;cnt>0;cnt--)
{
tempLow=Low[Lowest(NULL,0,MODE_LOW,DelimeterArray[cnt]-DelimeterArray[cnt-1],DelimeterArray[cnt-1]+1)];
if (_shift==0) Print("Low[",cnt,"]=",tempLow);
AveragePeriodLow=AveragePeriodLow+tempLow;
}
if (useFullPeriods==1)
{
tempLow=Low[Lowest(NULL,0,MODE_LOW,DelimeterArray[ActivatorPeriod]-DelimeterArray[ActivatorPeriod-1],DelimeterArray[ActivatorPeriod-1]+1)];
if (_shift==0) Print("Low[",ActivatorPeriod,"]=",tempLow);
AveragePeriodLow=AveragePeriodLow+tempLow;
AveragePeriodLow=AveragePeriodLow/NormalizeDouble(ActivatorPeriod,0);
}
else
{
tempLow=Low[Lowest(NULL,0,MODE_LOW,DelimeterArray[0]-_shift,_shift)];
if (_shift==0) Print("Low[",0,"]=",tempLow);
AveragePeriodLow=AveragePeriodLow+tempLow;
AveragePeriodLow=AveragePeriodLow/NormalizeDouble(ActivatorPeriod,0);
}
if (_shift==0) Print("AveragePeriodLow[",0,"]=",AveragePeriodLow);
//----
return(AveragePeriodLow);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,159);
SetIndexBuffer(0,SellActivator);
SetIndexEmptyValue(0,0.0);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,159);
SetIndexBuffer(1,BuyActivator);
SetIndexEmptyValue(1,0.0);
if (useFullPeriods!=0) useFullPeriods=1;
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
int cnt,limit;
if (Period()==10080) return;
if (counted_bars<0) return(-1);
if (counted_bars>0) limit=Bars-counted_bars;
if (counted_bars==0)
{
// íàéòè ïåðâûé è âòîðîé ðàçäåëèòåëü è óñòàíîâèòü limit
cnt=Bars-1;
while (!isDelimeter(Period(),cnt)) cnt--;
first=cnt;
cnt--;
counterPeriod=0;
while (counterPeriod<ActivatorPeriod)
{
while (!isDelimeter(Period(),cnt)) cnt--;
Print("Date=",TimeToStr(Time[cnt])," cnt=",cnt);
cnt--;
counterPeriod++;
}
cnt++;
Print("Set Limit"," Date=",TimeToStr(Time[cnt])," cnt=",cnt);
/* hh=Highest(NULL,0,MODE_HIGH,first-cnt,cnt+1);
ll=Lowest(NULL,0,MODE_LOW,first-cnt,cnt+1);
tv=NormalizeDouble((High[hh]+Low[ll]+Close[cnt+1])/3.0,Digits);
MaH=tv+NormalizeDouble((High[hh]-Low[ll])/2.0*Ratio,Digits);
MaL=tv-NormalizeDouble((High[hh]-Low[ll])/2.0*Ratio,Digits);
tvBuffer[cnt]=tv;
ExtMapBuffer1[cnt]=MaH;
ExtMapBuffer2[cnt]=MaL;
*/ limit=cnt;
}
//----
for (int shift=limit;shift>=0;shift--)
{
//Print("Shift=",shift);
if (Close[shift]>AverageHigh(shift))
{
//Print("Âûñòàâèì SellActivator shift=",shift);
SellActivator[shift]=AverageLow(shift);
BuyActivator[shift]=0.0;
continue;
}
if (Close[shift]<AverageLow(shift))
{
//Print("Âûñòàâèì BuyActivator shift=",shift);
BuyActivator[shift]=AverageHigh(shift);
SellActivator[shift]=0.0;
continue;
}
if (BuyActivator[shift+1]!=0.0) BuyActivator[shift]=AverageHigh(shift);
if (SellActivator[shift+1]!=0.0) SellActivator[shift]=AverageLow(shift);
}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments