Quant Dashboard — Single-File HTML Quantitative Dashboard
Build self-contained HTML dashboards for A-share quantitative analysis. Zero build step, zero server, zero API keys — open in any browser.
Trigger Conditions
Load this skill when the user asks for:
- A quantitative/quant trading dashboard or 仪表盘
- Stock backtesting / K-line chart tool as HTML
- Single-file financial data visualization
- Strategy engine with Chinese A-share data
Architecture Pattern
Single HTML file
├── CSS: Dark theme, CSS Grid 3-row full-viewport layout
├── Data Layer: fetch() to Eastmoney public APIs (CORS-friendly)
├── Charts: ECharts 5.x from CDN (no npm)
├── Strategy Engine: Pure JS multi-factor signal generator
└── Backtest: In-browser portfolio simulation with metrics
Data Sources — Eastmoney Public APIs
All APIs are free, no auth, CORS-enabled from browsers. Always set Referer: https://quote.eastmoney.com/ header.
K-line (Daily)
GET https://push2his.eastmoney.com/api/qt/stock/kline/get
Params: secid={market}.{code}, klt=101 (daily), fqt=1 (前复权),
beg={YYYYMMDD}, end={YYYYMMDD},
fields1=f1,f2,f3,f4,f5,f6,
fields2=f51,f52,f53,f54,f55,f56,f57,
lmt={count}
Returns: data.klines[] — each is "date,open,close,high,low,volume,amount"
Real-time Quote
GET https://push2.eastmoney.com/api/qt/stock/get
Params: secid={market}.{code},
fields=f43,f44,f45,f46,f47,f48,f49,f50,f51,f52,f55,f57,f58,f60,f116,f117,f162,f167,f168,f169,f170,f171
Key fields: f43=price(×100), f58=name, f169=change(×100), f170=change%(×100)
Minute Intraday
GET https://push2his.eastmoney.com/api/qt/stock/trends2/get
Params: secid={market}.{code},
fields1=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,
fields2=f51,f52,f53,f54,f55,f56,f57,f58,
ndays=1
Returns: data.trends[], data.prevClose
Market Code Convention
- Shanghai (6xxxxx): market=1, secid="1.600519"
- Shenzhen (0xxxxx/3xxxxx/2xxxxx): market=0, secid="0.000001"
ECharts Financial Chart Recipes
Candlestick (K-line)
series: [{
type: 'candlestick',
data: klineData.map(d => [d.open, d.close, d.low, d.high]),
itemStyle: { color: '#7fd962', color0: '#f26d78' }
}]
Always pair with dataZoom: [{type:'inside'}, {type:'slider', height:18}] for navigation.
Multi-panel Layout (Price + RSI + MACD)
Use grid array with percentage heights:
grid: [
{ left:55, right:15, top:5, height:'42%' }, // Price + MA + BB
{ left:55, right:15, top:'52%', height:'14%' }, // RSI
{ left:55, right:15, top:'71%', height:'14%' }, // MACD
]
Each series references xAxisIndex and yAxisIndex matching its grid panel.
Buy/Sell Markers
Use markPoint on a line series (not candlestick) for cleaner placement:
markPoint: { data: [
{ coord: [date, low], value: 'B', symbol: 'pin', symbolSize: 18,
itemStyle: { color: '#7fd962' }, label: { color: '#fff', fontSize: 10 } }
]}
Strategy Engine Design
Implement as pure JS functions — no external libraries needed:
- calcSMA(data, period) — Simple Moving Average
- calcEMA(data, period) — Exponential Moving Average
- calcRSI(data, period) — Wilder's RSI
- calcMACD(data, fast, slow, signal) — MACD + DIF + DEA + histogram
- calcBollinger(data, period, width) — Bollinger Bands (mid, upper, lower)
- calcKDJ(data, period) — KDJ indicator
- calcATR(data, period) — Average True Range
Multi-Factor Signal Generation
Score-based approach: each indicator contributes weighted points.
- Buy triggers: positive score crosses threshold
- Sell triggers: negative score crosses threshold
- Hold: score in neutral zone
Backtest Engine
runBacktestOnSignals(data, signals, initialCapital)
// Returns: { totalReturn, winRate, maxDrawdown, sharpe, calmar, trades[], equityCurve[] }
Key: use 0.1% transaction cost (bid-ask + commission) — multiply by 1.001 on buy, 0.999 on sell.
Backtest Playback Animation
Use setInterval to incrementally reveal signals on the K-line chart:
- Redraw chart each tick with only signals up to current index
- Update progress bar and date label
- Allow speed control (ms per frame)
- Provide stop/reset controls
Dark Theme Design System
:root {
--bg0: #0a0e14; /* Deepest background */
--bg1: #12171f; /* Panel background */
--bg2: #1a1f2b; /* Card/header background */
--border: #2a3040;
--text: #b0b8c0;
--accent: #39bae6;
--green: #7fd962;
--red: #f26d78;
}
Pitfalls
Windows + non-ASCII paths in git-bash / MSYS2:
cp/lscan fail on directories whose names contain Chinese characters. Write the file with your agent's file tools instead of shell redirection, or pass a native Windows path (backslashes, quoted) to a native binary.Eastmoney f43/f169/f170 fields: These are ×100 integers. Divide by 100 to get actual price/change values.
CORS with Referer: While the APIs generally allow CORS, set
Refererheader in fetch to avoid 403 errors from stricter endpoints.Minute data availability: The trends2 endpoint only returns data for the most recent trading day. Outside market hours, it may return empty — fall back to K-line data.
K-line
fqt=1: Use 前复权 (forward-adjusted) for backtesting to avoid gaps from dividends/splits.ECharts dark theme: Initialize with
echarts.init(dom, 'dark')for automatic dark styling of axes, tooltips, and dataZoom.
Layout Template
CSS Grid, full viewport, 3 rows:
Row 1 (38vh): Minute chart (flex:3) + Signal cards (flex:1, max 340px)
Row 2 (28vh): Strategy params (200px) + Multi-panel chart (flex:1) + Log (flex:1.2) + Direction gauge (flex:0.8)
Row 3 (34vh): K-line chart (full width) + Backtest controls