obv 신호선
This commit is contained in:
@@ -441,6 +441,45 @@ export function mergePlotDefs(saved: PlotDef[] | undefined, defaults: PlotDef[])
|
||||
});
|
||||
}
|
||||
|
||||
/** OBV·CCI·RSI·TRIX — registry 신호선(plot1) 병합·표시 보장 (DB에 plot0만 저장된 경우 대비) */
|
||||
const SIGNAL_LINE_INDICATOR_TYPES = new Set(['OBV', 'CCI', 'RSI', 'TRIX']);
|
||||
|
||||
function normalizeSignalLineIndicatorPlots(
|
||||
type: string,
|
||||
plots: PlotDef[],
|
||||
registryPlots: PlotDef[],
|
||||
plotVisibility: Record<string, boolean>,
|
||||
params: Record<string, number | string | boolean>,
|
||||
): { plots: PlotDef[]; plotVisibility: Record<string, boolean> } {
|
||||
if (!SIGNAL_LINE_INDICATOR_TYPES.has(type)) {
|
||||
return { plots, plotVisibility };
|
||||
}
|
||||
const merged = mergePlotDefs(plots, registryPlots);
|
||||
const regSignal = registryPlots.find(p => p.id === 'plot1');
|
||||
const nextPlots = regSignal
|
||||
? merged.map(p => {
|
||||
if (p.id !== 'plot1') return p;
|
||||
return {
|
||||
...regSignal,
|
||||
...p,
|
||||
id: 'plot1',
|
||||
title: regSignal.title,
|
||||
type: 'line' as const,
|
||||
lineWidth: Math.max(1, p.lineWidth ?? regSignal.lineWidth ?? 1),
|
||||
};
|
||||
})
|
||||
: merged;
|
||||
const nextVis = { ...plotVisibility };
|
||||
if (type === 'OBV') {
|
||||
nextVis.plot1 = true;
|
||||
} else if ((type === 'CCI' || type === 'RSI') && params.maType === 'None') {
|
||||
nextVis.plot1 = false;
|
||||
} else if (nextVis.plot1 !== false) {
|
||||
nextVis.plot1 = true;
|
||||
}
|
||||
return { plots: nextPlots, plotVisibility: nextVis };
|
||||
}
|
||||
|
||||
/** 업비트 OBV 신호선 MA 종류 (단순·지수·가중만) */
|
||||
export const OBV_MA_TYPE_OPTIONS = ['SMA', 'EMA', 'WMA'] as const;
|
||||
export type ObvMaType = (typeof OBV_MA_TYPE_OPTIONS)[number];
|
||||
@@ -520,18 +559,20 @@ export function enrichIndicatorConfig(
|
||||
if (cfgNorm.type === 'DMI') {
|
||||
params = normalizeDmiParams(params);
|
||||
}
|
||||
const plots = cfgNorm.type === 'BollingerBands'
|
||||
let plots = cfgNorm.type === 'BollingerBands'
|
||||
? mergeBbPlots(cfgNorm.plots, def.plots)
|
||||
: mergePlotDefs(cfgNorm.plots, def.plots);
|
||||
const plotVisibility: Record<string, boolean> = { ...cfgNorm.plotVisibility };
|
||||
let plotVisibility: Record<string, boolean> = { ...cfgNorm.plotVisibility };
|
||||
for (const p of plots) {
|
||||
if (plotVisibility[p.id] === undefined) plotVisibility[p.id] = true;
|
||||
}
|
||||
if (cfgNorm.type === 'OBV') {
|
||||
plotVisibility.plot1 = plotVisibility.plot1 !== false;
|
||||
} else if ((cfgNorm.type === 'CCI' || cfgNorm.type === 'RSI') && params.maType === 'None') {
|
||||
plotVisibility.plot1 = false;
|
||||
}
|
||||
({ plots, plotVisibility } = normalizeSignalLineIndicatorPlots(
|
||||
cfgNorm.type,
|
||||
plots,
|
||||
def.plots,
|
||||
plotVisibility,
|
||||
params,
|
||||
));
|
||||
|
||||
const out: import('../types').IndicatorConfig = {
|
||||
...cfgNorm,
|
||||
@@ -636,6 +677,9 @@ export async function calculateIndicator(
|
||||
if (type === 'CCI') {
|
||||
calcParams = normalizeCciParams(params);
|
||||
}
|
||||
if (type === 'OBV') {
|
||||
calcParams = normalizeObvParams(params);
|
||||
}
|
||||
if (type === 'IchimokuCloud') {
|
||||
const { senkou } = resolveIchimokuDisplacements(params);
|
||||
calcParams = { ...params, displacement: senkou };
|
||||
|
||||
Reference in New Issue
Block a user