백테스팅 오류 수정
This commit is contained in:
+30
-11
@@ -650,6 +650,9 @@ function App() {
|
||||
signals: BacktestSignal[];
|
||||
showPrice: boolean;
|
||||
} | null>(null);
|
||||
/** applyBacktestMarkersWhenReady rAF 재시도 시 최신 차트 종목·타임프레임 검증용 */
|
||||
const chartContextRef = useRef({ symbol, timeframe });
|
||||
chartContextRef.current = { symbol, timeframe };
|
||||
|
||||
const syncBacktestMarkersRef = useRef<() => void>(() => {});
|
||||
|
||||
@@ -658,17 +661,23 @@ function App() {
|
||||
payload: NonNullable<typeof btMarkerPayloadRef.current>,
|
||||
attempt = 0,
|
||||
) => {
|
||||
btMarkerPayloadRef.current = payload;
|
||||
const { symbol: curSym, timeframe: curTf } = chartContextRef.current;
|
||||
if (payload.symbol !== curSym || payload.timeframe !== curTf) return;
|
||||
|
||||
const mgr = managerRef.current;
|
||||
if (!mgr || !mgr.hasMainSeries()) {
|
||||
if (attempt < 30) {
|
||||
if (attempt < 120) {
|
||||
requestAnimationFrame(() => applyBacktestMarkersWhenReady(payload, attempt + 1));
|
||||
}
|
||||
return;
|
||||
}
|
||||
btMarkerPayloadRef.current = payload;
|
||||
if (payload.symbol !== chartContextRef.current.symbol
|
||||
|| payload.timeframe !== chartContextRef.current.timeframe) return;
|
||||
mgr.setBacktestMarkers(payload.signals, payload.showPrice);
|
||||
}, []);
|
||||
|
||||
/** reloadAll 직후 등 — payload 가 있을 때만 재적용 (없을 때 clear 하지 않음, 경쟁 방지) */
|
||||
const syncBacktestMarkers = useCallback(() => {
|
||||
const payload = btMarkerPayloadRef.current;
|
||||
if (
|
||||
@@ -678,9 +687,7 @@ function App() {
|
||||
payload.signals.length > 0
|
||||
) {
|
||||
applyBacktestMarkersWhenReady(payload);
|
||||
return;
|
||||
}
|
||||
managerRef.current?.clearBacktestMarkers();
|
||||
}, [symbol, timeframe, applyBacktestMarkersWhenReady]);
|
||||
|
||||
syncBacktestMarkersRef.current = syncBacktestMarkers;
|
||||
@@ -897,16 +904,18 @@ function App() {
|
||||
// 백테스팅 시그널 → ref 갱신 후 ChartManager 마커 동기화
|
||||
useEffect(() => {
|
||||
if (btMatchesChart && btSignals.length > 0) {
|
||||
btMarkerPayloadRef.current = {
|
||||
const payload = {
|
||||
symbol,
|
||||
timeframe,
|
||||
signals: btSignals,
|
||||
showPrice: appDefaults.btShowPrice,
|
||||
};
|
||||
btMarkerPayloadRef.current = payload;
|
||||
applyBacktestMarkersWhenReady(payload);
|
||||
} else {
|
||||
btMarkerPayloadRef.current = null;
|
||||
managerRef.current?.clearBacktestMarkers();
|
||||
}
|
||||
syncBacktestMarkers();
|
||||
let innerRaf = 0;
|
||||
const outerRaf = requestAnimationFrame(() => {
|
||||
innerRaf = requestAnimationFrame(syncBacktestMarkers);
|
||||
@@ -915,7 +924,7 @@ function App() {
|
||||
cancelAnimationFrame(outerRaf);
|
||||
if (innerRaf) cancelAnimationFrame(innerRaf);
|
||||
};
|
||||
}, [btMatchesChart, btSignals, btRunSeq, symbol, timeframe, appDefaults.btShowPrice, syncBacktestMarkers]);
|
||||
}, [btMatchesChart, btSignals, btRunSeq, symbol, timeframe, appDefaults.btShowPrice, applyBacktestMarkersWhenReady, syncBacktestMarkers]);
|
||||
|
||||
// ── 시뮬레이션 데이터 (Upbit 아닐 때) ──────────────────────────────────
|
||||
const [simBars, setSimBars] = useState<OHLCVBar[]>(() =>
|
||||
@@ -1716,12 +1725,14 @@ function App() {
|
||||
r.signals.length > 0
|
||||
) {
|
||||
const showPrice = appDefaults.btShowPrice;
|
||||
applyBacktestMarkersWhenReady({
|
||||
const payload = {
|
||||
symbol: runSymbol,
|
||||
timeframe: runTf,
|
||||
signals: r.signals,
|
||||
showPrice,
|
||||
});
|
||||
};
|
||||
btMarkerPayloadRef.current = payload;
|
||||
applyBacktestMarkersWhenReady(payload);
|
||||
}
|
||||
if (appDefaults.btAutoPopup) setShowBtResult(true);
|
||||
}
|
||||
@@ -1729,7 +1740,11 @@ function App() {
|
||||
onOpenBtSettings={() => setShowBtSettings(true)}
|
||||
onOpenBtResults={() => setShowBtResult(true)}
|
||||
hasBtResult={btMatchesChart}
|
||||
onClearBtMarkers={() => { btClear(); managerRef.current?.clearBacktestMarkers(); }}
|
||||
onClearBtMarkers={() => {
|
||||
btMarkerPayloadRef.current = null;
|
||||
btClear();
|
||||
managerRef.current?.clearBacktestMarkers();
|
||||
}}
|
||||
onToggleLiveStrategy={() => setShowLivePanel(v => !v)}
|
||||
liveStrategyActive={showLivePanel || monitoredMarkets.length > 0}
|
||||
/>
|
||||
@@ -2003,7 +2018,11 @@ function App() {
|
||||
<BacktestPanel
|
||||
stats={btStats}
|
||||
signalCount={btSignals.length}
|
||||
onClear={() => { btClear(); managerRef.current?.clearBacktestMarkers(); }}
|
||||
onClear={() => {
|
||||
btMarkerPayloadRef.current = null;
|
||||
btClear();
|
||||
managerRef.current?.clearBacktestMarkers();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -306,6 +306,7 @@ const TradingChart: React.FC<TradingChartProps> = ({
|
||||
m.resetPaneHeights(w.clientHeight);
|
||||
const fb = m.hasIchimoku() ? 28 : 0;
|
||||
m.setInitialVisibleRange(DISPLAY_COUNT, fb);
|
||||
if (delay === 1400) onDataLoaded?.();
|
||||
}, delay)
|
||||
);
|
||||
}, [applyPaneLayout, onDataLoaded, displayTimezone, timeframe, market]);
|
||||
|
||||
Reference in New Issue
Block a user