추가수정

This commit is contained in:
Macbook
2026-06-09 13:35:42 +09:00
parent 7928b4ef46
commit c98d1a188f
4 changed files with 14 additions and 29 deletions
@@ -157,7 +157,10 @@ const TradeSignalMiniChart: React.FC<Props> = ({
onNewCandle: handleNewCandle, onNewCandle: handleNewCandle,
enabled: enabled && useUpbit, enabled: enabled && useUpbit,
source: chartRealtimeSource, source: chartRealtimeSource,
deepObvHistory: needsDeepObv, deepObvHistory: false,
// OBV 있을 때: 200봉만 가져오면 OBV가 0부터 시작 → 신호선과 시각적 발산 보장
// WARMUP_COUNT(600) 불필요 — 미니차트 지표(OBV SMA-9, W%R 등)는 짧은 웜업으로 충분
fetchCount: needsDeepObv ? 200 : undefined,
}), [handleTickUpdate, handleNewCandle, enabled, useUpbit, needsDeepObv, chartRealtimeSource]), }), [handleTickUpdate, handleNewCandle, enabled, useUpbit, needsDeepObv, chartRealtimeSource]),
); );
@@ -300,7 +303,6 @@ const TradeSignalMiniChart: React.FC<Props> = ({
candleOverlayToggles={candleOverlayToggles} candleOverlayToggles={candleOverlayToggles}
onToggleCandleOverlay={handleToggleCandleOverlay} onToggleCandleOverlay={handleToggleCandleOverlay}
crosshairInfoVisible={false} crosshairInfoVisible={false}
resolveInitialDisplayCount={needsDeepObv ? () => 99999 : undefined}
/> />
)} )}
</div> </div>
@@ -9,6 +9,8 @@ interface Options {
onNewCandle: (bar: OHLCVBar) => void; onNewCandle: (bar: OHLCVBar) => void;
enabled?: boolean; enabled?: boolean;
deepObvHistory?: boolean; deepObvHistory?: boolean;
/** 직접 지정할 페치 봉 수 — UPBIT_DIRECT 전용 (deepObvHistory·WARMUP_COUNT 무시) */
fetchCount?: number;
source?: ChartRealtimeSource; source?: ChartRealtimeSource;
} }
@@ -29,6 +31,7 @@ export function useChartRealtimeData(
onNewCandle: opts.onNewCandle, onNewCandle: opts.onNewCandle,
enabled: opts.enabled !== false && !useStomp, enabled: opts.enabled !== false && !useStomp,
deepObvHistory: opts.deepObvHistory, deepObvHistory: opts.deepObvHistory,
fetchCount: opts.fetchCount,
}); });
return useStomp ? stomp : upbit; return useStomp ? stomp : upbit;
} }
+5 -4
View File
@@ -26,6 +26,8 @@ interface UpbitDataOptions {
enabled?: boolean; enabled?: boolean;
/** OBV 등 누적 지표: 상장 이력에 가깝게 장기 캔들 로드 */ /** OBV 등 누적 지표: 상장 이력에 가깝게 장기 캔들 로드 */
deepObvHistory?: boolean; deepObvHistory?: boolean;
/** 직접 지정할 페치 봉 수 (deepObvHistory·WARMUP_COUNT 무시) */
fetchCount?: number;
} }
interface UseUpbitDataReturn { interface UseUpbitDataReturn {
@@ -88,9 +90,8 @@ export function useUpbitData(
const marketChanged = prevMarketRef.current !== '' && prevMarketRef.current !== market; const marketChanged = prevMarketRef.current !== '' && prevMarketRef.current !== market;
prevMarketRef.current = market; prevMarketRef.current = market;
const fetchCount = opts.deepObvHistory const fetchCount = opts.fetchCount
? OBV_DEEP_HISTORY ?? (opts.deepObvHistory ? OBV_DEEP_HISTORY : DISPLAY_COUNT + WARMUP_COUNT);
: DISPLAY_COUNT + WARMUP_COUNT;
fetchUpbitCandlesCached(market, timeframe, fetchCount, marketChanged) fetchUpbitCandlesCached(market, timeframe, fetchCount, marketChanged)
.then(newBars => { .then(newBars => {
@@ -108,7 +109,7 @@ export function useUpbitData(
}); });
return () => { cancelled = true; }; return () => { cancelled = true; };
}, [market, timeframe, opts.enabled, opts.deepObvHistory]); }, [market, timeframe, opts.enabled, opts.deepObvHistory, opts.fetchCount]);
// ── 2. WebSocket: 실시간 체결 구독 ──────────────────────────────────── // ── 2. WebSocket: 실시간 체결 구독 ────────────────────────────────────
const handleMessage = useCallback((msg: UpbitMessage) => { const handleMessage = useCallback((msg: UpbitMessage) => {
+2 -23
View File
@@ -897,11 +897,8 @@ export class ChartManager {
const fallbackColor = config.type === 'OBV' && plotDef.id === 'plot0' const fallbackColor = config.type === 'OBV' && plotDef.id === 'plot0'
? (regPlot?.color ?? '#2196F3') ? (regPlot?.color ?? '#2196F3')
: (regPlot?.color ?? plotDef.color ?? '#2962FF'); : (regPlot?.color ?? plotDef.color ?? '#2962FF');
const resolvedColor = config.type === 'OBV' && plotDef.id === 'plot0'
? '#FFFF00'
: resolvePlotLineColor(plotDef.color, fallbackColor);
series = this.chart.addSeries(LineSeries, { series = this.chart.addSeries(LineSeries, {
color: resolvedColor, color: resolvePlotLineColor(plotDef.color, fallbackColor),
lineWidth: (config.type === 'OBV' && plotDef.id === 'plot0' lineWidth: (config.type === 'OBV' && plotDef.id === 'plot0'
? Math.max(2, plotDef.lineWidth ?? regPlot?.lineWidth ?? 2) ? Math.max(2, plotDef.lineWidth ?? regPlot?.lineWidth ?? 2)
: Math.max(1, plotDef.lineWidth ?? 1)) as 1 | 2 | 3 | 4, : Math.max(1, plotDef.lineWidth ?? 1)) as 1 | 2 | 3 | 4,
@@ -913,19 +910,6 @@ export class ChartManager {
...(indicatorPriceFormat ? { priceFormat: indicatorPriceFormat } : {}), ...(indicatorPriceFormat ? { priceFormat: indicatorPriceFormat } : {}),
}, pane); }, pane);
series.setData(filtered.map(p => ({ time: p.time as Time, value: p.value }))); series.setData(filtered.map(p => ({ time: p.time as Time, value: p.value })));
if (config.type === 'OBV') {
const p0 = result.plots['plot0'] as PlotData | undefined;
const p1 = result.plots['plot1'] as PlotData | undefined;
console.error(
`[OBV addIndicator] plotDef.id=${plotDef.id}`,
'| visible:', isPlotVisible,
'| filteredLen:', filtered.length,
'| first val:', filtered[0]?.value,
'| last val:', filtered[filtered.length - 1]?.value,
'| p0.length:', p0?.length, '| p1.length:', p1?.length,
'| pane:', pane,
);
}
seriesMeta.push({ plotId: plotDef.id, isHistogram: false, color: plotDef.color }); seriesMeta.push({ plotId: plotDef.id, isHistogram: false, color: plotDef.color });
} }
@@ -2903,12 +2887,7 @@ export class ChartManager {
const fallbackColor = entry.type === 'OBV' && pid === 'plot0' const fallbackColor = entry.type === 'OBV' && pid === 'plot0'
? (regPlot?.color ?? '#2196F3') ? (regPlot?.color ?? '#2196F3')
: (regPlot?.color ?? plot.color ?? '#aaa'); : (regPlot?.color ?? plot.color ?? '#aaa');
opts['color'] = (entry.type === 'OBV' && pid === 'plot0') opts['color'] = resolvePlotLineColor(plot.color, fallbackColor);
? '#FFFF00'
: resolvePlotLineColor(plot.color, fallbackColor);
if (entry.type === 'OBV') {
console.error(`[OBV applyStyle] pid=${pid} visible=${visible} color=${opts['color']}`);
}
opts['lineWidth'] = entry.type === 'OBV' && pid === 'plot0' opts['lineWidth'] = entry.type === 'OBV' && pid === 'plot0'
? Math.max(2, plot.lineWidth ?? regPlot?.lineWidth ?? 2) ? Math.max(2, plot.lineWidth ?? regPlot?.lineWidth ?? 2)
: Math.max(1, plot.lineWidth ?? regPlot?.lineWidth ?? 1); : Math.max(1, plot.lineWidth ?? regPlot?.lineWidth ?? 1);