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