83 lines
2.8 KiB
Java
83 lines
2.8 KiB
Java
package com.goldenchart.service;
|
|
|
|
import ch.qos.logback.classic.Level;
|
|
import ch.qos.logback.classic.Logger;
|
|
import ch.qos.logback.classic.LoggerContext;
|
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
|
import ch.qos.logback.core.filter.Filter;
|
|
import ch.qos.logback.core.read.ListAppender;
|
|
import ch.qos.logback.core.spi.FilterReply;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.ta4j.core.Rule;
|
|
import org.ta4j.core.TradingRecord;
|
|
|
|
/**
|
|
* Ta4j Rule 평가 시 TRACE 로그를 메모리에 수집 (AI 검증용).
|
|
*/
|
|
final class Ta4jRuleTraceCapture implements AutoCloseable {
|
|
|
|
private static final int MAX_LINES = 100;
|
|
private static final int MAX_LINE_LEN = 600;
|
|
|
|
private final ListAppender<ILoggingEvent> appender;
|
|
private final Logger rulesLogger;
|
|
private final Level previousLevel;
|
|
|
|
private Ta4jRuleTraceCapture(ListAppender<ILoggingEvent> appender, Logger rulesLogger, Level previousLevel) {
|
|
this.appender = appender;
|
|
this.rulesLogger = rulesLogger;
|
|
this.previousLevel = previousLevel;
|
|
}
|
|
|
|
static Ta4jRuleTraceCapture open() {
|
|
LoggerContext ctx = (LoggerContext) LoggerFactory.getILoggerFactory();
|
|
Logger rulesLogger = ctx.getLogger("org.ta4j.core.rules");
|
|
Level prev = rulesLogger.getLevel();
|
|
|
|
ListAppender<ILoggingEvent> appender = new ListAppender<>();
|
|
appender.addFilter(new Filter<>() {
|
|
@Override
|
|
public FilterReply decide(ILoggingEvent event) {
|
|
if (event == null || event.getLoggerName() == null) return FilterReply.DENY;
|
|
return event.getLoggerName().startsWith("org.ta4j.core.rules")
|
|
? FilterReply.ACCEPT
|
|
: FilterReply.DENY;
|
|
}
|
|
});
|
|
appender.setContext(ctx);
|
|
appender.start();
|
|
|
|
rulesLogger.setLevel(Level.TRACE);
|
|
rulesLogger.setAdditive(true);
|
|
rulesLogger.addAppender(appender);
|
|
|
|
return new Ta4jRuleTraceCapture(appender, rulesLogger, prev);
|
|
}
|
|
|
|
boolean evaluateWithTrace(Rule rule, int index, TradingRecord tradingRecord) {
|
|
return rule.isSatisfiedWithTraceMode(index, tradingRecord, Rule.TraceMode.VERBOSE);
|
|
}
|
|
|
|
java.util.List<String> lines() {
|
|
return appender.list.stream()
|
|
.filter(e -> e.getLevel().isGreaterOrEqual(Level.TRACE))
|
|
.map(ILoggingEvent::getFormattedMessage)
|
|
.map(Ta4jRuleTraceCapture::truncate)
|
|
.limit(MAX_LINES)
|
|
.toList();
|
|
}
|
|
|
|
@Override
|
|
public void close() {
|
|
rulesLogger.detachAppender(appender);
|
|
appender.stop();
|
|
rulesLogger.setLevel(previousLevel);
|
|
}
|
|
|
|
private static String truncate(String s) {
|
|
if (s == null) return "";
|
|
if (s.length() <= MAX_LINE_LEN) return s;
|
|
return s.substring(0, MAX_LINE_LEN) + "…";
|
|
}
|
|
}
|