价值追踪是一个全静态生成的美股机构 13F 信号仪表盘。Value Tracker tracks the trades of value investors, helping you see what they buy, sell, and hold over time.
页面由 Hugo 构建,后台数据链路现在保持为轻量的文件流水线:
- 原始接入:Longbridge 当前 13F / 行情、SEC 历史 13F、Longbridge 日 K 线等 provider 生成原始事实或更新缓存。
- 规范化:
scripts/stockhunt_backend.py在内存中比较最近两个 13F 报告期,生成raw/generated/snapshot.yaml。 - 历史曲线:
scripts/historical_backtest.py基于 SEC cache 和 Longbridge K 线 cache 生成重点机构 13F 持仓收益曲线。 - 静态导出:
scripts/generate_stockhunt_data.py合并 snapshot 和机构曲线,输出 Hugo 读取的data/stockhunt.json。
流水线不再维护中间数据库,也不把 live raw input 作为标准产物落盘。可持久化的是最终 JSON/JSONL 产物和外部数据 cache。
config/stockhunt.yaml 主配置:白名单、重点机构、策略参数
config/cusip-symbols.yaml 13F CUSIP -> Longbridge symbol 显式覆盖映射
raw/sample/13f_holdings.yaml sample 原始 13F + 行情输入
raw/generated/ 本地生成产物,已 gitignore
raw/generated/cache/ SEC / Longbridge K 线 cache
data/stockhunt.json Hugo 当前消费的数据
scripts/build_live_input.py Longbridge live data 调试入口
scripts/stockhunt_backend.py raw input -> normalized snapshot
scripts/historical_backtest.py SEC 历史 13F + Longbridge K 线 -> 机构收益曲线
scripts/generate_stockhunt_data.py
snapshot + institution curves -> Hugo data
需要本机有:
uv
hugo
longbridge首次使用真实 Longbridge 数据前,需要登录:
longbridge auth loginPython 依赖由 uv 根据 pyproject.toml / uv.lock 管理,不需要手动 pip install。
查看可用命令:
uv run build --help
uv run fetch --help
uv run fetch-all --help
uv run schedule --help只构建静态站点:
uv run build增量抓取数据,不运行 Hugo build:
uv run fetch全量抓取数据,刷新 SEC filing cache 和 Longbridge 价格 cache,不运行 Hugo build:
uv run fetch-all定时任务入口。daily 更新价格和机构曲线;weekly 会先检查 SEC 最新 13F 元数据,若 13F 未更新则提前退出;若更新则增量抓取 13F 并重算机构曲线。实际跑数据的任务执行完都会自动 build:
uv run schedule daily
uv run schedule weekly
uv run schedule weekly --force # 跳过早停检查,强制跑完整 weekly本地预览:
uv run hugo server默认访问:
http://localhost:1313/
仓库已支持 GitHub Actions 部署到 GitHub Pages。
GitHub Pages 设置:
Settings -> Pages -> Build and deployment -> Source: GitHub Actions
.github/workflows/deploy.yml
.github/workflows/schedule.yml
deploy.yml:
main分支 push 或手动触发。- 使用仓库当前
data/stockhunt.json构建 Hugo。 - 发布
public/到 GitHub Pages。
schedule.yml:
- 手动触发时可选择
daily、weekly、fetch-all。 - 定时触发:
- 周二/周三 09:30 Asia/Shanghai 跑
weekly。 - 周四/周五/周六 09:30 Asia/Shanghai 跑
daily。
- 周二/周三 09:30 Asia/Shanghai 跑
- 恢复
raw/generated/cache/、snapshot.yaml、raw/generated/historical/的 Actions cache。 - 数据变化时自动提交
data/stockhunt.json和补齐的content/en/**、content/zh/**,让仓库快照与 Pages 数据保持一致。 - 跑完数据任务后发布 GitHub Pages;weekly 若判定 13F 未更新,会跳过后续提交、cache 保存和 Pages 发布。
定时数据任务需要 GitHub Secrets:
LONGBRIDGE_CLIENT_ID
LONGBRIDGE_TOKEN_FILE_B64
CI 需要 SDK OAuth token 文件,不要使用 longbridge auth login 生成的 cli-auth。详细更新流程见 docs/ci-longbridge-token.md。
快速生成 token 文件:
CLIENT_ID="fd52fbc5-02a9-47f5-ad30-0842c841aae9"
uv run --with longbridge python -c 'from longbridge.openapi import OAuthBuilder; import webbrowser; OAuthBuilder("'$CLIENT_ID'").build(webbrowser.open)'生成 secrets:
printf "%s" "$CLIENT_ID"
base64 -i "$HOME/.longbridge/openapi/tokens/$CLIENT_ID" | tr -d '\n'把第一行输出填入 LONGBRIDGE_CLIENT_ID,第二行输出填入 LONGBRIDGE_TOKEN_FILE_B64。
第一次建议手动运行:
Actions -> Update Data and Deploy Pages -> Run workflow -> mode: fetch-all
之后定时任务会复用 Actions cache。若 cache 丢失,daily 会自动 fallback 到 fetch-all。
uv run fetch默认产物:
raw/generated/snapshot.yaml
raw/generated/historical/
raw/generated/cache/sec/
raw/generated/cache/longbridge-kline/
data/stockhunt.json
content/en/institutions/*.md
content/en/stocks/*.md
content/zh/institutions/*.md
content/zh/stocks/*.md
增量语义:
- Longbridge 当前 13F / 行情会在内存中生成 live raw input。
- 当前 snapshot 每次都从 raw input 和配置纯内存重算,不保留中间状态。
- SEC submissions index 会刷新,用于发现新 13F;已有 filing index / information table XML 继续复用 cache。
- 未显式映射的 CUSIP 会用 Longbridge US security-list 按 issuer name 自动匹配 symbol;成功匹配会追加写回
config/cusip-symbols.yaml,后续直接复用本地表。 - Longbridge 日 K 线按 symbol 追加缺失日期,不再按每个
start/end重新抓整段。 - 历史曲线写入
raw/generated/historical/JSONL store;非全量任务会在配置和 CUSIP 映射未变时从 checkpoint 续算尾部。 - 13F 指纹变化时,
dirty_from取最早变动 13F 的filing_date;没有 13F 变化时,只重算最新 equity point 之后的尾部。 data/stockhunt.json会重新导出,供后续build使用。content/en/**、content/zh/**会按白名单机构和股票自动补齐,用于详情页。
13F 没有 ticker,只有 CUSIP。数据抓取会先查 config/cusip-symbols.yaml;未命中时,用 Longbridge US security-list 按 issuer name 自动匹配 symbol,并把成功匹配追加到本地表。仍无法匹配的持仓会进入 warnings,不会进入榜单。
uv run fetch-all适合修改白名单、CUSIP 映射、核心计算逻辑,或想刷新外部数据 cache 口径。它会:
- 重新生成当前 Longbridge raw input。
- 刷新 SEC submissions、filing index、information table XML。
- 刷新 Longbridge 历史 K 线。
- 重新计算 snapshot、机构历史曲线和
data/stockhunt.json。
- 只使用当时已经公开披露的 13F 持仓,避免提前使用未来报告。
- 曲线以重点机构公开持仓的收益指数计算,不把 13F 总持仓规模变化计入收益。
- 今日、本月、YTD 和最大回撤都基于收益指数口径;持仓市值单独展示为当前公开持仓规模。
- 价格使用 Longbridge 日 K 线,默认
period=day、adjust=forward。
uv run build这个命令只执行 Hugo build,不抓数据、不重新回测。
推荐用两个 schedule:
# 每周更新:美股周一收盘后,香港时间周二早上执行
uv run schedule weekly
# 每日价格和收益更新:美股其他交易日收盘后执行
uv run schedule daily第一次部署先跑一次 uv run schedule weekly --force 或 uv run fetch-all && uv run build,生成历史机构曲线文件;之后 daily 只更新价格和收益。weekly 默认会在 SEC 13F 报告期/filing 指纹未变化时提前退出,不重跑 Longbridge、回测、导出和 Hugo build。
cron 示例:
# 周度更新。周二跑;周三再跑一次用于覆盖周一美股休市顺延的情况。
30 8 * * 2,3 cd /Users/jjy/Workspace/stockhunt && uv run schedule weekly >> /tmp/schedule-weekly.log 2>&1
# 日常价格更新。避开周二/周三,防止和 weekly 重复。
30 8 * * 4-6 cd /Users/jjy/Workspace/stockhunt && uv run schedule daily >> /tmp/schedule-daily.log 2>&1uv run fetch-all
uv run buildfetch-all 会重新拉取当前 Longbridge live raw input、刷新 SEC / K 线 cache、重新计算 snapshot 和历史回测并导出 Hugo 数据。build 只把当前 data/stockhunt.json 构建成 public/。
uv run fetch
uv run build当前增量语义:
- 当前 raw input 和 snapshot 每次重算。
- SEC 只刷新 submissions index 来发现新增 filing,已有 filing XML 继续使用 cache。
- 历史 K 线只追加缺失日期。
- 历史回测会按当前配置重新模拟。
如果只改了 Hugo 模板、CSS、JS 或文案:
uv run build如果已经有 raw/generated/snapshot.yaml 和 raw/generated/historical/,但改了 scripts/generate_stockhunt_data.py 或页面数据格式:
uv run python scripts/generate_stockhunt_data.py \
--snapshot raw/generated/snapshot.yaml \
--simulation raw/generated/historical
uv run build白名单在 config/stockhunt.yaml:
institutions:
whitelist_version: "2026-06-01-whitelist-v1"
managers:
- cik: "0001709323"
name: "Himalaya Capital Management LLC"
display_name: "李录"
enabled: true
style: "value"修改规则:
- 新增机构:添加一条
managers,设置enabled: true,并更新whitelist_version。 - 暂停机构:保留配置但设置
enabled: false,并更新whitelist_version。 - 修改展示名:改
display_name,建议也更新whitelist_version,保证静态数据可追溯。 - CIK 必须能被标准化为 10 位数字,脚本会自动补前导 0。
修改白名单后推荐全量重跑:
uv run fetch-all
uv run build如果新增机构的持仓里出现大量 unmapped CUSIP,优先检查 Longbridge security-list 是否能覆盖;无法稳定自动匹配的股类、ADR、改名证券,再手动补 config/cusip-symbols.yaml。
本地映射在 config/cusip-symbols.yaml。自动匹配成功会追加到这里;手动条目也写这里,并优先于 Longbridge 自动映射。它适合股类、ADR、改名证券或名称匹配可能漂移的情况:
mappings:
"037833100":
symbol: "AAPL.US"
company_name: "Apple Inc."
tags: ["Nasdaq 100", "S&P 500", "Mag7"]修改映射或自动映射逻辑后,需要重新生成 live input,因为 raw input 里已经按映射过滤过持仓:
uv run fetch-all
uv run build历史回测也依赖同一套映射逻辑。补充 CUSIP 后重新运行完整 build,历史 SEC 13F 会按新映射重新解析;已缓存的 SEC 原始文件和 K 线会复用。
重点机构在同一个配置文件:
key_institutions:
version: "2026-06-01-key-v1"
members:
- cik: "0001759760"
display_name: "段永平"
enabled: true修改重点机构会影响:
- 重点机构姓名标签
- 首页机构收益曲线
- 机构详情页曲线和图例
如果只改重点机构配置,推荐重新增量计算并 build:
uv run fetch
uv run build如果新增的重点机构本身不在白名单里,先修改白名单,再全量抓取:
uv run fetch-all
uv run build策略在:
strategy:
max_positions: 10
max_position_weight_pct: 50
weighting_method: "key_institution_signal_score"
score_weight_exponent: 1.0
rebalance_step_weight_pct: 20
min_buy_gap_weight_pct: 5
allocation_signal:
key_new_position_score: 30
key_added_score: 20
key_holding_score: 8
key_buy_intensity_score_per_pct: 8
key_buy_intensity_max_score: 40
below_key_latest_buy_price_bonus: 15
multiple_key_institution_bonus: 8
key_reduced_penalty: -15
key_exit_penalty: -50当前前端不展示规则化组合回测;策略参数主要保留给历史数据管线中的机构信号计算。首页排序和机构详情曲线使用公开 13F 持仓收益指数。
修改策略参数后,推荐重新抓取并 build:
uv run fetch
uv run build验证脚本语法和 Hugo 构建:
uv run python -m py_compile scripts/build_live_input.py scripts/historical_backtest.py scripts/historical_store.py scripts/stockhunt_backend.py scripts/generate_stockhunt_data.py scripts/tasks.py
uv run build检查关键产物:
du -sh raw/generated/snapshot.yaml raw/generated/historical data/stockhunt.json日常只需要 build、fetch、fetch-all、schedule。底层拆步调试时,可以直接用 uv run python scripts/*.py 调用具体脚本。
- Index tag adapter:自动维护 S&P 500、Nasdaq 100、Russell 1000/2000/3000、Mag7 标签。
- 更完整的历史数据质量报告:展示自动映射 CUSIP、未映射 CUSIP、退市股票、缺失价格和 13F value 单位修正。
- 为机构详情页补充更细的历史变动图表。