feat(paper): 双轨对账前端页——模拟盘菜单新增「双轨对账」:自动配对卡片(策略/实盘#vs影子#/日期/PASS徽标)+四指标卡(笔数全同/均价差bps/持仓逐只/净值月偏差,各带达标徽标)+成交对比表(symbol+side聚合vwap带符号bps,>10标红)+持仓对比表(数量差≠0标红)+日期选择查询;api getReconcilePairs+mock样例(路由须注册在/paper/{aid}前防吞);dev截图验证 [nas]
CI/CD / test (push) Successful in 11s
CI/CD / nas-deploy (push) Failing after 14m53s
CI/CD / nas-verify (push) Has been skipped

This commit is contained in:
2026-08-15 08:55:00 +08:00
parent 64b10fda41
commit d649d59c44
6 changed files with 280 additions and 0 deletions
+57
View File
@@ -160,3 +160,60 @@ export async function updatePaper(aid: number, req: PaperUpdateReq): Promise<{ u
const { data } = await apiClient.put(`/paper/${aid}`, req)
return data
}
// ===== 双轨对账(影子柜台 vs 实盘模拟,设计 §8.2)=====
export interface ReconcileTradeRow {
symbol: string
side: string
live_volume: number
shadow_volume: number
live_vwap: number | null
shadow_vwap: number | null
price_diff_bps: number | null
}
export interface ReconcilePositionRow {
symbol: string
live_volume: number
shadow_volume: number
volume_diff: number
}
export interface ReconcileReport {
date: string
live_account_id: number
shadow_account_id: number
trades: {
live_count: number
shadow_count: number
count_match: boolean
rows: ReconcileTradeRow[]
avg_price_diff_bps: number
pass_price: boolean
}
positions: { rows: ReconcilePositionRow[]; match: boolean }
nav: {
live_total: number | null
shadow_total: number | null
mtd_deviation_pct: number | null
pass_nav: boolean | null
live_mtd_return_pct?: number
shadow_mtd_return_pct?: number
note?: string
}
passed: boolean
}
export interface ReconcilePair {
live_account_id: number
shadow_account_id: number
strategy: string
report: ReconcileReport
}
export async function getReconcilePairs(date?: string): Promise<ReconcilePair[]> {
const { data } = await apiClient.get<{ pairs: ReconcilePair[] }>(
'/paper/reconcile', { params: date ? { date } : {} })
return data.pairs
}