매매 시그널 알림 화면 수정

This commit is contained in:
Macbook
2026-05-29 00:46:20 +09:00
parent cbad62a5b0
commit e43b5cbd5a
45 changed files with 2186 additions and 415 deletions
@@ -282,6 +282,13 @@ public class StrategyDslTimeframeNormalizer {
if (fromConditions.size() == 1) {
String required = fromConditions.iterator().next();
// START에 5m 등 명시 분봉이 있으면 조건 노드 기본값 1m 보다 우선 (편집기 START 변경 직후)
if ("1m".equals(required) && hasExplicitNon1mStart(fromStart)) {
if (fromStart.size() == 1) {
return fromStart;
}
return dropStale1mFromStart(fromStart, fromConditions);
}
// 레거시 [1m, X] — 조건이 X 단일 분봉이면 X만
if (fromStart.size() == 2 && fromStart.contains("1m") && fromStart.contains(required)) {
return Set.of(required);
@@ -302,11 +309,21 @@ public class StrategyDslTimeframeNormalizer {
// 조건에 복수 분봉 명시 — START가 상위집합이면 START 유지 (다중 OR)
if (fromStart.containsAll(fromConditions) && fromStart.size() >= fromConditions.size()) {
return fromStart;
return dropStale1mFromStart(fromStart, fromConditions);
}
return fromConditions;
}
/** START 에만 남은 stale 1m 제거 — 조건에 1m 이 없으면 평가·알림 분봉에서 제외 */
private static Set<String> dropStale1mFromStart(Set<String> fromStart, Set<String> fromConditions) {
if (!fromStart.contains("1m") || fromConditions.contains("1m")) {
return fromStart;
}
Set<String> filtered = new LinkedHashSet<>(fromStart);
filtered.remove("1m");
return filtered.isEmpty() ? fromStart : filtered;
}
private ObjectNode writeResolvedTimeframe(JsonNode root, String strategyName) {
Set<String> resolved = resolveStartCandleTypes(root);
if (resolved.isEmpty()) {
@@ -333,6 +350,14 @@ public class StrategyDslTimeframeNormalizer {
return fromStart.size() == 1 && fromStart.contains("1m");
}
/** START TIMEFRAME에 1m 이 아닌 분봉이 명시되어 있는지 */
private static boolean hasExplicitNon1mStart(Set<String> fromStart) {
for (String ct : fromStart) {
if (!"1m".equals(ct)) return true;
}
return false;
}
private ObjectNode reconcileStartCandleTypes(JsonNode tf) {
return reconcileStartCandleTypesStatic(tf);
}
@@ -355,8 +380,6 @@ public class StrategyDslTimeframeNormalizer {
long non1mCount = normalized.stream().filter(ct -> !"1m".equals(ct)).count();
if (non1mCount == 0) return copy;
// [1m, 3m, 5m] 등 1m+복수 상위봉 OR — 1m 의도적 선택으로 간주
if (non1mCount >= 2) return copy;
ArrayNode newArr = JsonNodeFactory.instance.arrayNode();
for (String ct : normalized) {