9일 신고가 매수 조건 오류

This commit is contained in:
Macbook
2026-06-22 12:49:36 +09:00
parent 2299381403
commit 53747b8773
3 changed files with 68 additions and 0 deletions
@@ -173,8 +173,56 @@ class PriceExtremeRuleTest {
assertFalse(hits.isEmpty(), "하락 추세에서 9·20일 신저가 복합 매도 조건이 최소 1회 충족되어야 함");
}
@Test
void nhPrior_crossUp_firesOnRealPriceBreakout_notConstantNine() throws Exception {
BarSeries series = buildFlatThenBreakoutSeries(97_000_000.0, 97_500_000.0, 15);
Rule buy = rule(series, """
{ "type": "CONDITION", "condition": {
"indicatorType": "NEW_HIGH",
"conditionType": "CROSS_UP",
"leftField": "CLOSE_PRICE",
"rightField": "NH_PRIOR_9",
"period": 9
}}
""");
List<Integer> hits = satisfiedIndices(buy, series);
assertFalse(hits.isEmpty(),
"97M대 종가가 9일 신고가선 상향 돌파 시 CROSS_UP — NH_PRIOR_9를 상수 9로 해석하면 영원히 false");
assertTrue(hits.stream().anyMatch(i -> i >= 9),
"9봉 워밍업 이후 돌파 봉에서만 시그널");
}
// ── helpers ─────────────────────────────────────────────────────────────
/** 횡보 후 한 봉에 종가 돌파 — NH_PRIOR CROSS_UP 검증용 */
private static BarSeries buildFlatThenBreakoutSeries(double flatPrice, double breakoutClose, int flatBars) {
Duration period = Duration.ofMinutes(3);
BarSeries series = new BaseBarSeriesBuilder()
.withName("flat-breakout")
.withNumFactory(DoubleNumFactory.getInstance())
.withBarBuilderFactory(new TimeBarBuilderFactory())
.build();
TimeBarBuilderFactory factory = new TimeBarBuilderFactory();
Instant base = Instant.parse("2024-01-01T00:00:00Z");
for (int i = 0; i < flatBars; i++) {
factory.createBarBuilder(series)
.timePeriod(period)
.endTime(base.plus(period.multipliedBy(i + 1L)))
.openPrice(flatPrice).highPrice(flatPrice + 1000).lowPrice(flatPrice - 1000).closePrice(flatPrice)
.volume(1000)
.add();
}
int i = flatBars;
factory.createBarBuilder(series)
.timePeriod(period)
.endTime(base.plus(period.multipliedBy(i + 1L)))
.openPrice(flatPrice).highPrice(breakoutClose + 500).lowPrice(flatPrice - 500).closePrice(breakoutClose)
.volume(5000)
.add();
return series;
}
private Rule rule(BarSeries series, String json) throws Exception {
JsonNode node = MAPPER.readTree(json);
return adapter.toRule(node, series, Map.of());