obv 추가수정

This commit is contained in:
Macbook
2026-06-09 22:18:18 +09:00
parent 27c60be1e9
commit 7b4fc1f811
5 changed files with 79 additions and 28 deletions
+65 -21
View File
@@ -808,17 +808,27 @@ export class ChartManager {
}
}
/** 스타일 갱신·초기 추가 후 OBV 등 본선(plot0) 시리즈 누락 보정 + 전체 setData */
private async _ensureDualLinePlotSeriesForEntry(entry: IndicatorEntry): Promise<void> {
if (!DUAL_LINE_INDICATOR_TYPES.has(entry.type)) return;
const config = enrichIndicatorConfig(entry.config!);
const def = getIndicatorDef(config.type);
if (!def) return;
if (this._dualLineMissingPlotIds(entry, config, def).length === 0) return;
/** plot0·plot1 시리즈 전부 제거 후 DB 설정 스타일로 재생성 */
private async _rebuildDualLinePlotSeriesForEntry(
entry: IndicatorEntry,
config: IndicatorConfig,
def: NonNullable<ReturnType<typeof getIndicatorDef>>,
): Promise<void> {
if (this.rawBars.length === 0) return;
const pane = entry.paneIndex ?? this._readSeriesPaneIndex(entry.seriesList[0]) ?? 2;
const indicatorHidden = !this._isIndicatorEffectivelyVisible(config);
for (const pl of entry.hlineRefs) {
try { entry.seriesList[0]?.removePriceLine(pl); } catch { /* ok */ }
}
entry.hlineRefs = [];
for (const s of entry.seriesList) {
try { this.chart.removeSeries(s); } catch { /* ok */ }
}
entry.seriesList = [];
entry.seriesMeta = [];
try {
const result = await calculateIndicator(config.type, this.rawBars.slice(), config.params);
this._appendMissingPlotSeriesToLists(
@@ -838,6 +848,30 @@ export class ChartManager {
const actualPane = this._readSeriesPaneIndex(entry.seriesList[0]);
if (actualPane >= 2) entry.paneIndex = actualPane;
}
} catch (e) {
console.error(`[Indicator] ${config.type} dual-line rebuild error:`, e);
}
}
/** 스타일 갱신·초기 추가 후 OBV 등 본선(plot0) 시리즈 누락 보정 + 전체 setData */
private async _ensureDualLinePlotSeriesForEntry(entry: IndicatorEntry): Promise<void> {
if (!DUAL_LINE_INDICATOR_TYPES.has(entry.type)) return;
const config = enrichIndicatorConfig(entry.config!);
const def = getIndicatorDef(config.type);
if (!def) return;
if (this.rawBars.length === 0) return;
const missing = this._dualLineMissingPlotIds(entry, config, def);
if (missing.length > 0) {
await this._rebuildDualLinePlotSeriesForEntry(entry, config, def);
return;
}
if (entry.seriesList.length === 0) return;
try {
const result = await calculateIndicator(config.type, this.rawBars.slice(), config.params);
this._setIndicatorPlotsFullData(entry, result.plots as Record<string, PlotData>, config);
entry.config = config;
} catch (e) {
console.error(`[Indicator] ${config.type} dual-line repair error:`, e);
}
@@ -1063,20 +1097,26 @@ export class ChartManager {
this._notifyPaneLayout();
}
/** OBV·RSI 등 본선(plot0) 시리즈 누락 시 재생성 + 전체 plot setData */
/** OBV·RSI 등 본선(plot0) 시리즈 누락 시 재생성 + 전체 plot setData + 스타일(DB) 반영 */
async repairDualLineSeries(): Promise<void> {
for (const entry of this.indicators.values()) {
if (!DUAL_LINE_INDICATOR_TYPES.has(entry.type) || !entry.config) continue;
await this._ensureDualLinePlotSeriesForEntry(entry);
if (entry.seriesList.length === 0 || this.rawBars.length === 0) continue;
try {
const config = enrichIndicatorConfig(entry.config);
const result = await calculateIndicator(
config.type, this.rawBars.slice(), config.params ?? {},
);
this._setIndicatorPlotsFullData(entry, result.plots as Record<string, PlotData>, config);
this.applyIndicatorStyle(config);
} catch { /* ok */ }
const config = enrichIndicatorConfig(entry.config);
const def = getIndicatorDef(entry.type);
if (!def) continue;
const missing = this._dualLineMissingPlotIds(entry, config, def);
if (missing.length > 0) {
await this._rebuildDualLinePlotSeriesForEntry(entry, config, def);
} else if (entry.seriesList.length > 0 && this.rawBars.length > 0) {
try {
const result = await calculateIndicator(
config.type, this.rawBars.slice(), config.params ?? {},
);
this._setIndicatorPlotsFullData(entry, result.plots as Record<string, PlotData>, config);
} catch { /* ok */ }
}
this.applyIndicatorStyle(config);
}
}
@@ -2902,7 +2942,7 @@ export class ChartManager {
* 인디케이터의 스타일(색상·선폭·plotVisibility)을 in-place 로 일괄 적용.
* 시리즈를 제거·재생성하지 않으므로 pane 재번호 문제가 없음.
*/
applyIndicatorStyle(config: IndicatorConfig): void {
applyIndicatorStyle(config: IndicatorConfig, options?: { skipDualLineRefresh?: boolean }): void {
config = enrichIndicatorConfig(config);
const entry = this.indicators.get(config.id);
if (!entry) return;
@@ -3035,8 +3075,12 @@ export class ChartManager {
void this._repaintHistogramSeries(config.id, config);
}
if (DUAL_LINE_INDICATOR_TYPES.has(config.type)) {
void this._ensureDualLinePlotSeriesForEntry(entry);
if (DUAL_LINE_INDICATOR_TYPES.has(config.type) && !options?.skipDualLineRefresh) {
void this._ensureDualLinePlotSeriesForEntry(entry).then(() => {
if (entry.config) {
this.applyIndicatorStyle(enrichIndicatorConfig(entry.config), { skipDualLineRefresh: true });
}
});
}
if (this._candleOnlyLayout && this._isSubPaneIndicator(entry)) {
+1
View File
@@ -453,6 +453,7 @@ function normalizeDualLinePlotDef(saved: PlotDef, reg: PlotDef): PlotDef {
title: reg.title,
type: 'line',
lineWidth: Math.max(1, saved.lineWidth ?? reg.lineWidth ?? 1),
lineStyle: saved.lineStyle ?? reg.lineStyle ?? 'solid',
color: resolvePlotLineColor(saved.color, reg.color),
};
}
@@ -64,10 +64,15 @@ export function initializeIndicatorConfigForEditor(
: { ...raw.params };
const visual = getVisualConfig?.(raw.type, def.plots, def.hlines);
const mergedPlots = mergePlotDefs(
raw.plots?.length ? raw.plots : undefined,
mergePlotDefs(visual?.plots, def.plots),
);
return enrichIndicatorConfig({
...raw,
params,
plots: raw.plots?.length ? raw.plots : visual?.plots,
plots: mergedPlots,
hlines: raw.hlines?.length ? raw.hlines : visual?.hlines,
cloudColors: raw.cloudColors ?? visual?.cloudColors,
bandBackground: raw.bandBackground ?? visual?.bandBackground,