diff --git a/apps/web/app/(pages)/evaluation/page.tsx b/apps/web/app/(pages)/evaluation/page.tsx index da77630..69dde9c 100644 --- a/apps/web/app/(pages)/evaluation/page.tsx +++ b/apps/web/app/(pages)/evaluation/page.tsx @@ -4,88 +4,109 @@ import { Badge } from "@/components/shared/badge"; import { formatPct, formatScore } from "@/lib/format"; export default async function EvaluationPage() { - const data = await api.evaluation(); + try { + const data = await api.evaluation(); - return ( -
테마 적중률
-{formatPct(data.rollingMetrics.themeHitRate * 100)}
-주도주 적중률
-{formatPct(data.rollingMetrics.leaderHitRate * 100)}
-오탐 비율
-{formatPct(data.rollingMetrics.falsePositiveRate * 100)}
-갭페이드 실패
-{formatPct(data.rollingMetrics.gapFadeMissRate * 100)}
-{item.version}
-- {item.description} -
-종합 점수 {formatScore(item.score)}
-테마 적중률 {formatPct(item.themeHitRate * 100)}
-주도주 적중률 {formatPct(item.leaderHitRate * 100)}
-테마 적중률
+{formatPct(data.rollingMetrics.themeHitRate * 100)}
+주도주 적중률
+{formatPct(data.rollingMetrics.leaderHitRate * 100)}
+오탐 비율
+{formatPct(data.rollingMetrics.falsePositiveRate * 100)}
+갭 페이드 실패
+{formatPct(data.rollingMetrics.gapFadeMissRate * 100)}
+{item.role}
-{item.model}
+ +{item.version}
++ {item.description} +
+종합 점수 {formatScore(item.score)}
+테마 적중률 {formatPct(item.themeHitRate * 100)}
+주도주 적중률 {formatPct(item.leaderHitRate * 100)}
+{item.role}
+{item.model}
++ 평균 지연 {item.avgLatencyMs}ms | 평균 비용 ${item.avgCostUsd.toFixed(4)} +
- 평균 지연 {item.avgLatencyMs}ms | 평균 비용 ${item.avgCostUsd.toFixed(4)} -
-오류 메시지
+{message}
Window
-{data.windowLabel}
-- 현재 추론 규칙과 동일한 로직을 과거 구간에 그대로 적용합니다. -
-Hit Days
-- {data.aggregate.positiveHitDays} / {data.aggregate.daysAnalyzed} -
-- 상위 테마 주도주 평균 수익률이 양호 이상이었던 날짜 수입니다. -
-Avg Leader Return
-- {formatPct(data.aggregate.avgLeaderCloseReturnPct)} -
-- 상위 테마 기준 주도주 평균 종가 수익률입니다. -
-Window
+{data.windowLabel}
++ 현재 운영 중인 추론 규칙을 같은 방식으로 과거 구간에 재적용한 결과입니다. +
+Hit Days
++ {data.aggregate.positiveHitDays} / {data.aggregate.daysAnalyzed} +
++ 상위 테마 주도주의 평균 종가 수익률이 양호 이상이었던 날짜 수입니다. +
+Avg Leader Return
++ {formatPct(data.aggregate.avgLeaderCloseReturnPct)} +
++ 전체 리플레이 기준 주도주 평균 종가 수익률입니다. +
+Replay Day
-- 추론 기준 시각 {day.asOfLabel} / evidence hash {day.evidencePackHash.slice(0, 12)} -
+Replay Day
++ 추론 기준 시각 {day.asOfLabel} / evidence hash {day.evidencePackHash.slice(0, 12)} +
+KOSPI {formatPct(day.marketContext.kospiCloseReturnPct)}
+KOSDAQ {formatPct(day.marketContext.kosdaqCloseReturnPct)}
+{day.marketContext.summary}
+KOSPI {formatPct(day.marketContext.kospiCloseReturnPct)}
-KOSDAQ {formatPct(day.marketContext.kosdaqCloseReturnPct)}
-{day.marketContext.summary}
-{day.summary}
-{day.summary}
++ {theme.rationale} +
+주도주 평균 {formatPct(theme.actualOutcome.avgLeaderCloseReturnPct)}
++ 최고 수익 {theme.actualOutcome.bestStockLabel ?? "-"} + {theme.actualOutcome.bestCloseReturnPct !== null + ? ` / ${formatPct(theme.actualOutcome.bestCloseReturnPct)}` + : ""} +
- {theme.rationale} -
-주도주 평균 {formatPct(theme.actualOutcome.avgLeaderCloseReturnPct)}
-- 최고 수익 {theme.actualOutcome.bestStockLabel ?? "-"} - {theme.actualOutcome.bestCloseReturnPct !== null - ? ` / ${formatPct(theme.actualOutcome.bestCloseReturnPct)}` - : ""} -
예상 주도주 / 2등주
-- 주도주: {theme.leaders.map((item) => `${item.ticker} ${item.name}`).join(", ") || "-"} -
-- 2등주: {theme.secondTier.map((item) => `${item.ticker} ${item.name}`).join(", ") || "-"} -
-- 무효화 조건: {theme.invalidationCondition} -
-실제 종목 반응
-- {stock.ticker} {stock.name} +
예상 주도주 / 2등주
++ 주도주: {theme.leaders.map((item) => `${item.ticker} ${item.name}`).join(", ") || "-"} +
++ 2등주: {theme.secondTier.map((item) => `${item.ticker} ${item.name}`).join(", ") || "-"} +
++ 무효화 조건: {theme.invalidationCondition} +
+실제 종목 반응
++ {stock.ticker} {stock.name} +
++ 시가 갭 {formatPct(stock.openGapPct)} / 종가 수익률 {formatPct(stock.closeReturnPct)} / 장중 변화{" "} + {formatPct(stock.intradayMovePct)}
-- 시가 갭 {formatPct(stock.openGapPct)} / 종가 수익률 {formatPct(stock.closeReturnPct)} / - 장중 변화 {formatPct(stock.intradayMovePct)} -
-- 실제 종목 데이터를 불러오지 못했습니다. -
- )} + )) + ) : ( ++ 실제 종목 데이터를 불러오지 못했습니다. +
+ )} +근거 이벤트
-- {item.categoryLabel} +
근거 이벤트
++ {item.categoryLabel} +
+{item.title}
++ {item.summary}
-+ {item.sourceName} / {item.publishedAtLabel} +
+ + 원문 보기 +{item.title}
-- {item.summary} -
-- {item.sourceName} / {item.publishedAtLabel} -
- - 원문 보기 - -오류 메시지
+{message}
+