不是纸面计划——文中的每条「实测」都来自 2026-11-15 的真实验证,配套代码已跑通、数据已入库、仪表盘已生成。
先明确边界:做什么、不做什么、用什么做。
在本机搭一个三件套:档案(持仓与目标的持久记忆)、哨兵(估值/波动/偏离的状态监控)、纪律(±5pct 偏离刻度),输出一张每天看一眼的仪表盘。
不预测涨跌、不荐股、不生成任何「建议买入/卖出」。输出只有客观状态:PE 分位 98.4% 过热 超配 +7.5pct
| 维度 | 选择 | 理由 |
|---|---|---|
| 技术栈 | Python 3.11 + SQLite + Pandas | 零成本、全本机、可审计,AI 改代码出错时可逐行验收 |
| 数据源 | 天天基金(净值)+ 蛋卷(估值)+ 新浪(行情) | 免费、无 Key、稳定,均有明确口径 |
| 存储 | 单个 platform.db | 备份 = 复制一个文件 |
| 输出 | 单文件站点 / HTML 仪表盘 | 双击即看、可打印、无外部依赖 |
| 成功标准 | 查看次数与操作次数 双双下降 | 晨报替代刷屏,提醒替代情绪 |
数据层 → 存储 → 计算 → 展示 → 一句话维护。每一层都可单独替换。
┌─────────────── 数据层(每天/每周定时跑)───────────────┐
│ fetch.py │
│ ├─ 天天基金 lsjz ──→ 复权净值(日增长率反推,含分红) │
│ ├─ 蛋卷 index_eva ─→ PE / PE分位 / PB(每日快照累积) │
│ └─ 新浪 hq/K线 ───→ 盘中价 + 降级备用(不复权,标注) │
└──────────────────────┬────────────────────────────────┘
▼
data/platform.db(SQLite,6 张表)
▼
┌──────────────── 计算层(calc.py / sentinel.py)────────┐
│ 净值合成(月末再平衡)→ 年化 / 回撤 / 夏普 │
│ 收益贡献 Σ w·r | 风险贡献 w(Σw)/σ² │
│ 哨兵:分位阈值 85%/15% | 偏离阈值 ±5pct │
└──────────────────────┬────────────────────────────────┘
▼
site/(本页面)+ out/dashboard.html(单文件版)
▼
cli.py 一句话维护:python3 -m src.cli all
选型原则:免费公开、口径可追溯、失败可降级。每个数字都能说出出处,说不出就不显示。
| 用途 | 接口 | 实测 | 口径与坑 |
|---|---|---|---|
| 复权净值 ★主源 | api.fund.eastmoney.com/f10/lsjz | ✓ 30/30 | 单页固定 20 条(pageSize 被服务端忽略),需分页约 96 页/标的;用官方「日增长率 JZZZL」反推复权净值 = 分红再投口径;实测 30 只全量 6.1 万行 / 170 秒 |
| 估值分位 ★主源 | danjuanfunds.com/djapi/index_eva/detail/<code> | ✓ 18/21 | PE、PB、历史分位一次返回;分位为全历史口径(与课件的「中证近十年」不同,页面必须标注);半导体/光伏/有色无公开分位 → 降级为仅波动监控 |
| 历史价格(降级) | 新浪 CN_MarketData.getKLineData | ✓ 可用 | 单次约 2000 条;不复权,直接当净值会低估分红,仅用于波动率与兜底,页面标注「低估分红」 |
| 盘中现价 | hq.sinajs.cn/list=… | ✓ 可用 | GBK 编码需转码;ETF 支持完整 |
| 中证官网 PE 序列 | csindex.com.cn/csindex-home/perf/index-perf | ⚠ 部分 | 官方 PE(peg 字段)可查,实测仅返回至 2025-12;作近十年分位的校验备源,不作主源 |
| 腾讯前复权 K 线 | web.ifzq.gtimg.cn | ✗ WAF 501 | 被腾讯 WAF 拦截,东财 push2his 亦连接失败。前复权价格口径不可得时,用净值口径替代并标注 |
runs 表留痕。够用就好。没有 ORM、没有微服务——一个文件,六张表。
| 表 | 关键字段 | 职责 |
|---|---|---|
| instruments | code PK · name · asset_class · bucket · sina_symbol · fund_code · index_code · pe_applicable | 30 只标的池;bucket 是五大资产归类(纳指/创业板/红利低波/黄金/国债) |
| nav | (code,date) PK · nav · source | 复权净值;source 记录 fund_nav / sina_price_unadjusted,口径可追溯 |
| valuation | (index_code,date) PK · pe · pe_pct · pct_window · pb · source | 每日估值快照累积;pct_window 永远记录「蛋卷口径(全历史)」这类标签 |
| holdings | (account,code,as_of) PK · shares · market_value | 多账户持仓档案;Excel 导入 / 截图识别的落点 |
| targets | (portfolio,bucket) PK · weight | 目标配置——纪律的刻度来源 |
| alerts / runs | 状态告警 / 运行留痕 | 出问题时能回溯「哪天开始、哪只标的、哪个源」 |
口径不一致是投研平台最常见的坑。所有公式集中在 calc.py 一个文件里。
| 指标 | 公式 | 实现要点 |
|---|---|---|
| 复权净值 | nav[t−1] = nav[t] ÷ (1 + r[t]),r 为官方日增长率 | 从最新单位净值往回反推 ⇒ 等价分红再投,消除 ETF 分红断层 |
| 年化收益 | (期末/期初)^(252/交易日数) − 1 | 不足一年按实际交易日折算 |
| 最大回撤 | max( nav[t]/max(nav[0..t]) − 1 ) | 用净值而非收盘价,避免折溢价噪声 |
| 夏普比率 | (年化收益 − 1.5%) ÷ 年化波动 | 无风险利率取现金计息率,与档案口径一致 |
| 收益贡献 | Σₜ wᵢ,ₜ₋₁ · rᵢ,ₜ(百分点) | 逐日权重漂移 + 月末再平衡;合计 ≈ 累计算术收益 |
| 风险贡献 | RCᵢ = wᵢ·(Σw)ᵢ ÷ σ²ₚ | 全区间日收益协方差年化;回答「钱占比 ≠ 风险占比」 |
| 配置偏离 | 当前权重 − 目标权重(±5pct) | 越线标黄、只报差距;阈值在 config.yaml 可改 |
| 波动分位 | 当前 20 日年化波动率在近 3 年序列中的位置 | ≥85% 异动偏高,≤15% 极低 |
照着做,第一天就能跑起来。验收标准对应第「验收三问」,不是走过场。
pip install pandas numpy pyyaml requests
config.yaml 的 30 只标的(code / sina / index / bucket),运行 python3 -m src.cli init
python3 -m src.cli update(首跑约 3 分钟)
status,把策略池数字与课件对照
python3 -m src.cli sentinel,检查分位合理性
demo 命令)
all,按「运维与验收」页的 SOP 维护