using Bitget_Server.Domain.Indicators; namespace Bitget_Server.Application.Indicators; [Serializable] public class ImpulseMacdConditionSetup { private int lengthMA; private int lengthSignal; private List srcList = new(); private List highList = new(); private List lowList = new(); private List smmaHighList = new(); private List smmaLowList = new(); private List zlemaList = new(); private List mdList = new(); private List sbList = new(); private List shList = new(); public ImpulseMacdConditionSetup(int lengthMA = 34, 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; highList[highList.Count - 1] = high; lowList[lowList.Count - 1] = low; } 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; if (flag) mdList.Add(md); else mdList[mdList.Count - 1] = md; double sb = mdList.Skip(mdList.Count - lengthSignal).Average(); double sh = md - sb; if (flag) { sbList.Add(sb); shList.Add(sh); } else { sbList[sbList.Count - 1] = sb; shList[shList.Count - 1] = sh; } if (mdList.Count < lengthSignal) return null; 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; } }