일목균형표 전략 추가
This commit is contained in:
@@ -487,6 +487,10 @@ public class StrategyDslToTa4jAdapter {
|
||||
Map<String, Object> indParams = condNodeParams.isEmpty() ? globalParams
|
||||
: mergeParams(globalParams, condNodeParams);
|
||||
|
||||
if ("ICHIMOKU_BB".equals(indType)) {
|
||||
return buildIchimokuBbRule(series, ctx, cond, condType, candleRangeMode, candleRange);
|
||||
}
|
||||
|
||||
try {
|
||||
Indicator<Num> left = resolveField(leftField, indType, indParams, series, condPeriod, leftPeriod, cond, ctx);
|
||||
Indicator<Num> right = resolveField(rightField, indType, indParams, series, condPeriod, rightPeriod, cond, ctx);
|
||||
@@ -1138,6 +1142,54 @@ public class StrategyDslToTa4jAdapter {
|
||||
return new CrossedUpIndicatorRule(close, priorCloudTop);
|
||||
}
|
||||
|
||||
/**
|
||||
* 일목 후행스팬(현재 종가) vs N봉 전 볼린저밴드 — 상향/하향 돌파·위/아래 유지.
|
||||
* cond.params.chikouDisplacement (기본 26), rightField: UPPER_BAND | MIDDLE_BAND | LOWER_BAND
|
||||
*/
|
||||
private Rule buildIchimokuBbRule(
|
||||
BarSeries series,
|
||||
RuleBuildContext ctx,
|
||||
JsonNode cond,
|
||||
String condType,
|
||||
String candleRangeMode,
|
||||
int candleRange) {
|
||||
Map<String, Map<String, Object>> allParams = ctx.indicatorParams();
|
||||
Map<String, Object> ichGlobal = allParams != null
|
||||
? allParams.getOrDefault("IchimokuCloud", Map.of())
|
||||
: Map.of();
|
||||
Map<String, Object> bbGlobal = allParams != null
|
||||
? allParams.getOrDefault("BollingerBands", Map.of())
|
||||
: Map.of();
|
||||
Map<String, Object> nodeParams = extractConditionNodeParams(cond);
|
||||
Map<String, Object> ichParams = nodeParams.isEmpty() ? ichGlobal
|
||||
: mergeParams(ichGlobal, nodeParams);
|
||||
Map<String, Object> bbParams = nodeParams.isEmpty() ? bbGlobal
|
||||
: mergeParams(bbGlobal, nodeParams);
|
||||
|
||||
int d = intP(ichParams, "chikouDisplacement",
|
||||
ichimokuChikouDisplacement(ichParams));
|
||||
String bandField = cond.path("rightField").asText("UPPER_BAND");
|
||||
if (!"UPPER_BAND".equals(bandField) && !"MIDDLE_BAND".equals(bandField) && !"LOWER_BAND".equals(bandField)) {
|
||||
bandField = "UPPER_BAND";
|
||||
}
|
||||
|
||||
ClosePriceIndicator close = new ClosePriceIndicator(series);
|
||||
Indicator<Num> bbLine = resolveField(bandField, "BOLLINGER", bbParams, series, -1, -1, cond, ctx);
|
||||
Indicator<Num> priorBb = new PreviousValueIndicator(bbLine, d);
|
||||
|
||||
Rule core = switch (condType) {
|
||||
case "CROSS_UP" -> buildCrossUpRule(close, priorBb);
|
||||
case "CROSS_DOWN" -> buildCrossDownRule(close, priorBb);
|
||||
case "GT", "GTE" -> new OverIndicatorRule(close, priorBb);
|
||||
case "LT", "LTE" -> new UnderIndicatorRule(close, priorBb);
|
||||
default -> {
|
||||
log.warn("[Adapter] ICHIMOKU_BB 미지원 conditionType: {}", condType);
|
||||
yield new BooleanRule(false);
|
||||
}
|
||||
};
|
||||
return applyCandleRangeWindow(core, candleRangeMode, candleRange, condType);
|
||||
}
|
||||
|
||||
/** 종가가 구름 위 */
|
||||
private Rule buildCloudAboveRule(BarSeries s, Map<String, Object> p) {
|
||||
NumericIndicator cloudTop = NumericIndicator.of(ichimokuSpanA(s, p)).max(ichimokuSpanB(s, p));
|
||||
|
||||
Reference in New Issue
Block a user