Skip to content
Agentmart
Submit a tool

CLAUDE.md · agentpit-io/hunter-community

CLAUDE.md from agentpit-io/hunter-community: 2494 lines covering 铁律:严禁 mock 兜底 · 空的比假的好, 数据坑:klines.volume 单位按板块不同 —— 科创板(688)是「股」,其他板块是「手」…

Template by agentpit-io

IndexedApache-2.0★ 570
Write a review

Install

Works with Claude Code. Read the repository before you give any tool access to your data.

curl -fsSL https://raw.githubusercontent.com/agentpit-io/hunter-community/main/CLAUDE.md -o CLAUDE.md

Read it and adapt it to your project before use.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

The CLAUDE.md file that agentpit-io/hunter-community (570 stars) keeps for coding agents. It has 2494 lines in 20 sections: 铁律:严禁 mock 兜底 · 空的比假的好; 数据坑:klines.volume 单位按板块不同 —— 科创板(688)是「股」,其他板块是「手」; 数据坑:外部扫描通道(screensource)的五个陷阱; 第三方代码:RS 相对强度评级移植自 IBD-RS-Rating(MIT)· 改动须保留版权声明; 全市场日线管线(quant/rshistory.py)· RS 线上涨天数 · 四条别改坏的; VCP 字段(quant/vcp.py)· 收缩次数 / 每次深度 / 量能递减 · 五条别改坏的; 量化侧的「市场」:回测 / 因子 / 数据下载按市场分开(2026-09-11 加美股)· 五条; 铁律:改 screenkw.py(本地关键词识别)必须先跑回归用例,且只能加不能删; 魔法筛选器第一轮执行用例(2026-09-14)· 挖出来的四条前端规矩; 策略中心静态页的标签页图标; 扫描筛选对照表:AI 识别过的说法沉淀下来(screenlearned); 扫描筛选:脚本编译不过也给「AI 修脚本」(screennl.fixscript)· 四条; 扫描源没有的 N 日均量(Average(volume, 50))· A 股日线成交量单位 · 五条; 筛选器 · ThinkScript 时间序列引擎(quant/screenseries.py,2026-09-15)· 八条; 筛选器 · 条件行 = plot 的顶层 and 项(screendsl.decompose,2026-09-15)· 五条; 筛选器 · 名字不分大小写(screendsl.fixcase,2026-09-19); 筛选器 · 官方示例「猎杀FOMO做空」(PRESETS key=fomoshort,2026-09-15)· 五条; 部署坑:apps/web/public/ 新增文件要 restart web,改动文件不用; 铁律:改结构走 db/migrations/,api 启动时自动执行; 铁律:/api/catalog/ 是免登录前缀 · 写接口不能挂进去. Use it as a model for your own project's instructions.

Use cases: documentation

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

What's in it

A CLAUDE.md file: project memory Claude Code loads at the start of every session.

For
Claude Code
Length
2,494 lines
File
CLAUDE.md

Sections

  1. 铁律:严禁 mock 兜底 · 空的比假的好
  2. 数据坑:klines.volume 单位按板块不同 —— 科创板(688)是「股」,其他板块是「手」
  3. 数据坑:外部扫描通道(screensource)的五个陷阱
  4. 第三方代码:RS 相对强度评级移植自 IBD-RS-Rating(MIT)· 改动须保留版权声明
  5. 全市场日线管线(quant/rshistory.py)· RS 线上涨天数 · 四条别改坏的
  6. VCP 字段(quant/vcp.py)· 收缩次数 / 每次深度 / 量能递减 · 五条别改坏的
  7. 量化侧的「市场」:回测 / 因子 / 数据下载按市场分开(2026-09-11 加美股)· 五条
  8. 铁律:改 screenkw.py(本地关键词识别)必须先跑回归用例,且只能加不能删
  9. 魔法筛选器第一轮执行用例(2026-09-14)· 挖出来的四条前端规矩
  10. 策略中心静态页的标签页图标
  11. 扫描筛选对照表:AI 识别过的说法沉淀下来(screenlearned)
  12. 扫描筛选:脚本编译不过也给「AI 修脚本」(screennl.fixscript)· 四条
  13. 扫描源没有的 N 日均量(Average(volume, 50))· A 股日线成交量单位 · 五条
  14. 筛选器 · ThinkScript 时间序列引擎(quant/screenseries.py,2026-09-15)· 八条
  15. 筛选器 · 条件行 = plot 的顶层 and 项(screendsl.decompose,2026-09-15)· 五条
  16. 筛选器 · 名字不分大小写(screendsl.fixcase,2026-09-19)
  17. 筛选器 · 官方示例「猎杀FOMO做空」(PRESETS key=fomoshort,2026-09-15)· 五条
  18. 部署坑:apps/web/public/ 新增文件要 restart web,改动文件不用
  19. 铁律:改结构走 db/migrations/,api 启动时自动执行
  20. 铁律:/api/catalog/ 是免登录前缀 · 写接口不能挂进去

