macd 추가수정

This commit is contained in:
Macbook
2026-06-16 01:29:42 +09:00
parent ea13347be8
commit 52300379c4
2 changed files with 59 additions and 8 deletions
+56 -5
View File
@@ -157,6 +157,10 @@ export function mergeHlines(
? savedList[0]
: undefined;
const defRoleLabels = new Set(
defs.map(d => d.label ?? getHLineLabel(d.price, defs.map(x => x.price))),
);
return defs
.map(def => {
const wantLabel = def.label ?? getHLineLabel(def.price, defs.map(d => d.price));
@@ -172,7 +176,9 @@ export function mergeHlines(
.concat(
savedList.filter(h => {
const lbl = labelOf(h);
return !defs.some(d => (d.label ?? getHLineLabel(d.price, defs.map(x => x.price))) === lbl);
if (defRoleLabels.has(lbl)) return false;
// registry에 없는 역할(잘못 분류된 과열/침체 orphan)은 제거 — 종가가 과열선으로 저장되는 MACD 버그 방지
return defRoleLabels.size > 1;
}).map(h => ({ ...h, label: labelOf(h) })),
)
.sort((a, b) => b.price - a.price);
@@ -254,19 +260,64 @@ export function normalizeHLines(
/** registry 기본 중앙선이 0인 지표에서 잘못 저장된 중앙선 가격을 0으로 고정 */
function clampZeroCenterHLines(hlines: HLineDef[], defaults?: HLineDef[]): HLineDef[] {
const defPrices = (defaults ?? []).map(d => d.price);
const defCenter = (defaults ?? []).find(
const defs = defaults ?? [];
const defPrices = defs.map(d => d.price);
const defCenter = defs.find(
d => (d.label ?? getHLineLabel(d.price, defPrices)) === '중앙선',
);
if (defCenter?.price !== 0) return hlines;
const prices = hlines.map(h => h.price);
return hlines.map(h => {
const defPriceSet = new Set(defPrices);
let list = hlines;
// MACD·AO 등 중앙 0선 단일 def — registry에 없는 가격(종가 orphan) 제거
if (defs.length === 1 && defs[0].price === 0) {
const orphanWasVisible = hlines.some(h => {
const prices = hlines.map(x => x.price);
const lbl = h.label ?? getHLineLabel(h.price, prices);
return lbl !== '중앙선' && h.visible !== false && !defPriceSet.has(h.price);
});
list = hlines.filter(h => {
const prices = hlines.map(x => x.price);
const lbl = h.label ?? getHLineLabel(h.price, prices);
if (lbl === '중앙선') return true;
return defPriceSet.has(h.price);
});
if (orphanWasVisible) {
list = list.map(h => {
const prices = list.map(x => x.price);
const lbl = h.label ?? getHLineLabel(h.price, prices);
return lbl === '중앙선' ? { ...h, visible: true } : h;
});
}
}
const prices = list.map(h => h.price);
return list.map(h => {
const lbl = h.label ?? getHLineLabel(h.price, prices);
return lbl === '중앙선' ? { ...h, price: 0 } : h;
});
}
/** 차트 draw 시 hline 실제 가격 — 중앙 0선 지표는 항상 0 */
export function resolveHLineDrawPrice(
indicatorType: string,
hl: HLineDef,
allHlines: HLineDef[],
): number {
const def = getIndicatorDef(indicatorType);
const defaults = def?.hlines ?? [];
const defPrices = defaults.map(d => d.price);
const prices = allHlines.map(h => h.price);
const lbl = hl.label ?? getHLineLabel(hl.price, prices);
const defCenter = defaults.find(
d => (d.label ?? getHLineLabel(d.price, defPrices)) === '중앙선',
);
if (lbl === '중앙선' && defCenter?.price === 0) {
return 0;
}
return hl.price;
}
export interface IndicatorDef {
type: string;
name: string;