obv 그래프 오류
This commit is contained in:
@@ -1989,7 +1989,10 @@ function barsKey(bars: OHLCVBar[], market = ''): string {
|
||||
if (bars.length === 0) return '';
|
||||
const last = bars[bars.length - 1];
|
||||
// last.close 제외 — 틱마다 full reload 방지 (실시간은 updateBar/appendBar 경로)
|
||||
return `${market}:${bars.length}:${bars[0].time}:${last.time}`;
|
||||
// volume 합계 — STOMP volume=0 → Upbit 폴백 후 OBV 등 지표 재계산 유도
|
||||
const volSum = bars.reduce((s, b) => s + (Number(b.volume) || 0), 0);
|
||||
const volFlag = volSum > 0 ? 'v' : '0';
|
||||
return `${market}:${bars.length}:${bars[0].time}:${last.time}:${volFlag}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,7 +54,7 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
||||
}) => {
|
||||
const { getParams, getVisualConfig } = useIndicatorSettings();
|
||||
const { defaults: appDefaults } = useAppSettings();
|
||||
const chartRealtimeSource = (appDefaults.chartRealtimeSource ?? 'BACKEND_STOMP') as ChartRealtimeSource;
|
||||
const appChartSource = (appDefaults.chartRealtimeSource ?? 'BACKEND_STOMP') as ChartRealtimeSource;
|
||||
const managerRef = useRef<ChartManager | null>(null);
|
||||
const canvasWrapRef = useRef<HTMLDivElement | null>(null);
|
||||
const [chartReloadTick, setChartReloadTick] = useState(0);
|
||||
@@ -77,6 +77,9 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
||||
[baseIndicators],
|
||||
);
|
||||
|
||||
/** OBV 누적값 — Upbit REST 직접 (STOMP 백엔드 volume=0 이면 본선 미표시) */
|
||||
const chartRealtimeSource: ChartRealtimeSource = needsDeepObv ? 'UPBIT_DIRECT' : appChartSource;
|
||||
|
||||
const {
|
||||
indicators: chartIndicators,
|
||||
candleOverlayToggles,
|
||||
@@ -166,6 +169,14 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
||||
barsMarketRef.current = barsMarket;
|
||||
const barsReady = bars.length >= 2 && barsMarket === market;
|
||||
|
||||
const obvBarsReady = useMemo(() => {
|
||||
if (!needsDeepObv) return true;
|
||||
if (bars.length < 2) return false;
|
||||
return bars.some(b => (Number(b.volume) || 0) > 0);
|
||||
}, [needsDeepObv, bars]);
|
||||
|
||||
const chartDataReady = barsReady && obvBarsReady;
|
||||
|
||||
useLayoutEffect(() => {
|
||||
chartLiveReadyRef.current = false;
|
||||
pendingBarRef.current = null;
|
||||
@@ -191,7 +202,7 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
||||
if (!canvasWrapRef.current) return;
|
||||
if (managerRef.current?.hasMainSeries()) {
|
||||
syncChartLayout();
|
||||
} else if (!chartReloadTriggeredRef.current && delay >= 600 && barsReady) {
|
||||
} else if (!chartReloadTriggeredRef.current && delay >= 600 && chartDataReady) {
|
||||
chartReloadTriggeredRef.current = true;
|
||||
setChartReloadTick(t => t + 1);
|
||||
}
|
||||
@@ -204,15 +215,15 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
||||
timers.forEach(clearTimeout);
|
||||
ro.disconnect();
|
||||
};
|
||||
}, [market, timeframe, enabled, barsReady, syncChartLayout, fillHeight]);
|
||||
}, [market, timeframe, enabled, chartDataReady, syncChartLayout, fillHeight]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled || !barsReady) return;
|
||||
if (!enabled || !chartDataReady) return;
|
||||
if (!managerRef.current?.hasMainSeries() && !chartReloadTriggeredRef.current) {
|
||||
chartReloadTriggeredRef.current = true;
|
||||
setChartReloadTick(t => t + 1);
|
||||
}
|
||||
}, [enabled, barsReady]);
|
||||
}, [enabled, chartDataReady]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled) return;
|
||||
@@ -246,13 +257,17 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
||||
].filter(Boolean).join(' ')}
|
||||
>
|
||||
{isLoading && <div className="tnl-mini-chart-loading">로딩…</div>}
|
||||
{needsDeepObv && !isLoading && !obvBarsReady && (
|
||||
<div className="tnl-mini-chart-loading">OBV 거래량 데이터 로딩…</div>
|
||||
)}
|
||||
{isLoadingMore && (
|
||||
<div className="chart-history-loading">
|
||||
<div className="loading-spinner" style={{ width: 12, height: 12 }} />
|
||||
</div>
|
||||
)}
|
||||
{chartDataReady && (
|
||||
<TradingChart
|
||||
key={`${market}-${timeframe}-${chartReloadTick}-${chartIndicators.map(i => i.id).join(',')}`}
|
||||
key={`${market}-${timeframe}-${chartReloadTick}-${chartRealtimeSource}-${needsDeepObv ? 'obv' : 'std'}-${chartIndicators.map(i => i.id).join(',')}`}
|
||||
chartVisible
|
||||
bars={bars}
|
||||
barsMarket={barsMarket}
|
||||
@@ -283,6 +298,7 @@ const TradeSignalMiniChart: React.FC<Props> = ({
|
||||
onToggleCandleOverlay={handleToggleCandleOverlay}
|
||||
crosshairInfoVisible={false}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user