[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Ehlers' MAMA in C#



PureBytes Links

Trading Reference Links

In the latest issue of TASC (September 2001), John F. Ehlers has an
article on MESA Adaptive Moving Averages (MAMA).

 

I’ve included a C# implementation of MAMA below.

 

using System;

using System.IO;

using System.Collections;

using System.Text.RegularExpressions;

 

class MAMA 

{

      public static void Main() 

      {

            ArrayList allValues = new ArrayList();

            ArrayList price = new ArrayList();

            string szSrcFile = "C:\\Temp\\Stocks\\IBM\\IBM.txt";

            string mamaFile = "C:\\Temp\\Stocks\\IBM\\mama.txt";

            MAMA sMama = new MAMA();

 

            allValues = sMama.ReadFile(szSrcFile);

            allValues.Reverse();

 

            foreach (object i in allValues)

            {

 

                  Regex r;

                  Match m;

 

                  r = new
Regex("(?<1>.*?\t.*?\t.*?\t.*?\t)(?<2>.*?)\t");

                  m = r.Match(i.ToString());

 

                  // Need try catch for Date - Open - High - Low line

                  try 

                  {

                        price.Add(Double.Parse(m.Groups[2].ToString()));

                  }

                  catch {}

 

            }

 

            Console.WriteLine(price[price.Count-1]);

 

            // the algorithm

            double[] smooth= new double[price.Count];

            double[] detrender = new double[price.Count];

            double[] period = new double[price.Count];

            double[] q1 = new double[price.Count];

            double[] i1 = new double[price.Count];

            double[] ji = new double[price.Count];

            double[] jq = new double[price.Count];

            double[] i2 = new double[price.Count];

            double[] q2 = new double[price.Count];

            double[] re = new double[price.Count];

            double[] im = new double[price.Count];

            double[] smoothperiod = new double[price.Count];

            double[] phase = new double[price.Count];

            double[] deltaphase = new double[price.Count];

            double[] alpha = new double[price.Count];

            double fastlimit = 0.5;

            double slowlimit = 0.05;

            double[] mama = new double[price.Count];

            double[] fama = new double[price.Count];

 

            for (int i = 5; i < price.Count; i++)

            {

                  smooth[i] = (4*(double) price[i-0] +
3*(double)price[i-1] + 2*(double)price[i-2] + (double)price[i-3])/10;

                  

                  try {detrender[i] = (.0962*smooth[i] +
.5769*smooth[i-2] - .5769*smooth[i-4] -
0.0962*smooth[i-6])*(.075*period[i-1]+0.54);

                         }

                  catch 

                  {

                        detrender[i] = 0;

                  }

 

                  try {q1[i] = (.0962*detrender[i] +
.5769*detrender[i-2] - 0.5769*detrender[i-4] +
.0962*detrender[6])*(.075*period[i-1]+0.54);}

                  catch

                  {

                        q1[i] = 0;

                  }

 

                  i1[i] = detrender[i-3];

 

                  try {ji[i] = (.0962*i1[i] + .5769*i1[i-2] -
.5769*i1[i-4] - .0962*i1[i-6])*(.075*period[i-1]+.54);}

                  catch

                  {

                        ji[i] = 0;

                  }

 

                  try {jq[i] = (.0962*q1[i] + .5769*q1[i-2] -
.5769*q1[i-4] - .0962*q1[i-6])*(.075*period[i-1]+.54);}

                  catch

                  {

                        jq[i] = 0;

                  }

 

                  i2[i] = i1[i] - jq[i];

                  q2[i] = q1[i] + ji[i];

 

                  i2[i] = .2*i2[i] + .8*i2[i-1];

                  q2[i] = .2*q2[i] + .8*q2[i-1];

 

                  re[i] = i2[i]*i2[i-1] + q2[i]*q2[i-1];

                  im[i] = i2[i]*q2[i-1] - q2[i]*i2[i-1];

                  re[i] = .2*re[i] + .8*re[i-1];

                  im[i] = .2*im[i] + .8*im[i-1];

                  if ((im[i] != 0) && (re[i] != 0))

                  {

                        period[i] = 360/Math.Atan(im[i]/re[i]);

                  }

 

                  if (period[i] > 1.5*period[i-1]) 

                  {

                        period[i] = 1.5*period[i-1];

                  }

 

                  if (period[i] < .67*period[i-1])

                  {

                        period[i] = .67*period[i-1];

                  }

 

                  if (period[i] < 6) 

                  {

                        period[i] = 6;

                  }

 

                  if (period[i] > 50)

                  {

                        period[i] = 50;

                  }

 

                  period[i] = .2*period[i] + .8*period[i-1];

                  smoothperiod[i] = .33*period[i] +
.67*smoothperiod[i-1];

 

                  if (i1[i] != 0) 

                  {

                        phase[i] = Math.Atan(q1[i]/i1[i]);

                  }

 

                  deltaphase[i] = phase[i-1] - phase[i];

 

                  if (deltaphase[i] < 1) 

                  {

                        deltaphase[i] = 1;

                  }

 

                  alpha[i] = fastlimit/deltaphase[i];

 

                  if (alpha[i] < slowlimit)

                  {

                        alpha[i] = slowlimit;

                  }

 

                  if (alpha[i] > fastlimit)

                  {

                        alpha[i] = fastlimit;

                  }

 

                  mama[i] = alpha[i]*(double)price[i] +
(1-alpha[i])*mama[i-1];

                  fama[i] = 0.5*alpha[i]*mama[i] +
(1-.5*alpha[i])*fama[i-1];

            }

 

            // write to file

            FileStream fs = new FileStream(mamaFile,
FileMode.OpenOrCreate, FileAccess.Write);

            StreamWriter w = new StreamWriter(fs);

 

            double[] profit = new double[price.Count];

            bool slong = true;

            double cumproft = 1;

            

            // calculate profit

            for (int i = 5; i < price.Count; i++)

            {

                  if (slong)  // long position

                  {

                        profit[i] = (double) price[i]/ (double)
price[i-1];

                        if (fama[i] < mama[i]) slong = false;

                  }

                  else        // short position

                  {

                        profit[i] = 1+((double) price[i-1] -
(double)price[i])/(double) price[i-1];

                        if (fama[i] > mama[i]) slong = true;

                  }

            }

            

            double cumprofit = 1;

 

            for (int i = 5; i < price.Count; i++)

            {

                  cumprofit *= profit[i];

                  w.WriteLine("{0} {1} {2} {3} {4}", price[i], mama[i],
fama[i], profit[i], cumprofit);

                  Console.WriteLine("{0} {1} {2} {3} {4}", price[i],
mama[i], fama[i], profit[i], cumprofit);

            }

 

            w.Flush();

            w.Close();

            fs.Close();

 

 

      }

      

      public ArrayList ReadFile (string szSrcFile)

      {

            string szSrcLine;

            ArrayList sData = new ArrayList();

 

            FileStream fsInput = new FileStream (szSrcFile,
FileMode.Open, FileAccess.Read);

            StreamReader srInput = new StreamReader(fsInput);

            while ((szSrcLine = srInput.ReadLine()) != null)

            {

                  sData.Add(szSrcLine);

            }

            srInput.Close();

            fsInput.Close();

 

            return sData;

      }

 

}