EMA它的定义是 Y=[2*X+(N-1)*Y']/(N+1) Y'是上一个周期的计算值。这样的函数是一个递归函数,不断的调用前一个周期的值来参加计算的。我们为了加快计算的速度,没有采用递归的方式。
实现的EMA是这样的
public static List<float> EMA(this List<float> input,int n)
{
float[] list = new float[input.Count];
list[0] = input[0];
float x;
float y;
float yLast;
for (int i = 1;i < input.Count;i++)
{
yLast = list[i - 1];
x = input[i];
y = (x * 2 + (n - 1) * yLast) / (n + 1);
list[i] = y;
}
return list.ToList();
}
我们直接根据原来的值返回一个有同样位数的返回值。这样软件同样可以非常方便的去判断。最后期的一个值是不是满足条件了。
现在来看一下如何写一个MACD的函数
public class MACD { /// <summary> /// DIFF : EMA(CLOSE,SHORT) - EMA(CLOSE,LONG); /// DEA : EMA(DIFF,M); /// MACD : 2*(DIFF-DEA), COLORSTICK; /// </summary> /// <param name="list"></param> /// <param name="?"></param> /// <returns></returns> public MacdInfo Calculate(List<StockLog> list,int s,int l,int m) { var closeList = list.Select(it => it.Close).ToList();//先得到所有的Close的值 var shortList = closeList.EMA(s);//算出短期的滑动平均 var longList = closeList.EMA(l);//算出长期的滑动平均 List<float> diff = new List<float>(); for (int i = 0;i < shortList.Count;i++)//使用循环的方法算出每一个周期的diff { diff.Add(shortList[i] - longList[i]); } var dea = diff.EMA(m);//跟据diff算出dea List<float> macd = new List<float>(); for (int i = 0;i < diff.Count;i++)//算出macd { macd.Add(2 * (diff[i] - dea[i])); } MacdInfo info = new MacdInfo(); info.DEA = dea; info.Diff = diff; info.MACD = macd; return info; } } ///StockLog是我们的股票K线记录类 public class StockLog { public string StockCode { get; set; } public DateTime Date { get; set; } public float Open { get; set; } public float Low { get; set; } public float Close { get; set; } public float High { get; set; } ///新浪不支持啊 //public decimal Amount //{ get; set; } public float Volume { get; set; } public StockLog Clone() { return this.MemberwiseClone() as StockLog; } public string ToChartTip() { return string.Format("高:{0}\r\n低:{1}\r\n开:{2}\r\n收:{3}\r\n日期:{4}", High.ToString("f3"), Low.ToString("f3"), Open.ToString("f3"), Close.ToString("f3"),Date.ToShortDateString()); } }