day-trader-skill实测:让Claude Code当交易助理,纯Python+确定性+fail-closed

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 做了这些事:

  1. 自动读 .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
  2. 输出 TSLA 行:10:15 AM TSLA $364.18 range 354.47 to 362.18 +0.55% over(逐字一致)
  3. 自动读 trader-risk/SKILL.md,跑 check.py --now '2026-10-19 10:15'
  4. PASS 输出逐字一致
  5. 自动编辑 config.json 把 50 改成 40,重新跑
  6. 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,而在:

  1. 把交易纪律编码成了代码:从 universe 过滤到 risk check 到 BLOCK 不下 broker,每一步都有硬限制;
  2. 把 Agent 工程范式摆出来了:SKILL.md + Python 脚本 + fixtures 快照 + 315 个单测,这是零依赖可复现 Agent 的教科书结构;
  3. 诚实性门槛拉得很高:不吹收益、不说满话、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 账户) 本文如实披露

相关阅读

相关推荐
CCblandy2 小时前
前缀缓存命中率不靠引擎靠排列:本机仿真 3 轮,易变字段放开头 98.0%→0.0%
人工智能·python·算法·自然语言处理·性能优化
Sakura_j_h_2 小时前
给 FastAPI 接大模型:超时、重试和 token 成本该怎么管
python·大模型·fastapi·超时重试·token计费
forest_093 小时前
用Python复刻ClaudeDuet:主动式Agent四件套,定时晨报、后台巡检、危险动作审批(附完整可运行代码)
人工智能·python·架构·prompt·agi
小小张说故事3 小时前
Python 的函数调用到底贵在哪?拆开一次 call:51 纳秒栈帧与 *args 的 40 纳秒罚单
python
程序猿乐锅4 小时前
【从0-1学习Python | 第七篇】Python 面向对象基础
开发语言·笔记·后端·python·学习·1024程序员节
lzqrzpt4 小时前
太阳能控制器选型要点:电路工艺与工程适配技术解析
python·1024程序员节
databook5 小时前
时间序列数据中,如何找出缺失值
python·数据分析
技术小甜甜5 小时前
【Cursor】Skill 被标黄色警告,怎么改成合格的 SKILL.md
开发语言·javascript·ai编程·cursor·1024程序员节·ai agent·skills
小小龙学IT6 小时前
Python Polars 高性能数据处理引擎深度解析
开发语言·python·rust·1024程序员节