| 
 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;
      }
 
}
 
 |