FIR_MA

This tool is a specialized technical analysis indicator designed to smooth out price movements on a trading chart. Rather than using a standard moving average, it employs a sophisticated mathematical approach known as a Finite Impulse Response (FIR) filter. This method helps traders identify underlying trends by reducing "noise" and fluctuations in the market data.

How the Logic Works

The core logic of this script revolves around how it weighs historical price data to determine the current trend line. It achieves this through three main components:

1. The Filtering Mechanism (Taps and Periods) Unlike simple averages that give equal importance to all recent prices, this script looks at a specific "window" of past data (defined by the Taps setting). It treats these prices as a sequence and applies a mathematical filter to them. The Periods setting allows you to control the "bandwidth" of this filter—essentially deciding how much of the price movement you want to let through and how much you want to block out as unnecessary volatility.

2. Windowing Functions The script includes several different "Window" modes, which are mathematical formulas used to weight the data points:

  • Some modes (like Rectangular) provide a straightforward average.
  • Other modes (such as Hanning, Hamming, Blackman, or Blackman-Harris) apply more complex curves to the data weighting. These different windows allow you to adjust how smoothly the resulting line appears on your chart; some are designed to be very precise, while others are optimized to create a much smoother, more fluid visual of the price action.

3. Calculation and Alignment For every point on your chart, the script performs a weighted calculation. It looks back at the closing prices, multiplies them by their specific weights based on the chosen window, and then normalizes the result so that it represents a consistent value relative to the sum of all weights.

Finally, because this type of mathematical filtering naturally looks "backward" into the past to calculate the current value, the script automatically adjusts the visual placement of the line on your chart. This ensures that the indicator aligns correctly with the current price action, providing you with a clean, readable trend line that reflects the filtered reality of the market.

Miscellaneous
Implements a curve of type %1
7 Views
0 Downloads
0 Favorites
FIR_MA
//+------------------------------------------------------------------+
//|                                                       FIR_MA.mq4 |
//|                                                  v.1  09/04/2006 |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
#property indicator_width1 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
//Indicator buffers
double FIRMA[];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
   ArrayInitialize(FIRMA, EMPTY_VALUE);
   IndicatorBuffers(1);
   SetIndexBuffer(0, FIRMA);
   SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 2);
   IndicatorShortName("FIRMA");
   SetIndexShift(0, -(Taps - 1) / 2);
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int deinit()
  {
    return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   double w[];
   ArrayResize(w, Taps);
   double wsum = 0.0;
   for(int k = 0; k < Taps; k++)
     {
       switch(Window)
         {
           // Rectangular window
           case 1: w[k] = 1.0; break; 
           // Hanning window
           case 2: w[k] = 0.50 - 0.50*MathCos(2.0*pi*k / Taps); break;
           // Hamming window
           case 3: w[k] = 0.54 - 0.46*MathCos(2.0*pi*k / Taps); break;
           //Blackman window
           case 4: w[k] = 0.42 - 0.50*MathCos(2.0*pi*k / Taps) + 
                          0.08*MathCos(4.0*pi*k / Taps); break;
           //Blackman-Harris window 
           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); break;
           //Rectangular window 
           default: w[k] = 1;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];
     }
   int i = Bars - 1 - IndicatorCounted();
   while(i >= 0)
     {
       if(i <= Bars - Taps)
         {
           FIRMA[i] = 0.0;
           for(k = 0; k < Taps; k++) 
               FIRMA[i] += Close[i+k]*w[k] / wsum;
         }
       i--;
     }
   return(0);
  }
//+------------------------------------------------------------------+

Comments