단순 이관
This commit is contained in:
146
Bitget_Server/Application/Services/PriceLevelTracker.cs
Normal file
146
Bitget_Server/Application/Services/PriceLevelTracker.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user