Parabolic Sub

Author: Copyright � 2004, MetaQuotes Software Corp.
Parabolic Sub

This script is a specialized technical analysis tool designed for the MetaTrader platform. It calculates a dynamic trend-following indicator, specifically a variation of the Parabolic SAR (Stop and Reverse), which helps traders identify potential turning points in market momentum.

Core Logic Overview

The primary goal of this script is to plot a series of dots on a price chart that act as "trailing" signals. These signals move in tandem with the market price, shifting based on whether the current trend is moving upward (bullish) or downward (bearish). When the price crosses one of these markers, the script interprets it as a signal to "reverse" the expected direction.

Key Components of the Logic

1. Trend Detection and Directional Tracking The logic maintains a continuous awareness of whether the market is currently in a long (upward) or short (downward) phase. It monitors price extremes—specifically the highest highs and lowest lows—to determine the strength and trajectory of the movement. If the price breaks through a previously established boundary, the script identifies this as a trend shift and updates its internal tracking accordingly.

2. Dynamic Calculation Mechanism Unlike static indicators that use a fixed distance, this script uses a "Step" and "Maximum" system:

  • The Step: This controls how quickly the indicator accelerates toward the price. As the trend continues without a reversal, the distance between the indicator and the price shrinks, making it more sensitive to sudden changes.
  • The Maximum: This acts as a safety ceiling for the acceleration. It ensures that the indicator doesn't become so aggressive that it creates "noise" or reacts too instantly to minor price fluctuations.

3. The "Stop and Reverse" Interaction The script constantly compares the current market price against its own calculated values:

  • In an Uptrend: The indicator stays below the price. If the price drops below the indicator's value, the logic triggers a reversal, flipping the trend to "Short" and resetting the calculation parameters.
  • In a Downtrend: The indicator stays above the price. If the price rises above the indicator's value, it triggers a reversal, flipping the trend to "Long."

4. Initialization and Memory The script includes specific logic to handle historical data. When first loaded, it scans back through previous price bars to establish a baseline for the current trend. It also contains specialized checks to ensure that the calculations remain stable when moving from one candle (bar) to the next, preventing "gaps" or erratic jumps in the visual representation on your chart.

Summary of User Experience

For a trader, this logic translates to a visual "trailing stop." You will see dots trailing behind the price candles. The goal is to follow the trend until the price touches a dot; at that moment, the script signals that the previous trend has likely ended and a reversal may be occurring.

Miscellaneous
Implements a curve of type %1
11 Views
0 Downloads
0 Favorites
Parabolic Sub
//+------------------------------------------------------------------+
//|                                                Parabolic Sub.mq4 |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
//----
//Added Fix1 September 6, 2006 Advance Index if new bar by Stanley Fiala http://merlin4x.com
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
//---- input parameters
extern double Step = 0.02;
extern double Maximum = 0.2;
//---- buffers
double SarBuffer[];
//----
int    save_lastreverse;
bool   save_dirlong;
double save_start;
double save_last_high;
double save_last_low;
double save_ep;
double save_sar;
int    bartime;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0, DRAW_ARROW);
   SetIndexArrow(0, 159);
   SetIndexBuffer(0, SarBuffer);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SaveLastReverse(int last, int dir, double start, double low, double high, 
                     double ep, double sar)
  {
   save_lastreverse = last;
   save_dirlong = dir;
   save_start = start;
   save_last_low = low;
   save_last_high = high;
   save_ep = ep;
   save_sar = sar;
  }
