ParMA_BB_001

Author: Copyright � 2006, MetaQuotes Software Corp.
ParMA_BB_001

This tool is designed to provide a sophisticated visual analysis of price trends by utilizing parabolic regression and volatility boundaries. Unlike standard moving averages that simply track the average price over a set timeframe, this script uses more advanced mathematical modeling to project the "curvature" of market movements.

Core Methodology: Parabolic Approximation

The primary logic of the script is based on a Parabolic Moving Average. Instead of looking at the market as a series of random points, the tool treats price action as a curve.

To achieve this, it performs a regression analysis on historical data. It calculates three specific coefficients that allow it to map out a parabola (a U-shaped or inverted U-shaped curve) that best fits the recent price history. By determining the "bend" of this curve, the indicator can identify the underlying momentum more smoothly than a standard linear average. This helps traders see where the price is naturally heading based on its current trajectory.

Optional Volatility Bands

The script includes an optional feature that adds Bollinger-style bands to the parabolic line. When enabled, the logic follows these steps:

  1. Standard Deviation Calculation: The tool measures how much the price "wiggles" or deviates from the average trend over a specific period.
  2. Volatility Boundaries: It establishes an upper and lower boundary based on this deviation.
  3. Visual Context: These bands represent the "normal" range of market noise. When price stays within these bands, it is considered standard behavior; when it pushes toward or through them, it may indicate significant volatility or a potential trend exhaustion point.

Key User Options

  • Period: This determines the look-back window. A larger number considers more history to create a smoother curve, while a smaller number reacts more quickly to sudden price changes.
  • Bands Enabled: A simple toggle to switch between seeing just the central trend line or the full visual suite including the upper and lower volatility boundaries.
  • Deviation (BandsDev): This allows the user to adjust the width of the bands. A higher value creates wider "safety zones," while a lower value tightens the bands around the parabolic trend.

Summary for Traders

Essentially, this script acts as a "trend mapper." The central line tells you the smoothed path of the price based on its current curve, and the optional bands tell you how much room that price has to move before it is considered an outlier. It is built to filter out minor market noise while highlighting the broader geometric direction of the price movement.

Miscellaneous
Implements a curve of type %1
12 Views
0 Downloads
0 Favorites
ParMA_BB_001
//+------------------------------------------------------------------+
//|                                                     ParMA_BB.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
 
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 BlueViolet // main line
#property indicator_color2 DodgerBlue // upper band
#property indicator_color3 DodgerBlue // lower band
//---- input parameters
extern int ParMA_Period  = 30;
extern bool BandsEnabled = false;
extern double BandsDev   = 1.0;
//---- buffers
double ParMABuffer[];
double UpperBandBuffer[];
double LowerBandBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
 {
  if (ParMA_Period <= 1) // fool-proof & to prevent zero divide error
   { ParMA_Period = 3; } 
 //---- indicators
  IndicatorDigits(Digits);
  //
  SetIndexStyle(0, DRAW_LINE);
  SetIndexBuffer(0, ParMABuffer);
  SetIndexLabel(0, "ParMA Line");
  SetIndexDrawBegin(0, ParMA_Period);
  //
  if (BandsEnabled == true) // initialize Bollinger Bands buffers, if allowed
  {
   SetIndexStyle(1, DRAW_LINE);
   SetIndexBuffer(1, UpperBandBuffer);
   SetIndexLabel(1, "ParMA Upper Band");
   SetIndexDrawBegin(1, ParMA_Period);
   //
   SetIndexStyle(2, DRAW_LINE);
   SetIndexBuffer(2, LowerBandBuffer);
   SetIndexLabel(2, "ParMA Lower Band");
   SetIndexDrawBegin(2, ParMA_Period);
  }
 //----
  return(0);
 }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
 {
 //----
  Comment(""); // remove comment when finished; see notes below
 //----
  return(0);
 }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
 {
  int counted_bars = IndicatorCounted();
  int Limit, cnt, i, k;
  double old_val, new_val, sum, std_dev;
 //----
  if (counted_bars < 0) { return(-1); } // to prevent possible erors
  Limit = Bars - counted_bars;
  //
  if (Limit > ParMA_Period) // run once when getting started
   { cnt = Limit - ParMA_Period; }
  else                     // run elsewhere
   { cnt = Limit; }
  // calculate ParMA - one step on time-serie bars array
  for (i=cnt; i>=0; i--)
   { ParMABuffer[i] = GetParMA(i, ParMA_Period); }
    //
  if (BandsEnabled == true) // draw Bollinger Bands, if allowed
   {
    // calculate standard deviation
    i = Bars - ParMA_Period;
    if (counted_bars > (ParMA_Period - 1)) 
     { i = Bars - counted_bars - 1; }
    while (i >= 0)
     {
      sum = 0.0;
      k = i + ParMA_Period - 1;
      old_val = ParMABuffer[i];
      while (k >= i)
       {
        new_val = Close[k] - old_val;
        sum += new_val * new_val;
        k--;
       }
      std_dev = MathSqrt(sum / ParMA_Period);
      // complete BB's buffers
      UpperBandBuffer[i] = old_val + BandsDev * std_dev;
      LowerBandBuffer[i] = old_val - BandsDev * std_dev;
      i--;
     }
    // optional - may be deleted without hesitations
    // if you did it, remove 'Comment("");' from deinit() procedure too
  
   }
  // optional - may be deleted without hesitations
  // if you did it, remove 'Comment("");' from deinit() procedure too
  if (BandsEnabled != true)
  
 //----
  return(0);
 }
