실시간 차트 백테스팅 결과 인쇄 기능 적용

This commit is contained in:
Macbook
2026-06-03 12:19:03 +09:00
parent ee7b1a6123
commit ba592b0789
2 changed files with 94 additions and 14 deletions
+39 -14
View File
@@ -111,7 +111,9 @@ import {
import { NotifyTopMenuBar, ChartToolbarNotify } from './components/NotifyUiBindings';
import { AppNotificationLayer } from './components/AppNotificationLayer';
import BacktestSettingsModal from './components/BacktestSettingsModal';
import { BacktestResultModal } from './components/BacktestResultModal';
import BacktestAnalysisReportModal from './components/backtest/BacktestAnalysisReportModal';
import { buildChartBacktestReportModel } from './utils/backtestReportModel';
import { fmtListTimestamp } from './utils/backtestUiUtils';
const DashboardPage = lazy(() => import('./components/DashboardPage'));
const StrategyPage = lazy(() => import('./components/StrategyPage'));
@@ -760,6 +762,7 @@ function App() {
const [showBtSettings, setShowBtSettings] = useState(false);
const [showBtResult, setShowBtResult] = useState(false);
const [btStrategyName, setBtStrategyName] = useState('전략');
const [btReportCreatedAt, setBtReportCreatedAt] = useState<string | undefined>();
/** 현재 차트와 일치하는 백테스팅 결과만 UI·마커에 반영 */
const btMatchesChart = useMemo(
@@ -1228,6 +1231,34 @@ function App() {
const barsMarket = useUpbit ? upbitBarsMarket : symbol;
barsMarketRef.current = barsMarket;
const chartBtReportModel = useMemo(() => {
if (!btMatchesChart) return null;
const reportSymbol = btSymbol ?? symbol;
const reportTf = btTimeframe ?? timeframe;
return buildChartBacktestReportModel({
analysis: btAnalysis,
stats: btStats,
signals: btSignals,
strategyName: btStrategyName,
symbol: reportSymbol,
timeframe: reportTf,
barCount: bars.length,
createdAt: btReportCreatedAt,
});
}, [
btMatchesChart,
btAnalysis,
btStats,
btSignals,
btStrategyName,
btSymbol,
btTimeframe,
symbol,
timeframe,
bars.length,
btReportCreatedAt,
]);
/** 종목·타임프레임 전환 시 이전 틱 버퍼·실시간 허용 플래그 초기화 (paint 전에 실행) */
useLayoutEffect(() => {
chartLiveReadyRef.current = false;
@@ -2315,6 +2346,7 @@ function App() {
};
btMarkerPayloadRef.current = payload;
applyBacktestMarkersWhenReady(payload);
setBtReportCreatedAt(fmtListTimestamp(new Date().toISOString()));
}
if (appDefaults.btAutoPopup) setShowBtResult(true);
}
@@ -2677,19 +2709,12 @@ function App() {
/>
)}
{/* 백테스팅 결과 모달 */}
{showBtResult && (
<BacktestResultModal
analysis={btAnalysis ?? null}
stats={btStats ?? null}
signals={btSignals}
strategyName={btStrategyName}
symbol={symbol}
timeframe={timeframe}
barCount={bars.length}
onClose={() => setShowBtResult(false)}
/>
)}
{/* 백테스팅 결과 — 투자분석 상세 레포트 (인쇄·PDF) */}
<BacktestAnalysisReportModal
open={showBtResult && chartBtReportModel != null}
onClose={() => setShowBtResult(false)}
model={chartBtReportModel}
/>
{/* 시리즈 클릭/호버 컨텍스트 툴바 */}
{ctxToolbar && (() => {