//+------------------------------------------------------------------+
//| Parabolic Sell And Reverse system                                |
//+------------------------------------------------------------------+
int start()
  {
   static bool first = true;
   bool   dirlong;
   double start, last_high, last_low;
   double ep, sar, price_low, price_high, price;
   int    i, counted_bars = IndicatorCounted();
//----
   if(Bars < 3) 
       return(0);
//---- initial settings
   i = Bars - 2;
//----
   if(counted_bars == 0 || first)
     {
       first = false;
       dirlong = true;
       start = Step;
       last_high = -10000000.0;
       last_low = 10000000.0;
       //----
       while(i > 0)
         {
           save_lastreverse = i;
           price_low = Low[i];
           //----
           if(last_low > price_low)
               last_low = price_low;
           price_high = High[i];
           //----
           if(last_high < price_high)
               last_high = price_high;
           //----
           if(price_high > High[i+1] && price_low > Low[i+1]) 
               break;
           //----
           if(price_high < High[i+1] && price_low < Low[i+1])
             { 
               dirlong = false; 
               break; 
             }
           i--;
         }
       //---- initial zero
       int k = i;
       Print("  k=", k, "  Bars=", Bars);      
       //----
       while(k < Bars)
         {
           SarBuffer[k] = 0.0;
           k++;
         }
       //---- check further
       if(dirlong)
         { 
           SarBuffer[i] = Low[i+1];
           ep = High[i];
         }
       else        
         { 
           SarBuffer[i] = High[i+1]; 
           ep = Low[i]; 
         }
       i--;
     }
   else
     {
       i =         save_lastreverse;
       start =     save_start;
       dirlong =   save_dirlong;
       last_high = save_last_high;
       last_low =  save_last_low;
       ep =        save_ep;
       sar =       save_sar;
       // Fix1 start
       // If new bar increment index   
       if(Time[0] != bartime)       
         {
           bartime = Time[0];
           i++;
         }
       //Fix1 end         
     }
//----
   while(i >= 0)
     {
       price_low = Low[i];
       price_high = High[i];
       //--- check for reverse from long to short
       if(dirlong && price_low < SarBuffer[i+1])
         {
           SaveLastReverse(i, true, start, price_low, last_high, ep, sar);
           start = Step; 
           dirlong = false;
           ep = price_low;  
           last_low = price_low;
           SarBuffer[i] = last_high;
           i--;
           continue;
         }
       //--- check for reverse from short to long  
       if(!dirlong && price_high > SarBuffer[i+1])
         {
           SaveLastReverse(i, false, start, last_low, price_high, ep, sar);
           start = Step; 
           dirlong = true;
           ep = price_high; 
           last_high = price_high;
           SarBuffer[i] = last_low;
           i--;
           continue;
         }
       //sar(i) = sar(i+1)+start*(ep-sar(i+1))
       price = SarBuffer[i+1];
       sar = price + start*(ep - price);
       //----
       if(dirlong)
         {
           if(ep < price_high && (start + Step) <= Maximum) 
               start += Step;
           //----
           if(price_high < High[i+1] && i == Bars - 2)  
               sar = SarBuffer[i+1];
           price = Low[i+1];
           //----
           if(sar > price)
               sar = price;
           price = Low[i+2];
           //----
           if(sar > price)
               sar = price;
           //----
           if(sar > price_low)
             {
               SaveLastReverse(i, true, start, price_low, last_high, ep, sar);
               start = Step; 
               dirlong = false; 
               ep = price_low;
               last_low = price_low;
               SarBuffer[i] = last_high;
               i--;
               continue;
             }
           //----
           if(ep < price_high)
             {
               last_high = price_high;
               ep = price_high;
             }
         }     //dir-long
       else
         {
           if(ep > price_low && (start + Step) <= Maximum) 
               start += Step;
           //----
           if(price_low < Low[i+1] && i == Bars - 2)  
               sar = SarBuffer[i+1];
           price = High[i+1];
           //----
           if(sar < price)
               sar = price;
           price = High[i+2];
           //----
           if(sar < price)
               sar = price;
           //----
           if(sar < price_high)
             {
               SaveLastReverse(i, false, start, last_low, price_high, ep,sar);
               start = Step; 
               dirlong = true; 
               ep = price_high;
               last_high = price_high;
               SarBuffer[i] = last_low;
               i--;
               continue;
             }
           //----
           if(ep > price_low)
             {
               last_low = price_low; 
               ep = price_low; 
             }
         }     //dir-short
       SarBuffer[i] = sar;
       i--;
     }        //while   
//   sar=SarBuffer[0];
//   price=iSAR(NULL,0,Step,Maximum,0);
//   if(sar!=price) Print("custom=",sar,"   SAR=",price,"   counted=",counted_bars);
//   if(sar==price) Print("custom=",sar,"   SAR=",price,"   counted=",counted_bars);
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments