백테스팅 분석결과 레포트 출력
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import type { BacktestAnalysis, BacktestSignal, BacktestStats } from '../utils/backendApi';
|
||||
import { useDraggablePanel } from '../hooks/useDraggablePanel';
|
||||
import { repairUtf8Mojibake } from '../utils/textEncoding';
|
||||
|
||||
// ── 포맷 유틸 ────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -60,6 +61,8 @@ export interface BacktestDashboardProps {
|
||||
timeframe: string;
|
||||
barCount: number;
|
||||
createdAt?: string;
|
||||
/** 레포트·PDF — 시그널 전체 표시·인쇄용 레이아웃 */
|
||||
reportMode?: boolean;
|
||||
}
|
||||
|
||||
// ── 섹션 제목 ─────────────────────────────────────────────────────────────
|
||||
@@ -177,8 +180,9 @@ const SIG_COLOR: Record<string, string> = {
|
||||
|
||||
export function BacktestDashboard({
|
||||
analysis, signals, strategyName, symbol, timeframe, barCount, createdAt,
|
||||
reportMode = false,
|
||||
}: BacktestDashboardProps) {
|
||||
const [sigExpanded, setSigExpanded] = useState(false);
|
||||
const [sigExpanded, setSigExpanded] = useState(reportMode);
|
||||
|
||||
const a = analysis;
|
||||
if (!a) {
|
||||
@@ -190,7 +194,7 @@ export function BacktestDashboard({
|
||||
);
|
||||
}
|
||||
|
||||
const sigLimit = sigExpanded ? signals.length : 8;
|
||||
const sigLimit = reportMode || sigExpanded ? signals.length : 8;
|
||||
const periodStr = signals.length >= 2
|
||||
? `${fmtDate(signals[0].time)} ~ ${fmtDate(signals[signals.length-1].time)}`
|
||||
: `${barCount}봉`;
|
||||
@@ -198,12 +202,12 @@ export function BacktestDashboard({
|
||||
const sharpeLevel = a.sharpeRatio >= 2 ? '탁월' : a.sharpeRatio >= 1 ? '우수' : a.sharpeRatio >= 0 ? '보통' : '미흡';
|
||||
|
||||
return (
|
||||
<div className="brd-dashboard">
|
||||
<div className={`brd-dashboard${reportMode ? ' brd-dashboard--report' : ''}`}>
|
||||
|
||||
{/* ── 대시보드 헤더 ── */}
|
||||
<div className="brd-dash-header">
|
||||
<div className="brd-dash-header-left">
|
||||
<div className="brd-dash-strategy">{strategyName}</div>
|
||||
<div className="brd-dash-strategy">{repairUtf8Mojibake(strategyName)}</div>
|
||||
<div className="brd-dash-meta">
|
||||
<span className="brd-dash-badge">{symbol}</span>
|
||||
<span className="brd-dash-badge">{timeframe}</span>
|
||||
@@ -211,12 +215,12 @@ export function BacktestDashboard({
|
||||
{createdAt && <span className="brd-dash-badge brd-dash-badge--time">실행 {fmtDateStr(createdAt)}</span>}
|
||||
</div>
|
||||
</div>
|
||||
<div className="brd-dash-header-kpi">
|
||||
<div className="brd-dash-big-kpi">
|
||||
<div className={`brd-dash-header-kpi${reportMode ? ' brd-dash-header-kpi--report' : ''}`}>
|
||||
<div className={`brd-dash-big-kpi${reportMode ? ' brd-dash-big-kpi--report' : ''}`}>
|
||||
<div className={`brd-dash-big-val ${colorCls(a.totalReturnPct)}`}>{pct(a.totalReturnPct)}</div>
|
||||
<div className="brd-dash-big-label">총 수익률</div>
|
||||
</div>
|
||||
<div className="brd-dash-big-kpi">
|
||||
<div className={`brd-dash-big-kpi${reportMode ? ' brd-dash-big-kpi--report' : ''}`}>
|
||||
<div className={`brd-dash-big-val ${colorCls(a.finalEquity - a.initialCapital)}`}>
|
||||
{wonFmt(a.finalEquity)}
|
||||
</div>
|
||||
@@ -390,7 +394,7 @@ export function BacktestDashboard({
|
||||
<td style={{fontVariantNumeric:'tabular-nums'}}>{fmtDate(s.time)}</td>
|
||||
<td>
|
||||
<span className={`brd-sig-badge ${SIG_COLOR[s.type] ?? ''}`}>
|
||||
{SIG_LABEL[s.type] ?? s.type}
|
||||
{repairUtf8Mojibake(SIG_LABEL[s.type] ?? s.type)}
|
||||
</span>
|
||||
</td>
|
||||
<td style={{textAlign:'right',fontVariantNumeric:'tabular-nums',fontWeight:600}}>
|
||||
@@ -402,7 +406,7 @@ export function BacktestDashboard({
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{signals.length > 8 && (
|
||||
{!reportMode && signals.length > 8 && (
|
||||
<button className="brd-expand-btn" onClick={() => setSigExpanded(v => !v)}>
|
||||
{sigExpanded ? '▲ 접기' : `▼ 전체 보기 (${signals.length}건)`}
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user