First lines (shown under the repo's Apache-2.0 license)

# CLAUDE.md — hunter-community

本文件是 Claude Code 在本仓库工作时会自动读取的项目指令。

---

## 铁律:严禁 mock 兜底 · 空的比假的好

量化 / 指标 / 因子 / 回测 / 评分 类代码,任何**用户会看到或送给 LLM 分析**的数字都必须是真算出来的。算不出就显示 `—` 并注明原因。

### 严禁的模式

- `Object.assign(mockDefault, realResult)` — 真数据缺字段时假数据会露出
- `realValue || 0` / `realValue ?? 0.5` — `0.00` 看起来像个结论
- 渲染层直接写常量或伪造公式(基准 `= 1 + i*0.005`、超额 `= ann_ret - 0.062`、相似度 `= [87,62,54][i]` 之类)
- API 转换层挂 `_mock` / `metrics_mock` 字段 — 修了展示层不算完,上游会继续注入
- 把不确定真假的指标送进 `askHunter` / LLM — 模型会认真点评根本不存在的业绩

### Why

2026-08-18 事故:「全能蓝筹」3 年回测同屏出现「年化 −1.2%」与「信息比率 0.98 / 月度胜率 62%」—— 后两个是 `backtest.html` 里写死的常量,因为后端 `_calc_metrics()` 从来没算过 `ir` / `win_rate`,`Object.assign` 用 mock 补上了。全量排查后共发现 4 个页面 **8 处**假数据(20 个因子的 60 个指标、6 个官方策略 metrics、净值曲线、基准直线、因子归因公式…),其中最糟的是 `askHunter` 把假指标发给 LLM 分析。

相关提交(按顺序读):
```
05c8d3d fix(quant): 回测不再用假数字冒充真结果 (_17 步1-3)
fefcb6c fix(quant): 清掉全部写死的假数据 (_17 全量排查)
13a6f8f feat(quant): 接真指数日线 + 实现回测基准
863d2d1 feat(quant): 指数成分股走代理拉取 + seed 真数据
ba62a96 fix(quant): 补完 _17 剩下四条
9335fe3 fix(quant): 修白屏 —— 漏了两处读取方与三类语法坑
```

演示模式不是借口 —— 要 demo 数据就跑一次真回测把结果存下来当样例,不要在渲染层编。

### 落地方法

**改动前** —— 先全量 grep,把所有假数据来源列一遍再动手:

```bash
grep -rn "mock\|_mock\|Object.assign\|writeDefault\|\|\| 0" apps/web/public apps/api/app
```

**修一处后要再全量排查一次** —— 上游 API 转换层常常在真数据上重新挂假字段。前科:先修了 `backtest.html` 的 mock,但 `app.js:197` 在 API 转换时又挂了 `metrics_mock`,真数据流下来被再次污染。

**删/改字段名要 grep 所有读取方,不能只搜字段名本身:**
- ❌ 只搜 `metrics_mock`
- ✅ 还要搜 `.metrics.` 、`?.metrics`、`s.metrics` 等直接属性访问
- 前科:白屏事故就是漏了 `s.metrics.ann_ret` 这种直接读取

**前端验证不能只靠 HTTP 200 / `node --check` / curl** —— 这些都测不到内联 `<script>` 里的错。用 `apps/web/public/strategies/render_check.js`,在 node 的 `vm` 里真跑一遍页面脚本,假 `document` / `localStorage` / `fetch` 兜住。

### 触发词

出现下列任一词的改动,自动触发本铁律:
> 回测 · 指标 · 因子 · 成分股 · 换手率 · 换仓频率 · 基准 · 超额 · IR · 信息比率 · 胜率 · 净值 · 归因 · 持仓 · 相似度 · 评分 · metrics · sharpe · ann_ret

---

## 数据坑:`klines.volume` 单位按板块不同 —— 科创板(688)是「股」,其他板块是「手」

2026-09-09 实测(2026-09-08 这天各板块 volume 中位数):主板 / 创业板约 12 万 ~ 53 万,
688 约 1470 万,差两个量级。对照真实成交量(600519 约 175 万股/日、688981 约 2800 万股/日),
腾讯源对 688 给的是「股」,其他给的是「手」。`local_kline.py` 没做归一,**存量数据就是这样**。

后果:任何用 volume 换算成交股数 / 成交额的地方(换手率、Amihud、成交额加权),688 会错 100 倍。
实测中芯国际(688981)换手率算成日均 1112%。

规矩:
- 要「股」一律过 `factor_engine._shares_traded(code, volume)`,不要自己乘 100。
- 只用比值的因子(量比、量价相关)不受影响,不必改。
- 新接数据源时先抽三个板块各一只对照真实成交量,把单位写进 provider 的注释。
- `klines` 表**不要**加 `amount` 列去「顺手修」——那是数据中心(doc 22)的事,加了列但历史为空会引出一批 `|| 0`。

同一天顺带发现:`financial_metric` 里少数股票的 `bps`(每股净资产)是错的(600941 给 3.02,真值约 65;
688981 给 659)。用它推股本 / 市值时必须带合理性边界(`_BPS_RANGE` / `_MCAP_RANGE` / `_TURNOVER_MAX`),
越界丢该股票,不进截面排名。

## 数据坑:外部扫描通道(`screen_source`)的五个陷阱

2026-09-10 接入全市场扫描(`apps/api/app/services/quant/screen_source.py` +
`screen_dsl.py`,前端 `strategies/screener.html`)时实测出来的。
它是上游的**非官方内部接口**(地址见 `screen_source._BASE`):免 key、国内直连,
中位 583ms,连打 30 次无限流。定位是**探索性初筛**,不进 `factor_value`、不进回测、不进推送。

### 1. 翻页不带 `sort` 会静默漏掉三分之一的池子(最隐蔽)

不带排序分四页拉美股(每页 2000),累计 8000 条里只有 **4914 只唯一**,重叠 3086 ——
约 2500 只票一次都没被扫到。上游默认顺序在请求之间不稳定,页与页互相错漏。

**症状不是报错**:有命中、有数据、看起来完全正常,只是结果少了一大截,无从察觉。
修法是请求里固定 `sort`(现用 `sortBy: name` 升序),之后 7487/7487 零重叠。
`fetch_rows` 另有一层按 symbol 去重兜底。

**新接任何"分页拉全量"的上游都先做这个测试**:拉两页,断言唯一数 == 累计数。

### 2. `type=stock` + `is_primary` 是正确性前提,不是优化

不加过滤,美股结果里会混进 ETF、权证和优先股存托份额。实测第一次就拿到
`NASDAQ:GOOGM` / `GOOGN`(Alphabet 可转换优先股份额):**市值字段直接继承母公司
4.12 万亿,PE 却是 2.38** —— 按市值排序时它们插在 GOOG 前面。
加过滤后字段填充率同时好转(A 股市值 70%→100%、ROE 68%→97%)。

### 3. `close|1M` **不是**一个月前的收盘价

多周期后缀指的是「该周期上最新那根 K 线」。实测 NVDA 的
`close` / `close|1W` / `close|1M` 三个值完全相同(223.67)。
拿它算动量会得到恒等于 0 的因子。要涨跌幅用 `Perf.W` / `Perf.1M` / `Perf.Y`。

**整个接口没有历史序列**,只有当前横截面快照 —— 所以扫描结果不能回测。

### 4. 市值字段与国内源口径不一致,且自相矛盾

A 股 10 只抽样对腾讯 `qt.gtimg.cn`:**PE / PB 对得很好**(9 只里 8 只 PE 在 ±5% 内,
PB 全部 ≤6%),但**市值差得多**:中芯国际 -37%、比亚迪 -8%、格力 -7%(A+H 两地上市尤甚)。
更糟的是它跟自己的股本字段也对不上 —— `close × total_shares_outstanding_current / market_cap_basic`
在 0.36~0.63 之间且每只不同。

规矩:`market_cap_basic` 只可用于排序和粗筛,**不许当市值真值展示给用户,不许写进因子**。
返回体里 `warnings` 每次都带这句,前端不折叠、不做"下次不再提示"。

### 5. A 股 / 港股的名称、板块是英文,结果行统一过 `screen_cn` 换中文(A 股 2026-09-17、港股 09-19 用户要求)

上游给 A 股的 `description` 是英文公司名、`sector` 是它自己的 21 个英文大类。两个 `_pick`(快照模式、时间序列模式)
在 `md.key == "a"` 时都走 `screen_cn.localize_a_pick`,**只改展示,求值早已结束**。新增第三种出结果的路径也要接上,否则又是英文。

- 名称:仓库自带 `data/stocks_catalog_baseline.json`(5534 只,零网络)打底,后台线程每 24 小时用 akshare
  `stock_info_a_code_name` 补新股(线上实测 5565 只 / 12 秒)。**不许改成同步拉**:会让每次扫描多等十几秒;失败只记日志、30 分钟后再试。
- 清单里是交易所简称原样(「万  科A」全角字母 + 对齐空格),NFKC 后去空白。
- 两级都查不到的保留英文名 —— 英文名是真的,不能留空也不能编。板块对照表里没有的新类别同理原样显示。
- 不用 `stock_industry` 表:只有 2977 只、分类老旧(还有「次新股」「开发区」),覆盖不到一半。
- **港股同样换中文(2026-09-19 用户要求)**:入口改成 `screen_cn.localize_pick(p, md.key)`(`localize_a_pick` 保留为老接口),
  港股按 **5 位代码**查 `data/hk_names_baseline.json`(akshare `stock_hk_spot` 新浪源生成,2803 只,当天港股扫描池 2634 只覆盖 2618 只;
  没覆盖的 16 只多是信托 / 新上市,保留英文),后台每 24 小时同样用 `stock_hk_spot` 补(线上 23 秒;**东财 `stock_hk_spot_em` 本机和 fin-r1 都连不上,别换过去**)。
  板块与 A 股同一张对照表。美股不动。清单要重新生成时照 `test_screen_cn.py` 断言的格式(`items: [{code 5 位, name}]`)。用例 `tests/test_screen_cn.py`。
- `industry` 字段(上游约 130 个细分行业)目前没翻,用户在脚本里显式加了才会出现,仍是英文。

### 另外两条

- **全市场都是延迟 15 分钟**(`update_mode = delayed_streaming_900`,美股/港股/A 股无一例外),
  盘中信号不能用。`lang=zh_CN` 实测**也只返回英文名**,没有中文名可拿。
- **`High.5D / High.1M / High.3M`(及 Low.*)是按日历往回数的,不是 5 / 21 / 63 个交易日。**
  2026-09-11(那周一劳动节休市)拿 16 只自家日线逐个窗口长度比对:5D 实测是最近 **4** 根、
  1M 21 根、3M **61** 根。`Highest(high, 63)` 映射到的就是 `High.3M`,**换写法不换数据**。
  映射提示里现在一律写明这点;要严格按交易日,用自家日线的 `high_5d / low_5d / high_21d / low_21d /
  high_63d / low_63d`(`vcp.py` · 每晚更新 · 只覆盖 RS 排名池)。
- **周期映射不上一律报错,不找"最接近的"顶替**。`Average(volume, 100)` 在扫描源
  只有 10/30/60/90 天均量 —— 拿 90 天冒充 100 天就是在编数字,违反本仓第一条铁律。
  报错信息里要写清可用值,LLM 和用户才能自己改。
  **均量是例外(2026-09-14)**:扫描源没有的周期由自家日线算**真 N 天**(见「扫描源没有的 N 日均量」一节),
  这不是顶替;「拿 90 天冒充 100 天」仍然禁止,超出自家日线上限(250 天)照样报错。
- 缺字段的行求值结果是 `None`,**不计入命中也不算"不满足"**,单独计进 `skipped_incomplete`
  并在 warnings 里说明。把 None 当 0 或当 False 会让 `close > 20` 把所有没报价的票判成
  "不满足",结果看起来完整、实际漏了几百只。

### 波动 / 收缩类筛选的三个坑(2026-09-11 · 用户写 VCP 时查出来的)

1. **`Volatility.D/W/M` 是「日均振幅」,不是这段时间的价格区间。** 拿自家日线反推 6 只票,
   它 ≈ 近 N 天 `(最高-最低)/股价` 的平均(NVDA 扫描源 2.48 vs 自算 2.56)。全市场中位数只有 3.8%,
   用户照「月波动率」的字面写 `Volatility.M < 20`,**90% 的票都满足,等于没筛**。
   中文名已改成「近1月日均振幅」。要「一个月价格波动不超过 10%」写

Signals

Stars
570
Forks
83
Open issues
21
Contributors
10
Last commit (this folder)
Oct 3, 2026 (26 days ago)
Last release
Oct 14, 2026 (15 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
Apache-2.0
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from agentpit-io

Cite this page

CLAUDE.md · agentpit-io/hunter-community. Agent Mart. https://agentmart.dev/templates/agentpit-io-hunter-community-claude-md (last updated 2026-10-24)