//+------------------------------------------------------------------+
/*
 Parabolic approximation: y(x) = b0 + b1 * x + b2 * x^2;
 To obtain coefficients b0, b1, b2 we have to solve a linear system:
 b0 * N          + b1 * Sum(x,N)   + b2 * Sum(x^2,N) = Sum(y,N);
 b0 * Sum(x,N)   + b1 * Sum(x^2,N) + b2 * Sum(x^3,N) = Sum((x*y),N);
 b0 * Sum(x^2,N) + b1 * Sum(x^3,N) + b2 * Sum(x^4,N) = Sum(((x^2)*y),N);
 that can easily be done explicitly by hands.
*/
//+------------------------------------------------------------------+
double GetParMA(int shift, int ma_period)
 {
  static int ro_cnt = 1; // run-once counter
  static double sum_x = 0.0, sum_x2 = 0.0, sum_x3 = 0.0, sum_x4 = 0.0;
  int i, loop_begin; // counters
  double sum_y, sum_xy, sum_x2y, var_tmp;
  double A, B, C, D, E, F, K, L, M, P, Q, R, S; // intermediates
  double B0, B1, B2; // parabolic regression coefficients
  double ret_val;    // value to be returned - parabolic MA
 //----
  // initial accumulation - run once when getting started
  while (ro_cnt <= ma_period)
   {
    var_tmp  = ro_cnt;
    sum_x   += var_tmp; // sum(x)
    var_tmp *= ro_cnt;
    sum_x2  += var_tmp; // sum(x^2)
    var_tmp *= ro_cnt;
    sum_x3  += var_tmp; // sum(x^3)
    var_tmp *= ro_cnt;
    sum_x4  += var_tmp; // sum(x^4)
    ro_cnt++;
   }
  // main calculation loop
  loop_begin = shift + ma_period - 1;
  sum_y   = 0.0;
  sum_xy  = 0.0;
  sum_x2y = 0.0;
  for (i = 1; i<=ma_period; i++)
   {
    var_tmp  = Close[loop_begin-i+1];
    sum_y   += var_tmp;
    sum_xy  += i * var_tmp;     // sum(x*y)
    sum_x2y += i * i * var_tmp; // sum((x^2)*y)
   }
  // initialization
  A = ma_period;
  B = sum_x; C = sum_x2; F = sum_x3;
  M = sum_x4; P = sum_y; R = sum_xy; S = sum_x2y;
  // intermediates
  D = B; E = C; K = C; L = F;
  Q = D / A; E = E - Q * B; F = F - Q * C;
  R = R - Q * P; Q = K / A; L = L - Q * B;
  M = M - Q * C; S = S - Q * P; Q = L / E;
  // calculate regression coefficients
  B2 = (S - R * Q) / (M - F * Q);
  B1 = (R - F * B2) / E;
  B0 = (P - B * B1 - C * B2) / A;
  // value to be returned - parabolic MA
  ret_val = B0 + (B1 + B2 * A) * A;
 //----
  return(ret_val);
 }
//+------------------------------------------------------------------+

Comments