86 lines
3.2 KiB
Java
86 lines
3.2 KiB
Java
package com.goldenchart.service;
|
|
|
|
import com.goldenchart.entity.GcAppSettings;
|
|
import com.goldenchart.entity.GcLiveStrategySettings;
|
|
import com.goldenchart.repository.GcLiveStrategySettingsRepository;
|
|
import com.goldenchart.storage.Ta4jStorage;
|
|
import lombok.RequiredArgsConstructor;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
import java.util.Comparator;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
|
|
/**
|
|
* 종목별 전략 평가 분봉 — DB gc_live_strategy_settings.candle_type.
|
|
*/
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
public class LiveStrategyTimeframeService {
|
|
|
|
private static final Set<String> ALLOWED = Ta4jStorage.CANDLE_TYPE_MAP.keySet();
|
|
|
|
private final GcLiveStrategySettingsRepository repo;
|
|
private final AppSettingsService appSettingsService;
|
|
|
|
@Transactional(readOnly = true)
|
|
public String resolveCandleType(String market, Long userId, String deviceId) {
|
|
Optional<GcLiveStrategySettings> row = find(userId, deviceId, market);
|
|
if (row.isPresent() && row.get().getCandleType() != null) {
|
|
return normalize(row.get().getCandleType());
|
|
}
|
|
GcAppSettings app = appSettingsService.getEntity(userId, deviceId);
|
|
String tf = app.getDefaultTimeframe();
|
|
if (tf != null) {
|
|
String mapped = mapChartTfToCandleType(tf);
|
|
if (mapped != null) return mapped;
|
|
}
|
|
return "1m";
|
|
}
|
|
|
|
/**
|
|
* 워커 스레드 등 user/device 컨텍스트 없을 때 — 해당 마켓 활성 설정의 candle_type.
|
|
*/
|
|
@Transactional(readOnly = true)
|
|
public String resolveCandleTypeForMarket(String market) {
|
|
return repo.findActiveByMarket(market).stream()
|
|
.filter(s -> s.getCandleType() != null && !s.getCandleType().isBlank())
|
|
.max(Comparator.comparing(
|
|
GcLiveStrategySettings::getUpdatedAt,
|
|
Comparator.nullsLast(Comparator.naturalOrder())))
|
|
.map(GcLiveStrategySettings::getCandleType)
|
|
.map(LiveStrategyTimeframeService::normalize)
|
|
.orElse("1m");
|
|
}
|
|
|
|
public static String normalize(String candleType) {
|
|
if (candleType == null || candleType.isBlank()) return "1m";
|
|
String c = candleType.trim().toLowerCase();
|
|
if ("1d".equals(c)) return "1d";
|
|
if ("1w".equals(c)) return "1w";
|
|
if ("1h".equals(c)) return "1h";
|
|
if ("4h".equals(c)) return "4h";
|
|
if (ALLOWED.contains(c)) return c;
|
|
return "1m";
|
|
}
|
|
|
|
private static String mapChartTfToCandleType(String chartTf) {
|
|
return switch (chartTf) {
|
|
case "1m", "3m", "5m", "10m", "15m", "30m" -> chartTf;
|
|
case "1h", "4h" -> chartTf;
|
|
case "1D" -> "1d";
|
|
case "1W" -> "1w";
|
|
case "1M" -> "1d";
|
|
default -> null;
|
|
};
|
|
}
|
|
|
|
private Optional<GcLiveStrategySettings> find(Long userId, String deviceId, String market) {
|
|
if (userId != null) return repo.findByUserIdAndMarket(userId, market);
|
|
if (deviceId != null && !deviceId.isBlank())
|
|
return repo.findByDeviceIdAndMarket(deviceId, market);
|
|
return Optional.empty();
|
|
}
|
|
}
|