diff --git a/frontend/src/api/factor.ts b/frontend/src/api/factor.ts index 7dff52b..1e84057 100644 --- a/frontend/src/api/factor.ts +++ b/frontend/src/api/factor.ts @@ -153,3 +153,32 @@ export async function submitBatchEval(req: BatchEvalSubmit): Promise { const { data } = await apiClient.post<{ task_id: string }>('/factor/eval/submit', req) return data.task_id } + + +// —— 标的池(New 页三层输入) —— + +export interface UniversePool { + key: string + name: string + count: number +} + +export interface UniverseStock { + code: string + name: string +} + +export async function getUniversePools(): Promise { + const { data } = await apiClient.get('/factor/universe/pools') + return data +} + +export async function getUniversePool(key: string): Promise { + const { data } = await apiClient.get(`/factor/universe/pool/${key}`) + return data +} + +export async function searchUniverse(q: string): Promise { + const { data } = await apiClient.get('/factor/universe/search', { params: { q } }) + return data +} diff --git a/frontend/src/constants/factorSamples.ts b/frontend/src/constants/factorSamples.ts new file mode 100644 index 0000000..5e1185f --- /dev/null +++ b/frontend/src/constants/factorSamples.ts @@ -0,0 +1,40 @@ +/** 跨行业 30 只样本(详情页「生成 tears 报告」与 New 页标的池预设共用同一份) */ +export interface SampleStock { + code: string + name: string +} + +export const TEARS_SAMPLE: SampleStock[] = [ + { code: '600519', name: '贵州茅台' }, + { code: '000858', name: '五粮液' }, + { code: '600036', name: '招商银行' }, + { code: '601318', name: '中国平安' }, + { code: '000001', name: '平安银行' }, + { code: '600000', name: '浦发银行' }, + { code: '300750', name: '宁德时代' }, + { code: '002594', name: '比亚迪' }, + { code: '600276', name: '恒瑞医药' }, + { code: '000538', name: '云南白药' }, + { code: '600887', name: '伊利股份' }, + { code: '000651', name: '格力电器' }, + { code: '000333', name: '美的集团' }, + { code: '600690', name: '海尔智家' }, + { code: '000725', name: '京东方A' }, + { code: '002415', name: '海康威视' }, + { code: '600030', name: '中信证券' }, + { code: '601166', name: '兴业银行' }, + { code: '600028', name: '中国石化' }, + { code: '601857', name: '中国石油' }, + { code: '600585', name: '海螺水泥' }, + { code: '000625', name: '长安汽车' }, + { code: '601633', name: '长城汽车' }, + { code: '002352', name: '顺丰控股' }, + { code: '600104', name: '上汽集团' }, + { code: '601398', name: '工商银行' }, + { code: '600941', name: '中国移动' }, + { code: '300059', name: '东方财富' }, + { code: '002230', name: '科大讯飞' }, + { code: '601888', name: '中国中免' }, +] + +export const TEARS_SAMPLE_CODES = TEARS_SAMPLE.map((s) => s.code) diff --git a/frontend/src/views/factor/FactorPicker.vue b/frontend/src/views/factor/FactorPicker.vue new file mode 100644 index 0000000..b20dedb --- /dev/null +++ b/frontend/src/views/factor/FactorPicker.vue @@ -0,0 +1,136 @@ + + + + + diff --git a/frontend/src/views/factor/LeaderboardDetail.vue b/frontend/src/views/factor/LeaderboardDetail.vue index b8b7120..ba562d0 100644 --- a/frontend/src/views/factor/LeaderboardDetail.vue +++ b/frontend/src/views/factor/LeaderboardDetail.vue @@ -2,6 +2,7 @@ import { ref, onMounted, watch, nextTick, computed } from 'vue' import { useRoute, useRouter } from 'vue-router' import { getEvalDetail, submitFactor, type EvalDetail } from '@/api/factor' +import { TEARS_SAMPLE_CODES } from '@/constants/factorSamples' import { useChart } from '@/composables/useChart' import { darkTitle, darkTooltip, darkGrid, darkAxis, BRAND } from '@/utils/echartsDark' import { useFactorCompareStore } from '@/stores/factorCompare' @@ -51,12 +52,6 @@ function toggleCompare() { // —— 一键生成 tears(方案A):排行榜数据没有分层序列,tears 要跑一次 alphalens 分析 // (固定 30 只跨行业样本 × 近 2.5 年,分钟级),跑完结果页即新版 ECharts tears。 -const TEARS_SAMPLE_SYMBOLS = [ - '600519', '000858', '600036', '601318', '000001', '600000', '300750', '002594', - '600276', '000538', '600887', '000651', '000333', '600690', '000725', '002415', - '600030', '601166', '600028', '601857', '600585', '000625', '601633', '002352', - '600104', '601398', '600941', '300059', '002230', '601888', -] const TEARS_SAMPLE_SPAN = { start: '2024-01-01', end: '2026-06-30' } const tearsSubmitting = ref(false) @@ -66,7 +61,7 @@ async function generateTears() { tearsSubmitting.value = true try { const tid = await submitFactor({ - symbols: TEARS_SAMPLE_SYMBOLS, + symbols: TEARS_SAMPLE_CODES, factor_names: [detail.value.factor], start: TEARS_SAMPLE_SPAN.start, end: TEARS_SAMPLE_SPAN.end, diff --git a/frontend/src/views/factor/New.vue b/frontend/src/views/factor/New.vue index 4fa80d3..f760917 100644 --- a/frontend/src/views/factor/New.vue +++ b/frontend/src/views/factor/New.vue @@ -1,46 +1,56 @@ diff --git a/frontend/src/views/factor/Result.vue b/frontend/src/views/factor/Result.vue index 7dc6b13..1908d8e 100644 --- a/frontend/src/views/factor/Result.vue +++ b/frontend/src/views/factor/Result.vue @@ -1,4 +1,9 @@ + +