using BitgetApi.IndicatorData; using System; using System.Collections.Generic; using System.Linq; namespace BitgetAPI.IndicatorConditionSetup { [Serializable] public class ImpulseMacdConditionSetup { private int lengthMA; private int lengthSignal; private List srcList = new List(); private List highList = new List(); private List lowList = new List(); private List smmaHighList = new List(); private List smmaLowList = new List(); private List zlemaList = new List(); private List mdList = new List(); private List sbList = new List(); private List shList = new List(); public ImpulseMacdConditionSetup(int lengthMA = 26, int lengthSignal = 12) { this.lengthMA = lengthMA; this.lengthSignal = lengthSignal; } public ImpulseMacdData AddDataPoint(double high, double low, double close, bool flag) { double src = (high + low + close) / 3.0; if (flag) { srcList.Add(src); highList.Add(high); lowList.Add(low); } else { srcList[srcList.Count - 1] = src; } double smmaHigh = CalculateSMMA(highList, smmaHighList, lengthMA); double smmaLow = CalculateSMMA(lowList, smmaLowList, lengthMA); double zlema = CalculateZLEMA(srcList, zlemaList, lengthMA); double md = 0.0; if (zlema > smmaHigh) md = zlema - smmaHigh; else if (zlema < smmaLow) md = zlema - smmaLow; mdList.Add(md); if (mdList.Count < lengthSignal) return null; double sb = mdList.Skip(mdList.Count - lengthSignal).Average(); double sh = md - sb; sbList.Add(sb); shList.Add(sh); if (mdList.Count > 100) { mdList.RemoveRange(0, 50); } if (sbList.Count > 100) { sbList.RemoveRange(0, 50); } if (shList.Count > 100) { shList.RemoveRange(0, 50); } return new ImpulseMacdData() { MD = md, SH = sh, SB = sb }; } private double CalculateSMMA(List src, List smmaList, int len) { if (src.Count < len) return src.Last(); double smma; if (smmaList.Count == 0) { smma = src.Skip(src.Count - len).Average(); } else { smma = (smmaList.Last() * (len - 1) + src.Last()) / len; } smmaList.Add(smma); return smma; } private double CalculateZLEMA(List src, List zlemaList, int length) { if (src.Count < length * 2) return src.Last(); var ema1 = CalculateEMA(src, length); var ema2 = CalculateEMA(ema1, length); double d = ema1.Last() - ema2.Last(); double zlema = ema1.Last() + d; zlemaList.Add(zlema); return zlema; } private List CalculateEMA(List src, int length) { List ema = new List(); double k = 2.0 / (length + 1); ema.Add(src.Take(length).Average()); for (int i = length; i < src.Count; i++) { double value = src[i] * k + ema.Last() * (1 - k); ema.Add(value); } return ema; } } }