AFIRMA_[1]-2

Download script
Author: Copyright � 2006, gpwr.
AFIRMA_[1]-2

This script is a sophisticated technical analysis tool designed to provide a smoother and more responsive view of price action compared to standard moving averages. It utilizes advanced signal processing techniques to filter out "noise" from the market while attempting to maintain the integrity of the underlying trend.

Core Logic and Functionality

The indicator operates through a multi-stage mathematical process to produce two distinct visual lines on your chart:

1. Advanced Signal Filtering (The FIRMA Component) Unlike a basic moving average that gives equal weight to all past prices, this script uses a Finite Impulse Response (FIR) method.

  • Weighting Windows: The script allows you to choose from different "window" types (such as Hanning, Hamming, or Blackman). These are mathematical formulas used to smooth out the data. Think of these as different "lenses" that determine how much influence past prices have on the current reading.
  • Bandwidth Control: It adjusts the filter based on a specific period setting. This allows it to target specific types of price fluctuations, effectively separating meaningful trends from random market jitters.

2. Regression Smoothing (The ARMA Component) Once the initial filtering is complete, the script applies a Regressive Moving Average logic.

  • Curve Fitting: Instead of just looking at the previous price, this part of the logic attempts to calculate a mathematical curve that "fits" the filtered data as closely as possible using least-squares regression.
  • Predictive Alignment: By calculating coefficients (the $a$ and $b$ values in the internal math), the script constructs a polynomial curve. This means the resulting line follows the price more fluidly, reducing the "lag" typically seen in standard indicators while remaining stable.

Summary of User Impact

  • Reduced Lag: Because it uses regression to fit the curve, the indicator reacts more quickly to trend changes than a traditional simple moving average.
  • Noise Reduction: The FIR filter ensures that minor price spikes do not cause the indicator to "wobble," providing a cleaner visual path for traders.
  • Dual Visualization: You receive two lines: one representing the primary filtered data and the other representing the smoothed regression curve, allowing for a more nuanced understanding of momentum and trend direction.
Miscellaneous
Implements a curve of type %1
10 Views
0 Downloads
0 Favorites
AFIRMA_[1]-2
//+------------------------------------------------------------------+
//|                                                       AFIRMA.mq4 |
//|                                          Copyright © 2006, gpwr. |
//+------------------------------------------------------------------+


#property copyright "Copyright © 2006, gpwr."
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_width1 2
#property indicator_width2 2
//Global constants
#define pi 3.141592653589793238462643383279502884197169399375105820974944592
//Input parameters
extern int  Periods = 4;   // 1/(2*Periods) sets the filter bandwidth
extern int  Taps    = 21;  // must be an odd number
extern int  Window  = 4;   // selects windowing function
//Global variables
double w[], wsum, sx2, sx3, sx4, sx5, sx6, den; 
int n;
//Indicator buffers
double FIRMA[];
double ARMA[];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
   //Calculate weights
   ArrayResize(w, Taps);
   wsum = 0.0;
   for(int k = 0; k < Taps; k++)
     {
       switch(Window)
         {
           case 1:  w[k] = 1.0; // Rectangular window
                    break;
           case 2:  w[k] = 0.50 - 0.50*MathCos(2.0*pi*k / Taps);   // Hanning window
                    break;
           case 3:  w[k] = 0.54 - 0.46*MathCos(2.0*pi*k / Taps);   // Hamming window
                    break;
           case 4:  w[k] = 0.42 - 0.50*MathCos(2.0*pi*k / Taps) +  
                           0.08*MathCos(4.0*pi*k / Taps);          // Blackman window
                    break;
           case 5:  w[k] = 0.35875 - 0.48829*MathCos(2.0*pi*k / Taps) + 
                           0.14128*MathCos(4.0*pi*k / Taps) - 
                           0.01168*MathCos(6.0*pi*k / Taps);       // Blackman - Harris window
                    break; 
           default: w[k] = 1;                                      //Rectangular window 
                    break;
         }
       if(k != Taps / 2.0) 
           w[k] = w[k]*MathSin(pi*(k - Taps / 2.0) / Periods) / pi / (k - Taps / 2.0);
       wsum += w[k];
     }
//Calculate sums for the least-squares method
   n = (Taps - 1) / 2;
   sx2 = (2*n + 1) / 3.0;
   sx3 = n*(n + 1) / 2.0;
   sx4 = sx2*(3*n*n+3*n - 1) / 5.0;
   sx5 = sx3*(2*n*n+2*n - 1) / 3.0;
   sx6 = sx2*(3*n*n*n*(n + 2) - 3*n+1) / 7.0;
   den = sx6*sx4 / sx5 - sx5;
//Initialize indicator
   IndicatorBuffers(2);
   SetIndexBuffer(0, FIRMA);
   SetIndexBuffer(1, ARMA);
   SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 2);
   SetIndexStyle(1, DRAW_LINE, STYLE_SOLID, 2);
   IndicatorShortName("AFIRMA");
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int deinit()
  {
    return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  { int j,n2;
//Calculate FIR MA for all bars except for the last n bars
   ArrayInitialize(FIRMA, EMPTY_VALUE);
   
   
  //..................................................................
   //....... Ýòî âcòàâëåííûé êîä äëÿ âèçóàëüíîãî òåñòèðîâàíèÿ èíäèêàòîðà 
   /**/  int start,start_j;
   /**/start_j=ObjectGet("start",OBJPROP_TIME1);     
   /**/if(GetLastError()==0) start=iBarShift(NULL,0,start_j,False); else start=0;
   //................êîíåö êîäà 
   //.....................................................................
   n2=n+start;
   for(int i = start; i <= Bars - Taps; i++)
     {
       FIRMA[i+n] = 0.0;
       for(int k = 0; k < Taps; k++)
           FIRMA[i+n] += Close[i+k]*w[k] / wsum;
     }
   //Calculate regressive MA for the remaining n bars
   double a0 = FIRMA[n2];
   double a1 = FIRMA[n2] - FIRMA[n2+1];
   double sx2y = 0.0;
   double sx3y = 0.0;
   
   for(i = 0; i <= n; i++)
     {
       sx2y += i*i*Close[n2-i];
       sx3y += i*i*i*Close[n2-i];
     }
   sx2y = 2.0*sx2y / n / (n + 1);
   sx3y = 2.0*sx3y / n / (n + 1);
   double p = sx2y - a0*sx2 - a1*sx3;
   double q = sx3y - a0*sx3 - a1*sx4;
   double a2 = (p*sx6 / sx5 - q) / den;
   double a3 = (q*sx4 / sx5 - p) / den;
   ArrayInitialize(ARMA, EMPTY_VALUE);
   for(i = 0; i <= n; i++)
       ARMA[n2-i] = a0 + i*a1 + i*i*a2 + i*i*i*a3;
   return(0);
  }
//+------------------------------------------------------------------+

Comments