Files
easy-tdx/web-ui/src/types.ts
T
Justin Gu ff3476f83a feat(backtest): 回测结果对比页
选 2-4 个已完成的回测 task,叠加净值曲线 + 横向指标对比。

后端(最小增量):
- task_runner.list_recent(limit):返回最近 N 个任务摘要(LRU 倒序)
- GET /backtest/tasks?limit=20:任务摘要列表端点(不含完整 result)
- TaskSummary / TaskListResponse schema

前端(/compare 对比页):
- CompareView:左栏勾选已完成 task,右栏叠加对比
- CompareChart:多 task 净值叠加图(归一化为初始=1)
- CompareTable:多 task 指标横向对比表(8 项指标)
- 按 result 结构判断可对比性(仅单标的 BacktestResult 可对比)

复用现有 task_runner LRU 表,无新增存储。测试:823 passed(+2 列表端点)
2026-07-03 04:11:29 +08:00

230 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 后端 API 的 TypeScript 类型镜像。
// 与 src/easy_tdx/web/backtest_schemas.py 及 backtest router 的响应保持一致。
// 后端是唯一事实源;这里只做类型契约。
// ── 策略 schemaGET /api/v1/backtest/strategies ───────────────────────────
export type ParamType = 'int' | 'float' | 'bool' | 'str'
export interface ParamSchema {
name: string
type: ParamType
default: number | string | boolean
label: string
min_value?: number
max_value?: number
choices?: string[]
description?: string
}
export interface StrategySchema {
name: string
label: string
description: string
params: ParamSchema[]
}
export interface StrategiesResponse {
strategies: StrategySchema[]
count: number
}
// ── OHLCV 行情(GET /api/v1/bars) ────────────────────────────────────────────
export interface Bar {
datetime: string
open: number
high: number
low: number
close: number
vol: number
amount: number
}
export interface DataFrameResponse {
data: Record<string, unknown>[]
count: number
}
// ── 回测请求(POST /api/v1/backtest/run ─────────────────────────────────────
export type ExecutionMode = 'next_open' | 'next_close' | 'this_close' | 'worst' | 'best'
export type Category = 'DAY' | 'WEEK' | 'MONTH' | 'MIN_5' | 'MIN_15' | 'MIN_30' | 'MIN_60'
export interface BacktestRequest {
strategy: string
params?: Record<string, number | string | boolean>
cash?: number
commission?: number
min_commission?: number
stamp_tax?: number
slippage?: number
execution?: ExecutionMode
ohlcv?: Bar[]
symbol?: string
category?: Category
count?: number
}
// ── 回测结果 ──────────────────────────────────────────────────────────────────
export interface Performance {
total_return: number
annual_return: number
max_drawdown: number
max_dd_duration: number
sharpe: number
sortino: number
calmar: number
total_trades: number
win_trades: number
lose_trades: number
rejected_trades: number
win_rate: number
profit_factor: number
avg_win: number
avg_loss: number
max_win: number
max_loss: number
avg_holding_days: number
volatility: number
}
export interface EquityPoint {
datetime: string
cash: number
position_value: number
total: number
drawdown: number
drawdown_pct: number
}
export interface Trade {
datetime: string
direction: 'BUY' | 'SELL'
size: number
price: number
commission: number
slippage: number
pnl: number
rejected: boolean
}
export interface BacktestResult {
performance: Performance
equity_curve: EquityPoint[]
trades: Trade[]
positions: Record<string, unknown>[]
config: Record<string, unknown>
}
// ── 后台任务(POST /api/v1/backtest/run/async + GET /tasks/{id} ─────────────
export interface TaskSubmitResponse {
task_id: string
status: 'pending' | 'running'
}
export type TaskStatus = 'pending' | 'running' | 'done' | 'failed'
export interface TaskState {
task_id: string
status: TaskStatus
result: BacktestResult | PortfolioResult | OptimizeResult | null
error: string | null
description: string
elapsed: number
}
// ── 任务摘要(Phase 5 对比页) ────────────────────────────────────────────────
export interface TaskSummary {
task_id: string
status: TaskStatus
description: string
created_at: number
elapsed: number
}
export interface TaskListResponse {
tasks: TaskSummary[]
count: number
}
// ── 组合回测(Phase 3) ───────────────────────────────────────────────────────
export interface PortfolioBacktestRequest {
strategy: string
params?: Record<string, number | string | boolean>
cash?: number
commission?: number
slippage?: number
execution?: ExecutionMode
stocks: string[]
category?: Category
start_date?: string
end_date?: string
}
export interface PortfolioResult {
total_performance: {
total_return: number
annual_return: number
total_stocks: number
total_cash: number
}
individual_results: Record<string, BacktestResult>
equity_allocation: Record<string, number>
combined_equity: EquityPoint[]
}
// ── 参数网格寻优(Phase 4) ──────────────────────────────────────────────────
export interface OptimizeBacktestRequest {
strategy: string
cash?: number
commission?: number
slippage?: number
execution?: ExecutionMode
param_grid: Record<string, Array<number | string>>
ohlcv?: Bar[]
symbol?: string
category?: Category
count?: number
start_date?: string
end_date?: string
}
export interface GridPointResult {
params: Record<string, number | string>
total_return: number | null
sharpe: number | null
max_drawdown: number | null
total_trades: number
win_rate: number | null
profit_factor: number | null
}
export interface OptimizeHeatmap {
x_name: string
y_name: string
x: Array<number | string>
y: Array<number | string>
data: Array<[number, number, number | null]>
}
export interface OptimizeResult {
strategy: string
param_names: string[]
results: GridPointResult[]
best: GridPointResult | null
heatmap: OptimizeHeatmap | null
}
// ── 错误响应(后端 ApiErrorResponse) ─────────────────────────────────────────
export interface ApiError {
error: string
detail: string
}