ParMA_BB





//+------------------------------------------------------------------+
//|                                                     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
    Comment("ParMA = ", NormalizeDouble(ParMABuffer[0], Digits), "\n",
            "UpperBand = ", NormalizeDouble(UpperBandBuffer[0], Digits), "\n",
            "LowerBand = ", NormalizeDouble(LowerBandBuffer[0], Digits));
   }
  // optional - may be deleted without hesitations
  // if you did it, remove 'Comment("");' from deinit() procedure too
  if (BandsEnabled != true)
   { Comment("ParMA = ", NormalizeDouble(ParMABuffer[0], Digits)); }
 //----
  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);
 }
//+------------------------------------------------------------------+



Sample





Analysis



Market Information Used:

Series array that contains close prices for each bar


Indicator Curves created:

Implements a curve of type DRAW_LINE


Indicators Used:



Custom Indicators Used:

Order Management characteristics:

Other Features: