GannSwingsXVI_v1

Download script
Author: Rosh
GannSwingsXVI_v1

This script functions as a dynamic market structure indicator, designed to identify and track significant price "swings" (peaks and valleys) while distinguishing between the overall trend and local price action. Instead of simply marking every high and low, it uses a logical filtering system to determine which price points are structurally important.

Here is a breakdown of the logic used by this script:

Core Trend Identification

The script maintains a memory of the current market direction (Upward or Downward). It classifies price action into two primary categories:

  • Trend Continuation: When price moves in the direction of the existing trend, the script monitors whether those movements are significant enough to redefine the "active" highs or lows.
  • Trend Reversal: The logic specifically looks for "breakout" conditions. If the price moves against the current trend with sufficient strength (based on a user-defined intensity level), the script flips the trend direction and resets the swing tracking.

Filtering Price Action

A key feature of this logic is its ability to handle "Outside Bars"—candles where the high is higher and the low is lower than the previous significant swing point.

  • Normal Bars: The script processes standard price action to build a continuous line of highs and lows.
  • Outside Bars: When an outside bar occurs, the script activates a special logic path. It identifies these as unique events that can either signify a volatile expansion of the range or a potential shift in momentum, marking them visually to alert the user.

Dynamic Swing Tracking

The script uses a counter-based system to manage how "sensitive" it is to new price peaks and valleys:

  • Sensitivity Levels: By adjusting the "Kind" setting, users can determine how many consecutive price movements are required to confirm a new trend or swing point. This helps filter out market "noise."
  • Swing Memory: The script keeps track of the most recent significant high and low. It has the capability to "move" the last known swing point if the price reaches the exact same level again, ensuring the chart remains clean and only shows the most relevant data points.

Visual Output Logic

The logic translates these internal calculations into several visual layers on the chart:

  1. ZigZag Path: Draws a continuous line connecting the major high and low swing points to show the primary structure of the market.
  2. Active Highs/Lows: Highlights the specific price levels that are currently being tested or "held" by the market.
  3. Directional Arrows: Provides visual cues for trend shifts, reversals, and specific types of "Outside Bars."
  4. Trend Buffer: An underlying calculation that dictates whether the current price action is being interpreted as a bullish or bearish movement.

Summary of Behavior

In plain terms, the script acts as an automated analyst that watches every candle to see if it makes a "new" high or low relative to the previous major turning point. It ignores minor fluctuations unless they meet specific criteria (based on your settings), and it specifically flags candles that exceed the previous range in both directions, providing a clear map of the market's skeleton.

