AFIRMA

Created at 08 Mar 2017, 11:45
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
jorgmarkwald's avatar

jorgmarkwald

Joined 16.01.2016

AFIRMA
08 Mar 2017, 11:45


Hi guys,

I've converted the AFIRMA indicator from mql4 to c#. It outputs the first series correctly (FIRMA) but the second one is stuck somewhere in the code (ARMA). Any ideas where or what keeps it from outputting? It seems like it's stuck somewhere.

Thank you for your time

 

namespace cAlgo.Indicators
{
    [Indicator(ScalePrecision = 5, AutoRescale = true, IsOverlay = true, AccessRights = AccessRights.None)]
    public class AFIRMA : Indicator
    {


        [Parameter("Periods", DefaultValue = 12)]
        public int Periods { get; set; }

        [Parameter("Taps", DefaultValue = 21)]
        public int Taps { get; set; }

        [Parameter("Window", DefaultValue = 4)]
        public int Window { get; set; }



        [Output("FIRMA", Color = Colors.Blue, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries FIRMA { get; set; }
        [Output("ARMA", Color = Colors.Red, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries ARMA { get; set; }


        int n;
        double den;
        double sx6;
        double sx5;
        double sx4;
        double sx3;
        double sx2;
        double wsum;
        double[] w;

        protected override void Initialize()
        {
            //Calculate weights
            Array.Resize(ref w, Taps);
            wsum = 0.0;
            for (int k = 0; k < Taps; k++)
            {
                switch (Window)
                {
                    case 1:
                        w[k] = 1.0;
                        break;
                    case 2:
                        w[k] = 0.5 - 0.5 * Math.Cos(2.0 * Math.PI * k / Taps);
                        break;
                    case 3:
                        w[k] = 0.54 - 0.46 * Math.Cos(2.0 * Math.PI * k / Taps);
                        break;
                    case 4:
                        w[k] = 0.42 - 0.5 * Math.Cos(2.0 * Math.PI * k / Taps) + 0.08 * Math.Cos(4.0 * Math.PI * k / Taps);
                        break;
                    case 5:
                        w[k] = 0.35875 - 0.48829 * Math.Cos(2.0 * Math.PI * k / Taps) + 0.14128 * Math.Cos(4.0 * Math.PI * k / Taps) - 0.01168 * Math.Cos(6.0 * Math.PI * k / Taps);
                        break;
                    default:
                        w[k] = 1;
                        break;
                }
                if (k != Taps / 2.0)
                    w[k] = w[k] * Math.Sin(Math.PI * (k - Taps / 2.0) / Periods) / Math.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;
        }


        public override void Calculate(int index)
        {



            //Calculate FIR MA for all bars except for the last n bars
            for (int i = 0; i <= Bars - Taps; i++)
            {
                FIRMA[i + n] = 0.0;
                for (int k = 0; k < Taps; k++)
                    FIRMA[i + n] += MarketSeries.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 (int i = 0; i <= n; i++)
            {
                sx2y += i * i * MarketSeries.Close[n - i];
                sx3y += i * i * i * MarketSeries.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;
            for (int i = 0; i <= n; i++)
            {
                ARMA[n - i] = a0 + i * a1 + i * i * a2 + i * i * i * a3;
                return;
            }
        }


        private int Bars
        {
            get { return MarketSeries.Close.Count; }
        }

    }

}

Also here's the reference MQL4 code:

#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 = 12;   // 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);
  }

 


@jorgmarkwald
Replies

... Deleted by UFO ...

jorgmarkwald
14 Mar 2017, 11:30

Thanks @lucian


@jorgmarkwald