Simon Lin
|
ed778c51ee
|
chore: release v0.5.15
v0.5.15
|
2026-08-19 15:50:46 +08:00 |
|
KK
|
8db46605b3
|
feat: support per-role api_key in role_llms for multi-gateway setups (#94)
* feat: support per-role api_key in role_llms for multi-gateway setups
* test: add per-role api_key precedence tests for openai_compatible provider
---------
Co-authored-by: k176060444-lgtm <k176060444-lgtm@users.noreply.github.com>
|
2026-08-19 15:43:12 +08:00 |
|
Simon Lin
|
0badc3340c
|
fix: 连字符分隔符被当成构词 / 版本号三处不同步(codex 第九轮)
1. `最终评级:**Sell**- 退出` 里的 - 只是分隔符,却被当成"会延续成更长的词"判否,
parse_rating 静默返回 Hold,记录下错误的决策。
判据再补一层:连字符要看后面——跟字母/数字是构词(Sell-off / Buy-side 拒),
跟空白或其它字符只是分隔符(Sell- 退出 收)。覆盖矩阵扩到 27 例。
2. 上一版改了 pyproject 和 CHANGELOG,漏了 CLAUDE.md 的「当前版本」行,后续 agent
和发版流程会读到旧版本。新增 test_version_consistency.py,三处不一致直接失败,
不再靠人记得。
测试:新增 4 例,369 passed / 13 skipped / 0 failed。→ v0.5.14
v0.5.14
|
2026-08-09 15:30:44 +12:00 |
|
Simon Lin
|
1edf4be27b
|
fix: 加粗+连字符仍被判成评级(正则回溯,codex 第八轮)
v0.5.12 把 markdown 收尾星号写成 \*{0,2}(?!词字符)——先消耗再判断会回溯:
`建议:**Sell**-off risk remains elevated` 里 \*{0,2} 先吃掉 **,被 - 判否后退一步
只吃一个 *,剩下那个 * 恰好满足边界,于是又判成 Sell。正好把这条规则本来要挡的
连字符散文放了回来。
改成把星号放进前瞻内部((?!\*{0,2}词字符))——"后面不能是(0~2 个星号 + 词字符)"
没有可回溯的余地。`最终评级:**Sell**` 不受影响。
⚠️ 刻意不用占有量词 (?>...) / *+:那是 Python 3.11+ 特性,而本项目声明
requires-python = ">=3.10",3.10 用户会在导入时就 re.error——比逻辑 bug 更硬的破坏。
新增守卫用例直接检查编译后的 pattern。
覆盖矩阵扩到 25 例。测试:新增 4 例,365 passed / 13 skipped / 0 failed。→ v0.5.13
|
2026-08-09 15:23:53 +12:00 |
|
Simon Lin
|
be38f469d8
|
refactor: 评级边界与 BESTIP 保护改用正确抽象(codex 第七轮)
这两块前后各被修了三轮"修了又漏",问题不在某个字符,在抽象选错了。
1. 评级边界:枚举标点 → 「不能延续成更长的词」
第七轮指出 v0.5.11 收紧后又误伤 `最终评级:Buy(基于风险收益比)`——枚举的是
收尾标点,没算开括号,合法评级被静默改写成 Hold。
三轮轨迹:无边界→`Buyer interest`判Buy;(?![A-Za-z])→`Sell-off`判Sell;
枚举收尾标点→`Buy(...)`反被判Hold。
枚举允许的标点是填不完的坑。改成只问:紧跟其后的字符会不会让它变成另一个词
([A-Za-z0-9_-])?会就不算评级,中文/括号/标点/空白/行尾一律放行。
新增 22 例参数化矩阵,并写明改这条规则必须整张过一遍。
2. BESTIP 保护:手动调还原 → 上下文管理器
原来在两处手动调 _restore_bestip(),再加一条提前返回就会漏,而漏掉的后果是
静默留下一台死服务器。改成 with _preserve_mootdx_bestip() as keep:选中时
调 keep() 表示这次覆写是想要的,其余每条退出路径(含异常)自动还原。
_get_mootdx_client 114 → 82 行。
端到端实测:真实探测 38 台全失败后,用户配置的 218.6.170.47 完好无损。
测试:新增 21 例,361 passed / 13 skipped / 0 failed。版本 → v0.5.12
|
2026-08-09 15:16:18 +12:00 |
|
Simon Lin
|
f5cd0ef67f
|
fix: 上一版那两个修复本身都没修对(codex 第六轮)
1. BESTIP 快照取到的是空默认值 → v0.5.10 的修复无效
新进程里 mootdx 要等 BaseQuotes.__init__ 调 config.setup() 之后才把持久化的值
读进来,此前 get("BESTIP") 是模块默认空值。快照到空值后,全部探测失败时的
"还原"反而把用户真实配置抹成空——比不还原更糟。
实测 0.11.7:setup 前 {'HQ': ''},setup 后 {'HQ': ['218.6.170.47', 7709]}。
现在快照前先显式 setup();端到端验证真实探测 38 台全失败后用户配置完好。
测试也改为复刻真实构造函数语义(旧假件不调 setup,抓不到这条)。
2. 评级边界仍放行连字符散文 → v0.5.10 的修复不完整
(?![A-Za-z]) 只挡紧跟字母的情况,连字符和数字后缀照样过关:
`建议:Sell-off risk remains elevated` → Sell、`最终评级:Buy2024` → Buy。
改为要求评级词后是真正的结束(行尾/空白/中文/常见标点),并先吃掉 markdown
收尾星号,`最终评级:**Sell**` 不受影响。
测试:新增 2 例,340 passed / 13 skipped / 0 failed。版本 → v0.5.11
|
2026-08-09 15:05:04 +12:00 |
|
Simon Lin
|
cbabc02fc9
|
fix: 探测覆写 mootdx 配置 / 中英混排评级误判(codex 第五轮)
两处都是新增行为自己带出来的副作用。
1. 探测服务器会覆写用户配置的 mootdx 服务器
StdQuotes.__init__ 里有 config.set('BESTIP', {'HQ': self.server})——每建一次
带 server 的 client 都会持久化写进配置文件。v0.5.6 把候选表扩到 38 台后,逐台
探测等于一路覆写用户原本配好的服务器,最后留下最后一台失败的:裸 factory 兜底
(读 BESTIP)再也救不回来,同机上其它用 mootdx 的程序也被连累。
现在探测前快照 BESTIP,兜底前与全失败时都还原。
2. 中文标签后跟英文散文被误判成评级
_CN_LABEL_EN_RE 缺词边界:`最终评级:Buyer interest remains weak` → Buy,
`建议:Selling pressure is high` → Sell。误判会写进记忆日志再污染绩效统计,
报告里完全看不出来。已加 (?![A-Za-z]),正常中英混排不受影响。
测试:新增 4 例,338 passed / 13 skipped / 0 failed。版本 → v0.5.10
|
2026-08-09 14:55:30 +12:00 |
|
Simon Lin
|
3968973958
|
fix: 未完成任务索引写失败不再静默吞掉(承接 #93)
#93 的重试 + 降级思路是对的,但最后一层 `except OSError: pass` 完全静默——
索引一直写不进去时用户永远不会知道,「未完成任务」列表长期不更新也无从排查。
改为打一条 warning:仍然不往上抛(不中断分析,读取端容错、下次会重建),
但至少可见。本项目对静默吞错一贯从严。
|
2026-08-09 14:50:12 +12:00 |
|
whxyw4
|
3b9346762f
|
fix: 修复 Web UI 崩溃 - Windows 文件锁冲突 (PermissionError WinError 5) (#93)
web/history.py _save_incomplete_index 的 tmp.replace() 在 Windows 上目标文件被占用时抛 PermissionError,导致多实例并发时侧边栏渲染崩溃。改为 3 次重试 + 降级直写 + 兜底静默,索引写失败不再致命(读取端已容错 JSON)。
Co-authored-by: Claude <noreply@anthropic.com>
|
2026-08-09 14:48:53 +12:00 |
|
Simon Lin
|
ed0c416907
|
fix: 裸跑 CLI 被打断 / 时区误判 / README 口径不符(codex 第四轮)
🔴 裸跑 tradingagents 被 v0.5.2 打断(升级即破坏)
Typer 只有一个命令时是"单命令模式",加了 performance 子命令后切换成命令组
模式,裸跑直接报 Missing command 退出——而 README 和所有文档写的都是裸跑,
每个现有用户升级后第一条命令就失败。加 invoke_without_command callback 保住
默认路径,--checkpoint 等原参数照常可用。
时区误判
_is_historical 用主机本地日期。主机在 UTC+9 以东(如新西兰)时当地已过零点
而上海还在前一天,当天分析被判成"复盘历史":实时资金流被略去、快照工具打出
莫须有的未来函数警告。改为固定按 Asia/Shanghai 市场时区计算。
README 口径与实际输出不符
v0.5.6 已把指标改名为 direction_accuracy / up_rate / outperform_rate,README
仍写"胜率 / alpha 胜率"——而这恰恰是 v0.5.6 要纠正的误导。中英文已同步。
测试:新增 5 例(含一例断言 callback 注释写明了后果,防止重构时被误删),
334 passed / 13 skipped / 0 failed。版本 → v0.5.9
|
2026-08-09 14:43:23 +12:00 |
|
Simon Lin
|
fb96e0ac9c
|
fix: codex 终轮四处(告警仍不触发/窗口没裁回/多建模型/显著性分母)
前三轮修的东西里,有两处"看着修好了、实际没生效":
1. 未来函数告警仍然不触发
v0.5.6 给 get_profit_forecast 补了 curr_date,但给了默认空串——LangChain 只把
ticker 标成必填,模型正常调用时 curr_date 为空,_is_historical("") 为 False,
告警照样一次都不触发。提示词里也没提这个参数。改为必填 + 提示词显式说明。
2. 历史资金流放大窗口后没裁回
为够回溯放大了请求窗口,过滤未来行后没裁回承诺的 20 个交易日——复盘 90 天前
返回约 40 行,改变了趋势窗口且返回体翻倍。
3. 未选中的分析师角色也会被建模型
role_llms 配了 policy 但本次只选 market 时,policy 的模型仍被实例化。一个永远
不执行的节点可能因缺 key 或缺可选依赖,把本来正常的分析在启动时打断。
4. 方向正确率的显著性用错分母
direction_accuracy 排除 Hold,却用已结算总数判断样本是否足够。20 条已结算里
只有 1 条有方向时,噪音提示被抑制,报告却显示"方向正确率 100%"。
测试:新增 7 例,329 passed / 13 skipped / 0 failed。版本 → v0.5.8
|
2026-08-09 14:29:14 +12:00 |
|
Simon Lin
|
e7af375595
|
docs: 补 pip 与 Python 版本对不上的排错 FAQ (#92)
用户装了 Python 3.14,pip install -e . 却报 requires a different Python: 3.9.6。
不是仓库问题——报错里的 3.9.6 就是当前 pip 绑定的解释器(macOS 自带 pip3 常指向
系统 3.9),但这句提示容易让人以为是项目要求写错了。
中英文 README 各加一条 FAQ:怎么确认 pip 对应哪个解释器、为什么推荐 python -m pip
的写法、配合虚拟环境的完整命令(含 Windows)。版本 → v0.5.7。
|
2026-08-09 14:14:49 +12:00 |
|
Simon Lin
|
eaf3876b28
|
fix: codex 复审五处(告警死代码/资金流被滤空/只试10台/参数串味/降级丢上限)
复审的价值这轮很明显——其中两条正是上一版修复自己留下的洞。
1. 未来函数告警是死代码
v0.5.1 给 get_profit_forecast 加了告警,但它的 @tool 只暴露 ticker、
route_to_vendor 也只传 ticker,curr_date 恒为 None → 判定永远 False,
告警一次都不会触发。审计了全部 17 个工具,只有这一个漏传。
2. 历史资金流被过滤成一条不剩
东财接口只给"从今天回溯 N 天"、无 end_date。固定要 20 天再按 curr_date 过滤,
复盘较早日期时返回的 20 行全在分析日之后,滤完一行不剩——把"数据不对"变成
"没有数据"。而当时的测试夹具返回了真实请求不会包含的旧数据,把问题盖住了。
现按间隔放大窗口(上限 500),取不到时明说原因。
3. mootdx 只试 10 台就判"全网不可达"
v0.5.5 为规避 bestip 全表测速而跳过它,导致 mootdx 自带表其余 28 台永远试不到。
候选表扩为 38 台(精选在前)逐台真实验证;TCP 预筛改并发(只并行化等 IO,
不改选取顺序)。实测 73.7s → 27.0s,覆盖面反而从 10 台升到 38 台。
4. 角色模型串味
role_llms 用别家 provider 时仍复用主 provider 的 llm_kwargs,
reasoning_effort/thinking_level/effort 是各家私有参数,别家可能直接拒收。
现按角色 provider 过滤,通用参数保留。
5. 订阅降级后 max_tokens 丢失
max_tokens 只进 llm_kwargs 没进 fallback_spec,撞额度降级后报告照样被截断。
测试:新增 6 例,322 passed / 13 skipped / 0 failed
|
2026-08-09 14:01:55 +12:00 |
|
Simon Lin
|
383a38dc31
|
fix: codex 审计五处修复(截断告警/防护漏洞/胜率算反/持有期/服务器探测)
五条全部实测复现,无一误报。
1. 截断告警对默认 provider 根本不会响
只认 Anthropic 的 stop_reason=max_tokens 与 Chat 的 finish_reason=length,
而 openai 是默认 provider 且走 Responses API(status=incomplete +
incomplete_details.reason=max_output_tokens),Gemini 是大写 MAX_TOKENS。
v0.5.1 加的这个告警在默认配置下一次都不会触发。现覆盖四种形状。
2. 非 A 股防护漏了三个 vendor
get_dragon_tiger_board / get_lockup_expiry / get_industry_comparison 直接调
safe_ticker_component 绕过了 _normalize_ticker。实测拿 00700 调用返回的是
看起来完全正常的报告("近30日未上龙虎榜"),模型会当成腾讯的事实。
v0.5.3 声称的"一个卡点覆盖 15 个接口"并不成立。
3. 绩效统计对看空评级把对错算反
给 Sell 后股价下跌是判断正确,原实现只看收益是否为正,记成失败。新增
direction_accuracy(按方向判定,Hold 不计入),原指标改名 up_rate /
outperform_rate —— 命名即口径,报告写明它们与判断对错无关。
4. 平均持有期永远缺失
记忆日志写 "5d",int() 抛异常被吞成 None。改为提取数字部分。
5. mootdx 提前收手会漏掉可用服务器
三台远端拒绝推不出本地封了协议,靠后的服务器可能是好的。移除提前退出,
跑完整张表。实测 18.7s → 23.7s(最初 >170s,bestip 全表测速仍单独规避)。
测试:新增 13 例,316 passed / 13 skipped / 0 failed
|
2026-08-09 13:38:45 +12:00 |
|
Simon Lin
|
4e181897dc
|
fix: ClaudeSDKError 占位符退化成 Exception 让计费护栏失效;测试套件恢复全绿
护栏隐患
可选依赖未装时 ClaudeSDKError 被占位成 Exception("防 except 子句 NameError")。
但它会进 _FALLBACK_ERRORS —— 决定哪些错误可降级到按 token 计费的 provider。
退化成 Exception 后 isinstance(任何异常, ...) 恒为真,连刻意排除在外的
_AuthError(订阅凭据失效)也被判成可降级,而这条护栏的全部意义就是不让
token 过期变成悄悄烧 API 账单。改用独立的 _MissingSDKError 占位。
测试套件
9 个用例会走到 SDK 自己的 API(ClaudeAgentOptions / create_sdk_mcp_server),
没装依赖就 ImportError 报红;同文件另外 3 个早已用 skipif 处理同样情况,这 9 个
只是漏加。长期红的代价是没人再看——本次排查前这批红被反复当成"缺依赖噪音"掠过,
而其中两条正是上面那条计费护栏的测试。按文件既有约定加 requires_sdk 标记。
干净 clone(pip install -e . 不带 [agentsdk]):303 passed, 13 skipped, 0 failed
|
2026-08-06 20:59:51 +12:00 |
|
Simon Lin
|
b0c39ea915
|
fix: 港股/美股代码不再被当成 A 股静默查询 (#43 前置)
_normalize_ticker 文档写着"返回纯 6 位代码"却从不校验位数:港股 00700 /
0700.HK、美股 AAPL 全部原样放行,拿去问 mootdx/腾讯/东财。这些源对不存在的
代码往往不报错,只返回空值或僵尸报价(北交所 920 号段同类问题),模型会拿一份
看起来正常、实际属于别的市场的数据写完整篇报告。
- 一个卡点覆盖 15 个数据接口(所有 vendor 方法都过 _normalize_ticker)
- 港股报错指明去处(global-stock-data)与 roadmap(#43),不只说"不支持"
- A 股各写法不受影响:SH600519 / 600519.SH / sz000001 / 北交所 920002
港股多 Agent 分析仍在 roadmap。数据层可行性已实测:腾讯/新浪/东财 push2/
Yahoo K线/东财港股三表 五个端点全部可用;但政策/游资/解禁三个 A 股特化角色
对港股不适用,需单独设计角色集。
测试:新增 24 例(两侧都锁),全量回归 301 passed
|
2026-08-06 20:53:04 +12:00 |
|
Simon Lin
|
cdca5e1f8f
|
feat: 决策绩效统计 + 修复中英混排评级被静默判成 Hold (#61)
新增 tradingagents performance
决策与真实收益一直都在记忆日志里(store_decision → 下次分析同一只票时自动拉
行情回填 raw/alpha),缺的只是汇总——此前全仓连一个胜率都算不出来。零 LLM 调用。
- 整体胜率 / alpha 胜率 / 平均与中位收益,按评级、按标的分组
- 评级区分度检验:五档从 Buy 到 Sell 平均 alpha 是否单调递减;仅在五档都有
样本时给结论
- --json 输出
三条不许骗人的设计:收益解析不出来的记录跳过而非计 0%;样本 <20 条报告自己标
注是噪音;结尾写明这不是回测(窗口重叠、无仓位管理、未计成本、可能有选择偏差)。
刻意不算夏普/年化——离散且重叠的决策点年化没有意义。
指标口径参考 Vibe-Trading(MIT)的 agent/backtest/metrics.py。
修复:`最终评级:Buy` 被静默判成 Hold
中文标签 + 英文评级词的混排躲过了原有每一条规则(英文标签规则要 "rating";
中文标签规则只认中文词;裸英文词扫描按空白切分,全角冒号 strip 不掉)。
决策评级被悄悄改写且报告里看不出来,是 #78/#80 的未修变种。这个洞会直接污染
上面的绩效统计,是用真实数据验证报告时撞出来的。
测试:新增 20 例,全量回归 277 passed
|
2026-08-06 20:48:57 +12:00 |
|
Simon Lin
|
5789834f43
|
fix: 未来函数 —— 三个接口收了日期参数却完全没用 (#61)
AST 扫全部 15 个数据接口,发现 get_fund_flow / get_fundamentals /
get_profit_forecast 收了 curr_date 却在正文里从未引用。在历史日期上跑分析时,
它们返回的是"今天"的数据,而报告里完全看不出被污染——静默失败。
- get_fund_flow 做真正的时点截断:历史日线逐行按 curr_date 过滤;复盘时整段
不取实时分钟资金流(只有今天的),并说明为何略去。当天分析行为不变。
- get_fundamentals / get_profit_forecast 的数据源不提供历史时点值,补不上就
明说:正文顶部插入未来函数告警,点名分析日期,并给模型明确指令不得当作
当天已知事实。当天分析不显示告警。
- 新增 _is_historical() / _snapshot_notice() 共用工具。
对照上游:TauricResearch/TradingAgents 无回测引擎,其 "backtesting" 指的正是这类
date fidelity(#475,覆盖 yfinance 新闻)。本次是 A 股数据层的同类审计。
测试:新增 15 例,含反向边界(当天分析不被误伤、解析不了的日期不算历史)。
全量回归 258 passed。
|
2026-08-06 20:35:36 +12:00 |
|
Simon Lin
|
579744100e
|
feat: 分角色模型(可选)+ 情绪分析师改为数据驱动 (#39 #61)
#39 role_llms(默认关闭,行为不变)
同一模型分饰多空两角时倾向自我附和,辩论失去意义。现在可给单个角色指定另一家
模型。16 个可配角色,agent 文件一个都没动——工厂签名本来就统一吃 llm。
- 角色名写错当场报错,不静默忽略
- 相同 provider+model 复用同一实例,不会开 N 条连接
- 换 provider 不继承主 provider 的 backend_url
- 与订阅覆盖并用时点名警告哪些角色会绕开订阅计费
#61 情绪分析师数据驱动
此前只有 get_news,只能从新闻语气推断情绪。补上 get_fund_flow / get_stock_data
/ get_hot_stocks,提示词改为「先看资金再看新闻」,强制报出「资金面与消息面是否
背离」。ToolNode 同步注册,并加测试锁死两处一致性。
承接 #90:修掉 v0.4.1 自己引入的退步
全表不可用时会跑 bestip 全表测速,首次调用实测 >170s。根因是协议层失败没被计数
——这批服务器在 Quotes.factory 握手期就抛错,走不到取数验证那步。修正计数、协议
被拒时跳过 bestip(同协议同主机,不可能有别的结果)、连续 3 台失败即停手。
实测 >170s → 18.7s,二次调用 0ms。报错据实区分「连不上」与「协议被拒」。
测试:新增 21 例,全量回归 243 passed
(11 failed 为缺可选依赖 claude_agent_sdk 的既有失败)
|
2026-08-06 20:18:10 +12:00 |
|
Simon Lin
|
574b6c2cdd
|
fix: 三处静默失败 —— mootdx 反复降级 / 报告被截断 / Kimi 401 (#90 #91 #89)
#90 mootdx 反复降级、永不恢复
_probe_tdx() 只做 TCP 握手就认定服务器可用,但内置服务器表里有相当一部分
TCP 能连上、通达信协议握手立刻被 RST。旧逻辑挑中这种服务器写进单例钉死,
之后每次取数都失败降级且永不重选。
- 选服务器必须真的拉到一根 K 线才采用,否则换下一台
- 所有 mootdx 调用走 _mootdx_call(),失败即弃用当前 client
- 全挂时记负缓存,5 分钟内快速失败,不再逐台重探
#91 报告输出到一半结束
撞的是输出 token 上限而非上下文,返回值合法、无任何提示。
- 截断时明确告警(anthropic/openai/google/azure 四条通道)
- 新增 max_tokens 配置项与 TRADINGAGENTS_MAX_TOKENS 环境变量
(OpenAI 兼容通道此前根本不转发该参数)
- 非 Claude 模型名走 anthropic 通道时默认放宽到 8192,避免落到
langchain 的 4096 兜底值;判据用模型名前缀,不误伤带日期的 Claude ID
#89 接 Kimi 报 401 invalid x-api-key
README 教用户设 ANTHROPIC_AUTH_TOKEN,而该变量本项目从不读取(Claude Code
CLI 的约定)。照做的用户请求发到 api.anthropic.com,报与 Kimi 无关的 401。
- 非 Claude 模型名且未配端点时启动即报错,写明该设什么
- 支持 ANTHROPIC_BASE_URL 环境变量
- 中英文 README 改正 + 新增两条 FAQ
测试:新增 19 例(服务器选取 6 / 输出上限与端点校验 13),全量回归 219 passed
(11 failed 为缺可选依赖 claude_agent_sdk 的既有失败,与本次改动无关)
|
2026-08-06 17:14:42 +12:00 |
|
Simon Lin
|
070d41bebe
|
Merge v0.4.0: claude_agent_sdk provider(走个人 Claude 订阅额度)
v0.4.0
|
2026-07-31 12:00:32 +12:00 |
|
Simon Lin
|
854be2f450
|
docs: 同步 ANTHROPIC_API_KEY 共存说明(护栏已由中止改为子进程隔离+告警)
|
2026-07-31 11:58:54 +12:00 |
|
Simon Lin
|
0d4a112d2c
|
fix: (role, content) 元组消息被静默清空为空 prompt
|
2026-07-31 11:56:46 +12:00 |
|
Simon Lin
|
8eb80e9646
|
fix: ResultMessage 401 不再静默降级计费;降级客户端补 callbacks
|
2026-07-31 11:54:38 +12:00 |
|
Simon Lin
|
b004616690
|
fix: 跨 provider 降级不再转发主 provider 的 backend_url
|
2026-07-31 11:50:49 +12:00 |
|
Simon Lin
|
a84ca4f940
|
fix: 子进程剥离 ANTHROPIC_API_KEY 以支持 anthropic 降级;收窄认证误判
|
2026-07-31 11:48:54 +12:00 |
|
Simon Lin
|
2a855817c6
|
fix: agent_sdk 降级 provider/model 必须成对配置,启动即校验
只设 agent_sdk_fallback_provider 不设 model,会把主 provider 的模型名配到另一家
(如 AnthropicClient(model="deepseek-chat"))。而降级路径**恰好在撞额度、
最需要它工作时才被走到**,那时再炸就晚了。改为启动时校验并给出明确报错。
|
2026-07-31 11:45:13 +12:00 |
|
Simon Lin
|
870b6886da
|
fix: Web UI「所有节点」不再把深度模型复制给 quick 节点
侧栏那个模型输入框只配深度节点。原实现把它同时赋给 agent_sdk_quick_model,
覆盖掉 sonnet 默认值——7 个分析师 + 辩手全跑 opus 会让订阅额度烧得极快,
且与 README 和侧栏提示所述矛盾。
|
2026-07-31 11:42:02 +12:00 |
|
Simon Lin
|
906c2baad3
|
feat: claude_agent_sdk provider — 节点可走个人 Claude Pro/Max 订阅额度 (v0.4.0, PR #86)
|
2026-07-31 11:40:03 +12:00 |
|
Simon Lin
|
d8c64507e0
|
docs: 订正 MiniMax 能力描述 + 同步英文 README;test: 锁住自由文本兜底
① CHANGELOG 原文照抄 PR 描述「DeepSeek 与 MiniMax 都不接受 tool_choice」,
但 PR 自己的代码与测试明确声明 MiniMax supports_tool_choice=True——
MiniMax 的问题是 json_mode 与 <think> 污染。以代码为准订正文档,
不据未实测的描述改行为(本地无 MiniMax key)。
② README_en.md 的 Gemini 安装与 FAQ 仍指向已移除的 [google] extra,同步。
③ 新增测试锁住:结构化返回 None 时退回自由文本,最坏情况与 PR 前等价,
不存在「拿不到结构化就崩」的回归。
v0.3.1
|
2026-07-31 11:21:13 +12:00 |
|
Simon Lin
|
d785335185
|
fix: 能力表声明的「不支持 tool_choice」要真正生效
原实现用 kwargs.setdefault("tool_choice", None):调用方显式传入时会被保留,
API 调用照样失败——能力声明形同虚设。改为 pop + 覆盖,并在丢弃显式值时 warning,
不静默改变调用方意图。
当前无调用方显式传该参数(潜在问题非活 bug),但声明与行为必须一致。
回归测试已验证:回退成 setdefault 即失败、改回即通过。
|
2026-07-31 11:13:07 +12:00 |
|
Simon Lin
|
d082b94eec
|
Merge v0.3.1: 静默失败修复 + 社区 PR #83/#84
解冲突说明:pr84 分支基于较旧的 main,据此误判 v0.3.0 漏更版本号与 CHANGELOG。
实际 main 已有正确的 0.3.0 条目与 version=0.3.0,本次合并保留之,仅叠加 0.3.1。
|
2026-07-31 11:09:42 +12:00 |
|
Simon Lin
|
505e2bd85d
|
fix: 收窄 DeepSeek 能力匹配到已实测的 V4 家族
codex review 指出 PR #83 的 `^deepseek-v\d` 会把 deepseek-v3*(catalog 在售的
V3.2)和未来所有版本一并归类为「不接受 tool_choice」,而该结论只在 V4/reasoner
上实测过。被误伤的型号结构化输出会从强制 schema 工具调用降级为可选调用,
反而更容易退回自由文本——正是这个 PR 要治的病。
改用 `^deepseek-v4(?:$|[.-])`,与 PR 作者自己给 MiniMax 写的
`^MiniMax-M2(?:$|[.-])`(含「不要假设 M3」注释)保持同一把尺子。
补两条回归测试锁住 V3 家族保持宽松默认、V4 家族仍被匹配。
|
2026-07-31 11:06:49 +12:00 |
|
Simon Lin
|
523c376c4f
|
docs: v0.3.1 CHANGELOG/README/版本号,补记漏更的 v0.3.0
|
2026-07-31 11:04:43 +12:00 |
|
Simon Lin
|
2c836c7f88
|
Merge branch 'pr83' into pr84
|
2026-07-31 11:02:07 +12:00 |
|
Simon Lin
|
bffb7c363b
|
fix: 北交所记忆条目静默永久 pending + uv sync 因 [google] extra 无解冲突而失败 (#87)
① 承接 PR #84:Yahoo 完全不覆盖北交所(实测 920002 的裸码/.BJ/.SS/.SZ 四种写法
全部返回空),PR 正确地没有硬造后缀,但这样北交所条目会每次运行白发一次请求、
永远 pending 且不给任何理由。新增 _is_unsupported_by_yfinance() 短路并明确说明原因。
② #87:langchain-google-genai>=4.0.0 要求 google-genai>=1.53.0,而该区间内**每一个**
google-genai 版本都要 httpx>=0.28.1;mootdx 钉死 httpx<0.26。冲突是结构性的,
没有任何版本组合能解。而 uv 构建的是覆盖所有 extra 的 universal lock,
所以这个 extra 的存在让**从不用 Gemini 的人也 uv sync 失败**。
移除该 extra(留空更糟:pip install .[google] 会静默什么都不装),
google_client.py 导入失败时给出可直接执行的安装命令而非裸 ModuleNotFoundError。
③ mootdx 下限 0.10.0→0.11.7:放宽会让 uv 回溯到要求 pandas<1.3.5 的远古版本,
报出与真实成因无关的 pandas 冲突,掩盖真正的 httpx 问题。
实测 uv lock 由失败转为成功解析。
|
2026-07-31 11:02:01 +12:00 |
|
wangyuxun6699
|
71b3ab454c
|
fix: remove unsupported Yahoo Finance .BJ mapping
|
2026-07-27 10:00:44 +08:00 |
|
wangyuxun6699
|
6a72fa975a
|
fix(llm):按模型能力处理 DeepSeek V4 与 MiniMax M2 结构化输出
|
2026-07-27 09:21:41 +08:00 |
|
Simon Lin
|
11045d6f6f
|
fix(prompt): trader 提示词补北交所「仅首日无涨跌幅」限定
上一版在 trader.py 只写了「新股前 5 个交易日无涨跌幅」,漏掉北交所是
「上市首日」这一例外,与 market_analyst / portfolio_manager 两处不一致,
可能让 agent 对北交所次新股在第 2-5 日套用错误约束。(codex review 发现)
v0.3.0
|
2026-07-26 17:56:58 +12:00 |
|
Simon Lin
|
fa8839e944
|
feat(docker): 补 Web UI compose 服务,并说明 tradingagents-web 入口
镜像 ENTRYPOINT 只有 CLI,compose 里没有任何 Web UI 服务,用户要在容器里
跑看板只能自己拼命令,常写成依赖 CWD 的 `streamlit run web/app.py`,工作
目录不对就报 File does not exist(issue #82)。
- compose 新增 web 服务:entrypoint 用 tradingagents-web(web.launch:main
按 __file__ 解析 app.py 绝对路径,与 CWD 无关),映射 8501
- 通过 STREAMLIT_SERVER_ADDRESS=0.0.0.0 让容器内监听全地址,否则端口映射进不来
(已实测 streamlit config show 确认三个环境变量均生效)
- README FAQ 增加对应条目
Reported-by: @Labear33
|
2026-07-26 17:42:41 +12:00 |
|
Simon Lin
|
2447782d4a
|
fix: 修正提示词中的 A 股交易规则,并把 920 号段路由到北交所
issue #85 提出 8 项,逐条查证后全部属实,均已修正。
规则类(4 个提示词文件):
- 创业板最低申报被写成 200 股 → 主板/创业板 100 股整数倍,仅科创板 200 股
起 1 股递增,北交所 100 股起 1 股递增
- ST ±5% 已失效且历来过度泛化 → 主板 ST/*ST 自 2026-07-06 起由 5% 调整为
10%(沪深北交易所同步修订);科创板/创业板 ST/*ST 一直是 20%,不因戴帽收窄
- 北交所此前在提示词中完全缺失(但代码接受北交所代码)→ 补 ±30% 及申报规则
- 新股上市前 5 个交易日不设涨跌幅限制 → 补充(次新股是游资追踪师的高频标的)
- 「跌停即完全无法卖出」表述不再严谨 → 盘后固定价格交易 15:05-15:30 自
2026-07-06 起覆盖全部 A 股,改述为「实际上被困住」而非「无法申报」
- 交易时段补齐集合竞价 09:15-09:25、收盘集合竞价 14:57-15:00、盘后 15:05-15:30
- 解禁监控补 2024 年《减持管理办法》第十条/第十一条:控股股东、实控人在破发、
破净或分红不达标情形下不得通过集中竞价**及大宗交易**减持
代码类(a_stock.py):
- _get_prefix 的 startswith(("6","9")) 把北交所 2024-10 起启用的 920 号段
误判为沪市。实测 sh920002 返回空载荷(静默失败),bj920002 正常返回。
改为先判 92→bj;900xxx 沪市 B 股仍走 sh(已实测确认)。
- _fetch_news_sina 里重复的 sh/sz 判断收敛到 _get_prefix,避免同类漂移
(已实测新浪该接口对前缀不敏感,改动等价)
新增 tests/test_market_prefix_routing.py 覆盖五个市场段。
全量回归:165 passed, 45 subtests passed(test_google_api_key 因缺可选
的 [google] 依赖跳过,与本次改动无关)。
Reported-by: @cheneyliu0304
|
2026-07-26 17:41:50 +12:00 |
|
Simon Lin
|
40409ce60c
|
docs: 联系方式全线统一为 X + Email,去掉 TikTok
|
2026-07-26 16:09:43 +12:00 |
|
Simon Lin
|
83c93af1ec
|
docs: 新增英文 README
- README_en.md:全文英译(MiMo 分章节翻译,代码块与表格结构逐项校验)
- README.md 顶部补语言切换行
- 英文版沿用统一版式:语言切换 · 标题 · slogan · 徽章 · 导航 · Support · License
|
2026-07-26 15:03:52 +12:00 |
|
Simon Lin
|
03973725ab
|
docs: README 版式统一
- 目录章节改为顶部居中导航行;章节标题去除 emoji
- 语言切换行统一为顶部居中,文件名统一 README_<lang>.md
- 尾部统一:免责/致谢 → 赞赏 → License
- 补齐缺失的赞赏入口与徽章条
|
2026-07-26 09:15:12 +12:00 |
|
Simon Lin
|
3cc8ce6fbd
|
chore: 赞赏入口改为 Buy Me a Coffee 二维码
链接形式统一替换为可点击的二维码图片(assets/bmc-qr.png,扫码/点击均指向
buymeacoffee.com/simonlin1212)。
|
2026-07-26 00:19:17 +12:00 |
|
Simon Lin
|
43363ca839
|
chore: 统一联系方式为 X/TikTok/Email,赞赏收敛到 Buy Me a Coffee
- 联系方式统一为 X @linsizhen · TikTok @simonlin0423 · simonlin0423@gmail.com
- 移除抖音、公众号、个人网站 simonlin.net、旧 TikTok @simonlin121212
- 赞赏渠道只保留 Buy Me a Coffee,移除爱发电与微信赞赏码
|
2026-07-26 00:06:12 +12:00 |
|
Simon Lin
|
d55820c08d
|
refactor!: 删除可执行价位能力,不再以配置开关形式保留
BREAKING CHANGE: 上一提交引入的 enable_execution_levels 开关一并移除。
改为直接删除而非默认关闭:荐股软件的认定看软件是否「具备」该功能,
留一个开关在代码里、README 还写着怎么打开,那软件依然具备该功能。
删掉才是真的不具备,同时少一个开关、少两个 schema 变体、少两处分支。
- 删除 TraderProposalWithLevels / PortfolioDecisionWithTarget 两个变体
与 trader_proposal_model() / portfolio_decision_model() 选择器
- 删除 entry_price / stop_loss / position_sizing / price_target 字段
- 渲染函数不再输出对应四节,getattr 兼容层一并移除
- create_trader / create_portfolio_manager / GraphSetup 去掉开关参数
- default_config 去掉 enable_execution_levels
- 提示词保持收紧(仅删字段挡不住模型写进散文字段)
- 测试 TestExecutionLevelsFlag → TestNoExecutionLevels:
锁定「schema 无价位字段 / 提示词禁止 / 渲染永不输出」
需要该能力的使用者可自行 fork 添加(Apache-2.0 允许)。
测试:161 passed + 48 subtests passed。
|
2026-07-24 19:54:24 +12:00 |
|
Simon Lin
|
35a297c3ab
|
feat!: 可执行价位改为默认关闭,明确项目定位为研究复现 (v0.3.0)
BREAKING CHANGE: 新增 enable_execution_levels 配置项,默认 False。
默认情况下 Trader / Portfolio Manager 只给方向与理由,不再产出
建仓价、止损位、仓位、目标价。
- schema 拆分为默认变体与 *WithLevels / *WithTarget opt-in 变体,
用 trader_proposal_model() / portfolio_decision_model() 按开关取用
- 提示词同步收紧:仅删字段挡不住模型把价位写进散文字段,
故系统提示与字段描述都显式要求不给价位
- 渲染函数改 getattr,两种变体共用,下游 markdown 格式不变
- ResearchPlan.strategic_actions 去掉 position sizing 指令
- README 新增「项目定位」:arXiv 2412.20138 框架的工程实现,
面向研究与教学,不提供投资服务,模型与数据由使用者自备
依赖 entry_price 等字段的下游代码,需改用 *WithLevels 变体
或在 config 中设 enable_execution_levels: True。
测试:新增 TestExecutionLevelsFlag(5 条),全量 164 passed。
|
2026-07-24 19:41:53 +12:00 |
|
Simon Lin
|
aabe38bd91
|
chore: 移除仓库内的个股分析案例与评级结论
- 删除 examples/cases/ 下 3 份含具体买卖价位/止损/目标价的个股分析报告
- DEV_LOG / CHANGES_FROM_UPSTREAM 的 E2E 记录改为脱敏样本,只保留工程指标
(耗时 / AI message 数 / 链路通过情况),移除个股评级与分析结论
本项目定位为多 Agent 框架的技术实现与研究复现,不在仓库内提供
针对具体证券的分析意见、评级或买卖建议。
|
2026-07-24 19:20:49 +12:00 |
|
wangyuxun6699
|
be5697e1f3
|
修复 A 股历史决策回报查询导致记忆长期 pending
|
2026-07-23 16:17:50 +08:00 |
|