feat(portfolio): strategy 字段全链透传(API→orchestrator→worker→runner_backtest + 前端选择器)
CI/CD / test (push) Successful in 10s
CI/CD / nas-deploy (push) Successful in 20s
CI/CD / nas-verify (push) Successful in 3s

后端: PortfolioBacktestRequest.strategy → submit_portfolio(strategy=) → spec →
portfolio_worker _build_argv --strategy(NAS local + Mac SSH 两分支)
前端: PortfolioBacktestReq.strategy? + 策略下拉(4选项) + 副标题动态 + onSubmit 透传
runner_backtest CLI 已支持 --strategy(choices 4 策略),本提交不动
This commit is contained in:
2026-08-01 23:01:26 +08:00
parent 5c5bd9d7bb
commit 7a14d7da82
5 changed files with 40 additions and 4 deletions
+1
View File
@@ -2,6 +2,7 @@ import { apiClient } from './client'
export interface PortfolioBacktestReq {
pool: string
strategy?: string
start_date: string
end_date: string
initial_cash: number
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { ref, reactive, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import type { EChartsCoreOption } from 'echarts'
import { useChart } from '@/composables/useChart'
@@ -28,6 +28,7 @@ let pollTimer: ReturnType<typeof setInterval> | null = null
const form = reactive({
pool: 'hs300_subset',
strategy: 'all_weather',
start: '2024-01-01',
end: '2024-02-29',
cash: 1_000_000,
@@ -39,6 +40,17 @@ const poolOptions = [
{ label: '全市场(慢,非 MVP)', value: 'all' },
]
const strategyOptions = [
{ label: '全天候轮动', value: 'all_weather' },
{ label: '牛熊动量', value: 'momentum_timing' },
{ label: '价值精选', value: 'value_selection' },
{ label: '小市值轮动', value: 'small_cap' },
]
const strategyLabel = computed(
() => strategyOptions.find((o) => o.value === form.strategy)?.label ?? form.strategy,
)
// 净值曲线
const equityEl = ref<HTMLDivElement>()
const { setOption: setEquityOption } = useChart(equityEl)
@@ -95,6 +107,7 @@ async function onSubmit(): Promise<void> {
try {
const tid = await postPortfolioBacktest({
pool: form.pool,
strategy: form.strategy,
start_date: form.start,
end_date: form.end,
initial_cash: form.cash,
@@ -150,7 +163,7 @@ async function onSubmit(): Promise<void> {
<div>
<h2 class="page-title">组合策略回测</h2>
<p class="page-subtitle">
BulletTrade + 全天候轮动策略 · 本地执行回测 · MVP 验证链路
BulletTrade + {{ strategyLabel }} · 本地执行回测 · MVP 验证链路
</p>
</div>
</div>
@@ -169,6 +182,17 @@ async function onSubmit(): Promise<void> {
</el-select>
<span class="muted form-hint">MVP 默认 HS300 子集(20-30 ),快速验证链路</span>
</el-form-item>
<el-form-item label="策略">
<el-select v-model="form.strategy" style="width: 320px">
<el-option
v-for="opt in strategyOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-select>
<span class="muted form-hint">选择回测策略</span>
</el-form-item>
<el-form-item label="开始日期">
<el-date-picker
v-model="form.start"