신심리도 추가, 투자심리도 수정

This commit is contained in:
Macbook
2026-05-29 23:03:47 +09:00
parent 320675ea6b
commit 359e6c9653
19 changed files with 226 additions and 74 deletions
@@ -101,7 +101,8 @@ public class IndicatorService {
case "VolumeOscillator" -> calcVolumeOscillator(series, p);
case "VR" -> calcVR(series, p);
case "Disparity" -> calcDisparity(series, p);
case "Psychological", "NewPsychological" -> calcPsychological(series, p);
case "Psychological" -> calcPsychological(series, p);
case "NewPsychological" -> calcNewPsychological(series, p);
case "InvestPsychological"-> calcInvestPsychological(series, p);
default -> throw new IllegalArgumentException("지원하지 않는 지표: " + type);
@@ -762,9 +763,14 @@ public class IndicatorService {
return Map.of("plot0", psychologicalPoints(s, period, false));
}
private Map<String, List<PlotPoint>> calcNewPsychological(BarSeries s, Map<String, Object> p) {
int period = intP(p, "length", 10);
return Map.of("plot0", newPsychologicalPoints(s, period));
}
private Map<String, List<PlotPoint>> calcInvestPsychological(BarSeries s, Map<String, Object> p) {
int period = intP(p, "length", 10);
return Map.of("plot0", psychologicalPoints(s, period, true));
return Map.of("plot0", psychologicalPoints(s, period, false));
}
private List<PlotPoint> psychologicalPoints(BarSeries s, int period, boolean volumeWeighted) {
@@ -805,6 +811,40 @@ public class IndicatorService {
return pts;
}
/** 신심리도: [상승일수×상승폭비율 − 하락일수×하락폭비율] × 100 / N */
private List<PlotPoint> newPsychologicalPoints(BarSeries s, int period) {
int n = s.getBarCount();
ClosePriceIndicator close = new ClosePriceIndicator(s);
List<PlotPoint> pts = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
Bar bar = s.getBar(i);
long t = bar.getEndTime().getEpochSecond() - bar.getTimePeriod().getSeconds();
if (i < period) {
pts.add(PlotPoint.builder().time(t).value(null).build());
continue;
}
double upSize = 0, downSize = 0;
int upDay = 0, downDay = 0;
for (int j = i - period + 1; j <= i; j++) {
Double c = safe(close.getValue(j));
Double cPrev = safe(close.getValue(j - 1));
if (c == null || cPrev == null) continue;
double diff = c - cPrev;
if (diff > 0) {
upSize += diff;
upDay++;
} else if (diff < 0) {
downSize += -diff;
downDay++;
}
}
double total = upSize + downSize;
Double val = total == 0 ? null : (upDay * (upSize / total) - downDay * (downSize / total)) * 100.0 / period;
pts.add(PlotPoint.builder().time(t).value(val).build());
}
return pts;
}
// ── EMA helper (double[], for TSI manual calc) ────────────────────────────
private double[] ema(double[] src, int len, int n) {