알림목록 캔들차트 매매 시그널 표시

This commit is contained in:
Macbook
2026-06-09 00:55:37 +09:00
parent c9b0441500
commit 8a2d8054ad
5 changed files with 125 additions and 8 deletions
@@ -19,6 +19,10 @@ import { DEFAULT_DISPLAY_TIMEZONE } from '../../utils/timezone';
import { useIndicatorSettings } from '../../hooks/useIndicatorSettings';
import { useSessionCandleOverlayControls } from '../../hooks/useSessionCandleOverlayControls';
import { ensurePaperChartOverlays } from '../../utils/strategyToChartIndicators';
import {
applyNotificationSignalMarkers,
type TradeSignalChartMarker,
} from '../../utils/tradeSignalChartMarkers';
interface Props {
market: string;
@@ -30,6 +34,8 @@ interface Props {
fillHeight?: boolean;
/** STOMP/WS 실시간 봉 수신 시 (목록 행 형광 플래시 등) */
onRealtimeActivity?: () => void;
/** 알림 발생 시점 매매 시그널 (캔들 마커) */
signalMarker?: TradeSignalChartMarker;
}
const noop = () => {};
@@ -42,6 +48,7 @@ const TradeSignalMiniChart: React.FC<Props> = ({
enabled = true,
fillHeight = false,
onRealtimeActivity,
signalMarker,
}) => {
const { getParams, getVisualConfig } = useIndicatorSettings();
const managerRef = useRef<ChartManager | null>(null);
@@ -53,6 +60,8 @@ const TradeSignalMiniChart: React.FC<Props> = ({
const chartLiveReadyRef = useRef(false);
const marketRef = useRef(market);
marketRef.current = market;
const signalMarkerRef = useRef(signalMarker);
signalMarkerRef.current = signalMarker;
const baseIndicators = useMemo(
() => ensurePaperChartOverlays(indicators, getParams, getVisualConfig),
@@ -66,6 +75,15 @@ const TradeSignalMiniChart: React.FC<Props> = ({
syncToManager,
} = useSessionCandleOverlayControls(managerRef, baseIndicators);
const applySignalMarkers = useCallback((attempt = 0) => {
const mgr = managerRef.current;
if (!mgr?.hasMainSeries()) {
if (attempt < 80) requestAnimationFrame(() => applySignalMarkers(attempt + 1));
return;
}
applyNotificationSignalMarkers(mgr, signalMarkerRef.current, false);
}, []);
const syncChartLayout = useCallback(() => {
const wrap = canvasWrapRef.current;
const mgr = managerRef.current;
@@ -81,11 +99,19 @@ const TradeSignalMiniChart: React.FC<Props> = ({
chartLiveReadyRef.current = true;
const pending = pendingBarRef.current;
const mgr = managerRef.current;
if (!pending || !mgr || barsMarketRef.current !== marketRef.current) return;
pendingBarRef.current = null;
mgr.updateBar(pending);
if (pending && mgr && barsMarketRef.current === marketRef.current) {
pendingBarRef.current = null;
mgr.updateBar(pending);
}
syncChartLayout();
}, [syncChartLayout]);
applySignalMarkers();
}, [syncChartLayout, applySignalMarkers]);
const handleManagerReady = useCallback((mgr: ChartManager) => {
managerRef.current = mgr;
syncToManager(mgr);
applySignalMarkers();
}, [syncToManager, applySignalMarkers]);
const applyRealtimeBar = useCallback((bar: OHLCVBar, append: boolean) => {
if (barsMarketRef.current !== marketRef.current) return;
@@ -134,8 +160,17 @@ const TradeSignalMiniChart: React.FC<Props> = ({
chartLiveReadyRef.current = false;
pendingBarRef.current = null;
chartReloadTriggeredRef.current = false;
managerRef.current?.clearBacktestMarkers();
}, [market, timeframe, enabled]);
useEffect(() => {
if (!enabled) {
managerRef.current?.clearBacktestMarkers();
return;
}
applySignalMarkers();
}, [enabled, signalMarker, applySignalMarkers, barsReady]);
useEffect(() => {
if (!enabled) return;
const wrap = canvasWrapRef.current;
@@ -223,10 +258,7 @@ const TradeSignalMiniChart: React.FC<Props> = ({
drawingsLocked
drawingsVisible={false}
onCrosshair={noop as (d: LegendData | null) => void}
onManagerReady={mgr => {
managerRef.current = mgr;
syncToManager(mgr);
}}
onManagerReady={handleManagerReady}
onAddDrawing={noop as (d: Drawing) => void}
onCandlesReady={handleCandlesReady}
magnifierEnabled={false}