Files
sanguo_vnpy_v2/docs/frontend_terminal_redesign_proposal.html
T
claude_dev 5c8a7e12c6
CI/CD / test (push) Successful in 18s
CI/CD / nas-deploy (push) Failing after 17s
CI/CD / nas-verify (push) Has been skipped
feat(frontend): 终端化重构+策略管理(代码→实例→4运行)+撮合设计+回测参数 [nas]
- 终端化: 科幻色板(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编辑器 + 策略实例删除/编辑入口 + 列表实例列
2026-08-12 23:23:23 +08:00

545 lines
38 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>