Files
BitGet_API/BitgetApi/IndicatorConditionSetup/ImpulseMacdConditionSetup.cs

151 lines
4.4 KiB
C#
Raw Normal View History

2025-04-18 15:04:49 +09:00
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<double> srcList = new List<double>();
private List<double> highList = new List<double>();
private List<double> lowList = new List<double>();
private List<double> smmaHighList = new List<double>();
private List<double> smmaLowList = new List<double>();
private List<double> zlemaList = new List<double>();
private List<double> mdList = new List<double>();
private List<double> sbList = new List<double>();
private List<double> shList = new List<double>();
2025-05-13 12:53:36 +09:00
public ImpulseMacdConditionSetup(int lengthMA = 34, int lengthSignal = 12)
2025-04-18 15:04:49 +09:00
{
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;
2025-05-13 12:53:36 +09:00
highList[highList.Count - 1] = high;
lowList[lowList.Count - 1] = low;
2025-04-18 15:04:49 +09:00
}
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;
2025-05-13 12:53:36 +09:00
if (flag)
{
mdList.Add(md);
}
else
{
mdList[mdList.Count - 1] = md;
}
2025-04-18 15:04:49 +09:00
double sb = mdList.Skip(mdList.Count - lengthSignal).Average();
double sh = md - sb;
2025-05-13 12:53:36 +09:00
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;
2025-04-18 15:04:49 +09:00
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;
}
}
}