fix(backtest): 结果页4个显示bug—成交枚举/时间/浮点精度/日志空
1. 交易详情方向/开平显原始枚举: Direction.LONG/Offset.OPEN → 买/卖、开仓/平仓/平今/平昨
(TradesTable 加 fmtDir/fmtOff, 方向带涨跌色)
2. 交易详情时间 2024-06-25T00:00:00+08:00 → 2024-06-25 (日内带时分则保留)
3. 每日收益浮点精度 0.6533000000054017 → 0.65 (toFixed2, 涨跌色), 日期去 00:00:00
4. 日志tab硬编码"暂无日志数据": 前端接 getLog(/task/:id/log) + 后端 cta_engine 加
stdout tee 把引擎 load/run/stats 输出落盘到 {task_id}.log (worker 进程内隔离)
→ 新回测日志 tab 显示真实引擎输出(2117字)
验证: 交易 买/开仓/2024-06-25, 收益 0.15, 日志 2117字真实内容
This commit is contained in:
@@ -3,7 +3,7 @@ import { ref, computed, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import {
|
||||
getResult, getEquityCurve, getDailyPnl, getTrades, getKline,
|
||||
getRelativeMetrics, getBenchmarkCurve, getRiskSeries,
|
||||
getRelativeMetrics, getBenchmarkCurve, getRiskSeries, getLog,
|
||||
type EquityPoint, type PnlPoint, type Trade, type KlineBar,
|
||||
type RelativeMetrics, type BenchmarkCurveData, type RiskSeriesData,
|
||||
} from '@/api/backtest'
|
||||
@@ -42,6 +42,7 @@ const equity = ref<EquityPoint[]>([])
|
||||
const pnl = ref<PnlPoint[]>([])
|
||||
const trades = ref<Trade[]>([])
|
||||
const kline = ref<KlineBar[]>([])
|
||||
const logText = ref('')
|
||||
|
||||
// statEntries is no longer used in the new layout but kept for potential future use
|
||||
// const statEntries = computed(() =>
|
||||
@@ -135,10 +136,32 @@ onMounted(async () => {
|
||||
kline.value = []
|
||||
}
|
||||
}
|
||||
try {
|
||||
logText.value = await getLog(taskId)
|
||||
} catch {
|
||||
logText.value = ''
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
// 每日收益格式化:浮点精度 → 2 位;日期去 00:00:00
|
||||
function fmtPnl(v: number | string): string {
|
||||
const n = typeof v === 'number' ? v : parseFloat(v)
|
||||
if (!Number.isFinite(n)) return String(v)
|
||||
return n.toFixed(2)
|
||||
}
|
||||
function fmtPnlClass(v: number | string): string {
|
||||
const n = typeof v === 'number' ? v : parseFloat(v)
|
||||
if (!Number.isFinite(n) || n === 0) return ''
|
||||
return n > 0 ? 'up' : 'down'
|
||||
}
|
||||
function fmtDate(d: string): string {
|
||||
if (!d) return ''
|
||||
const s = String(d).slice(0, 19).replace('T', ' ')
|
||||
return s.endsWith(' 00:00:00') ? s.slice(0, 10) : s
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -219,8 +242,12 @@ onMounted(async () => {
|
||||
<template #header><span class="section-title">每日收益</span></template>
|
||||
<div class="daily-pnl-section">
|
||||
<el-table :data="pnl" stripe size="small" empty-text="无数据">
|
||||
<el-table-column prop="date" label="日期" width="120" />
|
||||
<el-table-column prop="pnl" label="收益" width="120" />
|
||||
<el-table-column label="日期" width="140">
|
||||
<template #default="{ row }"><span class="mono">{{ fmtDate(row.date) }}</span></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="收益" width="120" align="right">
|
||||
<template #default="{ row }"><span class="mono" :class="fmtPnlClass(row.pnl)">{{ fmtPnl(row.pnl) }}</span></template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-card>
|
||||
@@ -230,7 +257,7 @@ onMounted(async () => {
|
||||
<el-tab-pane label="日志输出">
|
||||
<el-card>
|
||||
<template #header><span class="section-title">系统日志</span></template>
|
||||
<pre class="log-output">暂无日志数据</pre>
|
||||
<pre class="log-output">{{ logText || '暂无日志数据' }}</pre>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
Reference in New Issue
Block a user