알림팝업 수정, 전략평가 로직 개선

This commit is contained in:
Macbook
2026-06-05 10:32:40 +09:00
parent 238dd0cebe
commit 5278177bbb
9 changed files with 484 additions and 116 deletions
@@ -40,6 +40,8 @@ public class StrategyTriggerBranchEvaluator {
/**
* 트리거 분봉({@code triggerCandleType}) 마감 시 호출되는 Rule.
* {@code index}는 트리거 분봉 BarSeries의 확정봉 인덱스.
*
* @param useConfirmedOnly true → CANDLE_CLOSE: 비트리거 상위봉의 확정봉(endIndex-1) 사용
*/
public Rule buildTriggerRule(String conditionJson,
String market,
@@ -48,7 +50,8 @@ public class StrategyTriggerBranchEvaluator {
String triggerCandleType,
Map<String, Map<String, Object>> indicatorParams,
Map<String, Map<String, Object>> indicatorVisual,
Ta4jStorage storage) {
Ta4jStorage storage,
boolean useConfirmedOnly) {
BranchScope scope = parseScope(conditionJson);
if (scope.branches().isEmpty()) return new BooleanRule(false);
@@ -59,11 +62,26 @@ public class StrategyTriggerBranchEvaluator {
indicatorParams,
indicatorVisual != null ? indicatorVisual : Map.of(),
market,
storage);
storage,
useConfirmedOnly,
Map.of());
return new TriggerBranchRule(scope, market, strategyId, side, trigger, ctx);
}
/** 하위 호환 오버로드 (useConfirmedOnly=false) */
public Rule buildTriggerRule(String conditionJson,
String market,
long strategyId,
String side,
String triggerCandleType,
Map<String, Map<String, Object>> indicatorParams,
Map<String, Map<String, Object>> indicatorVisual,
Ta4jStorage storage) {
return buildTriggerRule(conditionJson, market, strategyId, side, triggerCandleType,
indicatorParams, indicatorVisual, storage, false);
}
BranchScope parseScope(String conditionJson) {
if (conditionJson == null || conditionJson.isBlank()) {
return new BranchScope("SINGLE", List.of());
@@ -225,14 +243,19 @@ public class StrategyTriggerBranchEvaluator {
BarSeries branchSeries = ctx.resolveSeries(branch.candleType());
if (branchSeries.isEmpty()) return false;
int branchIndex = branch.candleType().equals(triggerCandleType)
? index
: branchSeries.getEndIndex();
int branchIndex;
if (branch.candleType().equals(triggerCandleType)) {
branchIndex = index;
} else if (ctx.useConfirmedOnly()) {
// CANDLE_CLOSE: 마지막 확정봉 사용 (provisional 봉 오염 방지)
branchIndex = Math.max(branchSeries.getBeginIndex(), branchSeries.getEndIndex() - 1);
} else {
// REALTIME_TICK: 현재 봉(provisional 포함) 사용
branchIndex = branchSeries.getEndIndex();
}
if (branchIndex < 0 || branchIndex >= branchSeries.getBarCount()) return false;
StrategyDslToTa4jAdapter.RuleBuildContext branchCtx =
new StrategyDslToTa4jAdapter.RuleBuildContext(
branchSeries, ctx.indicatorParams(), ctx.indicatorVisual(), ctx.market(), ctx.storage());
StrategyDslToTa4jAdapter.RuleBuildContext branchCtx = ctx.withPrimary(branchSeries);
try {
Rule rule = adapter.toRule(subtree, branchCtx);
return rule.isSatisfied(branchIndex, null);