FirstStrike

Download script
Author: Itso
FirstStrike

This 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.
Price Data Components
Series array that contains the lowest prices of each barSeries array that contains the highest prices of each bar
Miscellaneous
Implements a curve of type %1
7 Views
0 Downloads
0 Favorites
FirstStrike
//+------------------------------------------------------------------+
//|                                                  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