Files
sanguo_vnpy_v2/docs/factor_research/factor-workbench-mockup.html
T

875 lines
56 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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>因子研究工作台</title>
<style>
/* ================= 三国量化研究台 · 科幻终端 tokens(与 frontend/src/styles/tokens.css 一致) ================= */
:root {
--bg: #05080d;
--bg-card: #0a0f17;
--bg-hover: #0e1622;
--bg-overlay: #0d1320;
--panel: #070b12;
--text: #d4e4f0;
--text-2: #7a8a9a;
--text-3: #4a5868;
--brand: #00e5ff;
--cyan-dim: #00b8cc;
--cyan-soft: rgba(0, 229, 255, 0.14);
--amber: #ffb000;
--amber-soft: rgba(255, 176, 0, 0.14);
--up: #ff4d5e;
--down: #2ee68a;
--lamp-ok: #2ee68a;
--lamp-warn: #ffb000;
--lamp-crit: #ff4d5e;
--lamp-idle: #4a5868;
--border: #16202e;
--border-2: #0f1822;
--grid-line: rgba(0, 229, 255, 0.035);
--grid-size: 32px;
--glow-cyan: 0 0 0 1px rgba(0, 229, 255, 0.22), 0 0 18px rgba(0, 229, 255, 0.08);
--sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px;
--r-sm: 2px; --r-md: 3px; --r-lg: 4px;
--mono: ui-monospace, 'JetBrains Mono', 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
--sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', Roboto, sans-serif;
--sidebar-w: 200px;
--header-h: 48px;
--ease: cubic-bezier(0.4, 0, 0.2, 1);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: var(--sans);
background: var(--bg);
color: var(--text);
font-size: 13px;
line-height: 1.55;
-webkit-font-smoothing: antialiased;
}
button { font: inherit; cursor: pointer; border: none; background: none; color: inherit; }
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
/* ================= mockup 说明条 ================= */
.mockbar {
display: flex; align-items: center; gap: 12px;
padding: 8px 20px;
background: var(--amber-soft); color: var(--amber);
font-size: 12px; font-family: var(--mono); letter-spacing: .03em;
border-bottom: 1px solid var(--border);
}
.mockbar .tag { font-size: 10.5px; font-weight: 700; border: 1px solid rgba(255,176,0,.4); border-radius: var(--r-sm); padding: 1px 7px; letter-spacing: .1em; }
.mockbar .hint { color: var(--text-2); font-family: var(--sans); }
/* ================= 布局骨架 ================= */
.layout { display: flex; min-height: calc(100vh - 35px); }
.term-grid {
background-image:
linear-gradient(var(--grid-line) 1px, transparent 1px),
linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
background-size: var(--grid-size) var(--grid-size);
}
.sidebar {
width: var(--sidebar-w); flex-shrink: 0;
background: var(--bg-card);
border-right: 1px solid var(--border);
display: flex; flex-direction: column;
}
.logo { display: flex; align-items: center; gap: 10px; padding: 16px; border-bottom: 1px solid var(--border-2); }
.logo-mark {
font-family: var(--mono); font-weight: 700; font-size: 13px;
color: var(--brand); border: 1px solid var(--brand);
border-radius: var(--r-md); padding: 3px 6px;
box-shadow: var(--glow-cyan);
}
.logo-text { font-size: 14px; font-weight: 700; letter-spacing: .06em; display: block; }
.logo-sub { font-family: var(--mono); font-size: 8.5px; color: var(--text-3); letter-spacing: .18em; display: block; }
.sys-status { display: flex; align-items: center; gap: 8px; padding: 10px 16px; border-bottom: 1px solid var(--border-2); font-family: var(--mono); font-size: 10px; color: var(--text-2); letter-spacing: .12em; }
.lamp { width: 7px; height: 7px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
.lamp-ok { background: var(--lamp-ok); box-shadow: 0 0 6px rgba(46,230,138,.7); }
.lamp-warn { background: var(--lamp-warn); box-shadow: 0 0 6px rgba(255,176,0,.7); }
.lamp-idle { background: var(--lamp-idle); }
.lamp-pulse { animation: pulse 2s infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .lamp-pulse { animation: none; } }
.nav { flex: 1; padding: 8px 0; overflow-y: auto; }
.nav-group { padding: 10px 16px 4px; font-family: var(--mono); font-size: 9.5px; color: var(--text-3); letter-spacing: .2em; text-transform: uppercase; }
.nav-item {
display: flex; align-items: center; gap: 8px;
width: 100%; text-align: left;
padding: 7px 16px 7px 18px;
color: var(--text-2); font-size: 13px;
border-left: 2px solid transparent;
transition: all .15s var(--ease);
}
.nav-item:hover { color: var(--text); background: var(--bg-hover); }
.nav-item.active {
color: var(--brand); background: var(--cyan-soft);
border-left-color: var(--brand);
text-shadow: 0 0 12px rgba(0,229,255,.5);
}
.nav-sub { padding-left: 30px; font-size: 12.5px; }
.sidebar-foot { padding: 12px 16px; border-top: 1px solid var(--border-2); font-family: var(--mono); font-size: 9.5px; color: var(--text-3); letter-spacing: .1em; display: flex; align-items: center; gap: 7px; }
/* ================= header ================= */
.right { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.header {
height: var(--header-h); display: flex; align-items: center; justify-content: space-between;
padding: 0 20px; background: var(--bg-card); border-bottom: 1px solid var(--border);
}
.sys-crumb { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.sys-group { color: var(--text-3); font-family: var(--mono); font-size: 11px; letter-spacing: .1em; }
.sys-sep { color: var(--text-3); }
.sys-name { color: var(--text); font-weight: 600; letter-spacing: .04em; }
.status-bar { display: flex; align-items: center; gap: 18px; }
.clock { font-family: var(--mono); display: flex; align-items: baseline; gap: 5px; }
.clock-time { color: var(--amber); font-size: 15px; font-weight: 600; letter-spacing: .05em; }
.clock-tz { color: var(--text-3); font-size: 9px; letter-spacing: .15em; }
.link-status { display: flex; align-items: center; gap: 7px; font-family: var(--mono); font-size: 10px; color: var(--text-2); letter-spacing: .1em; }
.cmdk {
display: flex; align-items: center; gap: 7px;
border: 1px solid var(--border); border-radius: var(--r-md);
padding: 4px 10px; color: var(--text-3); font-size: 11px;
background: var(--panel);
}
.cmdk-key { font-family: var(--mono); font-size: 10px; border: 1px solid var(--border); border-radius: var(--r-sm); padding: 0 4px; }
/* ================= 主内容区 ================= */
.main { padding: 22px 24px 60px; min-width: 0; }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: var(--sp-4); flex-wrap: wrap; }
.page-title { font-size: 18px; font-weight: 700; letter-spacing: .04em; }
.page-sub { color: var(--text-2); font-size: 12px; margin-top: 2px; font-family: var(--mono); letter-spacing: .02em; }
.btn {
font-size: 12.5px; font-weight: 600; border-radius: var(--r-md); padding: 7px 16px;
border: 1px solid var(--border); color: var(--text-2); background: var(--bg-card);
transition: all .15s var(--ease);
}
.btn:hover { color: var(--text); border-color: var(--text-3); }
.btn.primary {
color: #04141a; background: var(--brand); border-color: var(--brand);
box-shadow: var(--glow-cyan);
}
.btn.primary:hover { background: #33ecff; }
.btn:focus-visible, .nav-item:focus-visible, .chip-btn:focus-visible, .seg button:focus-visible {
outline: 1px solid var(--brand); outline-offset: 1px;
}
.view { display: none; }
.view.on { display: block; animation: fade .2s var(--ease); }
@keyframes fade { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .view.on { animation: none; } }
/* ================= 统计瓦片 ================= */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-3); margin-bottom: var(--sp-4); }
@media (max-width: 1100px) { .stats { grid-template-columns: repeat(2, 1fr); } }
.stat {
background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg);
padding: 13px 16px 11px; position: relative; overflow: hidden;
}
.stat::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
background: var(--brand); opacity: .55;
}
.stat.warn::before { background: var(--amber); }
.stat.ok::before { background: var(--lamp-ok); }
.stat .k { color: var(--text-3); font-family: var(--mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; }
.stat .v { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 23px; font-weight: 600; margin-top: 3px; color: var(--text); }
.stat .v.up { color: var(--up); }
.stat .v.cy { color: var(--brand); }
.stat .d { font-size: 11px; margin-top: 2px; color: var(--text-3); font-family: var(--mono); }
/* ================= 筛选栏 ================= */
.filterbar {
display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg);
padding: 9px 12px; margin-bottom: var(--sp-3);
}
.select {
font-family: var(--mono); font-size: 11.5px; color: var(--text-2);
border: 1px solid var(--border); border-radius: var(--r-sm);
padding: 4px 10px; background: var(--panel);
}
.select b { color: var(--text); font-weight: 600; }
.chips { display: flex; gap: 6px; }
.chip-btn {
font-family: var(--mono); font-size: 11px; font-weight: 600; color: var(--text-2);
border: 1px solid var(--border); border-radius: var(--r-sm);
padding: 2px 10px; letter-spacing: .3px; transition: all .15s var(--ease);
}
.chip-btn:hover { color: var(--text); border-color: var(--text-3); }
.chip-btn.on { color: var(--brand); background: rgba(0,229,255,.1); border-color: rgba(0,229,255,.3); }
.search {
font-family: var(--mono); font-size: 11px; color: var(--text-3);
border: 1px solid var(--border); border-radius: var(--r-sm); padding: 4px 10px;
background: var(--panel); min-width: 170px;
}
.seg { display: flex; border: 1px solid var(--border); border-radius: var(--r-sm); overflow: hidden; margin-left: auto; }
.seg button { font-family: var(--mono); font-size: 11px; padding: 4px 12px; color: var(--text-2); }
.seg button.on { background: rgba(0,229,255,.12); color: var(--brand); }
/* ================= 排行榜表格 ================= */
.tablewrap { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; }
.tablescroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; min-width: 980px; }
thead th {
text-align: right; font-family: var(--mono); font-size: 10px; font-weight: 600; letter-spacing: .12em;
color: var(--text-3); text-transform: uppercase;
background: var(--bg-hover); border-bottom: 1px solid var(--border);
padding: 8px 12px; white-space: nowrap;
}
thead th.l, tbody td.l { text-align: left; }
tbody td {
text-align: right; padding: 7px 12px; border-bottom: 1px solid var(--border-2);
font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 12px;
white-space: nowrap;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr { cursor: pointer; transition: background .12s; }
tbody tr:hover { background: var(--bg-hover); }
td .fname { font-weight: 600; color: var(--text); }
td .fname:hover { color: var(--brand); }
td .fexpr { color: var(--text-3); font-size: 10.5px; display: block; margin-top: 0; max-width: 250px; overflow: hidden; text-overflow: ellipsis; }
.cat-chip {
display: inline-block; padding: 1px 8px; border-radius: var(--r-sm);
font-family: var(--mono); font-size: 10.5px; font-weight: 600; line-height: 17px;
letter-spacing: .3px; border: 1px solid transparent;
}
.cat-alpha101 { color: var(--brand); background: rgba(0,229,255,.1); border-color: rgba(0,229,255,.3); }
.cat-alpha158 { color: #b48cff; background: rgba(180,140,255,.1); border-color: rgba(180,140,255,.3); }
.cat-builtin { color: var(--amber); background: rgba(255,176,0,.1); border-color: rgba(255,176,0,.3); }
.pos { color: var(--up); } .neg { color: var(--down); }
.icbar { display: inline-flex; align-items: center; gap: 7px; justify-content: flex-end; }
.icbar .track { width: 64px; height: 4px; border-radius: 2px; background: var(--border); position: relative; overflow: hidden; }
.icbar .fill { position: absolute; top: 0; bottom: 0; }
.icbar .fill.pos { background: var(--up); right: 0; box-shadow: 0 0 5px rgba(255,77,94,.5); }
.icbar .fill.neg { background: var(--down); left: 0; box-shadow: 0 0 5px rgba(46,230,138,.5); }
.st { display: inline-flex; align-items: center; gap: 5px; font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; }
.st-ok .lamp { background: var(--lamp-ok); box-shadow: 0 0 6px rgba(46,230,138,.7); }
.st-watch .lamp { background: var(--lamp-warn); box-shadow: 0 0 6px rgba(255,176,0,.7); }
.st-out .lamp { background: var(--lamp-idle); box-shadow: none; }
.rank { color: var(--text-3); font-size: 11px; }
tr.top3 td.rank { color: var(--brand); font-weight: 700; text-shadow: 0 0 10px rgba(0,229,255,.5); }
.tbl-foot {
padding: 9px 14px; color: var(--text-3); font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em;
display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap;
border-top: 1px solid var(--border); background: var(--panel);
}
/* ================= 详情页 ================= */
.backlink { color: var(--brand); font-size: 12px; margin-bottom: var(--sp-3); display: inline-block; font-family: var(--mono); letter-spacing: .03em; }
.backlink:hover { text-decoration: underline; text-underline-offset: 3px; }
.fcard {
background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg);
padding: 16px 18px; margin-bottom: var(--sp-3);
}
.fcard .hd { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.fcard .name { font-family: var(--mono); font-size: 17px; font-weight: 700; color: var(--brand); letter-spacing: .03em; }
.expr {
font-family: var(--mono); font-size: 11.5px; line-height: 1.7;
background: var(--panel); border: 1px solid var(--border-2); border-left: 2px solid var(--cyan-dim);
border-radius: var(--r-sm); padding: 11px 14px; color: var(--text-2);
overflow-x: auto; white-space: pre;
}
.metric-strip {
display: grid; grid-template-columns: repeat(6, 1fr); gap: 1px;
background: var(--border); border: 1px solid var(--border); border-radius: var(--r-lg);
overflow: hidden; margin-bottom: var(--sp-3);
}
@media (max-width: 1100px) { .metric-strip { grid-template-columns: repeat(3, 1fr); } }
.metric { background: var(--bg-card); padding: 11px 13px; }
.metric .k { color: var(--text-3); font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase; }
.metric .v { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 18px; font-weight: 600; margin-top: 2px; }
.charts { display: grid; grid-template-columns: 3fr 2fr; gap: var(--sp-3); }
@media (max-width: 1100px) { .charts { grid-template-columns: 1fr; } }
.chart-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 14px 16px; }
.chart-card h3 { font-size: 12.5px; font-weight: 600; letter-spacing: .04em; }
.chart-card .cs { color: var(--text-3); font-family: var(--mono); font-size: 10.5px; margin-bottom: 10px; }
.actions { display: flex; gap: 10px; margin-top: var(--sp-4); }
/* ================= 评估提交页 ================= */
.formcard {
background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg);
padding: 18px 20px; margin-bottom: var(--sp-3);
}
.formcard h3 { font-size: 13px; font-weight: 600; letter-spacing: .04em; margin-bottom: 2px; }
.formcard h3 .step { color: var(--brand); font-family: var(--mono); margin-right: 6px; }
.formcard .cs { color: var(--text-2); font-size: 11.5px; margin-bottom: var(--sp-3); }
.poolgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-3); }
@media (max-width: 1100px) { .poolgrid { grid-template-columns: 1fr; } }
.pool {
text-align: left; border: 1px solid var(--border); border-radius: var(--r-md);
padding: 13px 15px; background: var(--panel); transition: all .15s var(--ease);
}
.pool:hover { border-color: var(--cyan-dim); }
.pool.on { border-color: var(--brand); box-shadow: var(--glow-cyan); background: rgba(0,229,255,.04); }
.pool .pt { font-weight: 600; font-size: 13px; display: flex; align-items: center; gap: 8px; }
.pool .pd { color: var(--text-2); font-size: 11px; margin-top: 4px; line-height: 1.5; }
.pool .pc { font-family: var(--mono); color: var(--brand); font-size: 11.5px; margin-top: 6px; }
.radio { width: 12px; height: 12px; border-radius: 50%; border: 1.5px solid var(--text-3); display: inline-block; flex-shrink: 0; }
.pool.on .radio { border-color: var(--brand); background: radial-gradient(circle, var(--brand) 40%, transparent 45%); }
.checkrow { display: flex; gap: 10px; flex-wrap: wrap; }
.checkchip {
display: inline-flex; align-items: center; gap: 8px;
border: 1px solid var(--border); border-radius: var(--r-sm);
padding: 7px 12px; font-family: var(--mono); font-size: 11.5px; font-weight: 600; color: var(--text-2);
transition: all .15s var(--ease); letter-spacing: .3px;
}
.checkchip:hover { border-color: var(--cyan-dim); }
.checkchip.on { color: var(--brand); background: rgba(0,229,255,.1); border-color: rgba(0,229,255,.3); }
.box { width: 12px; height: 12px; border-radius: var(--r-sm); border: 1.5px solid var(--text-3); display: inline-block; position: relative; flex-shrink: 0; }
.checkchip.on .box { background: var(--brand); border-color: var(--brand); }
.checkchip.on .box::after {
content: ""; position: absolute; left: 3px; top: .5px; width: 4px; height: 7px;
border: solid #04141a; border-width: 0 1.5px 1.5px 0; transform: rotate(42deg);
}
.checkchip .cnt { color: var(--text-3); font-weight: 400; }
.daterow { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.datebox {
font-family: var(--mono); font-size: 12px; color: var(--text);
border: 1px solid var(--border); border-radius: var(--r-sm); padding: 6px 12px; background: var(--panel);
}
.submitbar { display: flex; align-items: center; gap: 14px; padding: 2px; flex-wrap: wrap; }
.submitbar .note { color: var(--text-3); font-size: 11.5px; }
</style>
</head>
<body>
<div class="mockbar">
<span class="tag">DESIGN v2</span>
<span>因子研究 · 投研组新增页面 · 与平台科幻终端风格一致</span>
<span class="hint">点击侧边栏「投研」下的菜单切换页面;排行榜类别筛选可点</span>
</div>
<div class="layout">
<!-- ============ 侧边栏(与 Layout.vue 一致的结构) ============ -->
<aside class="sidebar term-grid">
<div class="logo">
<span class="logo-mark">SG</span>
<div class="logo-txt">
<span class="logo-text">三国量化</span>
<span class="logo-sub">QUANT TERMINAL</span>
</div>
</div>
<div class="sys-status">
<span class="lamp lamp-ok lamp-pulse"></span>
<span>SYSTEM ONLINE</span>
</div>
<nav class="nav">
<button class="nav-item">工作台</button>
<div class="nav-group">策略</div>
<button class="nav-item nav-sub">策略库</button>
<button class="nav-item nav-sub">新建策略</button>
<div class="nav-group">回测</div>
<button class="nav-item nav-sub">个股回测</button>
<button class="nav-item nav-sub">组合回测</button>
<div class="nav-group">投研</div>
<button class="nav-item nav-sub active" data-view="board" onclick="showView('board', this)">IC 排行榜</button>
<button class="nav-item nav-sub" data-view="detail" onclick="showView('detail', this)">因子详情</button>
<button class="nav-item nav-sub" data-view="eval" onclick="showView('eval', this)">批量评估</button>
<button class="nav-item nav-sub" style="color:var(--text-3)">因子分析(现有)</button>
<div class="nav-group">模拟盘</div>
<button class="nav-item nav-sub">模拟盘列表</button>
<div class="nav-group">实盘</div>
<button class="nav-item nav-sub">实盘列表</button>
</nav>
<div class="sidebar-foot"><span class="lamp lamp-ok"></span> v2 · 终端化</div>
</aside>
<div class="right">
<!-- ============ header ============ -->
<header class="header">
<div class="sys-crumb">
<span class="sys-group">投研</span>
<span class="sys-sep"></span>
<span class="sys-name" id="crumbTitle">IC 排行榜</span>
</div>
<div class="status-bar">
<div class="clock"><span class="clock-time">21:36:05</span><span class="clock-tz">CST</span></div>
<div class="link-status"><span class="lamp lamp-ok lamp-pulse"></span><span>DATA LIVE</span></div>
<button class="cmdk"><span></span><span>命令面板</span><span class="cmdk-key">⌘K</span></button>
</div>
</header>
<main class="main term-grid">
<!-- ================= 视图 1IC 排行榜 ================= -->
<section class="view on" id="view-board">
<div class="page-head">
<div>
<h1 class="page-title">IC 排行榜</h1>
<p class="page-sub">批次 2026-08-24 · 全A 4,382 只 · 2018-01-01 ~ 2026-06-30 · 前瞻 5 日</p>
</div>
<button class="btn primary" onclick="showView('eval', document.querySelector('[data-view=eval]'))">发起新评估</button>
</div>
<div class="stats">
<div class="stat">
<div class="k">参评因子</div>
<div class="v cy">258</div>
<div class="d">alpha101 ×100 · alpha158 ×158</div>
</div>
<div class="stat ok">
<div class="k">有效因子</div>
<div class="v" style="color:var(--lamp-ok)">41</div>
<div class="d">|IC| &gt; 0.02 且 ICIR &gt; 0.3</div>
</div>
<div class="stat warn">
<div class="k">观察中</div>
<div class="v" style="color:var(--amber)">76</div>
<div class="d">指标边缘 · 待分年验证</div>
</div>
<div class="stat">
<div class="k">TOP1 多空年化</div>
<div class="v up">+18.4%</div>
<div class="d">alpha32 · 十组多空 · 扣费前</div>
</div>
</div>
<div class="filterbar">
<span class="select">批次 <b>2026-08-24 全量首跑</b></span>
<div class="chips" id="catChips">
<button class="chip-btn on" data-cat="all">全部</button>
<button class="chip-btn" data-cat="alpha101">alpha101</button>
<button class="chip-btn" data-cat="alpha158">alpha158</button>
<button class="chip-btn" data-cat="builtin">内置</button>
</div>
<input class="search" placeholder="搜索因子名 …">
<div class="seg" id="periodSeg">
<button>1D</button><button class="on">5D</button><button>10D</button>
</div>
</div>
<div class="tablewrap">
<div class="tablescroll">
<table id="boardTable">
<thead>
<tr>
<th class="l">#</th><th class="l">因子</th><th class="l">类别</th>
<th>IC 均值</th><th>ICIR</th><th>t 值</th><th>胜率</th>
<th>多空年化</th><th>换手/日</th><th>IC 趋势</th><th>结论</th>
</tr>
</thead>
<tbody>
<tr class="top3" data-cat="alpha101" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">1</td>
<td class="l"><span class="fname">alpha32</span><span class="fexpr">cs_rank(ts_corr(cs_rank(close),…)) 复合</span></td>
<td class="l"><span class="cat-chip cat-alpha101">alpha101</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:89%"></span></span><span class="pos">0.071</span></span></td>
<td class="pos">0.61</td><td class="pos">9.2</td><td class="pos">61.8%</td>
<td class="pos">+18.4%</td><td>12.4%</td>
<td><svg width="88" height="20"><polyline points="0,14 8,12 16,15 24,10 32,11 40,8 48,10 56,6 64,8 72,4 80,6 88,3" fill="none" stroke="var(--up)" stroke-width="1.5"/></svg></td>
<td><span class="st st-ok"><span class="lamp"></span>有效</span></td>
</tr>
<tr class="top3" data-cat="alpha101" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">2</td>
<td class="l"><span class="fname">alpha12</span><span class="fexpr">sign(ts_delta(volume,1)) * (-1*ts_delta(close,1))</span></td>
<td class="l"><span class="cat-chip cat-alpha101">alpha101</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:83%"></span></span><span class="pos">0.066</span></span></td>
<td class="pos">0.57</td><td class="pos">8.6</td><td class="pos">60.4%</td>
<td class="pos">+16.1%</td><td>28.9%</td>
<td><svg width="88" height="20"><polyline points="0,16 8,13 16,14 24,11 32,12 40,9 48,11 56,7 64,9 72,6 80,7 88,4" fill="none" stroke="var(--up)" stroke-width="1.5"/></svg></td>
<td><span class="st st-ok"><span class="lamp"></span>有效</span></td>
</tr>
<tr class="top3" data-cat="alpha101" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">3</td>
<td class="l"><span class="fname">alpha101</span><span class="fexpr">(close-open)/(high-low) 量能加权</span></td>
<td class="l"><span class="cat-chip cat-alpha101">alpha101</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:78%"></span></span><span class="pos">0.062</span></span></td>
<td class="pos">0.54</td><td class="pos">8.1</td><td class="pos">59.7%</td>
<td class="pos">+15.2%</td><td>9.8%</td>
<td><svg width="88" height="20"><polyline points="0,12 8,14 16,10 24,12 32,8 40,10 48,7 56,9 64,5 72,7 80,4 88,5" fill="none" stroke="var(--up)" stroke-width="1.5"/></svg></td>
<td><span class="st st-ok"><span class="lamp"></span>有效</span></td>
</tr>
<tr data-cat="alpha158" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">4</td>
<td class="l"><span class="fname">corr_20</span><span class="fexpr">ts_corr(close/delay(close,1), log(vol/…))</span></td>
<td class="l"><span class="cat-chip cat-alpha158">alpha158</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:74%"></span></span><span class="pos">0.059</span></span></td>
<td class="pos">0.51</td><td class="pos">7.7</td><td class="pos">58.9%</td>
<td class="pos">+13.8%</td><td>15.2%</td>
<td><svg width="88" height="20"><polyline points="0,13 8,11 16,13 24,9 32,10 40,8 48,9 56,6 64,8 72,5 80,6 88,4" fill="none" stroke="var(--up)" stroke-width="1.5"/></svg></td>
<td><span class="st st-ok"><span class="lamp"></span>有效</span></td>
</tr>
<tr data-cat="alpha101" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">5</td>
<td class="l"><span class="fname">alpha54</span><span class="fexpr">((-1×cs_rank(ts_std(low,3)))×…)</span></td>
<td class="l"><span class="cat-chip cat-alpha101">alpha101</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:71%"></span></span><span class="pos">0.057</span></span></td>
<td class="pos">0.49</td><td class="pos">7.4</td><td class="pos">58.2%</td>
<td class="pos">+13.1%</td><td>11.0%</td>
<td><svg width="88" height="20"><polyline points="0,10 8,12 16,9 24,11 32,8 40,9 48,6 56,8 64,9 72,6 80,4 88,5" fill="none" stroke="var(--up)" stroke-width="1.5"/></svg></td>
<td><span class="st st-ok"><span class="lamp"></span>有效</span></td>
</tr>
<tr data-cat="alpha158" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">6</td>
<td class="l"><span class="fname">wvma_20</span><span class="fexpr">ts_std(|r|·vol,20)/ts_mean(|r|·vol,20)</span></td>
<td class="l"><span class="cat-chip cat-alpha158">alpha158</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:68%"></span></span><span class="pos">0.054</span></span></td>
<td class="pos">0.47</td><td class="pos">7.1</td><td class="pos">57.8%</td>
<td class="pos">+12.4%</td><td>10.6%</td>
<td><svg width="88" height="20"><polyline points="0,11 8,10 16,12 24,9 32,7 40,9 48,10 56,7 64,8 72,5 80,6 88,6" fill="none" stroke="var(--up)" stroke-width="1.5"/></svg></td>
<td><span class="st st-ok"><span class="lamp"></span>有效</span></td>
</tr>
<tr data-cat="alpha101" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">7</td>
<td class="l"><span class="fname">alpha83</span><span class="fexpr">-1·cs_rank(ts_cov(cs_rank(high),cs_rank(vol),5))</span></td>
<td class="l"><span class="cat-chip cat-alpha101">alpha101</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:66%"></span></span><span class="pos">0.053</span></span></td>
<td class="pos">0.46</td><td class="pos">6.9</td><td class="pos">57.5%</td>
<td class="pos">+11.9%</td><td>13.7%</td>
<td><svg width="88" height="20"><polyline points="0,12 8,9 16,11 24,8 32,10 40,7 48,8 56,9 64,6 72,7 80,5 88,6" fill="none" stroke="var(--up)" stroke-width="1.5"/></svg></td>
<td><span class="st st-ok"><span class="lamp"></span>有效</span></td>
</tr>
<tr data-cat="alpha158" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">8</td>
<td class="l"><span class="fname">vsumd_10</span><span class="fexpr">量净上行占比 · 10日窗</span></td>
<td class="l"><span class="cat-chip cat-alpha158">alpha158</span></td>
<td><span class="icbar"><span class="track"><span class="fill neg" style="width:63%"></span></span><span class="neg">-0.050</span></span></td>
<td class="neg">-0.44</td><td class="neg">-6.6</td><td class="neg">43.1%</td>
<td class="neg">-11.2%</td><td>18.3%</td>
<td><svg width="88" height="20"><polyline points="0,8 8,10 16,7 24,9 32,11 40,8 48,12 56,10 64,13 72,12 80,15 88,16" fill="none" stroke="var(--down)" stroke-width="1.5"/></svg></td>
<td><span class="st st-ok"><span class="lamp"></span>有效</span></td>
</tr>
<tr data-cat="alpha101" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">9</td>
<td class="l"><span class="fname">alpha6</span><span class="fexpr">(-1)·ts_corr(open, volume, 10)</span></td>
<td class="l"><span class="cat-chip cat-alpha101">alpha101</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:61%"></span></span><span class="pos">0.049</span></span></td>
<td class="pos">0.42</td><td class="pos">6.3</td><td class="pos">56.9%</td>
<td class="pos">+10.7%</td><td>14.9%</td>
<td><svg width="88" height="20"><polyline points="0,10 8,11 16,8 24,10 32,12 40,9 48,10 56,8 64,9 72,7 80,8 88,6" fill="none" stroke="var(--amber)" stroke-width="1.5"/></svg></td>
<td><span class="st st-watch"><span class="lamp"></span>观察</span></td>
</tr>
<tr data-cat="alpha158" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">10</td>
<td class="l"><span class="fname">rsv_10</span><span class="fexpr">(close-ts_min(low,10))/(max-min)</span></td>
<td class="l"><span class="cat-chip cat-alpha158">alpha158</span></td>
<td><span class="icbar"><span class="track"><span class="fill neg" style="width:58%"></span></span><span class="neg">-0.046</span></span></td>
<td class="neg">-0.40</td><td class="neg">-6.0</td><td class="neg">43.6%</td>
<td class="neg">-9.8%</td><td>16.1%</td>
<td><svg width="88" height="20"><polyline points="0,9 8,7 16,10 24,8 32,11 40,9 48,12 56,10 64,14 72,13 80,15 88,17" fill="none" stroke="var(--amber)" stroke-width="1.5"/></svg></td>
<td><span class="st st-watch"><span class="lamp"></span>观察</span></td>
</tr>
<tr data-cat="alpha101" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">11</td>
<td class="l"><span class="fname">alpha44</span><span class="fexpr">ts_corr(vwap·cs_rank…, 5) 条件结构</span></td>
<td class="l"><span class="cat-chip cat-alpha101">alpha101</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:54%"></span></span><span class="pos">0.043</span></span></td>
<td class="pos">0.36</td><td class="pos">5.4</td><td class="pos">56.1%</td>
<td class="pos">+8.9%</td><td>21.5%</td>
<td><svg width="88" height="20"><polyline points="0,9 8,10 16,8 24,11 32,9 40,12 48,10 56,13 64,11 72,14 80,12 88,13" fill="none" stroke="var(--text-3)" stroke-width="1.5"/></svg></td>
<td><span class="st st-watch"><span class="lamp"></span>观察</span></td>
</tr>
<tr data-cat="builtin" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">12</td>
<td class="l"><span class="fname">return_1d</span><span class="fexpr">ts_delta(close,1) —— 一日反转</span></td>
<td class="l"><span class="cat-chip cat-builtin">内置</span></td>
<td><span class="icbar"><span class="track"><span class="fill neg" style="width:52%"></span></span><span class="neg">-0.041</span></span></td>
<td class="neg">-0.35</td><td class="neg">-5.2</td><td class="neg">44.2%</td>
<td class="neg">-8.6%</td><td>34.2%</td>
<td><svg width="88" height="20"><polyline points="0,8 8,9 16,11 24,10 32,12 40,14 48,12 56,15 64,13 72,16 80,14 88,17" fill="none" stroke="var(--amber)" stroke-width="1.5"/></svg></td>
<td><span class="st st-watch"><span class="lamp"></span>观察</span></td>
</tr>
<tr data-cat="alpha101" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">13</td>
<td class="l"><span class="fname">alpha18</span><span class="fexpr">-1·cs_rank(ts_std(|close-open|,5)+…)</span></td>
<td class="l"><span class="cat-chip cat-alpha101">alpha101</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:48%"></span></span><span class="pos">0.038</span></span></td>
<td class="pos">0.33</td><td class="pos">4.9</td><td class="pos">55.4%</td>
<td class="pos">+7.8%</td><td>19.4%</td>
<td><svg width="88" height="20"><polyline points="0,10 8,8 16,9 24,7 32,9 40,6 48,8 56,9 64,7 72,9 80,8 88,10" fill="none" stroke="var(--text-3)" stroke-width="1.5"/></svg></td>
<td><span class="st st-watch"><span class="lamp"></span>观察</span></td>
</tr>
<tr data-cat="alpha158" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">14</td>
<td class="l"><span class="fname">imxd_20</span><span class="fexpr">ts_argmax(high,20)-ts_argmin(low,20)</span></td>
<td class="l"><span class="cat-chip cat-alpha158">alpha158</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:45%"></span></span><span class="pos">0.036</span></span></td>
<td class="pos">0.31</td><td class="pos">4.6</td><td class="pos">54.8%</td>
<td class="pos">+7.1%</td><td>17.7%</td>
<td><svg width="88" height="20"><polyline points="0,11 8,9 16,10 24,12 32,9 40,11 48,8 56,10 64,12 72,9 80,11 88,12" fill="none" stroke="var(--text-3)" stroke-width="1.5"/></svg></td>
<td><span class="st st-watch"><span class="lamp"></span>观察</span></td>
</tr>
<tr data-cat="alpha101" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">15</td>
<td class="l"><span class="fname">alpha9</span><span class="fexpr">quesval 双层条件·极值差动量</span></td>
<td class="l"><span class="cat-chip cat-alpha101">alpha101</span></td>
<td><span class="icbar"><span class="track"><span class="fill pos" style="width:41%"></span></span><span class="pos">0.033</span></span></td>
<td class="pos">0.28</td><td class="pos">4.1</td><td class="pos">54.0%</td>
<td class="pos">+6.2%</td><td>26.8%</td>
<td><svg width="88" height="20"><polyline points="0,9 8,11 16,10 24,13 32,11 40,14 48,12 56,15 64,13 72,16 80,14 88,16" fill="none" stroke="var(--text-3)" stroke-width="1.5"/></svg></td>
<td><span class="st st-out"><span class="lamp"></span>淘汰</span></td>
</tr>
<tr data-cat="alpha101" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">16</td>
<td class="l"><span class="fname">alpha65</span><span class="fexpr">vwap 均值偏离 × 量能乘数</span></td>
<td class="l"><span class="cat-chip cat-alpha101">alpha101</span></td>
<td><span class="icbar"><span class="track"><span class="fill neg" style="width:34%"></span></span><span class="neg">-0.027</span></span></td>
<td class="neg">-0.22</td><td class="neg">-3.2</td><td class="neg">46.1%</td>
<td class="neg">-4.9%</td><td>23.9%</td>
<td><svg width="88" height="20"><polyline points="0,10 8,12 16,14 24,13 32,15 40,14 48,16 56,15 64,17 72,16 80,18 88,17" fill="none" stroke="var(--text-3)" stroke-width="1.5"/></svg></td>
<td><span class="st st-out"><span class="lamp"></span>淘汰</span></td>
</tr>
<tr data-cat="builtin" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">17</td>
<td class="l"><span class="fname">ma20</span><span class="fexpr">ts_mean(close,20)</span></td>
<td class="l"><span class="cat-chip cat-builtin">内置</span></td>
<td><span class="icbar"><span class="track"><span class="fill neg" style="width:26%"></span></span><span class="neg">-0.021</span></span></td>
<td class="neg">-0.17</td><td class="neg">-2.5</td><td class="neg">47.0%</td>
<td class="neg">-3.6%</td><td>20.1%</td>
<td><svg width="88" height="20"><polyline points="0,12 8,13 16,12 24,14 32,13 40,15 48,14 56,16 64,15 72,17 80,16 88,18" fill="none" stroke="var(--text-3)" stroke-width="1.5"/></svg></td>
<td><span class="st st-out"><span class="lamp"></span>淘汰</span></td>
</tr>
<tr data-cat="alpha158" onclick="showView('detail', document.querySelector('[data-view=detail]'))">
<td class="l rank">18</td>
<td class="l"><span class="fname">kmid</span><span class="fexpr">(close-open)/open</span></td>
<td class="l"><span class="cat-chip cat-alpha158">alpha158</span></td>
<td><span class="icbar"><span class="track"><span class="fill neg" style="width:22%"></span></span><span class="neg">-0.018</span></span></td>
<td class="neg">-0.14</td><td class="neg">-2.1</td><td class="neg">47.6%</td>
<td class="neg">-3.0%</td><td>31.5%</td>
<td><svg width="88" height="20"><polyline points="0,13 8,12 16,13 24,15 32,14 40,16 48,15 56,17 64,16 72,18 80,17 88,19" fill="none" stroke="var(--text-3)" stroke-width="1.5"/></svg></td>
<td><span class="st st-out"><span class="lamp"></span>淘汰</span></td>
</tr>
</tbody>
</table>
</div>
<div class="tbl-foot">
<span>显示 18 / 258 · 按 |IC| 降序</span>
<span>口径:日频 RankIC · 红正绿负 · 多空=Q10−Q1 等权 · 未做行业中性化</span>
</div>
</div>
</section>
<!-- ================= 视图 2:因子详情 ================= -->
<section class="view" id="view-detail">
<a class="backlink" href="#" onclick="showView('board', document.querySelector('[data-view=board]')); return false;">← 返回排行榜</a>
<div class="page-head">
<div>
<h1 class="page-title">因子详情 · alpha32</h1>
<p class="page-sub">批次 2026-08-24 · 全A 4,382 只 · 2018-01-01 ~ 2026-06-30</p>
</div>
</div>
<div class="fcard">
<div class="hd">
<span class="name">alpha32</span>
<span class="cat-chip cat-alpha101">alpha101</span>
<span class="st st-ok"><span class="lamp"></span>有效</span>
<span style="color:var(--text-3);font-family:var(--mono);font-size:10.5px;margin-left:auto;letter-spacing:.06em">WorldQuant #32 · 量价相关性族</span>
</div>
<div class="expr">cs_rank(ts_mean(close,7)/close) - 0.5
+ cs_rank(ts_corr(cs_rank(close), cs_rank(volume), 5)) * -1</div>
</div>
<div class="metric-strip">
<div class="metric"><div class="k">IC 均值 (5D)</div><div class="v pos">0.071</div></div>
<div class="metric"><div class="k">ICIR</div><div class="v pos">0.61</div></div>
<div class="metric"><div class="k">t 值</div><div class="v pos">9.2</div></div>
<div class="metric"><div class="k">IC 胜率</div><div class="v pos">61.8%</div></div>
<div class="metric"><div class="k">多空年化</div><div class="v pos">+18.4%</div></div>
<div class="metric"><div class="k">日均换手</div><div class="v" style="color:var(--text-2)">12.4%</div></div>
</div>
<div class="charts">
<div class="chart-card">
<h3>月度 IC 与累计 IC</h3>
<div class="cs">柱=月度 RankIC · 线=累计 IC · 102 个月</div>
<svg width="100%" height="215" viewBox="0 0 620 215" preserveAspectRatio="xMidYMid meet">
<line x1="0" y1="107" x2="620" y2="107" stroke="var(--border)" stroke-width="1"/>
<line x1="0" y1="53" x2="620" y2="53" stroke="var(--border-2)" stroke-width="1" stroke-dasharray="3 4"/>
<line x1="0" y1="161" x2="620" y2="161" stroke="var(--border-2)" stroke-width="1" stroke-dasharray="3 4"/>
<text x="2" y="48" font-size="9" fill="var(--text-3)" font-family="var(--mono)">+0.10</text>
<text x="2" y="104" font-size="9" fill="var(--text-3)" font-family="var(--mono)">0</text>
<text x="2" y="172" font-size="9" fill="var(--text-3)" font-family="var(--mono)">-0.10</text>
<g>
<rect x="8" y="95" width="8" height="12" fill="var(--up)" opacity=".8"/>
<rect x="20" y="83" width="8" height="24" fill="var(--up)" opacity=".8"/>
<rect x="32" y="110" width="8" height="3" fill="var(--down)" opacity=".8"/>
<rect x="44" y="77" width="8" height="30" fill="var(--up)" opacity=".8"/>
<rect x="56" y="89" width="8" height="18" fill="var(--up)" opacity=".8"/>
<rect x="68" y="71" width="8" height="36" fill="var(--up)" opacity=".8"/>
<rect x="80" y="115" width="8" height="8" fill="var(--down)" opacity=".8"/>
<rect x="92" y="87" width="8" height="20" fill="var(--up)" opacity=".8"/>
<rect x="104" y="73" width="8" height="34" fill="var(--up)" opacity=".8"/>
<rect x="116" y="81" width="8" height="26" fill="var(--up)" opacity=".8"/>
<rect x="128" y="97" width="8" height="10" fill="var(--up)" opacity=".8"/>
<rect x="140" y="69" width="8" height="38" fill="var(--up)" opacity=".8"/>
<rect x="152" y="113" width="8" height="6" fill="var(--down)" opacity=".8"/>
<rect x="164" y="79" width="8" height="28" fill="var(--up)" opacity=".8"/>
<rect x="176" y="85" width="8" height="22" fill="var(--up)" opacity=".8"/>
<rect x="188" y="91" width="8" height="16" fill="var(--up)" opacity=".8"/>
<rect x="200" y="65" width="8" height="42" fill="var(--up)" opacity=".8"/>
<rect x="212" y="93" width="8" height="14" fill="var(--up)" opacity=".8"/>
<rect x="224" y="75" width="8" height="32" fill="var(--up)" opacity=".8"/>
<rect x="236" y="83" width="8" height="24" fill="var(--up)" opacity=".8"/>
<rect x="248" y="106" width="8" height="1" fill="var(--down)" opacity=".8"/>
<rect x="260" y="71" width="8" height="36" fill="var(--up)" opacity=".8"/>
<rect x="272" y="81" width="8" height="26" fill="var(--up)" opacity=".8"/>
<rect x="284" y="87" width="8" height="20" fill="var(--up)" opacity=".8"/>
<rect x="296" y="61" width="8" height="46" fill="var(--up)" opacity=".8"/>
<rect x="308" y="89" width="8" height="18" fill="var(--up)" opacity=".8"/>
<rect x="320" y="77" width="8" height="30" fill="var(--up)" opacity=".8"/>
<rect x="332" y="112" width="8" height="5" fill="var(--down)" opacity=".8"/>
<rect x="344" y="83" width="8" height="24" fill="var(--up)" opacity=".8"/>
<rect x="356" y="67" width="8" height="40" fill="var(--up)" opacity=".8"/>
<rect x="368" y="87" width="8" height="20" fill="var(--up)" opacity=".8"/>
<rect x="380" y="73" width="8" height="34" fill="var(--up)" opacity=".8"/>
<rect x="392" y="91" width="8" height="16" fill="var(--up)" opacity=".8"/>
<rect x="404" y="63" width="8" height="44" fill="var(--up)" opacity=".8"/>
<rect x="416" y="85" width="8" height="22" fill="var(--up)" opacity=".8"/>
<rect x="428" y="95" width="8" height="12" fill="var(--up)" opacity=".8"/>
<rect x="440" y="71" width="8" height="36" fill="var(--up)" opacity=".8"/>
<rect x="452" y="79" width="8" height="28" fill="var(--up)" opacity=".8"/>
<rect x="464" y="117" width="8" height="10" fill="var(--down)" opacity=".8"/>
<rect x="476" y="75" width="8" height="32" fill="var(--up)" opacity=".8"/>
<rect x="488" y="89" width="8" height="18" fill="var(--up)" opacity=".8"/>
<rect x="500" y="65" width="8" height="42" fill="var(--up)" opacity=".8"/>
<rect x="512" y="83" width="8" height="24" fill="var(--up)" opacity=".8"/>
<rect x="524" y="91" width="8" height="16" fill="var(--up)" opacity=".8"/>
<rect x="536" y="69" width="8" height="38" fill="var(--up)" opacity=".8"/>
<rect x="548" y="81" width="8" height="26" fill="var(--up)" opacity=".8"/>
<rect x="560" y="93" width="8" height="14" fill="var(--up)" opacity=".8"/>
<rect x="572" y="75" width="8" height="32" fill="var(--up)" opacity=".8"/>
<rect x="584" y="85" width="8" height="22" fill="var(--up)" opacity=".8"/>
<rect x="596" y="71" width="8" height="36" fill="var(--up)" opacity=".8"/>
</g>
<polyline points="12,103 24,99 36,98 48,93 60,90 72,84 84,83 96,79 108,75 120,72 132,70 144,65 156,64 168,60 180,57 192,54 204,48 216,46 228,42 240,39 252,38 264,33 276,30 288,27 300,21 312,19 324,16 336,15 348,12 360,7 372,4 384,0 396,-2 408,-6 420,-9 432,-11 444,-15 456,-18 468,-23 480,-26 492,-30 504,-33 516,-36 528,-39 540,-43 552,-46 564,-49 576,-52 588,-55 600,-59"
fill="none" stroke="var(--brand)" stroke-width="1.8" style="filter: drop-shadow(0 0 4px rgba(0,229,255,.6))"/>
</svg>
</div>
<div class="chart-card">
<h3>十分组平均收益(5 日)</h3>
<div class="cs">Q1=因子值最低组 · 单调性=区分度</div>
<svg width="100%" height="215" viewBox="0 0 340 215" preserveAspectRatio="xMidYMid meet">
<line x1="170" y1="12" x2="170" y2="192" stroke="var(--border)" stroke-width="1"/>
<g font-family="var(--mono)" font-size="9" fill="var(--text-3)">
<rect x="16" y="146" width="24" height="32" rx="2" fill="var(--down)" opacity=".85"/>
<rect x="47" y="154" width="24" height="24" rx="2" fill="var(--down)" opacity=".85"/>
<rect x="78" y="160" width="24" height="18" rx="2" fill="var(--down)" opacity=".85"/>
<rect x="109" y="164" width="24" height="14" rx="2" fill="var(--down)" opacity=".7"/>
<rect x="140" y="168" width="24" height="10" rx="2" fill="var(--down)" opacity=".45"/>
<rect x="196" y="164" width="24" height="10" rx="2" fill="var(--up)" opacity=".4"/>
<rect x="227" y="156" width="24" height="18" rx="2" fill="var(--up)" opacity=".6"/>
<rect x="258" y="144" width="24" height="30" rx="2" fill="var(--up)" opacity=".75"/>
<rect x="289" y="132" width="24" height="42" rx="2" fill="var(--up)" opacity=".9"/>
<rect x="289" y="66" width="24" height="50" rx="2" fill="var(--up)"/>
<text x="22" y="190">Q1</text><text x="53" y="190">Q2</text><text x="84" y="190">Q3</text>
<text x="115" y="190">Q4</text><text x="146" y="190">Q5</text><text x="202" y="190">Q6</text>
<text x="233" y="190">Q7</text><text x="264" y="190">Q8</text><text x="295" y="190">Q9</text>
<text x="322" y="86" font-size="10">Q10</text>
<text x="286" y="58" font-size="9" fill="var(--up)">+0.42%</text>
<text x="16" y="138" font-size="9" fill="var(--down)">-0.38%</text>
</g>
</svg>
</div>
</div>
<div class="actions">
<button class="btn primary">查看完整 tears 报告</button>
<button class="btn">分年 IC 明细</button>
<button class="btn">加入对比</button>
</div>
</section>
<!-- ================= 视图 3:批量评估 ================= -->
<section class="view" id="view-eval">
<div class="page-head">
<div>
<h1 class="page-title">发起批量评估</h1>
<p class="page-sub">后台任务 · 完成后自动生成排行榜批次 · 建议先小样本冒烟</p>
</div>
</div>
<div class="formcard">
<h3><span class="step">01</span>股票池</h3>
<div class="cs">与实盘可交易域一致 · 退市股保留(无幸存者偏差)</div>
<div class="poolgrid">
<button class="pool on">
<span class="pt"><span class="radio"></span>全A 主板+创业板</span>
<span class="pd">剔除科创板/北交所 · 剔 ST · 剔上市&lt;120日</span>
<span class="pc">≈ 4,382 只</span>
</button>
<button class="pool">
<span class="pt"><span class="radio"></span>中证 800</span>
<span class="pd">成份股并集 · 按评估日动态取 · 快速迭代用</span>
<span class="pc">≈ 800 只</span>
</button>
<button class="pool">
<span class="pt"><span class="radio"></span>自定义列表</span>
<span class="pd">粘贴代码清单 · 沿用现有单因子分析入口</span>
<span class="pc">任意</span>
</button>
</div>
</div>
<div class="formcard">
<h3><span class="step">02</span>因子集</h3>
<div class="cs">按类批量勾选 · 未就绪的因子集显示占位</div>
<div class="checkrow">
<button class="checkchip on"><span class="box"></span>alpha101 <span class="cnt">×100</span></button>
<button class="checkchip on"><span class="box"></span>alpha158 <span class="cnt">×158</span></button>
<button class="checkchip"><span class="box"></span>内置基础 <span class="cnt">×7</span></button>
<button class="checkchip" style="opacity:.45"><span class="box"></span>gtja191 <span class="cnt">×191 · 待移植</span></button>
<button class="checkchip" style="opacity:.45"><span class="box"></span>聚宽量价 <span class="cnt">×104 · 待实现</span></button>
</div>
</div>
<div class="formcard">
<h3><span class="step">03</span>时间窗与口径</h3>
<div class="cs">日频因子值 · RankIC · 前瞻收益 1/5/10 日</div>
<div class="daterow">
<span class="datebox">2018-01-01</span>
<span style="color:var(--text-3)"></span>
<span class="datebox">2026-06-30</span>
<span style="color:var(--text-3);font-family:var(--mono);font-size:11px">全量预估 ~2.5h (NAS) · 建议晚间错峰</span>
</div>
</div>
<div class="submitbar">
<button class="btn primary" onclick="showView('board', document.querySelector('[data-view=board]'))">提交评估任务</button>
<span class="note">提交后进入任务中心排队 · 完成自动生成「2026-08-25 批次」排行榜</span>
</div>
</section>
</main>
</div>
</div>
<script>
const TITLES = { board: 'IC 排行榜', detail: '因子详情', eval: '批量评估' };
function showView(id, navBtn) {
document.querySelectorAll('.view').forEach(v => v.classList.remove('on'));
document.getElementById('view-' + id).classList.add('on');
document.querySelectorAll('.nav-item').forEach(n => n.classList.remove('active'));
(navBtn || document.querySelector('.nav-item[data-view="' + id + '"]')).classList.add('active');
document.getElementById('crumbTitle').textContent = TITLES[id];
}
document.getElementById('catChips').addEventListener('click', e => {
const chip = e.target.closest('.chip-btn');
if (!chip) return;
document.querySelectorAll('#catChips .chip-btn').forEach(c => c.classList.remove('on'));
chip.classList.add('on');
const cat = chip.dataset.cat;
document.querySelectorAll('#boardTable tbody tr').forEach(tr => {
tr.style.display = (cat === 'all' || tr.dataset.cat === cat) ? '' : 'none';
});
});
document.getElementById('periodSeg').addEventListener('click', e => {
const b = e.target.closest('button');
if (!b) return;
document.querySelectorAll('#periodSeg button').forEach(x => x.classList.remove('on'));
b.classList.add('on');
});
document.querySelectorAll('.pool').forEach(p => p.addEventListener('click', () => {
document.querySelectorAll('.pool').forEach(x => x.classList.remove('on'));
p.classList.add('on');
}));
document.querySelectorAll('.checkchip').forEach(c => {
if (!c.style.opacity) c.addEventListener('click', () => c.classList.toggle('on'));
});
</script>
</body>
</html>