From 94e1b59ec1438554c1022ac444d1ebad7c3aab4a Mon Sep 17 00:00:00 2001 From: claude_dev Date: Fri, 14 Aug 2026 09:18:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20K=E7=BA=BF=E5=91=A8=E6=9C=9F?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E7=BB=9F=E4=B8=80=E5=85=B1=E4=BA=AB=E5=B8=B8?= =?UTF-8?q?=E9=87=8F:=E5=88=97=E5=85=A8miniQMT=E6=88=90=E5=93=81K=E7=BA=BF?= =?UTF-8?q?(1m~60m/=E6=97=A5/=E5=91=A8/=E6=9C=88,=E5=91=A8=E6=9C=88?= =?UTF-8?q?=E7=94=B1=E6=97=A5=E7=BA=BF=E5=90=88=E6=88=90),=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E6=97=A5=E7=BA=BF;=E6=A8=A1=E6=8B=9F=E7=9B=98/?= =?UTF-8?q?=E5=AE=9E=E7=9B=98/=E7=AD=96=E7=95=A5=E5=AE=9E=E4=BE=8B?= =?UTF-8?q?=E4=B8=89=E8=A1=A8=E5=8D=95=E5=90=8C=E6=BA=90;=E6=A0=87?= =?UTF-8?q?=E6=B3=A8=E5=9B=9E=E6=94=BE=E6=95=B0=E6=8D=AE=E5=8F=AF=E7=94=A8?= =?UTF-8?q?=E6=80=A7(d/15m=E6=9C=AC=E5=9C=B0=E6=9C=89)=20[nas]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/intervals.ts | 28 ++++++++++++++++++++ frontend/src/views/live/New.vue | 12 ++++++--- frontend/src/views/paper/New.vue | 20 ++++++++------ frontend/src/views/strategy/InstanceEdit.vue | 15 ++++++----- 4 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 frontend/src/constants/intervals.ts diff --git a/frontend/src/constants/intervals.ts b/frontend/src/constants/intervals.ts new file mode 100644 index 0000000..2b494f2 --- /dev/null +++ b/frontend/src/constants/intervals.ts @@ -0,0 +1,28 @@ +// K 线周期选项(全局共享)。 +// 来源=miniQMT(xtdata)成品K线:订阅时直接指明周期,QMT 端已合成好,无需自己从 tick 拼。 +// 默认日线;策略/实例可自行改。 +// replayOk=本地库有该周期历史数据(回放/回测可用,当前 d/15m); +// 其余周期影子柜台实时订阅可用,回放待本地补数据。 +export interface IntervalOption { + label: string + value: string + matchHint?: string + replayOk?: boolean +} + +export const DEFAULT_INTERVAL = 'd' + +export const INTERVAL_OPTIONS: IntervalOption[] = [ + { label: '日线', value: 'd', matchHint: '每日 1 个撮合点', replayOk: true }, + { label: '60 分钟', value: '60m' }, + { label: '30 分钟', value: '30m' }, + { label: '15 分钟', value: '15m', matchHint: '每日约 16 个撮合点(每根 15m K线撮合)', replayOk: true }, + { label: '5 分钟', value: '5m' }, + { label: '1 分钟', value: '1m' }, + { label: '周线', value: 'w', matchHint: '由日线合成' }, + { label: '月线', value: 'mon', matchHint: '由日线合成' }, +] + +export function intervalLabel(v: string): string { + return INTERVAL_OPTIONS.find((o) => o.value === v)?.label ?? v +} diff --git a/frontend/src/views/live/New.vue b/frontend/src/views/live/New.vue index 7840a46..21ca259 100644 --- a/frontend/src/views/live/New.vue +++ b/frontend/src/views/live/New.vue @@ -4,6 +4,7 @@ import { useRoute, useRouter } from 'vue-router' import { ElMessage } from 'element-plus' import { createLive, type LiveCreateRequest } from '@/api/live' import { apiClient } from '@/api/client' +import { INTERVAL_OPTIONS } from '@/constants/intervals' const route = useRoute() const router = useRouter() @@ -58,7 +59,7 @@ const form = ref({ size: 100, forbid_short: true, }, - interval: '15m', + interval: 'd', initial_capital: 1_000_000, connect_wait_sec: 10, init_wait_sec: 60, @@ -206,8 +207,13 @@ async function onSubmit(): Promise { 可只写 6 位代码,自动补交易所后缀(.SSE / .SZSE) - - 如 15m / 1m / d + + + {{ o.label }} + 影子柜台实时可用·回放暂无本地数据 + + + miniQMT 成品K线,默认日线 diff --git a/frontend/src/views/paper/New.vue b/frontend/src/views/paper/New.vue index b9e5f35..cfdea17 100644 --- a/frontend/src/views/paper/New.vue +++ b/frontend/src/views/paper/New.vue @@ -5,6 +5,7 @@ import { ElMessage } from 'element-plus' import { createPaper, type PaperCreate } from '@/api/paper' import { apiClient } from '@/api/client' import { getStrategies, type StrategyItem } from '@/api/strategy' +import { INTERVAL_OPTIONS } from '@/constants/intervals' const route = useRoute() const router = useRouter() @@ -85,10 +86,6 @@ const modes = [ { value: 'replay', label: '回放', desc: '历史重放,立即出结果' }, { value: 'live', label: '实走', desc: '每日定时 step,长期跟踪' }, ] -const intervals = [ - { value: 'd', label: '日频' }, - { value: '15m', label: '15 分钟' }, -] const sessions = [ { value: 'next_open', label: '次日开盘', desc: '收盘型信号,T+1 开盘撮合' }, { value: 'current_close', label: '当日收盘', desc: '尾盘型信号,当日收盘撮合' }, @@ -209,10 +206,17 @@ function onSymbols(v: string): void { -
频率
- - {{ i.label }} - +
K 线周期
+ + + {{ i.label }} + 影子柜台实时可用·回放暂无本地数据 + + +
+ {{ INTERVAL_OPTIONS.find(o => o.value === form.interval)?.matchHint || (form.interval === 'd' ? '' : '分钟级周期需标的分钟数据') }} +
diff --git a/frontend/src/views/strategy/InstanceEdit.vue b/frontend/src/views/strategy/InstanceEdit.vue index 0cb84ba..bfd377d 100644 --- a/frontend/src/views/strategy/InstanceEdit.vue +++ b/frontend/src/views/strategy/InstanceEdit.vue @@ -3,6 +3,7 @@ import { ref, reactive, computed, onMounted, watch } from 'vue' import { useRoute, useRouter } from 'vue-router' import { ElMessage, ElMessageBox } from 'element-plus' import { getParams } from '@/api/strategy' +import { INTERVAL_OPTIONS } from '@/constants/intervals' import { apiClient } from '@/api/client' interface CodeFile { @@ -49,10 +50,7 @@ const POOL_OPTIONS = [ { label: '中证2000', value: 'ZZ2000' }, { label: '全市场', value: 'ALL' }, ] -const INTERVAL_OPTIONS = [ - { label: '日线', value: 'd', matchHint: '每日 1 个撮合点' }, - { label: '15 分钟', value: '15m', matchHint: '每日约 16 个撮合点(每根 15m K线撮合)' }, -] +// miniQMT 成品K线周期全量选项(共享常量,默认日线) const SESSION_OPTIONS = [ { label: '下一根 K线 · 开盘价(防未来函数,推荐)', value: 'next_open', dayOnly: false }, { label: '当前 K线 · 收盘价', value: 'current_close', dayOnly: false }, @@ -220,9 +218,12 @@ async function onDelete(): Promise { - - {{ o.label }} - + + + {{ o.label }} + 影子柜台实时可用·回放暂无本地数据 + + 撮合频率 = 精度 · {{ matchHint }}