t3_RSI_ZigZag

Author:
t3_RSI_ZigZag

This script is a specialized technical analysis tool designed to track and smooth price momentum while identifying significant structural turning points in the market. It combines three distinct layers of mathematical logic to create a clean, readable visual for traders.

1. The Momentum Base (RSI)

The foundation of the tool is the Relative Strength Index (RSI). This standard metric measures the speed and change of price movements. By using this as a starting point, the script establishes a baseline for whether an asset is becoming overbought, oversold, or simply trending in a specific direction.

2. The Triple Smoothing Layer (T3)

To filter out the "noise" or small, erratic price fluctuations that often confuse traders, the script applies a sophisticated smoothing algorithm known as a T3 moving average to the RSI data. Unlike standard moving averages which can be sluggish or overly smooth, the T3 logic is designed to reduce lag while maintaining a very fluid curve. This ensures that the resulting line reacts quickly to meaningful trend changes without jumping erratically at every minor price tick.

3. The Structural Mapping (ZigZag Logic)

The final and most complex layer of the script involves a "ZigZag" style detection system. Instead of just showing a smooth curve, the logic performs the following tasks:

  • Peak and Trough Detection: It scans the smoothed data to identify local highs and lows based on specific depth and deviation settings. This helps isolate the "bones" of the market structure.
  • Validation Filtering: The script checks these peaks and troughs against a "backstep" rule. This prevents the tool from marking too many insignificant points in a row, ensuring that only substantial structural shifts are recorded.
  • Conflict Resolution: If the logic detects multiple points simultaneously, it uses a priority system to decide which point is the most significant. It essentially "cleans up" the data by discarding overlapping or contradictory signals.

Summary of Visual Behavior

When looking at this indicator on a chart, the user sees a refined representation of price momentum. Rather than a messy web of data, the script provides a stabilized path that highlights the core trajectory of the market. It identifies where the trend has shifted significantly (turning points) while providing a smoothed line that allows traders to see the underlying strength of the current move more clearly than a standard RSI would allow.

Indicators Used
Relative strength index
Miscellaneous
Implements a curve of type %1
14 Views
0 Downloads
0 Favorites
t3_RSI_ZigZag
//+------------------------------------------------------------------+
//|                                                t3_RSI_ZigZag.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#property indicator_separate_window
//#property indicator_minimum 0
//#property indicator_maximum 100
#property indicator_buffers 2
#property indicator_color1 DodgerBlue
#property indicator_color2 Red
//---- input parameters
extern int RSIPeriod=14;
extern int t3_period=8;
extern double b=0.7;
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
extern int LowLevel=30;
extern int MedLevel=50;
extern int HighLevel=70;
extern int Price=0; // 0 = Close             
                    // 1 = Open
                    // 2 = High
                    // 3 = Low
                    // 4 = (H+L)/2
                    // 5 = (H+L+C)/3
                    // 6 = (H+L+C+C)/4
                    // other = Close                    
//---- buffers
double RSIBuffer[];
double t3_RSIBuffer[];
double ExtMapBuffer[];
double ExtLowBuffer[];
double ExtHighBuffer[];
double e1, e2, e3, e4, e5, e6, c1, c2, c3, c4, n, w1, w2, b2, b3;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;
//---- 2 additional buffers are used for counting.
   IndicatorBuffers(5);
   SetIndexBuffer(2,RSIBuffer);
   SetIndexBuffer(3,ExtLowBuffer);
   SetIndexBuffer(4,ExtHighBuffer);
//---- indicator line
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,t3_RSIBuffer);
   SetIndexStyle(1,DRAW_SECTION);
   SetIndexBuffer(1,ExtMapBuffer);
   SetIndexEmptyValue(1,0.0);
//---- name for DataWindow and indicator subwindow label
   short_name="RSI("+RSIPeriod+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);
//----
   SetIndexDrawBegin(0,RSIPeriod+t3_period);
   SetIndexDrawBegin(1,RSIPeriod+t3_period);
   SetLevelValue(0,LowLevel);
   SetLevelValue(1,MedLevel);
   SetLevelValue(2,HighLevel);
   b2=b*b;
   b3=b2*b;
   c1=-b3;
   c2=(3*(b2+b3));
   c3=-3*(2*b2+b+b3);
   c4=(1+3*b+b3+3*b2);
   n=t3_period;

   if (n<1) n=1;
   n = 1 + 0.5*(n-1);
   w1 = 2 / (n + 1);
   w2 = 1 - w1;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int start()
  {
   int    i,counted_bars=IndicatorCounted();
   double rel,negative,positive;
//----   
   int    shift, back,lasthighpos,lastlowpos,index;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;
//----
   if(Bars<=RSIPeriod) return(0);
//---- initial zero
   if(counted_bars<1)
      for(i=1;i<=RSIPeriod;i++) RSIBuffer[Bars-i]=0.0;

   i=Bars-RSIPeriod-1;
   if(counted_bars>=RSIPeriod) i=Bars-counted_bars-1;
   if(Price<0 || Price>6) Price=0;
   for(; i>=0; i--)
    {
     RSIBuffer[i]=iRSI(NULL,0,RSIPeriod,Price,i);
    } 
   for(i=Bars-1; i>=0; i--)
    {
     e1 = w1*RSIBuffer[i] + w2*e1;
     e2 = w1*e1 + w2*e2;
     e3 = w1*e2 + w2*e3;
     e4 = w1*e3 + w2*e4;
     e5 = w1*e4 + w2*e5;
     e6 = w1*e5 + w2*e6;

     t3_RSIBuffer[i] = c1*e6 + c2*e5 + c3*e4 + c4*e3;
    }
   for(shift=Bars-1; shift>=0; shift--)
     {
      int n, sn, r, result;
      bool ft=true;
      for(n=1; n<ExtDepth; n++)
       {
        sn=shift+n;
        if(ft)
         {
          if(t3_RSIBuffer[shift]<t3_RSIBuffer[sn]) result=shift;
          else result=sn;
          r=result;
          ft=false;
         } 
        else
         {
          if(t3_RSIBuffer[r]<t3_RSIBuffer[sn]) result=r;
          else result=sn;
          r=result;
         }
       }    
      index=r;
      val=t3_RSIBuffer[index];
      if(val==lastlow) val=0.0;
      else 
        { 
         lastlow=val; 
         if((t3_RSIBuffer[shift]-val)>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=ExtLowBuffer[shift+back];
               if((res!=0)&&(res>val)) ExtLowBuffer[shift+back]=0.0; 
              }
           }
        } 
      ExtLowBuffer[shift]=0.0;
      if(val!=0.0) ExtLowBuffer[index]=val;
      //--- high
      ft=true;
      for(n=1; n<ExtDepth; n++)
       {
        sn=shift+n;
        if(ft)
         {
          if(t3_RSIBuffer[shift]>t3_RSIBuffer[sn]) result=shift;
          else result=sn;
          r=result;
          ft=false;
         }
        else
         {
          if(t3_RSIBuffer[r]>t3_RSIBuffer[sn]) result=r;
          else result=sn;
          r=result;
         }
       }  
      index=r;
      val=t3_RSIBuffer[index];
      if(val==lasthigh) val=0.0;
      else 
        {
         lasthigh=val;
         if((val-t3_RSIBuffer[shift])>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=ExtHighBuffer[shift+back];
               if((res!=0)&&(res<val)) ExtHighBuffer[shift+back]=0.0; 
              } 
           }
        }
      ExtHighBuffer[shift]=0.0;
      if(val!=0.0) ExtHighBuffer[index]=val;
     }
//---- final cutting 
   lasthigh=-1; lasthighpos=-1;
   lastlow=-1;  lastlowpos=-1;

   for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      curlow=ExtLowBuffer[shift];
      curhigh=ExtHighBuffer[shift];
      if(curlow==0 && curhigh==0) continue;
      //---
      if(curhigh!=0)
        {
         if(lasthigh>0) 
           {
            if(lasthigh<curhigh) ExtHighBuffer[lasthighpos]=0;
            else ExtHighBuffer[shift]=0;
           }
         //---
         if(lasthigh<curhigh || lasthigh<0)
           {
            lasthigh=curhigh;
            lasthighpos=shift;
           }
         lastlow=-1;
        }
      //----
      if(curlow!=0)
        {
         if(lastlow>0)
           {
            if(lastlow>curlow) ExtLowBuffer[lastlowpos]=0;
            else ExtLowBuffer[shift]=0;
           }
         //---
         if((curlow<lastlow)||(lastlow<0))
           {
            lastlow=curlow;
            lastlowpos=shift;
           } 
         lasthigh=-1;
        }
     }
//---- merge 2 buffers
   lasthighpos=-1;
   lastlowpos=-1;
   for(shift=Bars-1; shift>=0; shift--)
     {
      if(shift>=Bars-ExtDepth) ExtMapBuffer[shift]=0.0;
      else
        {
         curlow=ExtLowBuffer[shift];
         curhigh=ExtHighBuffer[shift];
         //----
         res=0;
         if(curlow!=0)
           {
            if(lastlowpos==-1)
              {
               res=curlow;
               lastlowpos=shift;
              }
            else
              {
               if(lasthighpos!=-1 && lastlowpos>lasthighpos)
                 {
                  res=curlow;
                  lastlowpos=shift;
                 }
              }
           }
         if(curhigh!=0)
           {
            if(lasthighpos==-1)
              {
               res=curhigh;
               lasthighpos=shift;
              }
            else
              {
               if(lastlowpos!=-1 && lasthighpos>lastlowpos)
                 {
                  res=curhigh;
                  lasthighpos=shift;
                 }
              }
           }
         //----
         ExtMapBuffer[shift]=res;
        }
     }
           
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments