using Bitget_Server.Application.State;
using Bitget_Server.Domain;
using Bitget_Server.Domain.Enums;
using Bitget_Server.Domain.Models;
using Bitget_Server.Infrastructure.Bitget;
using Bitget_Server.Infrastructure.Utils;
namespace Bitget_Server.Application.Services;
///
/// 기존 MainForm.getMarketCandleData_WebService 이식.
/// 신호 검색 대상 마켓/인터벌 조합의 초기 캔들 데이터를 일괄 로드한다.
/// BitgetRateLimiter 를 자연스럽게 경유하므로 별도 Thread.Sleep(50) 이 불필요.
///
public class InitialCandleLoader
{
private const int CandleCount = 200;
private readonly BitgetClient _client;
private readonly MarketState _state;
private readonly ILogger _logger;
public InitialCandleLoader(BitgetClient client, MarketState state, ILogger logger)
{
_client = client;
_state = state;
_logger = logger;
}
///
/// 체크된 마켓 목록에 대해 캔들 데이터를 채운다.
///
public async Task LoadAsync(IEnumerable marketNames, IEnumerable intervalDescriptions, CancellationToken ct)
{
var intervalSet = new HashSet(intervalDescriptions ?? Array.Empty());
foreach (var marketName in marketNames ?? Array.Empty())
{
if (ct.IsCancellationRequested) break;
MarketCandleDataList marketCandleDataList;
lock (_state.SyncRoot)
{
marketCandleDataList = _state.candleDataLists.Find(i => i.ConGoodsData?.MarketName == marketName);
}
if (marketCandleDataList == null) continue;
foreach (MCandleTimeType interval in Enum.GetValues(typeof(MCandleTimeType)))
{
if (ct.IsCancellationRequested) break;
var description = Convertor.GetEnumDescription(interval);
if (!intervalSet.Contains(description)) continue;
var url = string.Format(
BitgetEndpoints.MarketCandle_Future,
marketName,
description,
CandleCount.ToString(),
"USDT-FUTURES");
try
{
await _client.SendWebServerAsync(
ExchangeWebReqType.BitgetCandleStick_Future,
url,
marketCandleDataList,
interval,
ct: ct).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "초기 캔들 로드 실패 ({Market} / {Interval})", marketName, description);
}
}
}
}
}