분석 레포트 화면 수정

This commit is contained in:
Macbook
2026-06-07 17:43:22 +09:00
parent 7ec754770d
commit 5928599fd0
11 changed files with 1802 additions and 187 deletions
@@ -4,7 +4,7 @@
* BacktestDashboard — 카드 기반 대시보드 (재사용 가능)
* BacktestResultModal — 드래그 팝업으로 Dashboard를 감싸는 래퍼
*/
import React, { useState } from 'react';
import React from 'react';
import type { BacktestAnalysis, BacktestSignal, BacktestStats } from '../utils/backendApi';
import { useDraggablePanel } from '../hooks/useDraggablePanel';
import { repairUtf8Mojibake } from '../utils/textEncoding';
@@ -21,6 +21,7 @@ import {
CompareBar,
} from './shared/analysisDashboardUi';
import { analysisMethodLabel } from '../utils/analysisMethodLabels';
import BacktestSignalTable from './backtest/BacktestSignalTable';
const fmtDate = (ts: number) => {
const d = new Date(ts * 1000);
@@ -55,17 +56,12 @@ export interface BacktestDashboardProps {
createdAt?: string;
/** 레포트·PDF — 시그널 전체 표시·인쇄용 레이아웃 */
reportMode?: boolean;
/** false — 거래 시그널 섹션 숨김 (별도 패널에 표시) */
hideSignals?: boolean;
}
// ── 시그널 타입 ───────────────────────────────────────────────────────────
const SIG_LABEL: Record<string, string> = {
BUY:'매수', SELL:'매도', SHORT_ENTRY:'공매도', SHORT_EXIT:'공매도청산', PARTIAL_SELL:'분할매도',
};
const SIG_COLOR: Record<string, string> = {
BUY:'brd-sig-buy', SELL:'brd-sig-sell', SHORT_ENTRY:'brd-neg', SHORT_EXIT:'brd-pos', PARTIAL_SELL:'brd-warn',
};
// ══════════════════════════════════════════════════════════════════════════
// BacktestDashboard — 메인 대시보드 컴포넌트 (재사용 가능)
// ══════════════════════════════════════════════════════════════════════════
@@ -73,9 +69,8 @@ const SIG_COLOR: Record<string, string> = {
export function BacktestDashboard({
analysis, signals, strategyName, symbol, timeframe, barCount, createdAt,
reportMode = false,
hideSignals = false,
}: BacktestDashboardProps) {
const [sigExpanded, setSigExpanded] = useState(reportMode);
const a = analysis;
if (!a) {
return (
@@ -86,7 +81,6 @@ export function BacktestDashboard({
);
}
const sigLimit = reportMode || sigExpanded ? signals.length : 8;
const periodStr = signals.length >= 2
? `${fmtDate(signals[0].time)} ~ ${fmtDate(signals[signals.length-1].time)}`
: `${barCount}`;
@@ -276,54 +270,11 @@ export function BacktestDashboard({
</div>
{/* ── Row 4: 거래 시그널 목록 ── */}
<div className="brd-row">
<div className="brd-card brd-card--full">
<SectionTitle icon="📋" title="거래 시그널" right={
<span className="brd-section-count">{signals.length}</span>
}/>
{signals.length === 0 ? (
<div className="brd-empty-msg"> .</div>
) : (
<>
<div className="brd-sig-scroll">
<table className="brd-sig-table">
<thead>
<tr>
<th style={{width:36}}>#</th>
<th></th>
<th></th>
<th style={{textAlign:'right'}}></th>
<th style={{textAlign:'center',width:50}}>#</th>
</tr>
</thead>
<tbody>
{signals.slice(0, sigLimit).map((s, i) => (
<tr key={i} className={i % 2 === 0 ? 'brd-sig-even' : ''}>
<td style={{textAlign:'center',color:'var(--text3)'}}>{i+1}</td>
<td style={{fontVariantNumeric:'tabular-nums'}}>{fmtDate(s.time)}</td>
<td>
<span className={`brd-sig-badge ${SIG_COLOR[s.type] ?? ''}`}>
{repairUtf8Mojibake(SIG_LABEL[s.type] ?? s.type)}
</span>
</td>
<td style={{textAlign:'right',fontVariantNumeric:'tabular-nums',fontWeight:600}}>
{Math.round(s.price).toLocaleString()}
</td>
<td style={{textAlign:'center',color:'var(--text3)'}}>{s.barIndex}</td>
</tr>
))}
</tbody>
</table>
</div>
{!reportMode && signals.length > 8 && (
<button className="brd-expand-btn" onClick={() => setSigExpanded(v => !v)}>
{sigExpanded ? '▲ 접기' : `▼ 전체 보기 (${signals.length}건)`}
</button>
)}
</>
)}
{!hideSignals && (
<div className="brd-row">
<BacktestSignalTable signals={signals} expanded={reportMode} />
</div>
</div>
)}
</div>
);