Files
BitGet_API/Bitget_Server/Application/Services/PriceLevelTracker.cs

147 lines
6.5 KiB
C#
Raw Normal View History

2026-04-20 20:27:42 +09:00
using Bitget_Server.Domain.Enums;
using Bitget_Server.Domain.Models;
namespace Bitget_Server.Application.Services;
/// <summary>
/// 기존 IndicatorProcess.Calculate전고점 / 전저고점 dictionary bookkeeping 이식.
/// 단일 인스턴스로 보관되며 키는 "MarketName + Interval(Description)" 문자열이다.
/// </summary>
public class PriceLevelTracker
{
private readonly Dictionary<string, Dictionary<string, double>> _levels = new();
public IReadOnlyDictionary<string, Dictionary<string, double>> Levels => _levels;
public void Clear() => _levels.Clear();
public bool ContainsKey(string key) => _levels.ContainsKey(key);
public Dictionary<string, double> GetOrCreate(string key)
{
if (_levels.TryGetValue(key, out var existing)) return existing;
var dic = new Dictionary<string, double>
{
{ "전고가", 0 }, { "전저가", 0 },
{ "전전고가", 0 }, { "전전저가", 0 },
{ "전전전저가", 0 }, { "전전전고가", 0 },
{ "전전전전저가", 0 }, { "전전전전고가", 0 },
{ "tempHighVal", 0 }, { "tempLowVal", 0 },
{ "tempHigh2Val", 0 }, { "tempLow2Val", 0 },
{ "tempHigh3Val", 0 }, { "tempLow3Val", 0 },
{ "tempHigh4Val", 0 }, { "tempLow4Val", 0 },
{ "switchLowVal", 0 }, { "switchHighVal", 0 },
{ "Type", 0 }
};
_levels[key] = dic;
return dic;
}
/// <summary>
/// 기존 IndicatorProcess.Calculate전고점 이식.
/// 전봉/전전봉/전전전봉의 이동평균(4일) 값으로 local minima/maxima 를 추적한다.
/// </summary>
public bool Calculate(string market, string intervalKey, MCandleTimeType type,
double 전봉, double 전전봉, double 전전전봉, CandleData candleData)
{
var key = market + intervalKey;
var 저고점 = GetOrCreate(key);
var nowUnix = ((DateTimeOffset)candleData.Argument).ToUnixTimeSeconds();
// === 전저가 계산 ===
if (전봉 > 전전봉 && 전전봉 < 전전전봉 &&
저고점["tempHighVal"] >= 저고점["tempLowVal"] &&
저고점["tempLowVal"] != nowUnix &&
nowUnix - 저고점["tempHighVal"] >= 120 * (int)type)
{
저고점["tempLow4Val"] = 저고점["tempLowVal"];
저고점["tempLowVal"] = 저고점["tempLow2Val"];
저고점["tempLow2Val"] = 저고점["tempLowVal"];
저고점["tempLowVal"] = nowUnix;
저고점["switchLowVal"] = 저고점["전전전전저가"];
저고점["전전전전저가"] = 저고점["전전저가"];
저고점["전전전저가"] = 저고점["전전저가"];
저고점["전전저가"] = 저고점["전저가"];
저고점["전저가"] = 전전봉;
저고점["Type"] = 0;
}
else if (전봉 > 전전봉 && 전전봉 < 전전전봉 &&
저고점["tempHighVal"] < 저고점["tempLowVal"] &&
저고점["tempLowVal"] != nowUnix &&
nowUnix - 저고점["tempHighVal"] >= 120 * (int)type)
{
if (저고점["전저가"] > 전전봉)
{
저고점["tempLowVal"] = nowUnix;
저고점["전저가"] = 전전봉;
}
저고점["Type"] = 0;
}
else if (전봉 > 전전봉 && 전전봉 < 전전전봉 &&
저고점["tempLowVal"] != nowUnix &&
nowUnix - 저고점["tempHighVal"] < 120 * (int)type)
{
// 이전 상태로 롤백 (High)
저고점["전고가"] = 저고점["전전고가"];
저고점["전전고가"] = 저고점["전전전고가"];
저고점["전전전고가"] = 저고점["전전전전고가"];
저고점["Type"] = 0;
저고점["전전전전고가"] = 저고점["switchLowVal"];
저고점["tempHighVal"] = 저고점["tempHigh2Val"];
저고점["tempHigh2Val"] = 저고점["tempHighVal"];
저고점["tempHighVal"] = 저고점["tempHigh4Val"];
if (저고점["전저가"] > 전전봉) 저고점["전저가"] = 전전봉;
}
// === 전고가 계산 ===
if (전전봉 > 전봉 && 전전봉 > 전전전봉 &&
저고점["tempHighVal"] <= 저고점["tempLowVal"] &&
저고점["tempHighVal"] != nowUnix &&
nowUnix - 저고점["tempLowVal"] >= 120 * (int)type)
{
저고점["tempHigh4Val"] = 저고점["tempHighVal"];
저고점["tempHighVal"] = 저고점["tempHigh2Val"];
저고점["tempHigh2Val"] = 저고점["tempHighVal"];
저고점["tempHighVal"] = nowUnix;
저고점["switchHighVal"] = 저고점["전전전전고가"];
저고점["전전전전고가"] = 저고점["전전전고가"];
저고점["전전전고가"] = 저고점["전전고가"];
저고점["전전고가"] = 저고점["전고가"];
저고점["Type"] = 1;
저고점["전고가"] = 전전봉;
}
else if (전전봉 > 전봉 && 전전봉 > 전전전봉 &&
저고점["tempHighVal"] > 저고점["tempLowVal"] &&
저고점["tempHighVal"] != nowUnix &&
nowUnix - 저고점["tempLowVal"] >= 120 * (int)type)
{
if (저고점["전고가"] < 전전봉)
{
저고점["tempHighVal"] = nowUnix;
저고점["전고가"] = 전전봉;
}
}
else if (전전봉 > 전봉 && 전전봉 > 전전전봉 &&
저고점["tempHighVal"] != nowUnix &&
nowUnix - 저고점["tempLowVal"] < 120 * (int)type)
{
// 이전 상태로 롤백 (Low)
저고점["전저가"] = 저고점["전전저가"];
저고점["전전저가"] = 저고점["전전전저가"];
저고점["전전전저가"] = 저고점["전전전전저가"];
저고점["전전전전저가"] = 저고점["switchHighVal"];
저고점["Type"] = 1;
저고점["tempLowVal"] = 저고점["tempLow2Val"];
저고점["tempLow2Val"] = 저고점["tempLowVal"];
저고점["tempLowVal"] = 저고점["tempLow4Val"];
if (저고점["전고가"] < 전전봉) 저고점["전고가"] = 전전봉;
}
return 저고점["전전전저가"] != 0 && 저고점["전전전고가"] != 0;
}
}