
GitHub 532★ 的 day-trader-skill 是 11 个纯 Python 零依赖的 Claude Code skill,从 market scanner 到 risk check 到 broker 下单全覆盖。本机 Python 3.14.7 跑 315 个单测全过,seed 19 确定性复现逐字一致,fail-closed 风控链从过期 plan 到缺 budget 到 BLOCK 单不下 broker 闭环实测。关键发现:不是"AI 帮你选股",是"AI 帮你不做蠢事"。国内直连 Yahoo 不可达,但 fixtures 离线快照解决。Claude Code 接硅基流动有坑(必须用 AUTH_TOKEN 不是 API_KEY)。
一、怎么撞上这个项目的
今天的 GitHub AI 项目日报里,day-trader-skill 以 490★(几天后涨到 532★,10-23 实拉 532/99 星 fork)挤进前二十,标签是 claude-code-skill + trading。我扫了一眼 README 的 SKILL.md 结构------11 个 skill 目录,每个只有一个 SKILL.md + 一个 scan.py/check.py,没有 pip install 行。
零依赖 + 纯 Python + Claude Code skill,这三条同时满足的项目不多。把 tarball 拉下来解压 399KB,11 个目录整整齐齐:scanner、news、entry、exit、timemachine、risk、budget、broker、alerts、analyst、pelosi。
二、第一个停下来的点:SKILL.md 的诚实性写法
做了这么多年后端工具,我第一次看到工具文档里明写这种话:
"Most people who day trade lose money; the scanner does not change that. It only saves you from flipping through 5,000 charts by hand."
"A scan is a list of charts that match a rule, not a list of stocks to buy."
"Partial results are said as partial: Fetched 4,980 of 5,259 charts (279 failed or had no data). Never round a partial scan up to 'the whole market'."
"never say a buy"
这不是产品宣传语,这是写作者的工程纪律。风控出身的人对这种"不说满"的写法有本能好感。后面实测的 fail-closed 设计从 SKILL.md 里已经能闻到味道。
三、第二个停下来的点:seed 19 确定性
tests/fixtures 目录有一个完整的快照 wall5m-2026-10-19.json.gz,是 10 月 19 日 234 只股票的 5 分钟线原始数据。README 里直接给了复现命令和预期输出:
python3 scan.py orb --offline wall5m-2026-10-19.json.gz --now "2026-10-19 10:15" --min-price 0
Fetched 233 of 234 charts; 231 usable; 95 candidates, 95 confirmed.
42 of 231 charts closed above their opening-range high by 10:15 AM:
...
10:15 AM TSLA $364.18 range 354.47 to 362.18 +0.55% over
我在本机跑了三次,每次输出逐字一致。315 个 unittest 27 秒全过,其中有个 timemachine 测试 seed 19 跑 59 天回测,输出 "target 29.4% / stop 25.5% / neither 45.1%"------每次完全一样。
这和前两天 DeepInfer 那篇实测里提到的 batch-invariant inference 开关撞在一起了:真正的可复现不是靠"尽量别变",而是靠 seed + 快照 + 固定时间戳。day-trader-skill 把这三件事都做了,还把它们写进了 README 的示例里。DeepInfer 是在推理框架层面提供确定性开关,day-trader-skill 是在 agent 工具层面用确定性做实测基线------两边不约而同地对"可复现"给出了同样的答案。
四、第三个停下来的点:fail-closed 风控链
把 TSLA 的 plan.json 丢进 risk/check.py,默认 max_loss_per_trade_usd=50:
PASS #1 buy TSLA 8 shares, entry
entry 364.18, stop 358.32, target 370.04: risk 5.86 a share
max loss $46.88 (limit $50), reward:risk 1.00 (min 1)
Every order passed. trader-broker still asks you yes or no for each one.
然后改 config.json 把 max_loss 从 50 调到 40,重新跑:
BLOCK #1 buy TSLA 8 shares, entry
max loss $46.88 (limit $40)
- loss: 8 shares x 5.86 risk a share = $46.88 at the stop, over your $40 max loss per trade
Blocked orders do not go to the broker. Fix the order or your rules, then check again.
风控出身的人看到这个会本能停下来:不是"报错退出",不是"返回一个状态码",而是明确告诉你"被 BLOCK 的单不会到 broker"。整条 fail-closed 链是:
- 过期 plan → 直接拒绝,输出 "the plan is for 2026-10-19 and today is 2026-10-22"
- 缺 budget → 直接拒绝,输出 "you have 0 and the order costs 2,913"
- risk BLOCK → 不下 broker,明确写 "Blocked orders do not go to the broker"
budget 模块还有个更细的设计:四层仓位限制取最小。max_loss_per_trade_usd 绑定 8 股,position cap 允许 10 股,max_order 允许 10 股,cash 允许 12 股------最终取 8。这个"限额收敛"的逻辑和并发调优那篇里讲的背压设计是同一个路子:永远取最紧的那个限制。
五、Claude Code 完整 agent 链路实测
这才是最有意思的部分。把 11 个 skill 目录拷到项目级 .claude/skills/,让 Claude Code 自己编排:scanner 找 setup → risk 验证 → budget 算仓位 → broker 下单。
5.1 踩了 SiliconFlow 接入的坑
Claude Code 直连硅基流动一开始报 401,折腾了两小时才找到根因:
| 变量名 | Claude Code 发送的 header | 我的初始设置 | 正确设置 |
|---|---|---|---|
ANTHROPIC_API_KEY |
x-api-key: <key> |
✅ 用了这个 | ❌ 不用 |
ANTHROPIC_AUTH_TOKEN |
Authorization: Bearer <token> |
❌ 没设 | ✅ 必须用这个 |
还有几个细节坑:
ANTHROPIC_BASE_URL不带 /v1 ,Claude Code 会自动追加/v1/messages;- 国内用户推荐
api.siliconflow.cn端点(这篇实测用的就是这个,api.siliconflow.com未做对照验证); - 模型 ID 用
deepseek-ai/DeepSeek-V4-Flash,不要随便加-0813或[1m]后缀。
最终配置(测试环境,不动你全局 ark 设置):
ANTHROPIC_BASE_URL=https://api.siliconflow.cn
ANTHROPIC_AUTH_TOKEN=sk-xxx
ANTHROPIC_MODEL=deepseek-ai/DeepSeek-V4-Flash
5.2 agent 编排全程
给 Claude Code 的 prompt:"用 trader-scanner 跑 fixtures 离线扫描找 TSLA setup,然后读 trader-risk/SKILL.md 跑 risk check,PASS 后改 config.json 的 max_loss 到 40 再跑一次"。
Claude Code 做了这些事:
- 自动读
.claude/skills/trader-scanner/SKILL.md,拼出scan.py orb --offline wall5m-2026-10-19.json.gz --now '2026-10-19 10:15' --min-price 0 - 输出 TSLA 行:
10:15 AM TSLA $364.18 range 354.47 to 362.18 +0.55% over(逐字一致) - 自动读 trader-risk/SKILL.md,跑
check.py --now '2026-10-19 10:15' - PASS 输出逐字一致
- 自动编辑 config.json 把 50 改成 40,重新跑
- BLOCK 输出逐字一致,自己总结"被 BLOCK 的单不会到 broker"
15 轮对话、109,824 tokens cache read(SiliconFlow 缓存效果极好)、$0.43 总成本。
5.3 国内直连实测矩阵
| 服务 | 端点 | 国内直连 | 备注 |
|---|---|---|---|
| GitHub API | api.github.com | ✅ 200 | tarball 下载 399KB 成功 |
| Nasdaq Trader | nasdaqtrader.com | ✅ 200 | universe 实拉 13,297 行→5,945 只 |
| SEC | sec.gov | ✅ 200(需 UA) | EDGAR 查询 |
| Yahoo Finance | query2.finance.yahoo.com | ❌ 403/429 | 最大限制,fixtures 离线复现绕过 |
| SiliconFlow | api.siliconflow.cn | ✅ 200 | Anthropic 兼容端点 |
Yahoo 不可直连对国内用户是硬伤,但 day-trader-skill 的 --offline 参数把这个问题解决了------所有历史测试数据都存在 tests/fixtures 里,任何机器任何时间跑结果一致。这也是确定性设计的延伸。
六、如果我把它搬到 A 股------改 1 行正则就能用
写到这里有读者肯定会问:美市的东西对 A 股有用吗?我的风控背景让我对这个问题特别敏感------如果工具换个市场就得重写一半逻辑,那它的价值就打折了。所以我拿 risk/check.py 做了个最小迁移试验。
6.1 代码里哪些地方锁死了美市
扫完整个 risk/check.py,4 处美市硬编码:
| 位置 | 硬编码内容 | 对 A 股的影响 |
|---|---|---|
| L87 TICKER 正则 | ^[A-Z]{1,5}([.\-][A-Z]{1,2})?$ 只允许美市 1-5 位字母 |
600519 这种 6 位数字直接被 asset 检查拒掉 |
| L94-114 NYSE_HOLIDAYS | 写死美国 2026-2027 节假日 | A 股交易日会被"市场关闭"block |
| L139-147 时区转换 | eastern_offset() 写死美东夏令时规则 |
--now 解析会偏移 8 小时 |
| L122-124 交易窗口 | 9:30-16:00 ET | A 股 9:30-11:30/13:00-15:00 时段对不上 |
好消息是风控计算逻辑本身一行都不用改:risk/share 数值、max_loss 限额、reward:risk 比例、daily loss 累计、position cap,这些全是纯数值运算,和叫 TSLA 还是 600519 没关系。
6.2 改 1 行正则 + 今日真实 A 股行情跑通风控
我不想停留在 mock 数据,所以拿今日(2026-10-23,周四,A 股交易日)的真实行情做了完整验证。数据源是东方财富的公开行情接口(push2.eastmoney.com,国内直连 200 OK),拉了全市场 5000 只股票的实时快照。
今日市场特征:光模块板块领跌(中际旭创 -5.02%、新易盛 -6.57%),三只涨停(天娱数科、兆威机电、襄阳轴承,10%,买不进)。选了宇树科技 688836(科创板,机器人概念)做风控验证,理由:
- 现价 530.10,涨幅 +1.94%,日内位置 85.8%(接近高点但没封板,可交易)
- 成交额 11.06 亿,流动性够
- 走势:10-19 暴拉 +16.15%、10-20 再涨 +6.07%,然后回调 3 天,今日反弹
20 天 K 线算的合理交易计划(entry 530.10,stop 477.64,target 582.56,risk/share=52.46,R:R=1.0)。stop 设为 2x 日均振幅(26.23)之下,刚好落在 20 日均线(469.79)上方,技术上合理。
TICKER 正则改 1 行(加 \|\d{6} 分支),其他不动:
python
# 改前
TICKER = re.compile(r"^[A-Z]{1,5}([.\-][A-Z]{1,2})?$")
# 改后:
TICKER = re.compile(r"^([A-Z]{1,5}([.\-][A-Z]{1,2})?|\d{6})$")
调 config.json(budget=60w,max_loss=6000,position cap=75%),跑 risk/check.py:
PASS(60w 账户,max_loss=6000,5 层 limit 全部通过):
PASS #1 buy 688836 100 shares, entry
entry 530.10, stop 477.64, target 582.56: risk 52.46 a share
max loss $5,246 (limit $6,000), reward:risk 1.00 (min 1)
1 passed, 0 blocked
Cash after the passed orders: $546,990 (paper account).
BLOCK(max_loss 降到 4000,仅此一层触发):
BLOCK #1 buy 688836 100 shares, entry
max loss $5,246 (limit $4,000)
- loss: 100 shares x 52.46 risk a share = $5,246 at the stop, over your $4,000 max loss per trade
0 passed, 1 blocked
Blocked orders do not go to the broker. Fix the order or your rules, then check again.
还有一个有意思的发现:用原始的小账户 config(budget=5000,max_order=4000)直接跑这只 530.10 的票,5 层 limit 同时触发 BLOCK:
- size: $53,010 is over your $4,000 max order
- cash: needs $53,010 but only $5,000 cash
- position: 1060.2% of $5,000 account, over 75% cap
- loss: $5,246 over $50 max loss
- daily loss: $5,246 over $150 daily limit
这就是 fail-closed 的威力:你不需要等某一条规则单独触发,任何一条超限都直接 BLOCK,被 BLOCK 的单不会到 broker。
改 1 行正则 + 一组 config 参数 + 今日真实行情,风控逻辑直接跨市场 。而且这个改动不会破坏美市支持------正则是"美市 1-5 位字母 或 A 股 6 位数字",两条路并存。
6.3 哪些 skill 可以直接拿过来
11 个 skill 按依赖分三类:
| 类别 | skill | 美市硬依赖 | A 股迁移成本 |
|---|---|---|---|
| 可直接复用(纯计算/纯文件) | risk、budget、timemachine(回放) | 无 | 零 |
| 改 1 行正则+数据源 | exit(stop/before/entry 逻辑) | TICKER 正则 | < 10 分钟 |
| 重写数据源 | scanner(行情)、entry(行情)、news(Yahoo RSS) | Yahoo Finance、nasdaqtrader | 2-3 小时,换东方财富/新浪财经接口 |
| 绑券商 | broker | Alpaca SDK | 需换 A 股券商 SDK 或改为仅输出下单指令 |
对国内交易者来说,risk + budget + fail-closed 风控链 这一套是零成本可以抄的------这也是这篇实测里最有价值的部分:不是那个 scanner 找 setup,而是找到 setup 之后那一套"先算 risk 再算 budget 再算 position cap,任何一层超限都 BLOCK,被 BLOCK 的单不会到 broker"的流水线。
七、我的判断
day-trader-skill 解决的不是"帮你选股",而是"帮你不做蠢事"。它的核心价值不在 alpha,而在:
- 把交易纪律编码成了代码:从 universe 过滤到 risk check 到 BLOCK 不下 broker,每一步都有硬限制;
- 把 Agent 工程范式摆出来了:SKILL.md + Python 脚本 + fixtures 快照 + 315 个单测,这是零依赖可复现 Agent 的教科书结构;
- 诚实性门槛拉得很高:不吹收益、不说满话、Partial results 老实报。
适用场景:做交易系统的人可以参考它的 fail-closed 和确定性设计;做 Claude Code skill 的人可以直接套它的目录结构和 SKILL.md 模板;想体验"agent 编排"的人可以直接装这 11 个 skill 跑 fixtures。
不适用场景:想让 AI 帮你选股票赚快钱的(它明说 never say a buy);没有美国券商账户的(broker 模块绑 Alpaca);对秒级行情有要求的(Yahoo 是 5 分钟 bar,而且国内不可达)。
附录:核验数据
| 项目 | 数值 | 来源 |
|---|---|---|
| 星/fork | 532 / 99 | GitHub API Jakeschincariol/day-trader-skill,2026-10-23 实拉 |
| 测试通过率 | 315/315,27 秒 | python -m unittest discover,Python 3.14.7 |
| 确定性 | seed 19 三次输出逐字一致 | 本机三次复现 |
| fail-closed | 过期 plan 拒 / 缺 budget 拒 / BLOCK 不下 broker | 三处实测证据 |
| 成本 | 15 轮 $0.43 | Claude Code JSON 输出 |
| 未实测 | broker 实盘下单(需 Alpaca paper 账户) | 本文如实披露 |
相关阅读