Up_Down
Download scriptThis script is designed as a specialized technical indicator for the MetaTrader 4 platform. Its primary purpose is to identify and plot specific price levels—specifically highs and lows—based on historical market data across various timeframes.
Core Logic Overview
The indicator works by scanning through historical price bars to find significant "peaks" (Highs) and "troughs" (Lows). Instead of just looking at the most recent price, it calculates average levels based on a user-defined period of these past extremes.
The script is highly "context-aware," meaning it changes its mathematical behavior depending on the specific timeframe you are viewing (e.g., 5 minutes, 1 hour, daily, etc.). This ensures that the "High" and "Low" levels remain relevant to the scale of the chart.
Key Functional Components
1. Timeframe-Specific Detection The script contains unique logic for several specific timeframes:
- Short-term (5 & 15 Minutes): Focuses on hour-by-hour changes to identify local price action.
- Medium-term (30 & 60 Minutes): Looks for specific hourly intervals (e.g., every 4 hours) to find significant structural points.
- Long-term (Daily, Weekly, Monthly): Switches logic to recognize day changes, weekly transitions, and monthly roll-overs.
2. High/Low Identification & Averaging For every relevant time period identified above, the script:
- Locates the highest high and lowest low within a specific window of bars.
- Collects these values over a set number of occurrences (defined by the
HL_period). - Calculates an average "High" level and an average "Low" level.
3. Price Relationship & Signal Logic Once these average levels are calculated, the script compares the current closing price (adjusted for the "Spread"—the difference between buying and selling prices) against these averages:
- Bullish Context: If the price closes above the calculated Average High, it identifies a specific state.
- Bearish Context: If the price closes below the calculated Average Low, it identifies the opposite state.
4. Visual Representation The script uses two different visual buffers to display these results on your chart:
- It highlights specific "Upper" or "Lower" price levels using colored arrows (Lime for one condition, Tomato for the other).
- It dynamically clears and plots these values so that the most relevant trend signal is visible to the user without cluttering the screen with unnecessary data points.
Summary for the User
In simple terms, this script acts as a "smart" historical anchor. It looks back at where the market has historically hit its highest and lowest points during specific cycles (hours, days, or months) and calculates an average for those points. It then tells you—via visual markers on your chart—when the current price action is interacting with those significant historical boundaries.
//+------------------------------------------------------------------+
//| Up&Down.mq4 |
//| |
//| |
//+------------------------------------------------------------------+
#property copyright ""
#property link ""
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Lime
#property indicator_color2 Tomato
//---- input parameters
extern int HL_period=3;
extern int NumBars=200;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
//------
double ur[][2];
int h1[];
int l1[];
int hh=0;
int ll=0;
double spread;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,159);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexEmptyValue(0,0.0);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,159);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexEmptyValue(1,0.0);
//----
ArrayResize(ur,NumBars+1);
ArrayResize(h1,HL_period);
ArrayResize(l1,HL_period);
spread = Ask-Bid;
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int n,shift,Nbar,k,mm;
double MaH,MaL;
//----
if( Period() == 5 )
{
ArrayInitialize(ur,0);
ArrayInitialize(h1,0);
ArrayInitialize(l1,0);
for( shift = NumBars; shift>=0; shift-- )
{
if( TimeHour(Time[shift + 1]) != TimeHour(Time[shift]) )
{
Nbar = -1;
k = 0;
mm = 0;
n = shift - 15;
while( n <= shift + HL_period * 12 + 5 )
{
if( n < 0 )
{
n = 1;
Nbar = 0;
}
if( TimeHour(Time[n + 1]) != TimeHour(Time[n]) && Nbar == -1 )
{
Nbar = n;
mm = n;
n++;
continue;
}
if( TimeHour(Time[n + 1]) != TimeHour(Time[n]) && Nbar != -1 )
{
h1[k] = Highest(NULL,0,MODE_HIGH,n - Nbar,n-(n-Nbar)+1);
l1[k] = Lowest(NULL,0,MODE_LOW,n - Nbar,n-(n-Nbar)+1);
k++;
Nbar = n;
}
n++;
}
MaH = 0;
MaL = 0;
for( n = 0; n<HL_period; n++ )
{
MaH = MaH + High[h1[n]]+spread;
MaL = MaL + Low[l1[n]];
}
MaH = MaH / HL_period;
MaL = MaL / HL_period;
ur[shift][0] = MaH;
ur[shift][1] = MaL;
if( Close[mm + 1]+spread/2 >= MaH ) { ll = 1; hh = 0; }
if( Close[mm + 1]+spread/2 <= MaL ) { hh = 1; ll = 0; }
}
if( ur[shift,1] == 0 )
{
ur[shift][0] = ur[shift + 1][0];
ur[shift][1] = ur[shift + 1][1];
}
if( ll == 1 )
{
ExtMapBuffer2[shift]=0;
ExtMapBuffer1[shift]=ur[shift][1];
}
if( hh == 1 )
{
ExtMapBuffer1[shift]=0;
ExtMapBuffer2[shift]=ur[shift][0];
}
}
return(0);
}
//-----------------------------
if( Period() == 15 )
{
ArrayInitialize(ur,0);
ArrayInitialize(h1,0);
ArrayInitialize(l1,0);
for( shift = NumBars; shift>=0; shift-- )
{
if( TimeHour(Time[shift + 1]) != TimeHour(Time[shift]) )
{
Nbar = -1;
k = 0;
mm = 0;
n = shift - 5;
while( n <= shift + HL_period * 4 + 2 )
{
if( n < 0 )
{
n = 1;
Nbar = 0;
}
if( TimeHour(Time[n + 1]) != TimeHour(Time[n]) && Nbar == -1 )
{
Nbar = n;
mm = n;
n++;
continue;
}
if( TimeHour(Time[n + 1]) != TimeHour(Time[n]) && Nbar != -1 )
{
h1[k] = Highest(NULL,0,MODE_HIGH,n - Nbar,n-(n-Nbar)+1);
l1[k] = Lowest(NULL,0,MODE_LOW,n - Nbar,n-(n-Nbar)+1);
k++;
Nbar = n;
}
n++;
}
MaH = 0;
MaL = 0;
for( n = 0; n<HL_period; n++ )
{
MaH = MaH + High[h1[n]]+spread;
MaL = MaL + Low[l1[n]];
}
MaH = MaH / HL_period;
MaL = MaL / HL_period;
ur[shift][0] = MaH;
ur[shift][1] = MaL;
if( Close[mm + 1]+spread/2 >= MaH ) { ll = 1; hh = 0; }
if( Close[mm + 1]+spread/2 <= MaL ) { hh = 1; ll = 0; }
}
if( ur[shift,1] == 0 )
{
ur[shift][0] = ur[shift + 1][0];
ur[shift][1] = ur[shift + 1][1];
}
if( ll == 1 )
{
ExtMapBuffer2[shift]=0;
ExtMapBuffer1[shift]=ur[shift][1];
}
if( hh == 1 )
{
ExtMapBuffer1[shift]=0;
ExtMapBuffer2[shift]=ur[shift][0];
}
}
return(0);
}
//-------------------------
if( Period() == 30 )
{
ArrayInitialize(ur,0);
ArrayInitialize(h1,0);
ArrayInitialize(l1,0);
for( shift = NumBars; shift>=0; shift-- )
{
if( TimeMinute(Time[shift])==0 && (TimeHour(Time[shift])==0 || TimeHour(Time[shift])==4 || TimeHour(Time[shift])==8 || TimeHour(Time[shift])==12 || TimeHour(Time[shift])==16 || TimeHour(Time[shift])==20) )
{
Nbar = -1;
k = 0;
mm = 0;
n = shift - 10;
while( n <= shift + HL_period * 8 + 5 )
{
if( n < 0 )
{
n = 1;
Nbar = 0;
}
if( TimeMinute(Time[n])==0 && (TimeHour(Time[n])==0 || TimeHour(Time[n])==4 || TimeHour(Time[n])==8 || TimeHour(Time[n])==12 || TimeHour(Time[n])==16 || TimeHour(Time[n])==20) && Nbar == -1 )
{
Nbar = n;
mm = n;
n++;
continue;
}
if( TimeMinute(Time[n])==0 && (TimeHour(Time[n])==0 || TimeHour(Time[n])==4 || TimeHour(Time[n])==8 || TimeHour(Time[n])==12 || TimeHour(Time[n])==16 || TimeHour(Time[n])==20) && Nbar != -1 )
{
h1[k] = Highest(NULL,0,MODE_HIGH,n - Nbar,n-(n-Nbar)+1);
l1[k] = Lowest(NULL,0,MODE_LOW,n - Nbar,n-(n-Nbar)+1);
k++;
Nbar = n;
}
n++;
}
MaH = 0;
MaL = 0;
for( n = 0; n<HL_period; n++ )
{
MaH = MaH + High[h1[n]]+spread;
MaL = MaL + Low[l1[n]];
}
MaH = MaH / HL_period;
MaL = MaL / HL_period;
ur[shift][0] = MaH;
ur[shift][1] = MaL;
if( Close[mm + 1]+spread/2 >= MaH ) { ll = 1; hh = 0; }
if( Close[mm + 1]+spread/2 <= MaL ) { hh = 1; ll = 0; }
}
if( ur[shift,1] == 0 )
{
ur[shift][0] = ur[shift + 1][0];
ur[shift][1] = ur[shift + 1][1];
}
if( ll == 1 )
{
ExtMapBuffer2[shift]=0;
ExtMapBuffer1[shift]=ur[shift][1];
}
if( hh == 1 )
{
ExtMapBuffer1[shift]=0;
ExtMapBuffer2[shift]=ur[shift][0];
}
}
return(0);
}
//----
if( Period() == 60 )
{
ArrayInitialize(ur,0);
ArrayInitialize(h1,0);
ArrayInitialize(l1,0);
for( shift = NumBars; shift>=0; shift-- )
{
if( TimeMinute(Time[shift])==0 && (TimeHour(Time[shift])==0 || TimeHour(Time[shift])==4 || TimeHour(Time[shift])==8 || TimeHour(Time[shift])==12 || TimeHour(Time[shift])==16 || TimeHour(Time[shift])==20) )
{
Nbar = -1;
k = 0;
mm = 0;
n = shift - 6;
while( n <= shift + HL_period * 4 + 3 )
{
if( n < 0 )
{
Nbar = 0;
n = 1;
}
if( TimeMinute(Time[n])==0 && (TimeHour(Time[n])==0 || TimeHour(Time[n])==4 || TimeHour(Time[n])==8 || TimeHour(Time[n])==12 || TimeHour(Time[n])==16 || TimeHour(Time[n])==20) && Nbar == -1 )
{
Nbar = n;
mm = n;
n++;
continue;
}
if( TimeMinute(Time[n])==0 && (TimeHour(Time[n])==0 || TimeHour(Time[n])==4 || TimeHour(Time[n])==8 || TimeHour(Time[n])==12 || TimeHour(Time[n])==16 || TimeHour(Time[n])==20) && Nbar != -1 )
{
h1[k] = Highest(NULL,0,MODE_HIGH,n - Nbar,n-(n-Nbar)+1);
l1[k] = Lowest(NULL,0,MODE_LOW,n - Nbar,n-(n-Nbar)+1);
k++;
Nbar = n;
}
n++;
}
MaH = 0;
MaL = 0;
for( n = 0; n<HL_period; n++ )
{
MaH = MaH + High[h1[n]]+spread;
MaL = MaL + Low[l1[n]];
}
MaH = MaH / HL_period;
MaL = MaL / HL_period;
ur[shift][0] = MaH;
ur[shift][1] = MaL;
if( Close[mm + 1]+spread/2 >= MaH ) { ll = 1; hh = 0; }
if( Close[mm + 1]+spread/2 <= MaL ) { hh = 1; ll = 0; }
}
if( ur[shift,1] == 0 )
{
ur[shift][0] = ur[shift + 1][0];
ur[shift][1] = ur[shift + 1][1];
}
if( ll == 1 )
{
ExtMapBuffer2[shift]=0;
ExtMapBuffer1[shift]=ur[shift][1];
}
if( hh == 1 )
{
ExtMapBuffer1[shift]=0;
ExtMapBuffer2[shift]=ur[shift][0];
}
}
return(0);
}
//--------------
if( Period() == 240 )
{
ArrayInitialize(ur,0);
ArrayInitialize(h1,0);
ArrayInitialize(l1,0);
for( shift = NumBars; shift>=0; shift-- )
{
if( TimeDay(Time[shift + 1]) != TimeDay(Time[shift]) )
{
Nbar = -1;
k = 0;
mm = 0;
n = shift - 8;
while( n <= shift + HL_period * 8 + 4 )
{
if( n < 0 )
{
Nbar = 0;
n = 1;
}
if( TimeDay(Time[n + 1]) != TimeDay(Time[n]) && Nbar == -1 )
{
Nbar = n;
mm = n;
n++;
continue;
}
if( TimeDay(Time[n + 1]) != TimeDay(Time[n]) && Nbar != -1 )
{
h1[k] = Highest(NULL,0,MODE_HIGH,n - Nbar,n-(n-Nbar)+1);
l1[k] = Lowest(NULL,0,MODE_LOW,n - Nbar,n-(n-Nbar)+1);
k++;
Nbar = n;
}
n++;
}
MaH = 0;
MaL = 0;
for( n = 0; n<HL_period; n++ )
{
MaH = MaH + High[h1[n]]+spread;
MaL = MaL + Low[l1[n]];
}
MaH = MaH / HL_period;
MaL = MaL / HL_period;
ur[shift][0] = MaH;
ur[shift][1] = MaL;
if( Close[mm + 1]+spread/2 >= MaH ) { ll = 1; hh = 0; }
if( Close[mm + 1]+spread/2 <= MaL ) { hh = 1; ll = 0; }
}
if( ur[shift,1] == 0 )
{
ur[shift][0] = ur[shift + 1][0];
ur[shift][1] = ur[shift + 1][1];
}
if( ll == 1 )
{
ExtMapBuffer2[shift]=0;
ExtMapBuffer1[shift]=ur[shift][1];
}
if( hh == 1 )
{
ExtMapBuffer1[shift]=0;
ExtMapBuffer2[shift]=ur[shift][0];
}
}
return(0);
}
//----
if( Period() == 1440 )
{
ArrayInitialize(ur,0);
ArrayInitialize(h1,0);
ArrayInitialize(l1,0);
for( shift = NumBars; shift>=0; shift-- )
{
if( TimeDayOfWeek(Time[shift + 1]) == 5 && TimeDayOfWeek(Time[shift]) == 1 )
{
Nbar = -1;
k = 0;
mm = 0;
n = shift - 6;
while( n <= shift + HL_period * 5 + 3 )
{
if( n < 0 )
{
Nbar = 0;
n = 1;
}
if( TimeDayOfWeek(Time[n + 1])==5 && TimeDayOfWeek(Time[n])==1 && Nbar == -1 )
{
Nbar = n;
mm = n;
n++;
continue;
}
if( TimeDayOfWeek(Time[n + 1])==5 && TimeDayOfWeek(Time[n])==1 && Nbar != -1 )
{
h1[k] = Highest(NULL,0,MODE_HIGH,n - Nbar,n-(n-Nbar)+1);
l1[k] = Lowest(NULL,0,MODE_LOW,n - Nbar,n-(n-Nbar)+1);
k++;
Nbar = n;
}
n++;
}
MaH = 0;
MaL = 0;
for( n = 0; n<HL_period; n++ )
{
MaH = MaH + High[h1[n]]+spread;
MaL = MaL + Low[l1[n]];
}
MaH = MaH / HL_period;
MaL = MaL / HL_period;
ur[shift][0] = MaH;
ur[shift][1] = MaL;
if( Close[mm + 1]+spread/2 >= MaH ) { ll = 1; hh = 0; }
if( Close[mm + 1]+spread/2 <= MaL ) { hh = 1; ll = 0; }
}
if( ur[shift,1] == 0 )
{
ur[shift][0] = ur[shift + 1][0];
ur[shift][1] = ur[shift + 1][1];
}
if( ll == 1 )
{
ExtMapBuffer2[shift]=0;
ExtMapBuffer1[shift]=ur[shift][1];
}
if( hh == 1 )
{
ExtMapBuffer1[shift]=0;
ExtMapBuffer2[shift]=ur[shift][0];
}
}
return(0);
}
//----
if( Period() == 10080 )
{
ArrayInitialize(ur,0);
ArrayInitialize(h1,0);
ArrayInitialize(l1,0);
for( shift = NumBars; shift>=0; shift-- )
{
if( TimeMonth(Time[shift + 1]+1440*60) != TimeMonth(Time[shift]+1440*60) )
{
Nbar = -1;
k = 0;
mm = 0;
n = shift - 8;
while( n <= shift + HL_period * 8 + 4 )
{
if( n < 0 )
{
Nbar = 0;
n = 1;
}
if( TimeMonth(Time[n + 1]+1440*60) != TimeMonth(Time[n]+1440*60) && Nbar == -1 )
{
Nbar = n;
mm = n;
if( n>NumBars-18 ) Print(TimeToStr(Time[n]));
n++;
continue;
}
if( TimeMonth(Time[n + 1]+1440*60) != TimeMonth(Time[n]+1440*60) && Nbar != -1 )
{
h1[k] = Highest(NULL,0,MODE_HIGH,n - Nbar,n-(n-Nbar)+1);
l1[k] = Lowest(NULL,0,MODE_LOW,n - Nbar,n-(n-Nbar)+1);
k++;
Nbar = n;
}
n++;
}
MaH = 0;
MaL = 0;
for( n = 0; n<HL_period; n++ )
{
MaH = MaH + High[h1[n]]+spread;
MaL = MaL + Low[l1[n]];
}
MaH = MaH / HL_period;
MaL = MaL / HL_period;
ur[shift][0] = MaH;
ur[shift][1] = MaL;
if( Close[mm + 1]+spread/2 >= MaH ) { ll = 1; hh = 0; }
if( Close[mm + 1]+spread/2 <= MaL ) { hh = 1; ll = 0; }
}
if( ur[shift,1] == 0 )
{
ur[shift][0] = ur[shift + 1][0];
ur[shift][1] = ur[shift + 1][1];
}
if( ll == 1 )
{
ExtMapBuffer2[shift]=0;
ExtMapBuffer1[shift]=ur[shift][1];
}
if( hh == 1 )
{
ExtMapBuffer1[shift]=0;
ExtMapBuffer2[shift]=ur[shift][0];
}
}
return(0);
}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments