전략 시간봉 오류 수정

This commit is contained in:
Macbook
2026-05-28 00:36:49 +09:00
parent 2713b2951d
commit 4f6694b206
16 changed files with 285 additions and 127 deletions
@@ -68,8 +68,20 @@ public class StrategyConditionTimeframeService {
ensureDslRepaired(strategy);
Set<String> out = new LinkedHashSet<>();
collectFromJson(strategy.getBuyConditionJson(), out, strategy.getName());
collectFromJson(strategy.getSellConditionJson(), out, strategy.getName());
boolean buyScoped = collectStartScopeFromJson(strategy.getBuyConditionJson(), out);
boolean sellScoped = collectStartScopeFromJson(strategy.getSellConditionJson(), out);
if (!out.isEmpty()) {
return out;
}
// 레거시: START(TIMEFRAME) 래핑 없는 DSL
if (!buyScoped) {
collectLegacyFromJson(strategy.getBuyConditionJson(), out, strategy.getName());
}
if (!sellScoped) {
collectLegacyFromJson(strategy.getSellConditionJson(), out, strategy.getName());
}
if (out.isEmpty()) {
String fromName = StrategyDslTimeframeNormalizer.inferFromStrategyName(strategy.getName());
@@ -106,19 +118,39 @@ public class StrategyConditionTimeframeService {
}
}
private void collectFromJson(String json, Set<String> out, String strategyName) {
if (json == null || json.isBlank()) return;
/**
* START 루트 TIMEFRAME(candleTypes)만 수집 — 조건 노드 leftCandleType·내부 1m 기본값은 제외.
*
* @return JSON 에 START 스코프가 있으면 true (빈 조건이어도)
*/
private boolean collectStartScopeFromJson(String json, Set<String> out) {
if (json == null || json.isBlank()) return false;
try {
collectFromNode(objectMapper.readTree(json), out, strategyName);
return collectStartScopeFromNode(objectMapper.readTree(json), out);
} catch (Exception e) {
log.warn("[StrategyTimeframes] JSON 파싱 실패: {}", e.getMessage());
return false;
}
}
private boolean collectStartScopeFromNode(JsonNode node, Set<String> out) {
if (node == null || node.isNull()) return false;
return collectTimeframesFromNode(node, out);
}
/** 레거시 DSL — START 래핑 없을 때만 조건 트리·전략명에서 추론 */
private void collectLegacyFromJson(String json, Set<String> out, String strategyName) {
if (json == null || json.isBlank()) return;
try {
collectLegacyFromNode(objectMapper.readTree(json), out, strategyName);
} catch (Exception e) {
log.warn("[StrategyTimeframes] legacy JSON 파싱 실패: {}", e.getMessage());
addFallbackTimeframe(out, strategyName);
}
}
private void collectFromNode(JsonNode node, Set<String> out, String strategyName) {
private void collectLegacyFromNode(JsonNode node, Set<String> out, String strategyName) {
if (node == null || node.isNull()) return;
if (collectTimeframesFromNode(node, out)) return;
Set<String> meaningful = StrategyDslTimeframeNormalizer.collectMeaningfulCandleTypes(node);
if (!meaningful.isEmpty()) {