diff --git a/backend/src/main/java/com/goldenchart/dto/BacktestRequest.java b/backend/src/main/java/com/goldenchart/dto/BacktestRequest.java index 9019673..1d4e247 100644 --- a/backend/src/main/java/com/goldenchart/dto/BacktestRequest.java +++ b/backend/src/main/java/com/goldenchart/dto/BacktestRequest.java @@ -39,9 +39,10 @@ public class BacktestRequest { private String timeframe; /** - * 지표 파라미터 오버라이드. + * 지표 파라미터 오버라이드 (선택). * key = indicatorType (e.g. "CCI"), value = {length:13, ...} - * 없으면 IndicatorService 기본값 사용. + * BacktestingService 가 deviceId 기반으로 DB 저장값을 자동 로드하므로 + * 보통 생략해도 되며, 명시 시 DB 값 위에 덮어쓴다(우선 적용). */ private Map> indicatorParams; diff --git a/backend/src/main/java/com/goldenchart/service/BacktestingService.java b/backend/src/main/java/com/goldenchart/service/BacktestingService.java index d383929..acc511e 100644 --- a/backend/src/main/java/com/goldenchart/service/BacktestingService.java +++ b/backend/src/main/java/com/goldenchart/service/BacktestingService.java @@ -45,6 +45,7 @@ public class BacktestingService { private final GcStrategyRepository strategyRepository; private final GcBacktestResultRepository resultRepository; private final ObjectMapper objectMapper; + private final IndicatorSettingsService indicatorSettingsService; private static final BacktestSettingsDto DEFAULT_SETTINGS = new BacktestSettingsDto(); @@ -76,8 +77,20 @@ public class BacktestingService { } } - Map> params = req.getIndicatorParams() != null - ? req.getIndicatorParams() : Map.of(); + // DB 저장 인디케이터 설정을 기본으로 로드 (디바이스별 저장값 → 하드코딩 기본값 방지) + Map> dbParams = Map.of(); + if (req.getDeviceId() != null && !req.getDeviceId().isBlank()) { + try { + dbParams = indicatorSettingsService.getAll(null, req.getDeviceId()); + } catch (Exception e) { + log.warn("[Backtest] 인디케이터 설정 DB 로드 실패 (deviceId={}): {}", req.getDeviceId(), e.getMessage()); + } + } + // 요청에 포함된 파라미터가 있으면 DB 값 위에 덮어씀 (요청값 우선) + Map> params = mergeIndicatorParams(dbParams, req.getIndicatorParams()); + if (params.isEmpty()) { + log.warn("[Backtest] 인디케이터 파라미터 없음 — deviceId={}, 지표 기본값 사용 가능성 있음", req.getDeviceId()); + } BacktestSettingsDto cfg = req.getSettings() != null ? req.getSettings() : DEFAULT_SETTINGS; @@ -814,6 +827,36 @@ public class BacktestingService { }; } + /** + * DB 기본 파라미터 위에 요청 파라미터를 병합한다 (요청값 우선). + * + *
    + *
  • base: DB에서 로드한 사용자 저장 인디케이터 파라미터
  • + *
  • override: 요청에 포함된 파라미터 (없으면 null)
  • + *
+ * 같은 indicatorType 키가 있을 경우 override 내부 필드가 base를 덮어씌운다. + */ + private static Map> mergeIndicatorParams( + Map> base, + Map> override) { + + if (override == null || override.isEmpty()) return base; + if (base == null || base.isEmpty()) return override; + + Map> merged = new java.util.LinkedHashMap<>(base); + override.forEach((type, overrideParams) -> { + Map baseParams = merged.get(type); + if (baseParams == null || baseParams.isEmpty()) { + merged.put(type, overrideParams); + } else { + Map inner = new java.util.LinkedHashMap<>(baseParams); + inner.putAll(overrideParams); + merged.put(type, inner); + } + }); + return merged; + } + private BacktestResponse emptyResponse(String reason) { log.warn("[BacktestingService] 빈 결과: {}", reason); BacktestAnalysisDto emptyAnalysis = BacktestAnalysisDto.builder().build();