| # |
+ 评级 |
策略 |
参数 |
总收益 |
@@ -275,6 +295,14 @@ function num(v: number | null | undefined, d = 2): string {
:class="{ best: i === 0 }"
>
{{ i + 1 }} |
+
+
+ |
{{ r.strategy_label }} |
{{ JSON.stringify(r.params) }} |
@@ -438,4 +466,7 @@ function num(v: number | null | undefined, d = 2): string {
font-size: 11px;
padding: 2px 8px;
}
+.grade-cell {
+ width: 56px;
+}
diff --git a/web-ui/src/views/PortfolioView.vue b/web-ui/src/views/PortfolioView.vue
index 530707a..675d3f1 100644
--- a/web-ui/src/views/PortfolioView.vue
+++ b/web-ui/src/views/PortfolioView.vue
@@ -5,11 +5,13 @@ import { computed, nextTick, onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import EquityChart from '../components/EquityChart.vue'
+import GradeDetails from '../components/GradeDetails.vue'
import PortfolioCompareChart from '../components/PortfolioCompareChart.vue'
import PortfolioSummaryTable from '../components/PortfolioSummaryTable.vue'
import StocksPicker from '../components/StocksPicker.vue'
import StrategyPicker from '../components/StrategyPicker.vue'
import { formatError, saveStrategy } from '../api'
+import { gradePortfolio } from '../grading'
import type { Category, ExecutionMode } from '../types'
import { useBacktestStore } from '../stores/backtest'
@@ -98,6 +100,12 @@ const strategyLabel = computed(
() => store.strategies.find((s) => s.name === strategy.value)?.label ?? strategy.value,
)
+// 组合评级:从 combined_equity 重算夏普/卡玛/波动率等(组合级净值算不出胜率/利润因子),
+// 用 5 维度评分。净值点数过少(< 60 个交易日)视为样本不足。
+const grade = computed(() =>
+ store.portfolioResult ? gradePortfolio(store.portfolioResult) : null,
+)
+
function openSaveForm() {
saveName.value = `${strategyLabel.value} · 组合${stocks.value.length}只`
saveTags.value = ''
@@ -227,6 +235,11 @@ async function onSave() {
{{ saveMsg }}
+
+
组合整体绩效
diff --git a/web-ui/tsconfig.app.json b/web-ui/tsconfig.app.json
index d72aa75..12e7039 100644
--- a/web-ui/tsconfig.app.json
+++ b/web-ui/tsconfig.app.json
@@ -11,5 +11,6 @@
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true
},
- "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
+ "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/**", "src/**/*.test.ts", "scripts/**"]
}
|