Miscellaneous
Implements a curve of type %1
6 Views
0 Downloads
0 Favorites
GannSwingsXVI_v1
//+------------------------------------------------------------------+
//|                                                GannSwingsXVI.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Rosh"
#property link      "http://www.metaquotes.net"
//----
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 Yellow
#property indicator_color2 Yellow
#property indicator_color3 Blue
#property indicator_color4 Red
#property indicator_color5 Aqua
#property indicator_color6 HotPink
//#property indicator_color7 Lime
#define version "XVI"
extern int kind=2;// òèï òåíäåíöèè, 1- ìàëàÿ, 2 - ïðîìåæóòî÷íàÿ, 3 - îñíîâíàÿ
extern bool ShowHiLo=true;
extern bool ShowOutSideBars=true;
extern bool MoveLastSwing=false; // åñëè ðàâíî true, òî êîí÷èê õâîñòà áóäåò ñäâèãàòüñÿ áëèæå ê íóëåâîìó áàðó äëÿ äâóõ îäèíàêîâûõ áàðîâ ïî High èëè Low
//---- buffers
double HighSwings[];
double LowSwings[];
double HighsBuffer[];
double LowsBuffer[];
double TrendBuffer[];
double UpCloseOutSideBuffers[];
double DownCloseOutSideBuffers[];
double Needles[];
double SwingHigh,SwingLow;
int prevSwing,LastSwing,myBars,lowCounter,highCounter , cnt;
int ahtung;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(8);
   SetIndexStyle(0,DRAW_ZIGZAG);
   SetIndexBuffer(0,HighSwings);
   SetIndexEmptyValue(0,0.0);
   SetIndexLabel(0,"HighSwing");
   SetIndexStyle(1,DRAW_ZIGZAG);
   SetIndexBuffer(1,LowSwings);
   SetIndexEmptyValue(1,0.0);
   SetIndexLabel(1,"LowSwing");
   SetIndexBuffer(2,HighsBuffer);
   SetIndexLabel(2,"HighActive");
   SetIndexEmptyValue(2,0.0);
   SetIndexBuffer(3,LowsBuffer);
   SetIndexLabel(3,"LowActive");
   SetIndexEmptyValue(3,0.0);
   if (ShowHiLo)
     {
      SetIndexStyle(2,DRAW_ARROW);
      SetIndexArrow(2,159);
      SetIndexStyle(3,DRAW_ARROW);
      SetIndexArrow(3,159);
     }
   else
     {
      SetIndexStyle(2,DRAW_NONE);
      SetIndexStyle(3,DRAW_NONE);
     }
   SetIndexBuffer(4,UpCloseOutSideBuffers);
   SetIndexStyle(4,DRAW_ARROW);
   SetIndexArrow(4,108);
   SetIndexLabel(4,"UpClose");
   SetIndexEmptyValue(4,0.0);
   SetIndexBuffer(5,DownCloseOutSideBuffers);
   SetIndexStyle(5,DRAW_ARROW);
   SetIndexArrow(5,108);
   SetIndexLabel(5,"DownClose");
   SetIndexEmptyValue(5,0.0);
   SetIndexBuffer(6,Needles);
   //SetIndexStyle(6,DRAW_NONE);
   SetIndexEmptyValue(6,0.0);
   //   SetIndexStyle(6,DRAW_ARROW);
   //   SetIndexArrow(6,108);
   SetIndexBuffer(7,TrendBuffer);
   SetIndexEmptyValue(7,0.0);
//----
   for(int i=Bars-1; i>=0; i--)
     {
      HighSwings[i]=0.0;
      LowSwings[i]=0.0;
      HighsBuffer[i]=0.0;
      LowsBuffer[i]=0.0;
      TrendBuffer[i]=0.0;
      UpCloseOutSideBuffers[i]=0.0;
      DownCloseOutSideBuffers[i]=0.0;
     }
   SwingHigh=0.0;
   SwingLow=0.0;
   prevSwing=0;
   LastSwing=0.0;
   myBars=0;
   lowCounter=0;
   highCounter=0;
   Comment("\n","GannSwings ",version," kind=",kind);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   Comment("\n","\n","            ");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
