//+------------------------------------------------------------------+ //| 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() { //Calculate FIR MA for all bars except for the last n bars ArrayInitialize(FIRMA, EMPTY_VALUE); for(int i = 0; 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[n]; double a1 = FIRMA[n] - FIRMA[n+1]; double sx2y = 0.0; double sx3y = 0.0; for(i = 0; i <= n; i++) { sx2y += i*i*Close[n-i]; sx3y += i*i*i*Close[n-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[n-i] = a0 + i*a1 + i*i*a2 + i*i*i*a3; return(0); } //+------------------------------------------------------------------+