FirstStrike
Download scriptThis technical tool is designed to identify significant price extremes by analyzing the relationship between different timeframes. Instead of looking at a single chart in isolation, the logic scans through nested time periods (such as moving from Daily charts down to Hourly, or Hourly down to Minute charts) to determine where "first strikes" on price occur.
Core Operational Logic
The script functions by performing a deep recursive search through multiple timeframes to pinpoint the most significant price boundaries. Here is the breakdown of how it processes market data:
1. Multi-Timeframe Contextual Analysis The tool identifies the current timeframe you are viewing and automatically looks at the immediate "child" timeframe (the smaller unit of time directly below it). It then systematically moves downward through these timeframes to gather a complete picture of price movement.
2. High and Low Extremes Detection For every specific period, the script scans all the price candles within that window to identify two critical data points:
- The Minimum Price reached during that interval.
- The Maximum Price reached during that interval.
3. The "First Strike" Decision Engine The tool determines which of these extremes (the high or the low) is more significant based on their chronological appearance. It follows a specific hierarchy:
- If the lowest price was reached before the highest price within a timeframe, it marks that point as a primary significant value.
- If the highest price was reached before the lowest price, it selects that instead.
- Recursive Refinement: If both extremes occur at the exact same time, the script does not stop there. It "drills down" into the next smaller timeframe to perform another search, repeating this process until it can uniquely identify which price action occurred first.
4. Visual Output Once the logic identifies these significant price points, it places visual markers (arrows) on your chart. These markers highlight the specific price levels where the "first strike" occurred, helping traders visualize key structural boundaries that are influenced by multi-timeframe price action.
Key Constraints
- Timeframe Compatibility: The tool is specifically designed to function on timeframes larger than 1 minute. It will not initialize or provide data on a 1-minute chart.
- Visual Representation: The results are displayed using distinct colors (Red and Blue) to differentiate between the types of price extremes identified by the logic.
//+------------------------------------------------------------------+
//| FirstStrike.mq4 |
//| Itso |
//| itso@dir.bg |
//+------------------------------------------------------------------+
#property copyright "Itso"
#property link "itso@dir.bg"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue
//---- buffers
double BuffMin[];
double BuffMax[];
int Periods[] = {
PERIOD_M1,
PERIOD_M5,
PERIOD_M15,
PERIOD_M30,
PERIOD_H1,
PERIOD_H4,
PERIOD_D1,
PERIOD_W1,
PERIOD_MN1
};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
if (Period()==PERIOD_M1)
{
Print("This indicator doesn\'t work on M1 timeframe!");
return(0);
}
//---- indicators
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,217);
SetIndexBuffer(0,BuffMin);
SetIndexEmptyValue(0,0.0);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,218);
SetIndexBuffer(1,BuffMax);
SetIndexEmptyValue(1,0.0);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
if (Period()==PERIOD_M1) return(0);
int counted_bars=IndicatorCounted();
//----
if(counted_bars>0) counted_bars--;
int limit=Bars-counted_bars;
double Value;
for (int i=0; i<limit; i++)
{
switch(GetFirstStrike(Period(),i,Value))
{
case -1:
{
BuffMin[i]=Value;
break;
}
case 1:
{
BuffMax[i]=Value;
break;
}
case 0:
{
BuffMin[i]=Value;
BuffMax[i]=Value;
}
}
}
return(0);
}
//+------------------------------------------------------------------+
int GetFirstStrike(int ParentPeriod, int ParentBar, double& Value)
{
int CurrPeriod;
datetime StartTime, EndTime;
int ChildFirstBar, ChildLastBar;
int idxMin, idxMax;
double ValMin, ValMax;
for(int i=0;i<ArrayRange(Periods,0);i++)
{
if(Periods[i]==ParentPeriod)
{
CurrPeriod=Periods[i-1];
break;
}
}
if (ParentBar==0)
{
StartTime=TimeCurrent();
ChildFirstBar=0;
}
else
{
StartTime=iTime(Symbol(),ParentPeriod,ParentBar-1);
ChildFirstBar=iBarShift(Symbol(),CurrPeriod,StartTime);
ChildFirstBar++;
}
EndTime=iTime(Symbol(),ParentPeriod,ParentBar);
ChildLastBar=iBarShift(Symbol(),CurrPeriod,EndTime);
ValMin=2*Bid;
ValMax=0;
for(i=ChildLastBar;i>=ChildFirstBar;i--)
{
double CurrLow=iLow(Symbol(),CurrPeriod,i);
double CurrHigh=iHigh(Symbol(),CurrPeriod,i);
if(CurrLow<ValMin)
{
ValMin=CurrLow;
idxMin=i;
}
if(CurrHigh>ValMax)
{
ValMax=CurrHigh;
idxMax=i;
}
}
if (idxMin>idxMax)
{
Value=ValMin;
return(-1);
}
else if(idxMin<idxMax)
{
Value=ValMax;
return(1);
}
else
{
if(CurrPeriod==PERIOD_M1)
{
Value=ValMax;
return(0);
}
else
{
return(GetFirstStrike(CurrPeriod,idxMax,Value));
}
}
}
Comments