GannSwingsXVI

Download script
Author: Rosh
GannSwingsXVI

This script is designed to identify and visualize significant price fluctuations—specifically "swings" or structural turning points—on a trading chart. Rather than simply marking every high and low, it uses a specific logical framework to distinguish between the continuation of a trend and a legitimate reversal of market direction.

Core Logic Overview

The script processes market data by looking for specific relationships between price bars. It categorizes movements into three main types:

1. Trend Identification (Up and Down Trends) The logic maintains an internal "memory" of the current market direction. It monitors whether prices are making progressively higher highs or lower lows.

  • If the market is in an UpTrend, it looks for a specific price action signal to trigger a reversal to a DownTrend.
  • If the market is in a DownTrend, it watches for the opposite signal to trigger a reversal back to an UpTrend.

2. Swing Point Detection The script identifies "Swings" based on whether a new bar exceeds the previous high or low reached during the current trend movement.

  • It uses counters to track these movements. Depending on the user's configuration (the "kind" setting), it determines how many consecutive pushes in one direction are required before it acknowledges a significant structural point.
  • When a reversal is confirmed, it marks the peak or trough as a "Swing High" or "Swing Low."

3. OutSide Bar Handling A unique feature of this script is its handling of "OutSide Bars"—bars that have both a high higher than the previous swing high and a low lower than the previous swing low (essentially "engulfing" the previous price range). The script treats these differently:

  • It identifies these bars separately to ensure that volatile, erratic price action doesn't provide "false positives" for trend reversals.
  • It applies specific rules to determine if an OutSide Bar represents a genuine shift in trend or simply a moment of high volatility within the existing trend.

Visual and Functional Behavior

  • ZigZag Visualization: The primary goal is to draw a "ZigZag" style line connecting the major turning points, helping traders see the underlying structure of the market more clearly.
  • Dynamic Updates: The script includes a logic toggle to move the "tip" of the most recent swing. If two consecutive bars share the same highest or lowest point, the script can automatically adjust the marker to the most recent bar to keep the visual representation accurate.
  • Trend Buffering: Behind the scenes, the script maintains a buffer that keeps track of the trend state (Up vs. Down) for every bar, ensuring that the logic remains consistent as new price data arrives in real-time.

Summary for the User

In simple terms, this tool cleans up "market noise." Instead of showing you every tiny wiggle in the price, it waits for the market to prove it is actually changing direction. It identifies the significant peaks and valleys (Swings) by calculating whether the current price movement has enough momentum to overcome the previous trend, then draws a clear path connecting those key points on your chart.

Miscellaneous
Implements a curve of type %1
9 Views
0 Downloads
0 Favorites
GannSwingsXVI
//+------------------------------------------------------------------+
//|                                                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