diff --git a/frontend/src/components/tradeNotification/TradeSignalMiniChart.tsx b/frontend/src/components/tradeNotification/TradeSignalMiniChart.tsx index 50ce71a..0ec6c4b 100644 --- a/frontend/src/components/tradeNotification/TradeSignalMiniChart.tsx +++ b/frontend/src/components/tradeNotification/TradeSignalMiniChart.tsx @@ -213,8 +213,9 @@ const TradeSignalMiniChart: React.FC = ({ managerRef.current?.clearBacktestMarkers(); return; } + if (!chartDataReady) return; applySignalMarkers(); - }, [enabled, signalMarker, applySignalMarkers, barsReady]); + }, [enabled, signalMarker, applySignalMarkers, chartDataReady]); useEffect(() => { if (!enabled) return; @@ -226,6 +227,7 @@ const TradeSignalMiniChart: React.FC = ({ if (!canvasWrapRef.current) return; if (managerRef.current?.hasMainSeries()) { syncChartLayout(); + applySignalMarkers(); } else if (!chartReloadTriggeredRef.current && delay >= 600 && chartDataReady) { chartReloadTriggeredRef.current = true; setChartReloadTick(t => t + 1); @@ -239,7 +241,7 @@ const TradeSignalMiniChart: React.FC = ({ timers.forEach(clearTimeout); ro.disconnect(); }; - }, [market, timeframe, enabled, chartDataReady, syncChartLayout, fillHeight]); + }, [market, timeframe, enabled, chartDataReady, syncChartLayout, applySignalMarkers, fillHeight]); useEffect(() => { if (!enabled || !chartDataReady) return; diff --git a/frontend/src/utils/tradeSignalChartMarkers.ts b/frontend/src/utils/tradeSignalChartMarkers.ts index 899b01c..e6c3d40 100644 --- a/frontend/src/utils/tradeSignalChartMarkers.ts +++ b/frontend/src/utils/tradeSignalChartMarkers.ts @@ -2,6 +2,7 @@ * 알림 목록 미니 차트 — 매매 시그널 마커 */ import type { ChartManager } from './ChartManager'; +import { normalizeEpochSec } from './backtestUiUtils'; export interface TradeSignalChartMarker { candleTime: number; @@ -46,7 +47,9 @@ export function buildNotificationSignalMarkers( marker: TradeSignalChartMarker | undefined, ): Array<{ time: number; type: string; price: number }> { if (!marker || !Number.isFinite(marker.price) || marker.price <= 0) return []; - const time = resolveSignalMarkerBarTime(mgr, marker.candleTime); + const candleTimeSec = normalizeEpochSec(marker.candleTime); + if (candleTimeSec <= 0) return []; + const time = resolveSignalMarkerBarTime(mgr, candleTimeSec); if (time == null) return []; return [{ time, type: marker.signalType, price: marker.price }]; } @@ -56,10 +59,15 @@ export function applyNotificationSignalMarkers( marker: TradeSignalChartMarker | undefined, showPrice = false, ): void { - const signals = buildNotificationSignalMarkers(mgr, marker); - if (signals.length === 0) { + if (!marker) { mgr.clearBacktestMarkers(); return; } + // 차트·캔들 미준비 시 조기 clearBacktestMarkers() 호출 금지 (레이아웃/지표 로드 레이스) + if (!mgr.hasMainSeries() || mgr.getRawBarsLength() < 2) return; + + const signals = buildNotificationSignalMarkers(mgr, marker); + if (signals.length === 0) return; + mgr.setBacktestMarkers(signals, showPrice); }