Files
BitGet_API/Bitget_Server/Application/Indicators/ImpulseMacdConditionSetup.cs
2026-04-20 20:27:42 +09:00

117 lines
3.3 KiB
C#

using Bitget_Server.Domain.Indicators;
namespace Bitget_Server.Application.Indicators;
[Serializable]
public class ImpulseMacdConditionSetup
{
private int lengthMA;
private int lengthSignal;
private List<double> srcList = new();
private List<double> highList = new();
private List<double> lowList = new();
private List<double> smmaHighList = new();
private List<double> smmaLowList = new();
private List<double> zlemaList = new();
private List<double> mdList = new();
private List<double> sbList = new();
private List<double> 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<double> src, List<double> 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<double> src, List<double> 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<double> CalculateEMA(List<double> src, int length)
{
List<double> ema = new List<double>();
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;
}
}