feat(frontend): 终端化重构+策略管理(代码→实例→4运行)+撮合设计+回测参数 [nas]
CI/CD / test (push) Successful in 18s
CI/CD / nas-deploy (push) Failing after 17s
CI/CD / nas-verify (push) Has been skipped

- 终端化: 科幻色板(tokens/EP/reset/chips/echarts)+Layout(Cmd+K/时钟/状态灯)+mock全接口+Dashboard/Result/Monitor样板+6图表配色
- 策略管理: 策略库三层(代码→实例→4运行)+新建策略(组合/CTA模板+Monaco)+在线代码编辑(Monaco)+实例CRUD(参数反射/标的池type切/interval/match_session)
- 实例→运行关联: backtest/paper/live New页读instance预填
- 撮合设计: match_session(下一根K线开盘/收盘/集合竞价)+interval定频率+实走限日线/分钟走miniQMT
- 回测参数: 基准下拉+日期默认1年localStorage记忆+滑点/手续费UI
- 账户管理页+命名重整(模拟盘/实盘,消除撞名)
- spec §11-13(菜单/策略管理/撮合设计) + Monaco编辑器 + 策略实例删除/编辑入口 + 列表实例列
This commit is contained in:
2026-08-12 23:23:23 +08:00
parent 58b5d08280
commit 5c8a7e12c6
45 changed files with 3935 additions and 459 deletions
@@ -0,0 +1,544 @@
<title>三国量化 · 终端化重构提案</title>
<style>
:root{
--void:#05080d; --panel:#0a0f17; --panel-2:#0d141f; --panel-3:#111a27;
--grid:#15212f; --grid-2:#1d2c3d;
--cyan:#00e5ff; --cyan-dim:#0093a8; --cyan-glow:rgba(0,229,255,.14);
--amber:#ffb000; --amber-dim:#8a5f00; --amber-glow:rgba(255,176,0,.12);
--ink:#d4e4f0; --ink-2:#8aa0b5; --ink-3:#56697c;
--up:#ff4d5e; --down:#2ee68a;
--danger:#ff4d5e; --warn:#ffb000; --ok:#2ee68a;
--mono:ui-monospace,'SF Mono','JetBrains Mono',Menlo,Consolas,monospace;
--sans:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0;background:var(--void);color:var(--ink);font-family:var(--sans);font-size:14px;line-height:1.55;-webkit-font-smoothing:antialiased}
body{
background-image:
linear-gradient(var(--grid) 1px,transparent 1px),
linear-gradient(90deg,var(--grid) 1px,transparent 1px);
background-size:48px 48px;
background-position:-1px -1px;
}
a{color:var(--cyan);text-decoration:none}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.wrap{max-width:1320px;margin:0 auto;padding:0 28px 80px}
/* ── top status bar ── */
.topbar{position:sticky;top:0;z-index:50;background:rgba(5,8,13,.92);backdrop-filter:blur(8px);border-bottom:1px solid var(--grid-2);box-shadow:0 0 0 1px var(--void),0 1px 24px rgba(0,229,255,.05)}
.topbar-in{max-width:1320px;margin:0 auto;padding:0 28px;height:46px;display:flex;align-items:center;gap:18px}
.brand{display:flex;align-items:center;gap:10px}
.brand-mark{width:24px;height:24px;display:grid;place-items:center;background:var(--cyan);color:var(--void);font-family:var(--mono);font-weight:800;font-size:11px;letter-spacing:.5px}
.brand-name{font-family:var(--mono);font-size:13px;font-weight:700;letter-spacing:.6px;color:var(--ink)}
.brand-sub{font-family:var(--mono);font-size:11px;color:var(--cyan);letter-spacing:1.5px;text-transform:uppercase}
.topbar-sep{width:1px;height:18px;background:var(--grid-2)}
.crumb{font-family:var(--mono);font-size:12px;color:var(--ink-3)}
.crumb b{color:var(--ink-2);font-weight:500}
.topbar-right{margin-left:auto;display:flex;align-items:center;gap:16px;font-family:var(--mono);font-size:11px;color:var(--ink-3)}
.lamp{display:inline-flex;align-items:center;gap:6px}
.dot{width:7px;height:7px;border-radius:50%;background:var(--ok);box-shadow:0 0 8px var(--ok)}
.dot.pulse{animation:pulse 1.8s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1;box-shadow:0 0 8px var(--ok)}50%{opacity:.35;box-shadow:0 0 2px var(--ok)}}
.cmdk{display:inline-flex;align-items:center;gap:6px;padding:3px 8px;border:1px solid var(--grid-2);color:var(--ink-2)}
.cmdk kbd{font-family:var(--mono);font-size:10px;color:var(--cyan);border:1px solid var(--grid-2);padding:0 4px}
/* ── section frame ── */
.sec{margin-top:56px}
.sec-head{display:flex;align-items:baseline;gap:14px;margin-bottom:20px;border-bottom:1px solid var(--grid);padding-bottom:12px}
.sec-no{font-family:var(--mono);font-size:12px;color:var(--cyan);letter-spacing:2px}
.sec-title{font-family:var(--mono);font-size:20px;font-weight:700;color:var(--ink);letter-spacing:.5px;margin:0}
.sec-desc{margin-left:auto;font-size:12px;color:var(--ink-3);font-family:var(--mono)}
/* ── hero ── */
.hero{padding:64px 0 8px}
.hero-tag{font-family:var(--mono);font-size:11px;color:var(--cyan);letter-spacing:3px;text-transform:uppercase;margin-bottom:18px}
.hero h1{font-family:var(--mono);font-weight:800;font-size:54px;line-height:1.05;letter-spacing:-1px;margin:0 0 18px;color:var(--ink);text-wrap:balance}
.hero h1 .accent{color:var(--cyan)}
.hero h1 .amber{color:var(--amber)}
.hero p.lead{font-size:16px;color:var(--ink-2);max-width:62ch;margin:0 0 28px;line-height:1.7}
.hero-meta{display:flex;gap:0;border:1px solid var(--grid-2);background:var(--panel);max-width:780px}
.hero-meta>div{flex:1;padding:16px 20px;border-right:1px solid var(--grid)}
.hero-meta>div:last-child{border-right:none}
.hm-k{font-family:var(--mono);font-size:10px;color:var(--ink-3);letter-spacing:1.5px;text-transform:uppercase;margin-bottom:8px}
.hm-v{font-family:var(--mono);font-size:15px;color:var(--ink)}
.hm-v .arr{color:var(--cyan)}
/* ── generic panels ── */
.panel{background:var(--panel);border:1px solid var(--grid-2);position:relative}
.panel-head{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--grid);background:var(--panel-2)}
.panel-head .corner{color:var(--cyan);font-family:var(--mono);font-size:10px}
.panel-head .pt{font-family:var(--mono);font-size:12px;color:var(--ink);letter-spacing:.5px;font-weight:600}
.panel-head .pid{margin-left:auto;font-family:var(--mono);font-size:10px;color:var(--ink-3);letter-spacing:1px}
/* ── §1 diagnosis ── */
.diag-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
.diag{padding:18px 20px;background:var(--panel);border:1px solid var(--grid-2);border-left:2px solid var(--danger)}
.diag.k{border-left-color:var(--warn)}
.diag.g{border-left-color:var(--cyan)}
.diag h4{margin:0 0 6px;font-family:var(--mono);font-size:13px;color:var(--ink);letter-spacing:.3px}
.diag p{margin:0;font-size:13px;color:var(--ink-2);line-height:1.6}
.diag .tag{display:inline-block;font-family:var(--mono);font-size:10px;padding:1px 6px;margin-bottom:8px;letter-spacing:1px;border:1px solid currentColor}
.tag.dg{color:var(--danger)} .tag.wn{color:var(--warn)} .tag.cy{color:var(--cyan)}
/* ── §2 visual language ── */
.lang-grid{display:grid;grid-template-columns:1.2fr 1fr;gap:14px}
.swatches{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--grid-2);border:1px solid var(--grid-2)}
.sw{padding:16px;display:flex;flex-direction:column;gap:8px;min-height:96px;justify-content:flex-end}
.sw .hex{font-family:var(--mono);font-size:11px;letter-spacing:.5px}
.sw .nm{font-family:var(--mono);font-size:11px;opacity:.8}
.type-card{padding:20px}
.type-row{display:flex;align-items:baseline;justify-content:space-between;gap:16px;padding:14px 0;border-bottom:1px dashed var(--grid)}
.type-row:last-child{border-bottom:none}
.type-l{font-family:var(--mono);font-size:10px;color:var(--ink-3);letter-spacing:1.5px;text-transform:uppercase}
.t-disp{font-family:var(--mono);font-size:30px;font-weight:800;color:var(--ink);letter-spacing:-.5px}
.t-body{font-size:15px;color:var(--ink)}
.t-data{font-family:var(--mono);font-size:22px;color:var(--amber);font-variant-numeric:tabular-nums}
.lamprow{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--grid-2);border:1px solid var(--grid-2);margin-top:14px}
.lampcell{background:var(--panel);padding:14px;display:flex;align-items:center;gap:10px;font-family:var(--mono);font-size:11px;color:var(--ink-2)}
.lampcell .d{width:8px;height:8px;border-radius:50%}
/* ── §3 mockup (hero moment) ── */
.mockup{border:1px solid var(--grid-2);background:var(--panel);box-shadow:0 0 0 1px var(--void),0 30px 80px -20px rgba(0,229,255,.12)}
.mu-top{display:flex;align-items:center;gap:14px;padding:9px 14px;background:var(--panel-2);border-bottom:1px solid var(--grid-2);font-family:var(--mono);font-size:11px;color:var(--ink-2);overflow-x:auto;white-space:nowrap}
.mu-top .tid{color:var(--cyan)}
.mu-top .sep{color:var(--grid-2)}
.mu-top .name{color:var(--ink)}
.mu-top .right{margin-left:auto;display:flex;align-items:center;gap:14px}
.chip{font-family:var(--mono);font-size:10px;padding:2px 7px;border:1px solid var(--grid-2);color:var(--ink-2);letter-spacing:.5px}
.chip.ok{color:var(--ok);border-color:rgba(46,230,138,.4)}
.mu-body{display:grid;grid-template-columns:200px 1fr 220px;gap:1px;background:var(--grid)}
.mu-col{background:var(--panel)}
.mu-subhead{font-family:var(--mono);font-size:10px;color:var(--ink-3);letter-spacing:1.5px;text-transform:uppercase;padding:8px 14px;border-bottom:1px solid var(--grid);background:var(--panel-2)}
/* metric tower */
.mt{padding:6px 0}
.mi{display:flex;align-items:baseline;justify-content:space-between;padding:9px 14px;border-bottom:1px solid var(--grid)}
.mi:last-child{border-bottom:none}
.mi-k{font-family:var(--mono);font-size:10px;color:var(--ink-3);letter-spacing:.5px}
.mi-v{font-family:var(--mono);font-size:15px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--ink)}
.mi-v.up{color:var(--up)} .mi-v.down{color:var(--down)} .mi-v.amber{color:var(--amber)}
/* main chart area */
.chart-block{padding:0;border-bottom:1px solid var(--grid)}
.chart-head{display:flex;align-items:center;gap:10px;padding:9px 14px}
.chart-head .ct{font-family:var(--mono);font-size:11px;color:var(--ink);font-weight:600}
.legend{display:flex;gap:12px;margin-left:auto;font-family:var(--mono);font-size:10px;color:var(--ink-2)}
.legend span{display:inline-flex;align-items:center;gap:5px}
.legend i{width:12px;height:2px;display:inline-block}
.scanwrap{position:relative;height:188px;padding:0 8px;overflow:hidden}
.scanline{position:absolute;left:0;right:0;top:0;height:60px;background:linear-gradient(180deg,transparent,rgba(0,229,255,.06),transparent);pointer-events:none;animation:scan 5.5s linear infinite}
@keyframes scan{0%{transform:translateY(-60px)}100%{transform:translateY(188px)}}
/* right rail */
.pos{padding:12px 14px;border-bottom:1px solid var(--grid)}
.pos .sym{font-family:var(--mono);font-size:14px;color:var(--ink);font-weight:700}
.pos .nm{font-family:var(--mono);font-size:10px;color:var(--ink-3);margin-bottom:8px}
.pos-row{display:flex;justify-content:space-between;font-family:var(--mono);font-size:11px;color:var(--ink-2);padding:3px 0}
.pos-row b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.pos-row b.up{color:var(--up)} .pos-row b.down{color:var(--down)}
.signal{display:flex;align-items:center;gap:8px;padding:8px 14px;font-family:var(--mono);font-size:11px;border-bottom:1px solid var(--grid)}
.signal .arr{color:var(--up);font-weight:700}
.signal.sell .arr{color:var(--down)}
/* monthly heatmap */
.heat{padding:12px 14px}
.heat-grid{display:grid;grid-template-columns:34px repeat(12,1fr);gap:2px}
.heat-grid .hlab{font-family:var(--mono);font-size:9px;color:var(--ink-3);display:grid;place-items:center}
.hc{height:18px;display:grid;place-items:center;font-family:var(--mono);font-size:8px;color:rgba(255,255,255,.7)}
/* ticker */
.ticker{display:flex;align-items:center;gap:0;border-top:1px solid var(--grid-2);background:var(--panel-2);overflow:hidden}
.tk-label{font-family:var(--mono);font-size:10px;color:var(--cyan);letter-spacing:1px;padding:0 12px;border-right:1px solid var(--grid);height:34px;display:grid;place-items:center}
.tk-track{display:flex;gap:28px;padding:0 14px;font-family:var(--mono);font-size:11px;white-space:nowrap;animation:tk 32s linear infinite}
@keyframes tk{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}
.tk-item span.k{color:var(--ink-3)} .tk-item span.v{color:var(--ink)} .tk-item .up{color:var(--up)} .tk-item .down{color:var(--down)}
/* ── §4 priority table ── */
.pri-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.pri{background:var(--panel);border:1px solid var(--grid-2)}
.pri-head{display:flex;align-items:center;gap:8px;padding:12px 16px;border-bottom:1px solid var(--grid)}
.pri-head .pl{font-family:var(--mono);font-size:10px;letter-spacing:1.5px;padding:2px 7px}
.pl.p0{color:var(--ok);border:1px solid rgba(46,230,138,.4)}
.pl.p1{color:var(--amber);border:1px solid rgba(255,176,0,.4)}
.pl.p2{color:var(--cyan);border:1px solid rgba(0,229,255,.4)}
.pri-head .pt{font-family:var(--mono);font-size:13px;color:var(--ink);font-weight:600}
.pri-head .pw{margin-left:auto;font-family:var(--mono);font-size:10px;color:var(--ink-3)}
.pri ul{list-style:none;margin:0;padding:6px 0}
.pri li{display:flex;gap:10px;padding:8px 16px;font-size:12.5px;color:var(--ink-2);border-bottom:1px dashed var(--grid)}
.pri li:last-child{border-bottom:none}
.pri li .mk{color:var(--cyan);font-family:var(--mono);font-size:11px;flex-shrink:0;margin-top:1px}
.pri li b{color:var(--ink);font-weight:600}
/* ── §5 ux essence ── */
.ux-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
.ux{padding:18px 20px;background:var(--panel);border:1px solid var(--grid-2);position:relative}
.ux .uno{position:absolute;top:14px;right:16px;font-family:var(--mono);font-size:11px;color:var(--cyan-dim);letter-spacing:1px}
.ux h4{margin:0 0 6px;font-family:var(--mono);font-size:13px;color:var(--ink);letter-spacing:.3px;padding-right:36px}
.ux p{margin:0 0 8px;font-size:12.5px;color:var(--ink-2);line-height:1.6}
.ux .src{font-family:var(--mono);font-size:10px;color:var(--ink-3);letter-spacing:.5px}
/* ── §6 roadmap ── */
.road{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--grid-2);border:1px solid var(--grid-2)}
.sp{background:var(--panel);padding:18px}
.sp-no{font-family:var(--mono);font-size:11px;color:var(--cyan);letter-spacing:2px;margin-bottom:6px}
.sp h4{margin:0 0 4px;font-family:var(--mono);font-size:14px;color:var(--ink)}
.sp .dur{font-family:var(--mono);font-size:10px;color:var(--amber);letter-spacing:.5px;margin-bottom:12px}
.sp ul{list-style:none;margin:0;padding:0}
.sp li{font-size:12px;color:var(--ink-2);padding:5px 0;padding-left:16px;position:relative;border-bottom:1px dashed var(--grid);line-height:1.5}
.sp li:last-child{border-bottom:none}
.sp li:before{content:'▸';position:absolute;left:0;color:var(--cyan-dim);font-family:var(--mono)}
/* footer */
.foot{margin-top:72px;padding-top:24px;border-top:1px solid var(--grid);display:flex;align-items:center;gap:14px;font-family:var(--mono);font-size:11px;color:var(--ink-3)}
.foot .rt{margin-left:auto}
@media (max-width:980px){
.hero h1{font-size:38px}
.mu-body{grid-template-columns:1fr}
.diag-grid,.lang-grid,.pri-grid,.ux-grid{grid-template-columns:1fr}
.road{grid-template-columns:repeat(2,1fr)}
.hero-meta{flex-direction:column}
.hero-meta>div{border-right:none;border-bottom:1px solid var(--grid)}
}
@media (prefers-reduced-motion:reduce){
.dot.pulse,.scanline,.tk-track{animation:none}
}
.scanwrap svg,.chart-block svg{display:block;width:100%;height:100%}
</style>
<div class="wrap">
<!-- HERO -->
<section class="hero">
<div class="hero-tag">// frontend redesign proposal · v0.1</div>
<h1>从「研究工具」<br><span class="accent"> 量化终端</span></h1>
<p class="lead">当前前端是合格的暗色后台——功能齐全,但视觉停留在 <span class="mono" style="color:var(--ink)">GitHub&nbsp;Dark</span> 工具感,信息密度低、无命令面板、无归因深度。本提案把它重做成一台 <span class="amber">科幻终端</span>:荧光青 × 琥珀数据 × 多面板高密度,对标 Bloomberg / Wind 的终端 UXQuantConnect 的分析深度。</p>
<div class="hero-meta">
<div><div class="hm-k">现状风格</div><div class="hm-v">GitHub Dark · 单列低密度</div></div>
<div><div class="hm-k">目标风格</div><div class="hm-v"><span class="arr"></span> 深空黑 · 荧光青 · 琥珀</div></div>
<div><div class="hm-k">设计系统</div><div class="hm-v">已变量化 · CSS 换肤友好</div></div>
<div><div class="hm-k">调研覆盖</div><div class="hm-v">10+ 开源项目 · 11 平台</div></div>
</div>
</section>
<!-- §1 DIAGNOSIS -->
<section class="sec">
<div class="sec-head">
<span class="sec-no">[ 01 ]</span>
<h2 class="sec-title">现状诊断</h2>
<span class="sec-desc">cta_7a92d1f6 截图 · 功能骨架已齐 · 视觉与密度待升级</span>
</div>
<div class="diag-grid">
<div class="diag"><span class="tag dg">PAIN</span><h4>单列堆叠 · 信息密度低</h4><p>11 个指标卡横排 + 6 张图纵向 el-card 堆叠,一屏只塞得下 1-2 张图。tokens.css 注释写着"高密度",实现却是低密度——设计意图与实现的落差。</p></div>
<div class="diag"><span class="tag dg">PAIN</span><h4>无命令面板 · 无快捷键</h4><p>Bloomberg <span class="mono">&lt;GO&gt;</span>、Wind 键盘精灵、iFinD 代码简拼——三家顶级终端无一例外都有命令行式交互。当前全靠侧栏点选,power-user 效率为零。</p></div>
<div class="diag k"><span class="tag wn">GAP</span><h4>分析深度停在 P0 基线</h4><p>缺月度收益热力图、Rolling Sharpe/Beta、回撤 Top5 标注、每日收益柱状图;指标卡缺胜率/盈亏比/换手率(11 项里只有 8 项)。归因(Brinson/Barra)完全空白。</p></div>
<div class="diag k"><span class="tag wn">GAP</span><h4>无导出 · 无对比 · 无选股闭环</h4><p>所有数据表无 Excel/CSV 导出;无多回测对比页;无选股器(EQS→回测→归因是专业终端的产品灵魂,4 家终端都做闭环)。</p></div>
<div class="diag g"><span class="tag cy">BASE</span><h4>设计系统已变量化 ✅</h4><p><span class="mono">--bg / --brand / --mono / --r-sm / --ease</span> + 统一 <span class="mono">echartsDark</span> 主题(红涨绿跌)。科幻风改造主要落在 CSS 变量层 + 视觉叠加层,不用重写 Element Plus 组件。</p></div>
<div class="diag g"><span class="tag cy">BASE</span><h4>功能框架齐全 ✅</h4><p>单标的 CTA 全链路(新建→进度→结果→历史)+ 组合回测 + 参数优化 + 因子分析 + 模拟盘 + 实盘模拟 + Dashboard。美化为主,功能查漏为辅。</p></div>
</div>
</section>
<!-- §2 VISUAL LANGUAGE -->
<section class="sec">
<div class="sec-head">
<span class="sec-no">[ 02 ]</span>
<h2 class="sec-title">视觉语言</h2>
<span class="sec-desc">深空黑 · 荧光青 · 琥珀 · 等宽数据</span>
</div>
<div class="lang-grid">
<div>
<div class="swatches">
<div class="sw" style="background:#05080d"><span class="nm">VOID</span><span class="hex" style="color:#56697c">#05080d</span></div>
<div class="sw" style="background:#0d141f"><span class="nm">PANEL</span><span class="hex" style="color:#8aa0b5">#0d141f</span></div>
<div class="sw" style="background:#00e5ff"><span class="nm" style="color:#05080d">CYAN · 主强调</span><span class="hex" style="color:#05080d">#00e5ff</span></div>
<div class="sw" style="background:#ffb000"><span class="nm" style="color:#05080d">AMBER · 数据高亮</span><span class="hex" style="color:#05080d">#ffb000</span></div>
<div class="sw" style="background:#ff4d5e"><span class="nm" style="color:#05080d">UP · 红涨(A股)</span><span class="hex" style="color:#05080d">#ff4d5e</span></div>
<div class="sw" style="background:#2ee68a"><span class="nm" style="color:#05080d">DOWN · 绿跌</span><span class="hex" style="color:#05080d">#2ee68a</span></div>
</div>
<div class="lamprow">
<div class="lampcell"><span class="d" style="background:var(--ok);box-shadow:0 0 6px var(--ok)"></span>RUNNING</div>
<div class="lampcell"><span class="d" style="background:var(--warn);box-shadow:0 0 6px var(--warn)"></span>WARN</div>
<div class="lampcell"><span class="d" style="background:var(--danger);box-shadow:0 0 6px var(--danger)"></span>CRITICAL</div>
</div>
</div>
<div class="panel type-card">
<div class="type-row"><span class="type-l">DISPLAY · 终端标题</span><span class="t-disp">终端化</span></div>
<div class="type-row"><span class="type-l">BODY · 正文叙述</span><span class="t-body">量化研究台正文阅读</span></div>
<div class="type-row"><span class="type-l">DATA · 等宽 tabular-nums</span><span class="t-data">+18.42%</span></div>
<div class="type-row"><span class="type-l">规则</span><span class="mono" style="font-size:11px;color:var(--ink-2)">数据全右对齐 · 等宽列对齐 · 直角/2px 圆角 · 几何角标代替 emoji · 1px 网格底 · 克制动效(扫描线/呼吸灯)</span></div>
</div>
</div>
</section>
<!-- §3 MOCKUP -->
<section class="sec">
<div class="sec-head">
<span class="sec-no">[ 03 ]</span>
<h2 class="sec-title">改造后 · 回测结果页</h2>
<span class="sec-desc">高保真 mockup · 多面板终端布局 · 非实现,视觉目标</span>
</div>
<div class="mockup">
<!-- top strip -->
<div class="mu-top">
<span class="tid">cta_7a92d1f6</span><span class="sep"></span>
<span class="name">DoubleMa</span><span class="sep">·</span><span>600519 贵州茅台</span><span class="sep">·</span><span>2023-01-01 ~ 2024-06-30</span><span class="sep">·</span><span>日线</span><span class="sep">·</span><span>基准 沪深300</span>
<span class="right">
<span class="chip ok">● DONE · 1.8s</span>
<span class="chip">⌘K</span>
</span>
</div>
<div class="mu-body">
<!-- LEFT: metric tower -->
<div class="mu-col">
<div class="mu-subhead">核心指标</div>
<div class="mt">
<div class="mi"><span class="mi-k">年化收益</span><span class="mi-v up">+18.42%</span></div>
<div class="mi"><span class="mi-k">Sharpe</span><span class="mi-v">1.34</span></div>
<div class="mi"><span class="mi-k">Sortino</span><span class="mi-v">1.71</span></div>
<div class="mi"><span class="mi-k">最大回撤</span><span class="mi-v down">-9.80%</span></div>
<div class="mi"><span class="mi-k">Alpha</span><span class="mi-v up">6.20%</span></div>
<div class="mi"><span class="mi-k">Beta</span><span class="mi-v">0.78</span></div>
<div class="mi"><span class="mi-k">胜率</span><span class="mi-v">54%</span></div>
<div class="mi"><span class="mi-k">盈亏比</span><span class="mi-v amber">1.82</span></div>
<div class="mi"><span class="mi-k">换手率</span><span class="mi-v">3.2x</span></div>
<div class="mi"><span class="mi-k">PSR</span><span class="mi-v amber">0.92</span></div>
</div>
</div>
<!-- CENTER: charts -->
<div class="mu-col">
<!-- equity -->
<div class="chart-block">
<div class="chart-head">
<span class="ct">净值曲线 · 策略 / 基准 / 超额</span>
<span class="legend">
<span><i style="background:var(--cyan)"></i>策略</span>
<span><i style="background:var(--ink-3)"></i>沪深300</span>
<span><i style="background:var(--amber)"></i>超额</span>
</span>
</div>
<div class="scanwrap">
<div class="scanline"></div>
<svg viewBox="0 0 600 180" preserveAspectRatio="none">
<defs>
<linearGradient id="g1" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#00e5ff" stop-opacity=".28"/><stop offset="1" stop-color="#00e5ff" stop-opacity="0"/></linearGradient>
</defs>
<!-- grid -->
<g stroke="#15212f" stroke-width="1">
<line x1="0" y1="45" x2="600" y2="45"/><line x1="0" y1="90" x2="600" y2="90"/><line x1="0" y1="135" x2="600" y2="135"/>
</g>
<!-- benchmark (dull) -->
<polyline fill="none" stroke="#56697c" stroke-width="1.4" points="0,120 40,118 80,125 120,122 160,128 200,124 240,130 280,126 320,132 360,128 400,122 440,118 480,124 520,120 560,116 600,114"/>
<!-- strategy -->
<path d="M0,120 L40,110 L80,115 L120,98 L160,104 L200,82 L240,90 L280,68 L320,74 L360,55 L400,62 L440,40 L480,48 L520,32 L560,38 L600,22 L600,180 L0,180 Z" fill="url(#g1)"/>
<polyline fill="none" stroke="#00e5ff" stroke-width="2" points="0,120 40,110 80,115 120,98 160,104 200,82 240,90 280,68 320,74 360,55 400,62 440,40 480,48 520,32 560,38 600,22"/>
<!-- excess (amber dashed) -->
<polyline fill="none" stroke="#ffb000" stroke-width="1.4" stroke-dasharray="4 3" points="0,150 40,148 80,146 120,140 160,138 200,130 240,128 280,118 320,116 360,104 400,102 440,88 480,86 520,76 560,74 600,62"/>
<!-- end dot -->
<circle cx="600" cy="22" r="3.5" fill="#00e5ff"/>
<circle cx="600" cy="22" r="7" fill="#00e5ff" opacity=".25"/>
</svg>
</div>
</div>
<!-- drawdown underwater -->
<div class="chart-block">
<div class="chart-head">
<span class="ct">回撤水下图 · Top5 回撤期标注</span>
<span class="legend"><span><i style="background:var(--up)"></i>回撤</span><span><i style="background:var(--warn)"></i>Top5</span></span>
</div>
<div class="scanwrap" style="height:96px">
<svg viewBox="0 0 600 90" preserveAspectRatio="none">
<line x1="0" y1="0" x2="600" y2="0" stroke="#1d2c3d"/>
<path d="M0,0 L30,0 L60,18 L90,12 L120,28 L150,22 L180,0 L220,0 L260,40 L300,32 L330,48 L370,20 L400,0 L440,0 L480,55 L520,38 L560,14 L600,0 L600,0 L0,0 Z" fill="#ff4d5e" fill-opacity=".22" stroke="#ff4d5e" stroke-width="1.2"/>
<!-- top5 markers -->
<g fill="#ffb000"><circle cx="270" cy="40" r="3"/><circle cx="330" cy="48" r="3"/><circle cx="135" cy="28" r="3"/><circle cx="490" cy="55" r="3"/><circle cx="300" cy="36" r="3"/></g>
<g font-family="monospace" font-size="8" fill="#ffb000"><text x="272" y="52">1</text><text x="332" y="60">2</text></g>
</svg>
</div>
</div>
<!-- monthly heatmap -->
<div class="chart-block" style="border-bottom:none">
<div class="chart-head"><span class="ct">月度收益热力图 · 20232024</span><span class="legend"><span><i style="background:var(--up)"></i></span><span><i style="background:var(--down)"></i></span></span></div>
<div class="heat">
<div class="heat-grid">
<div class="hlab"></div><div class="hlab">1</div><div class="hlab">2</div><div class="hlab">3</div><div class="hlab">4</div><div class="hlab">5</div><div class="hlab">6</div><div class="hlab">7</div><div class="hlab">8</div><div class="hlab">9</div><div class="hlab">10</div><div class="hlab">11</div><div class="hlab">12</div>
<div class="hlab">23</div>
<div class="hc" style="background:#ff4d5e;opacity:.5">+3</div><div class="hc" style="background:#2ee68a;opacity:.4">-2</div><div class="hc" style="background:#ff4d5e;opacity:.8">+6</div><div class="hc" style="background:#ff4d5e;opacity:.3">+1</div><div class="hc" style="background:#2ee68a;opacity:.6">-3</div><div class="hc" style="background:#ff4d5e;opacity:.6">+4</div><div class="hc" style="background:#ff4d5e;opacity:.9">+7</div><div class="hc" style="background:#2ee68a;opacity:.3">-1</div><div class="hc" style="background:#ff4d5e;opacity:.4">+2</div><div class="hc" style="background:#2ee68a;opacity:.7">-4</div><div class="hc" style="background:#ff4d5e;opacity:.5">+3</div><div class="hc" style="background:#ff4d5e;opacity:.7">+5</div>
<div class="hlab">24</div>
<div class="hc" style="background:#2ee68a;opacity:.5">-3</div><div class="hc" style="background:#ff4d5e;opacity:.7">+5</div><div class="hc" style="background:#ff4d5e;opacity:.4">+2</div><div class="hc" style="background:#2ee68a;opacity:.4">-2</div><div class="hc" style="background:#ff4d5e;opacity:.6">+4</div><div class="hc" style="background:#ff4d5e;opacity:.85">+6</div><div class="hc" style="background:rgba(214,228,240,.08)"></div><div class="hc" style="background:rgba(214,228,240,.08)"></div><div class="hc" style="background:rgba(214,228,240,.08)"></div><div class="hc" style="background:rgba(214,228,240,.08)"></div><div class="hc" style="background:rgba(214,228,240,.08)"></div><div class="hc" style="background:rgba(214,214,214,.08)"></div>
</div>
</div>
</div>
</div>
<!-- RIGHT rail -->
<div class="mu-col">
<div class="mu-subhead">持仓 · 信号</div>
<div class="pos">
<div class="sym">600519</div>
<div class="nm">贵州茅台 · 多头</div>
<div class="pos-row"><span>持仓</span><b>400 股</b></div>
<div class="pos-row"><span>成本</span><b>1,685.20</b></div>
<div class="pos-row"><span>现价</span><b>1,722.50</b></div>
<div class="pos-row"><span>浮盈</span><b class="up">+2.21%</b></div>
<div class="pos-row"><span>暴露</span><b>68.9%</b></div>
</div>
<div class="signal"><span class="arr">▲ BUY</span><span>2024-05-16 · 1,680</span></div>
<div class="signal sell"><span class="arr">▼ SELL</span><span>2024-06-20 · 1,722</span></div>
<div class="signal"><span class="arr">▲ BUY</span><span>2024-06-28 · 1,705</span></div>
<div class="mu-subhead" style="margin-top:0">风险</div>
<div class="pos">
<div class="pos-row"><span>VaR(95%)</span><b class="down">-2.1%</b></div>
<div class="pos-row"><span>行业暴露</span><b>食饮 69%</b></div>
<div class="pos-row"><span>风格</span><b>大盘·价值</b></div>
</div>
</div>
</div>
<!-- ticker -->
<div class="ticker">
<div class="tk-label">TRADES ▸</div>
<div class="tk-track">
<span class="tk-item"><span class="k">BUY</span> <span class="v">600519</span> <span class="up">@1685</span> ×400</span>
<span class="tk-item"><span class="k">SELL</span> <span class="v">600519</span> <span class="down">@1702</span> ×400</span>
<span class="tk-item"><span class="k">BUY</span> <span class="v">600519</span> <span class="up">@1660</span> ×400</span>
<span class="tk-item"><span class="k">SELL</span> <span class="v">600519</span> <span class="down">@1688</span> ×400</span>
<span class="tk-item"><span class="k">BUY</span> <span class="v">600519</span> <span class="up">@1672</span> ×400</span>
<span class="tk-item"><span class="k">BUY</span> <span class="v">600519</span> <span class="up">@1685</span> ×400</span>
<span class="tk-item"><span class="k">SELL</span> <span class="v">600519</span> <span class="down">@1702</span> ×400</span>
<span class="tk-item"><span class="k">BUY</span> <span class="v">600519</span> <span class="up">@1660</span> ×400</span>
<span class="tk-item"><span class="k">SELL</span> <span class="v">600519</span> <span class="down">@1688</span> ×400</span>
<span class="tk-item"><span class="k">BUY</span> <span class="v">600519</span> <span class="up">@1672</span> ×400</span>
</div>
</div>
</div>
<p style="font-family:var(--mono);font-size:11px;color:var(--ink-3);margin-top:12px">// 上图为视觉目标 mockup(假数据)。一屏承载:10 指标 + 净值/基准/超额 + 回撤Top5 + 月度热力图 + 持仓信号 + 风险 + 交易滚动条 —— 信息密度对标 Wind/Choice 综合屏。</p>
</section>
<!-- §4 PRIORITY -->
<section class="sec">
<div class="sec-head">
<span class="sec-no">[ 04 ]</span>
<h2 class="sec-title">功能优先级</h2>
<span class="sec-desc">调研对照 · P0 立即补齐 / P1 差异化 / P2 长期</span>
</div>
<div class="pri-grid">
<div class="pri">
<div class="pri-head"><span class="pl p0">P0</span><span class="pt">立即补齐</span><span class="pw">12 周</span></div>
<ul>
<li><span class="mk"></span><b>科幻视觉层</b>:CSS 变量换肤(深空黑/荧光青/琥珀)+ 网格底 + 信号灯 + tabular-nums,全站换肤不重构组件</li>
<li><span class="mk"></span><b>Cmd+K 命令面板</b>:代码/拼音/命令三模式,全局快捷入口</li>
<li><span class="mk"></span><b>月度收益热力图</b>QuantConnect 标杆,全头部都有</li>
<li><span class="mk"></span><b>回撤 Top5 标注</b> + 每日收益柱状图</li>
<li><span class="mk"></span><b>补 3 指标</b>:胜率 / 盈亏比 / 换手率</li>
<li><span class="mk"></span><b>导出</b>:所有表加 Excel/CSV 按钮</li>
</ul>
</div>
<div class="pri">
<div class="pri-head"><span class="pl p1">P1</span><span class="pt">差异化体验</span><span class="pw">12 月</span></div>
<ul>
<li><span class="mk"></span><b>多面板可拖拽布局</b>vue-grid-layout + 模板切换 + 联动</li>
<li><span class="mk"></span><b>股票代码智能补全</b>:代码/中文/拼音 fuzzy(米筐独占级体验)</li>
<li><span class="mk"></span><b>选股→回测→归因闭环</b>:选股器 + universe 透传</li>
<li><span class="mk"></span><b>Crisis Events</b>2015股灾/2018贸易战/2020新冠/2024微盘崩期间表现</li>
<li><span class="mk"></span><b>Rolling Sharpe/Beta</b>6M/12M 滚动)+ <b>PSR</b> 概率化夏普</li>
</ul>
</div>
<div class="pri">
<div class="pri-head"><span class="pl p2">P2</span><span class="pt">长期 / 选型</span><span class="pw">视定位</span></div>
<ul>
<li><span class="mk"></span><b>Brinson / Barra 归因</b>:国内聚宽/优矿/Choice 杀手锏</li>
<li><span class="mk"></span><b>无代码策略生成器</b>:指标 + 风控可视化搭建</li>
<li><span class="mk"></span><b>AI 策略助手</b>:对话式开发 + 研报总结</li>
<li><span class="mk"></span><b>社区 / 策略广场</b>:热度榜 + 实体引用</li>
<li><span class="mk"></span><b>Bar Replay</b> 历史回放(TradingView 独占级)</li>
</ul>
</div>
</div>
</section>
<!-- §5 UX ESSENCE -->
<section class="sec">
<div class="sec-head">
<span class="sec-no">[ 05 ]</span>
<h2 class="sec-title">终端 UX 精华落地</h2>
<span class="sec-desc">Bloomberg / Wind / iFinD / Choice 共识 · 7 条</span>
</div>
<div class="ux-grid">
<div class="ux"><span class="uno">01</span><h4>全局命令面板 ⌘K</h4><p>Bloomberg <span class="mono">&lt;GO&gt;</span> / Wind 键盘精灵 / iFinD 简拼——三终端无一例外。三模式:<span class="mono">600519</span>切标的 · <span class="mono">gzmt</span>拼音 · <span class="mono">bt/fac/opt</span>路由。配合 vim 风格单键跳转。</p><span class="src">SRC: Bloomberg · Wind · iFinD</span></div>
<div class="ux"><span class="uno">02</span><h4>多面板可拖拽工作区</h4><p>四面板 + Tabbed Panel + 布局保存(4 家终端都做)。预设模板:单策略深挖 / 多策略 2×2 对比 / 选股+回测 / 组合归因。<b style="color:var(--cyan)">面板间联动</b>——点持仓高亮净值图买卖点。</p><span class="src">SRC: Bloomberg · Wind · iFinD · Choice</span></div>
<div class="ux"><span class="uno">03</span><h4>语义化色彩 · 颜色承载信息</h4><p>严格 token:涨/跌/中性/预警/信息分层(项目已有红涨绿跌,补预警/信息色)。数字右对齐 + <span class="mono">tabular-nums</span>(Bloomberg 做得最彻底)。涨跌色三档可切换。</p><span class="src">SRC: Bloomberg amber-on-black</span></div>
<div class="ux"><span class="uno">04</span><h4>选股 → 回测 → 归因闭环</h4><p>Bloomberg <span class="mono">EQS→BTST→PORT</span> / Wind <span class="mono">EQS→EQBT→PMS</span>。产品流灵魂:选股结果"送入回测"→结果页"因子归因"tab→统一 portfolio schema 跨模块透传。</p><span class="src">SRC: 4 家专业终端共识</span></div>
<div class="ux"><span class="uno">05</span><h4>数据密度 + 零摩擦导出</h4><p>ag-Grid / TanStack Tabletabular-nums + 冻结表头 + 内联 sparkline(持仓行迷你净值)。所有表右上角"导出 Excel"exceljs 前端生成多 sheet)。数字格式全平台统一。</p><span class="src">SRC: Bloomberg XLTP · Wind =WSD() · iFinD</span></div>
<div class="ux"><span class="uno">06</span><h4>实体引用 · 符号触发</h4><p>编辑器/备注/讨论区:<span class="mono">$SH600519$</span>→股票卡片 · <span class="mono">#DoubleMa#</span>→策略聚合 · <span class="mono">@因子:momentum_20d</span>→因子详情。从股票页进新建回测自动填 universe。</p><span class="src">SRC: 雪球</span></div>
</div>
</section>
<!-- §6 ROADMAP -->
<section class="sec">
<div class="sec-head">
<span class="sec-no">[ 06 ]</span>
<h2 class="sec-title">落地路线图</h2>
<span class="sec-desc">4 Sprint · 视觉先行 · 每步可验收</span>
</div>
<div class="road">
<div class="sp">
<div class="sp-no">SPRINT 01</div>
<h4>视觉层 · 设计系统</h4>
<div class="dur">~ 1 周 · 低风险</div>
<ul>
<li>CSS 变量层换肤(深空黑/青/琥珀)</li>
<li>等宽数据字体 + 全局 tabular-nums</li>
<li>网格底 / 信号灯 / 扫描线 / 角标</li>
<li>不改组件结构,全站换肤</li>
</ul>
</div>
<div class="sp">
<div class="sp-no">SPRINT 02</div>
<h4>结果页重构 + P0 功能</h4>
<div class="dur">~ 2 周</div>
<ul>
<li>结果页转多面板终端布局</li>
<li>月度热力图 / 回撤 Top5 / 每日收益</li>
<li>补胜率/盈亏比/换手率指标</li>
<li>Cmd+K 命令面板 + 表导出</li>
</ul>
</div>
<div class="sp">
<div class="sp-no">SPRINT 03</div>
<h4>P1 差异化</h4>
<div class="dur">~ 46 周</div>
<ul>
<li>多面板可拖拽 + 布局保存</li>
<li>股票智能补全(代码/中文/拼音)</li>
<li>选股→回测→归因闭环</li>
<li>Crisis Events / Rolling / PSR</li>
</ul>
</div>
<div class="sp">
<div class="sp-no">SPRINT 04</div>
<h4>P2 选型</h4>
<div class="dur">视定位</div>
<ul>
<li>Brinson / Barra 因子归因</li>
<li>无代码策略生成器</li>
<li>AI 策略助手</li>
<li>社区 / 策略广场 / Bar Replay</li>
</ul>
</div>
</div>
</section>
<div class="foot">
<span class="brand-mark" style="width:18px;height:18px;font-size:9px">SG</span>
<span>三国量化研究台 · 终端化重构提案</span>
<span style="color:var(--grid-2)"></span>
<span>调研:10+ 开源项目 · 11 专业平台</span>
<span class="rt">sanguo_vnpy_v2 · 前后端 session</span>
</div>
</div>