void DownTrendOutSide()
  {
//---- 
//-1
   if (Close[cnt]<=Open[cnt] && lowCounter==1)
     {
      SwingHigh=High[cnt];
      SwingLow=Low[cnt];
      HighSwings[cnt]=High[cnt];
      LowSwings[cnt]=Low[cnt];
      highCounter=0;
      lowCounter=0;
      LastSwing=cnt;
      Needles[cnt]=1.0;
      ahtung=0.0;
      return;
     }
//-2
   if(Close[cnt]>Open[cnt] && lowCounter==1)
     {
      LowSwings[LastSwing]=0.0;
      SwingLow=Low[cnt];
      SwingHigh=High[cnt];
      HighSwings[cnt]=High[cnt];
      LowSwings[cnt]=Low[cnt];
      highCounter=0;
      LastSwing=cnt;
      if (kind>1)
        {
         Needles[cnt]=1.0;
         lowCounter=1;
         ahtung=-1; // æäåì åùå îäíîãî Low äëÿ ïðîäîëæåíèÿ âíèç
         TrendBuffer[cnt]=1.0;
        }
      else
        {
         lowCounter=0;
         TrendBuffer[cnt]=1.0;
         ahtung=0.0;
        }
      return;
      //Print("breakout äàóíòðåíä ÷åðåç âíåøíèé áàð");
     }
//-3
   if (Close[cnt]<=Open[cnt] && highCounter==kind)
     {
      SwingLow=Low[cnt];
      SwingHigh=High[cnt];
      LowSwings[cnt]=Low[cnt];
      HighSwings[cnt]=High[cnt];
      highCounter=0;
      lowCounter=0;
      LastSwing=cnt;
      Needles[cnt]=1.0;
      TrendBuffer[cnt]=1.0;
      ahtung=0.0;
      return;
      //Print("breakout äàóíòðåíä ÷åðåç âíåøíèé áàð");
     }
//-4
   if (Close[cnt]>Open[cnt] && highCounter==kind)
     {
      Print("Ýòîò áëîê ¹-4 íå äîëæåí ðàáîòàòü");
      SwingLow=Low[cnt];
      SwingHigh=High[cnt];
      if (Low[cnt]<LowSwings[LastSwing])
        {
         LowSwings[LastSwing]=0.0;
         LowSwings[cnt]=Low[cnt];
        }
      HighSwings[cnt]=High[cnt];
      highCounter=0;
      lowCounter=0;
      LastSwing=cnt;
      //Print("Ðàçâîðîò äàóíòðåíäà ÷åðåç âíåøíèé áàð");
      TrendBuffer[cnt]=1.0;
      Needles[cnt]=1.0;
      ahtung=0.0;
      return;
     }
//----
   return;
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
void UpTrendOutSide()
  {
//---- 
   //+1
   if(Close[cnt]>=Open[cnt] && highCounter==1)
     {
      SwingLow=Low[cnt];
      SwingHigh=High[cnt];
      LowSwings[cnt]=Low[cnt];
      HighSwings[cnt]=High[cnt];
      highCounter=0;
      lowCounter=0;
      LastSwing=cnt;
      Needles[cnt]=1.0;
      ahtung=0.0;
      //Print("Ïðîäîëæåíèå àïòðåíä ÷åðåç âíåøíèé áàð");
      return;
     }
   //+2
   if (Close[cnt]< Open[cnt] && highCounter==1)
     {
      HighSwings[LastSwing]=0.0;
      SwingLow=Low[cnt];
      SwingHigh=High[cnt];
      LowSwings[cnt]=Low[cnt];
      HighSwings[cnt]=High[cnt];
      lowCounter=0;
      LastSwing=cnt;
      if (kind>1)
        {
         Needles[cnt]=1.0;
         highCounter=1;
         ahtung=1; // æäåì åùå îäíîãî High äëÿ ïðîäîëæåíèÿ ââåðõ
         TrendBuffer[cnt]=-1.0;
        }
      else
        {
         highCounter=0;
         TrendBuffer[cnt]=-1.0;
         ahtung=0.0;
        }
      //Print("breakout àïòðåíä ÷åðåç âíåøíèé áàð");
      return;
     }
   //+3
   if (Close[cnt]>= Open[cnt] && lowCounter==kind)
     {
      SwingLow=Low[cnt];
      SwingHigh=High[cnt];
      LowSwings[cnt]=Low[cnt];
      HighSwings[cnt]=High[cnt];
      highCounter=0;
      lowCounter=0;
      LastSwing=cnt;
      //TrendBuffer[cnt]=-1.0;
      Needles[cnt]=1.0;
      ahtung=0.0;
      //Print("breakout àïòðåíä ÷åðåç âíåøíèé áàð");
      return;
     }
   //+4
   if (Close[cnt]<Open[cnt] && lowCounter==kind)
     {
      Print("Ýòîò áëîê ¹+4 íå äîëæåí ðàáîòàòü");
      SwingLow=Low[cnt];
      SwingHigh=High[cnt];
      if (High[cnt]>HighSwings[LastSwing])
        {
         HighSwings[LastSwing]=0.0;
         HighSwings[cnt]=High[cnt];
        }
      LowSwings[cnt]=Low[cnt];
      highCounter=0;
      lowCounter=0;
      LastSwing=cnt;
      //Print("Ðàçâîðîò àïòðåíäà ÷åðåç âíåøíèé áàð");
      TrendBuffer[cnt]=-1.0;
      ahtung=0.0;
     }
//----
   return;
  }
//+------------------------------------------------------------------+
//| OutSidePart function                                             |
//+------------------------------------------------------------------+
void OutSidePart()
  {
//---- 
   if (TrendBuffer[cnt+1]==1.0)
     {
      UpTrendOutSide();
     }//TrendBuffer[cnt+1]==1.0;
   else
     {// TrendBuffer[cnt+1]==-1.0
      DownTrendOutSide();
     }//TrendBuffer[cnt+1]==-1.0
//----
   return;
  }
//+------------------------------------------------------------------+
//| nonOutSidePart() function                                        |
//+------------------------------------------------------------------+
void nonOutSidePart()
  {
//---- 
   if (TrendBuffer[cnt+1]==-1.0)
     {
      if (lowCounter==1)
        {
         if (LastSwing!=Bars-1) LowSwings[LastSwing]=0.0; // çàòðåì ïðåäûäóùèé ñâèíã
         //Print("çàòðåì ïðåäûäóùèé Down ñâèíã");
         LastSwing=cnt;
         //Neeldles[cnt]=1.0;
         SwingHigh=High[cnt];
         SwingLow=Low[cnt];
         //TrendBuffer[cnt]=-1.0;
         highCounter=0;
         lowCounter=0;
         LowSwings[cnt]=Low[cnt];
         HighsBuffer[cnt]=SwingHigh;
         ahtung=0.0;
         //Print("ïðîäîëæåíèå äàóíòðåíäà");
        }
      else
        {
         if (highCounter==kind)
           {
            //if (LastSwing=!cnt) 
            if (ahtung==1) CutLastNeedle(cnt);
            LastSwing=cnt;
            SwingHigh=High[cnt];
            SwingLow=Low[cnt];
            TrendBuffer[cnt]=1.0;
            highCounter=0;
            lowCounter=0;
            HighSwings[cnt]=High[cnt];
            LowsBuffer[cnt]=SwingLow;
            ahtung=0.0;
            //Neeldles[cnt]=1.0;            
            //Print("ðàçâîðîò äàóíòðåíäà");
           }
         else
           {
            if (Low[cnt]==SwingLow && MoveLastSwing)
              {
               LowSwings[LastSwing]=0.0;
               LastSwing=cnt;
               LowSwings[cnt]=Low[cnt];
               //                     continue;
              }
           }
        }
     }//   TrendBuffer[cnt+1]==-1.0
   else     //   TrendBuffer[cnt+1]==1.0          
     {
      if (highCounter==1)
        {
         if (LastSwing!=Bars-1) HighSwings[LastSwing]=0.0; // çàòðåì ïðåäûäóùèé ñâèíã
         LastSwing=cnt;
         //Neeldles[cnt]=1.0;
         SwingHigh=High[cnt];
         SwingLow=Low[cnt];
         highCounter=0;
         lowCounter=0;
         HighSwings[cnt]=High[cnt];
         HighsBuffer[cnt]=SwingHigh;
         LowsBuffer[cnt]=SwingLow;
         ahtung=0.0;
         //Print("ïðîäîëæåíèå àïòðåíäà");
        }
      else
        {
         if (lowCounter==kind)
           {
            if (ahtung==-1) CutLastNeedle(cnt);
            LastSwing=cnt;
            SwingHigh=High[cnt];
            SwingLow=Low[cnt];
            TrendBuffer[cnt]=-1.0;
            highCounter=0;
            lowCounter=0;
            LowSwings[cnt]=Low[cnt];
            HighsBuffer[cnt]=SwingHigh;
            LowsBuffer[cnt]=SwingLow;
            ahtung=0.0;
            //Neeldles[cnt]=1.0;
            //Print("ðàçâîðîò àïòðåíäà");
           }
         else
           {
            if (High[cnt]==SwingHigh && MoveLastSwing)
              {
               HighSwings[LastSwing]=0.0;
               LastSwing=cnt;
               HighSwings[cnt]=High[cnt];
              }
           }
        }
     } //TrendBuffer[cnt+1]==1.0           
//----
   return;
  }
//+------------------------------------------------------------------+
//| return shift of last swing                                       |
//+------------------------------------------------------------------+
int GetLastSwing()
  {
//---- 
   int point=1;
   while(HighSwings[point]==0.0 && Needles[point]==0.0 && point<Bars) point++;
//----
   return(point);
  }
//+------------------------------------------------------------------+
//| setting NULL values to last Needle                               |
//+------------------------------------------------------------------+
void CutLastNeedle(int shift)
  {
   while(Needles[shift]==0.0) shift++;
   HighSwings[shift]=0.0;
   LowSwings[shift]=0.0;
  }
//+------------------------------------------------------------------+
//| Check prev swing                                                 |
//+------------------------------------------------------------------+
void SetPrevSwing()
  {
//---- 
   int LastPoint;
   LastPoint=GetLastSwing();
   HighSwings[0]=0.0;
   SwingHigh=High[LastPoint];
   SwingLow=Low[LastPoint];
   LastSwing=LastPoint;
//----
   return;
  }
//+------------------------------------------------------------------+
//| check Out side bar                                               |
//+------------------------------------------------------------------+
bool isOutSideSwingBar(int shift)
  {
   bool res=false;
//---- 
   res=((High[shift]>SwingHigh)&&(Low[shift]<SwingLow));
   if (res && ShowOutSideBars)
     {
      if (Close[shift]>Open[shift]) UpCloseOutSideBuffers[shift]=(High[shift]+Low[shift])/2.0;
      else DownCloseOutSideBuffers[shift]=(High[shift]+Low[shift])/2.0;
     }
//----
   return(res);
  }
//+------------------------------------------------------------------+
//| Check new low                                                    |
//+------------------------------------------------------------------+
void SetSwings(int shift)
  {
//---- 
//----
   return;
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
   int limit;
   bool nonOutSide;
   if (counted_bars==0)
     {
      limit=Bars-1;
      LowsBuffer[limit]=Low[limit];
      LowSwings[limit]=Low[limit];
      SwingHigh=High[limit];
      SwingLow=Low[limit];
      LastSwing=limit;
      TrendBuffer[limit]=-1.0;
      Needles[limit]=1.0; // çàôèêñèðóåì ïåðâûé óçåë ñâèíãà
     }
   if (counted_bars>0) limit=Bars-counted_bars;
   if((counted_bars<0)|| ((counted_bars>0)&&(Bars-myBars>1)))init();
   limit--;
//---- 
   for( cnt=limit;cnt>0;cnt--)
     {
      //if (cnt==0) SetPrevSwing();
      nonOutSide=!isOutSideSwingBar(cnt);
//----
      if (High[cnt]>SwingHigh) {highCounter++;SwingHigh=High[cnt];HighsBuffer[cnt]=SwingHigh;}
      if (Low[cnt]<SwingLow) {lowCounter++;SwingLow=Low[cnt];LowsBuffer[cnt]=SwingLow;}
//----
      TrendBuffer[cnt]=TrendBuffer[cnt+1];// åñëè íå áóäóò èçìåíåíèé - òðåíä ñîõðàíèòñÿ
      if (nonOutSide)
        {
         nonOutSidePart(); // òóò ìû ðàáîòàåì ñ îáû÷íûìè áàðàìè          
        }// if (nonOutSide)         
      else // outSideBars
        {
         OutSidePart();
        }// isOutSideSwingBar(cnt)          
     } // ÊÎÍÅÖ ÖÈÊËÀ
   myBars=Bars;
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments