ZigZagOnParabolic

ZigZagOnParabolic

This technical script is designed to provide a visual representation of market trends and price extremes on a trading chart. It works by combining two distinct analytical components: the Parabolic SAR (Stop and Reverse) indicator and a dynamic ZigZag mapping system.

The core logic follows these primary functions:

1. Trend Detection via Parabolic SAR

The script constantly monitors the "Parabolic SAR" values, which are represented as dots on your chart. This component serves as the primary trigger for identifying shifts in market momentum. The script looks for specific "flips" or crossovers where the SAR value moves from one side of the price midpoint to the other, signaling a potential change in direction (from bullish to bearish or vice versa).

2. Price Extremum Identification

While the Parabolic SAR identifies the moment of a trend shift, this script uses that information to pinpoint and "draw" the highest highs and lowest lows reached during that specific trend movement:

  • Peaks: When the trend is moving upward, the script tracks the highest price point reached. Once the Parabolic SAR signals a downward flip, the script marks that peak.
  • Troughs (Valleys): When the trend is moving downward, the script tracks the lowest price point reached. Once the Parabolic SAR signals an upward flip, the script marks that trough.

3. Smart Positioning Logic

A key feature of this script is how it places these "Peaks" and "Troughs" on the chart:

  • Temporal Offset: Instead of just placing a mark at the exact moment a trend reverses (which can sometimes look messy or misaligned), the script includes an option to shift the visual marker.
  • Dynamic Adjustment: It can be configured to place the marker either at the specific bar where the reversal was confirmed or at the actual historical peak/valley of the price action. This allows traders to see the "true" structural extremes of the market more clearly.

4. Performance and History Management

To ensure the trading platform remains responsive, the script includes logic to manage data calculation:

  • History Limiting: Users can define how far back into the past the indicator should calculate (or set it to analyze the entire available history).
  • Update Efficiency: The script is designed to recognize when new bars are forming and only perform necessary calculations, preventing unnecessary strain on your computer's resources.

Summary of Visual Output

When applied to a chart, this script provides a clean visual summary of market structure. It highlights the "swing points" of price action, allowing you to easily see where previous highs and lows were established based on the interaction between price volatility and trend-reversal signals.

Indicators Used
Parabolic Stop and Reverse system
Miscellaneous
Implements a curve of type %1
11 Views
0 Downloads
0 Favorites
ZigZagOnParabolic
#property indicator_chart_window // â îêíå èíñòðóìåíòà
#property indicator_buffers 3
#property indicator_color1 Aqua
#property indicator_color3 Blue
//--âíåøíèå ïåðåìåííûå
extern double Step=0.02; // íà÷àëüíîå çíà÷åíèå è øàã
extern double Maximum=0.2; // êîíå÷íîå çíà÷åíèå

extern bool ExtremumsShift=1; // ïîëîæåíèå ýêñòðåìóìîâ: 0 - ïî âðåìåíè èõ îïðåäåëíèÿ; 1 - ïî èõ ôàêòè÷åñêîìó ïîëîæåíèþ 
extern int History=0; // êîë-âî áàðîâ ïðåäûñòîðèè; 0 - âñå

//--
double   Peak[], // áóôåð ZigZag ïî ïèêàì
         Trough[], // áóôåð ZigZag ïî âïàäèíàì
         SAR[]; // áóôåð Parabolic

//=============================================================
int init()
  {
   SetIndexBuffer(0,Peak); // ïèêè
   SetIndexStyle(0,DRAW_ZIGZAG);
   SetIndexLabel(0,"Peak");
   SetIndexEmptyValue(0,0.0);

   SetIndexBuffer(1,Trough); // êðåñòû, ò.å. âïàäèíû)))
   SetIndexStyle(1,DRAW_ZIGZAG);
   SetIndexLabel(1,"Trough");
   SetIndexEmptyValue(1,0.0);

   SetIndexBuffer(2,SAR); // Ïàðàáîëèê
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,159);
   SetIndexLabel(2,"SAR");
   SetIndexEmptyValue(2,0.0);
     
   return(0);
  }

//=============================================================
int start()
  {
   static int BarsPrev; // çíà÷åíèå Bars íà ïðåä.áàðå
   bool MissBars=Bars-BarsPrev>1; // 1 - åñòü ïðîïóùåííûå áàðû
   bool NewBar=Bars-BarsPrev==1; // 1 - ïåðâûé òèê íóëåâîãî áàðà
   if(MissBars && BarsPrev!=0) BarsPrev=reinit(); // ïðîóùåííûå áàðû â ïðîöåññå - ïåðåñ÷åò çàíîâî
   
   int limit=Bars-BarsPrev-(BarsPrev==0); BarsPrev=Bars; // êîë-âî ïåðåñ÷åòîâ
   if(History!=0 && limit>History) limit=History-1; // êîë-âî ïåðåñ÷åòîâ ïî èñòîðèè

   for(int i=limit; i>=0; i--) // öèêë ïî íåïîñ÷èòàííûì è ïðåäïîñëåäíåìó áàðàì
     {   
      SAR[i]=iSAR(NULL,0,Step,Maximum, i); // Ïàðàáîëèê
      double mid[2]; // ñð. öåíà
      mid[0]=(High[i]+Low[i])/2; // ñð.öåíà íà òåêóùåì áàðå
      mid[1]=(High[i+1]+Low[i+1])/2; // ñð.öåíà íà ïðåä.áàðå

      static int j; // ñ÷åò÷èê ñìåùåíèÿ ìåæäó ìîìåíòîì îïðåäåëåíÿ ýêñòðåìóìà è åãî ïîëîæåíèåì âî âðåìåíè
      static bool dir; // ôëàã íàïðàâëåíèÿ; 0 - âíèç, 1 - ââåðõ
      static double h,l; // òåêóùèå ýêñòðåìàëüíûå çíà÷åíèÿ
      int shift; // ñìåùåíèå ìåæäó ìîìåíòîì îïðåäåëåíÿ ýêñòðåìóìà è åãî ïîëîæåíèåì âî âðåìåíè

      if(i>0) j++; // åñëè áàð çàâåðøåí, òî èíêðåìåíò ñ÷åò÷èêà ñìåùåíèÿ
      if(dir) // ëîâëÿ  ïèêà
        {
         if(h<High[i]) {h=High[i]; j=NewBar;} // òåêóùèé ìàêñèìóì; ñáðîñ ñ÷åò÷èêà ñìåùåíèÿ
         if(SAR[i+1]<=mid[1] && SAR[i]>mid[0]) // ïåðåâîðîò Ïàðàáîëèêà âíèç
           {
            shift=i+ExtremumsShift*(j+NewBar); // ñìåùåíèå
            Peak[shift]=h; // ïèê
            dir=0; // íàïðàâëåíèå âíèç
            l=Low[i]; j=0; // òåêóùèé ìàêñèìóì, ñáðîñ ñ÷åò÷èêà ñìåùåíèÿ
           }
        }
      else // ëîâëÿ âïàäèíû
        {
         if(l>Low[i]) {l=Low[i]; j=NewBar;} // òåêóùèé ìèíèìóì; ñáðîñ ñ÷åò÷èêà ñìåùåíèÿ
         if(SAR[i+1]>=mid[1] && SAR[i]<mid[0]) // ïåðåâîðîò Ïàðàáîëèêà ââåðõ
           {
            shift=i+ExtremumsShift*(j+NewBar); // ñìåùåíèå
            Trough[shift]=l; // âïàäèíà
            dir=1; // íàïðàâëåíèå ââåðõ
            h=High[i]; j=0; // òåêóùèé ìàêñèìóì, ñáðîñ ñ÷åò÷èêà ñìåùåíèÿ
           }
        }
     }

//   if(MissBars) Print("limit: ",limit," Bars:",Bars," IndicatorCounted: ",IndicatorCounted());

   return(0);
  }
//=============================================================

// ô-ÿ äîïîëíèòåëüíîé èíèöèàëèçàöèè
int reinit()
  {
   ArrayInitialize(Peak,0.0);
   ArrayInitialize(Trough,0.0);
   ArrayInitialize(SAR,0.0);
   return(0);
  }
 

Comments