All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
For user-friendly release highlights, see the GitHub Releases page.
- 🌍 补齐
REPORT_LANGUAGE启动解析与历史展示本地化边界 —Config在启动时继续遵循“真实环境变量优先、.env兜底”的既有语义,并在两者冲突时输出显式告警,减少REPORT_LANGUAGE来源不清带来的误判;同时/api/v1/history/{id}英文详情响应会同步本地化sentiment_label,历史 Markdown 也会正确识别英文bias_status的风险等级 emoji,避免出现乐观或🚨Safe这类中英混排/误报展示。
- 🔎 SearXNG 公共实例自动发现与受控轮询(#752)— 新增
SEARXNG_PUBLIC_INSTANCES_ENABLED,在未配置SEARXNG_BASE_URLS时默认从searx.space拉取公共实例列表,并按受控轮询顺序选择实例;同次请求内遇到超时、连接错误、HTTP 非 200 或无效 JSON 会自动切换到下一个实例。已配置自建实例的用户保持原有优先级与语义不变;daily_analysisGitHub Actions 工作流也已支持显式透传该开关并在启动日志中展示当前状态。 - 📈 TickFlow market review enhancement (#632) — 新增可选
TICKFLOW_API_KEY;配置后,A 股大盘复盘的主要指数行情优先尝试 TickFlow;若当前 TickFlow 套餐支持标的池查询,市场涨跌统计也会优先尝试 TickFlow。失败或权限不足时立即回退到现有AkShare / Tushare / efinance链路;板块涨跌榜回退顺序保持不变。接入层同时适配了真实 SDK 契约:主指数查询按单次请求上限分批拉取,并将 TickFlow 返回的比例型change_pct/amplitude统一转换为项目内部的百分比口径。 - 💼 持仓账本并发写入串行化(#742)— 持仓源事件写入/删除现在会在 SQLite 下先获取串行化写锁,减少并发卖出把超售流水写入账本的窗口;直接持仓写接口在锁竞争时返回
409 portfolio_busy,CSV 导入保持逐条提交并把 busy 计入failed_count。 - 🚀 Agent 与普通分析模型解耦(Issue #692) — 新增
AGENT_LITELLM_MODEL(留空继承LITELLM_MODEL,无前缀按openai/<model>归一);Agent 执行链路与/api/v1/agent/models的is_primary/is_fallback标记改为基于 Agent 实际模型链路;系统配置与启动期校验补齐AGENT_LITELLM_MODEL的unknown_model/missing_runtime_source检查;Web 设置页新增 Agent 主模型选择并与渠道模式运行时配置同步。 - 🌍 报告输出语言可配置(Issue #758)— 新增
REPORT_LANGUAGE=zh|en,默认zh;语言设置会同步注入普通分析与 Agent Prompt,并覆盖 Markdown/Jinja 模板、通知 fallback、历史/APIreport_language元数据及 Web 报告页固定文案,避免“英文内容 + 中文壳子”的混合输出。
- 新增 Ollama 本地模型配置说明,同步更新 README.md 与 docs/README_EN.md(Fixes #690)
- 完善 Ollama 配置说明:
docs/full-guide.md/docs/full-guide_EN.md环境变量表与 Note 补充OLLAMA_API_BASE,避免英文用户误以为 Ollama 不能作为独立配置入口;合并重复的OLLAMA_API_BASE条目为单一条目
- 💱 持仓页汇率刷新禁用语义修正(#772)— 当
PORTFOLIO_FX_UPDATE_ENABLED=false时,POST /api/v1/portfolio/fx/refresh现在会返回显式refresh_enabled=false与disabled_reason,Web/portfolio页面会明确提示“汇率在线刷新已被禁用”,不再误报“当前范围无可刷新的汇率对”。 - 🤖 Agent timeout and config hardening —
AGENT_ORCHESTRATOR_TIMEOUT_Snow also protects the legacy single-agent ReAct loop, parallel tool batches stop waiting once the remaining budget is exhausted, and invalid numeric.envvalues fall back to safe defaults with warnings instead of crashing startup. - 🌐 CORS wildcard + credentials compatibility —
CORS_ALLOW_ALL=trueno longer combinesallow_origins=["*"]with credentialed requests, avoiding browser-side cross-origin failures in demo/development setups. - 🧭 Unavailable Agent settings hidden from Web UI — Deep Research / Event Monitor controls are now treated as compatibility-only metadata in the current branch and are removed from the Settings page to avoid exposing non-functional toggles.
- 💱 持仓页汇率手动刷新入口补齐(#748)— Web
/portfolio页面现在会在“汇率状态”卡片中展示“刷新汇率”按钮,直接调用现有POST /api/v1/portfolio/fx/refresh接口;刷新后会仅重载快照与风险数据,并以内联摘要反馈“已更新 / 仍 stale / 刷新失败”的结果,减少用户对fxStale长时间停留的误解。
- Dashboard state slice and workspace closure — moved Home / Dashboard state into
stockPoolStore, consolidated history selection, report loading, task syncing, polling refresh, and markdown drawer handling under a single state slice. - Dashboard panel standardization — kept the current dashboard layout contract stable while unifying history, report, news, and markdown presentation with shared tokens, standardized states, and bounded in-panel scrolling for the history list.
- Dashboard-to-chat follow-up bridge — routed “Ask AI” follow-ups through report-context hydration instead of direct cross-page state coupling, while keeping chat sends usable when enriched history context is still loading.
- Frontend regression coverage for PR7 — expanded targeted tests for
HomePage,ChatPage,stockPoolStore,AuthContext,useDashboardLifecycle,useTaskStream, and history interactions, and validated lint, full web tests, build, and Playwright smoke coverage.
3.8.0 - 2026-03-17
- 🎨 Web 界面完成一轮骨架升级 — 新的 App Shell、侧边导航、主题能力、登录与系统设置流程已经串成统一体验,桌面端加载背景也完成对齐。
- 📈 分析上下文继续补强 — 美股新增社交舆情情报,A 股补齐财报与分红结构化上下文,Tushare 新接入筹码分布和行业板块涨跌数据。
- 🔒 运行稳定性与配置兼容性提升 — 退出登录会立即让旧会话失效,定时启动兼容旧配置,运行中的
MAX_WORKERS调整和新闻时效窗口反馈更清晰。 - 💼 持仓纠错链路更完整 — 超售会被前置拦截,错误交易/资金流水/公司行为可以直接删除回滚,便于修复脏数据。
- 📱 美股社交舆情情报 — 新增 Reddit / X / Polymarket 社交媒体情绪数据源,为美股分析提供实时社交热度、情绪评分和提及量等补充指标;完全可选,仅在配置
SOCIAL_SENTIMENT_API_KEY后对美股生效。 - 📊 A 股财报与分红结构化增强(Issue #710)—
fundamental_context.earnings.data新增financial_report与dividend字段;分红统一按“仅现金分红、税前口径”计算,并补充ttm_cash_dividend_per_share与ttm_dividend_yield_pct;分析/历史 API 的details追加financial_report、dividend_metrics可选字段,保持 fail-open 与向后兼容。 - 🔍 接入 Tushare 筹码与行业板块接口 — 新增筹码分布、行业板块涨跌数据获取能力,并统一纳入配置化数据源优先级;默认按上海时间区分盘中/盘后交易日取数,优先使用 Tushare 同花顺接口,必要时降级到东财。
- 🧱 Web UI 基础骨架升级 — 重建共享设计令牌与通用组件,新增 App Shell、Theme Provider、侧边导航,并同步调整 Electron 加载背景,为 Web / Desktop 的统一体验打底。
- 🔐 登录与系统设置流程重做 — 重构 Login、Settings 与 Auth 管理流程,补上显式的认证 setup-state 处理,并让 Web 端与运行时认证配置 API 行为对齐。
- 🧪 前端回归与冒烟覆盖补强 — 新增并扩展登录、首页、聊天、移动端 Shell、设置页、回测入口等关键路径的组件测试与 Playwright smoke coverage。
- 🧭 页面接入新 Shell 布局契约 — Home、Chat、Settings、Backtest 已统一接入新的页面容器、抽屉和滚动约定,降低 UI 迁移期间的页面行为不一致。
- 💾 设置页状态同步更稳 — 优化草稿保留、直接保存同步与冲突处理,减少模块级保存后前后端配置状态不一致的问题。
- 🎭 登录页视觉基线回归 — 登录页恢复到既有
006分支的视觉基线,同时保留新的认证状态逻辑和统一表单交互模型。 - 🏛️ AI 协作治理资产加固 — 收敛并加强
AGENTS.md、CLAUDE.md、Copilot 指令和校验脚本的一致性约束,降低治理资产长期漂移风险。
- Web UI foundation refresh — rebuilt shared design tokens and common primitives, introduced the app shell, theme provider, sidebar navigation, and Electron loading background alignment for the upgraded desktop/web experience
- Settings and auth workflow overhaul — rebuilt the Login, Settings, and Auth management flows, added explicit auth setup-state handling, and aligned the Web UI with the runtime auth configuration APIs
- UI regression coverage and smoke checks — expanded targeted frontend tests and added Playwright smoke coverage for login, home, chat, mobile shell, settings, and backtest entry flows
- Shell-driven page integration — aligned Home, Chat, Settings, and Backtest with the new shell layout contract so routing, drawer behavior, and page-level scrolling are consistent during the UI migration
- Settings state consistency — refined draft preservation, direct-save synchronization, and conflict handling so module-level saves no longer leave the page out of sync with backend config state
- Login visual baseline — restored the login page visual treatment to the established
006branch baseline while keeping the newer auth-state logic and unified form interaction model
- ⏰ 定时启动立即执行兼容旧配置(Issue #726)—
SCHEDULE_RUN_IMMEDIATELY未设置时会回退读取RUN_IMMEDIATELY,修复升级后旧.env在定时模式下的兼容性问题;同时澄清.env.example/ README 中两个配置项的适用范围,并注明 Outlook / Exchange 强制 OAuth2 暂不支持。 - 🧵 运行期
MAX_WORKERS配置生效与可解释性增强(#633)— 修复异步分析队列未按MAX_WORKERS同步的问题;新增任务队列并发 in-place 同步机制(空闲即时生效、繁忙延后),并在设置保存反馈与运行日志中明确输出profile/max/effective,减少“参数未生效”误解。 - 🔐 退出登录立即失效现有会话 —
POST /api/v1/auth/logout现在会轮换 session secret,避免旧 cookie 在退出后仍可继续访问受保护接口;同浏览器标签页和并发页面会被同步登出。认证开启时,该接口也不再属于匿名白名单,未登录请求会返回401,避免匿名请求触发全局 session 失效。 - 🧮 Tushare 板块/筹码调用限流与跨日缓存修复 — 新增的
trade_cal、行业板块排行、筹码分布链路统一接入_check_rate_limit();交易日历缓存改为按自然日刷新,避免服务跨天运行后继续沿用旧交易日判断取数日期。 - 💼 持仓超售拦截与错误流水恢复(#718)—
POST /api/v1/portfolio/trades现在会在写入前校验可卖数量,超售返回409 portfolio_oversell;持仓页新增交易 / 资金流水 / 公司行为删除能力,删除后会同步失效仓位缓存与未来快照,便于从错误流水中直接恢复。 - 📧 邮件中文发件人名编码(#708)— 邮件通知现在会对包含中文的
EMAIL_SENDER_NAME自动做 RFC 2047 编码,并在异常路径补充 SMTP 连接清理,修复 GitHub Actions / QQ SMTP 下'ascii' codec can't encode characters导致的发送失败。 - 🐛 港股 Agent 实时行情去重与快速路由 — 统一
HK01810/1810.HK/01810等港股代码归一规则;港股实时行情改为直接走单次akshare_hk路径,避免按 A 股 source priority 重复触发同一失败接口;Agent 运行期对显式retriable=false的工具失败增加短路缓存,减少同轮分析中的重复失败调用。 - 📰 新闻时效硬过滤与策略分窗(#697)— 新增
NEWS_STRATEGY_PROFILE(ultra_short/short/medium/long)并与NEWS_MAX_AGE_DAYS统一计算有效窗口;搜索结果在返回后执行发布时间硬过滤(时间未知剔除、超窗剔除、未来仅容忍 1 天),并在历史 fallback 链路追加相同约束,避免旧闻再次进入“最新动态/风险警报”。
- ☁️ 新增云服务器 Web 界面部署与访问教程(Fixes #686)— 补充从云端部署到外部访问的落地说明,降低远程自托管门槛。
- 🌍 补齐英文文档索引与协作文档 — 新增英文文档索引、贡献指南、Bot 命令文档,并补充中英双语 issue / PR 模板,方便中英文协作与外部贡献者理解项目入口。
- 🏷️ 本地化 README 补充 Trendshift badge — 在多语言 README 中同步补上新版能力入口标识,减少中英文说明面不一致。
3.7.0 - 2026-03-15
-
💼 持仓管理 P0 全功能上线(#677,对应 Issue #627)
- 核心账本与快照闭环:新增账户、交易、现金流水、企业行为、持仓缓存、每日快照等核心数据模型与 API 端点;支持 FIFO / AVG 双成本法回放;同日事件顺序固定为
现金 → 企业行为 → 交易;持仓快照写入采用原子事务。 - 券商 CSV 导入:支持华泰 / 中信 / 招商首批适配,含列名别名兼容;两阶段接口(解析预览 + 确认提交);
trade_uid优先、key-field hash 兜底的幂等去重;前导零股票代码完整保留。 - 组合风险报告:集中度风险(Top Positions + A 股板块口径)、历史回撤监控(支持回填缺失快照)、止损接近预警;多币种统一换算 CNY 口径;汲取失败时回退最近成功汇率并标记 stale。
- Web 持仓页(
/portfolio):组合总览、持仓明细、集中度饼图、风险摘要、全组合 / 单账户切换;手工录入交易 / 资金流水 / 企业行为;内嵌账户创建入口;CSV 解析 + 提交闭环与券商选择器。 - Agent 持仓工具:新增
get_portfolio_snapshot数据工具,默认紧凑摘要,可选持仓明细与风险数据。 - 事件查询 API:新增
GET /portfolio/trades、GET /portfolio/cash-ledger、GET /portfolio/corporate-actions,支持日期过滤与分页。 - 可扩展 Parser Registry:应用级共享注册,支持运行时注册新券商;新增
GET /portfolio/imports/csv/brokers发现接口。
- 核心账本与快照闭环:新增账户、交易、现金流水、企业行为、持仓缓存、每日快照等核心数据模型与 API 端点;支持 FIFO / AVG 双成本法回放;同日事件顺序固定为
-
🎨 前端设计系统与原子组件库(#662)
- 引入渐进式双主题架构(HSL 变量化设计令牌),清理历史 Legacy CSS;重构 Button / Card / Badge / Collapsible / Input / Select 等 20+ 核心组件;新增
clsx+tailwind-merge类名合并工具;提升历史记录、LLM 配置等页面可读性。
- 引入渐进式双主题架构(HSL 变量化设计令牌),清理历史 Legacy CSS;重构 Button / Card / Badge / Collapsible / Input / Select 等 20+ 核心组件;新增
-
⚡ 分析 API 异步契约与启动优化(#656)
- 规范
POST /api/v1/analysis/analyze异步请求的返回契约;优化服务启动辅助逻辑;修复前端报告类型联合定义与后端响应对齐问题。
- 规范
- 🔔 Discord 环境变量向后兼容(#659):运行时新增
DISCORD_CHANNEL_ID→DISCORD_MAIN_CHANNEL_ID的 fallback 读取;历史配置用户无需修改即可恢复 Discord Bot 通知;全部相关文档与.env.example对齐。 - 🔧 GitHub Actions Node 24 升级(#665):将所有 GitHub 官方 actions 升级至 Node 24 兼容版本,消除 CI 日志中的 Node.js 20 deprecation warning(影响 2026-06-02 强制升级窗口)。
- 📅 持仓页默认日期本地化:手工录入表单默认日期改用本地时间(
getFullYear/Month/Date),修复 UTC-N 时区用户在当天晚间出现日期偏移的问题。 - 🔁 CSV 导入去重逻辑加固:dedup hash 纳入行序号作为区分因子,确保同字段合法分笔成交不被误折叠;同时在
trade_uid存在时也持久化 hash,防止混合来源重复写入。
POST /api/v1/portfolio/trades在同账户内trade_uid冲突时返回409。- 持仓风险响应新增
sector_concentration字段(增量扩展),原有concentration字段保持不变。 - 分析 API
analyze接口异步行为契约文档化;前端报告类型联合更新。
- 新增持仓核心服务测试(FIFO / AVG 部分卖出、同日事件顺序、重复
trade_uid返回 409、快照 API 契约)。 - 新增 CSV 导入幂等性、合法分笔成交不误去重、去重边界、风险阈值边界、汇率降级行为测试。
- 新增 Agent
get_portfolio_snapshot工具调用测试。 - 新增分析 API 异步契约回归测试。
3.6.0 - 2026-03-14
-
📊 Web UI Design System — implemented dual-theme architecture and terminal-inspired atomic UI components
-
📊 UI Components Refactoring — integrated
clsxandtailwind-mergefor robust class composition across Web UI -
🗑️ History batch deletion — Web UI now supports multi-selection and batch deletion of analysis history; added
POST /api/v1/history/batch-deleteendpoint andConfirmDialogcomponent. -
🔐 Auth settings API — new
POST /api/v1/auth/settingsendpoint to enable or disable Web authentication at runtime and set the initial admin password when needed -
openclaw Skill 集成指南 — 新增 docs/openclaw-skill-integration.md,说明如何通过 openclaw Skill 调用 DSA API
-
⚙️ LLM channel protocol/test UX —
.envand Web settings now share the same channel shape (LLM_CHANNELS+LLM_<NAME>_PROTOCOL/BASE_URL/API_KEY/MODELS/ENABLED); settings page adds per-channel connection testing, primary/fallback/vision model selection, and protocol-aware model prefixing -
🤖 Agent architecture Phase 0+1 — shared protocols (
AgentContext,AgentOpinion,StageResult), extractedrun_agent_loop()runner,AGENT_ARCHswitch (single/multi), config registry entries -
🔍 Bot NL routing — two-layer natural-language routing: cheap regex pre-filter (stock codes + finance keywords) → lightweight LLM intent parsing; controlled by
AGENT_NL_ROUTING=true; supports multi-stock and strategy extraction -
💬
/askmulti-stock analysis — comma orvsseparated codes (max 5), parallel thread execution with 150s timeout (preserves partial results), Markdown comparison summary table at top -
📋
/historycommand — per-user session isolation via{platform}_{user_id}:{scope}format (colon delimiter prevents prefix collision); lists both/chatand/asksessions; view detail or clear -
📊
/strategiescommand — lists available strategy YAML files grouped by category (趋势/形态/反转/框架) with ✅/⬜ activation status -
🔧 Backtest summary tools —
get_strategy_backtest_summaryandget_stock_backtest_summaryregistered as read-only Agent tools -
⚙️ Agent auto-detection —
is_agent_available()auto-detects fromLITELLM_MODEL; explicitAGENT_MODE=true/falsetakes full precedence -
🏗️ Multi-Agent orchestrator (Phase 2) —
AgentOrchestratorwith 4 modes (quick/standard/full/strategy); drop-in replacement forAgentExecutorviaAGENT_ARCH=multi;BaseAgentABC with tool subset filtering, cached data injection, and structuredAgentOpinionoutput -
🧩 Specialised agents (Phase 2-4) —
TechnicalAgent(8 tools, trend/MA/MACD/volume/pattern analysis),IntelAgent(news & sentiment, risk flag propagation),DecisionAgent(synthesis into Decision Dashboard JSON),RiskAgent(7 risk categories, two-level severity with soft/hard override) -
📈 Strategy system (Phase 3) —
StrategyAgent(per-strategy evaluation from YAML skills),StrategyRouter(rule-based regime detection → strategy selection),StrategyAggregator(weighted consensus with backtest performance factor) -
🔬 Deep Research agent (Phase 5) —
ResearchAgentwith 3-phase approach (decompose → research sub-questions → synthesise report); token budget tracking; new/researchbot command with aliases (/深研,/deepsearch) -
🧠 Memory & calibration (Phase 6) —
AgentMemorywith prediction accuracy tracking, confidence calibration (activates after minimum sample threshold), strategy auto-weighting based on historical win rate -
📊 Portfolio Agent (Phase 7) —
PortfolioAgentfor multi-stock portfolio analysis (position sizing, sector concentration, correlation risk, cross-market linkage, rebalance suggestions) -
🔔 Event-driven alerts (Phase 7) —
EventMonitorwithPriceAlert,VolumeAlert,SentimentAlertrules; async checking, callback notifications, serializable persistence -
⚙️ New config entries —
AGENT_ORCHESTRATOR_MODE,AGENT_RISK_OVERRIDE,AGENT_DEEP_RESEARCH_BUDGET,AGENT_MEMORY_ENABLED,AGENT_STRATEGY_AUTOWEIGHT,AGENT_STRATEGY_ROUTING— all registered inconfig.py+config_registry.py(WebUI-configurable)
- 🔐 Auth password state semantics — stored password existence is now tracked independently from auth enablement; when auth is disabled,
/api/v1/auth/statusreturnspasswordSet=falsewhile preserving the saved password for future re-enable - 🔐 Auth settings re-enable hardening — re-enabling auth with a stored password now requires
currentPassword, and failed session creation rolls back the auth toggle to avoid lockout - ♻️ AgentExecutor refactored —
_run_loopdelegates to sharedrunner.run_agent_loop(); removed duplicated serialization/parsing/thinking-label code - ♻️ Unified agent switch — Bot, API, and Pipeline all use
config.is_agent_available()instead of divergentconfig.agent_modechecks - 📖 README.md — expanded Bot commands section (ask/chat/strategies/history), added NL routing note, updated agent mode description
- 📖 .env.example — added
AGENT_ARCHandAGENT_NL_ROUTINGconfiguration documentation - 🔌 Analysis API async contract —
POST /api/v1/analysis/analyzenow documents distinct async202payloads for single-stock vs batch requests, andreport_type=fullis treated consistently with the existing full-report behavior
- 🐛 Analysis API blank-code guardrails —
POST /api/v1/analysis/analyzenow drops whitespace-only entries before batch enqueue and returns400when no valid stock code remains - 🐛 Bare
/apiSPA fallback — unknown API paths now return JSON404consistently for both/api/...and the exact/apipath - 🎮 Discord channel env compatibility — runtime now accepts legacy
DISCORD_CHANNEL_IDas a fallback forDISCORD_MAIN_CHANNEL_ID, and the docs/examples now use the same variable name as the actual workflow/config implementation - 🐛 Session secret rotation on Windows — use atomic replace so auth toggles invalidate existing sessions even when
.session_secretalready exists - 🐛 Auth toggle atomicity — persist
ADMIN_AUTH_ENABLEDbefore rotating session secret; on rotation failure, roll back to the previous auth state - 🔧 LLM runtime selection guardrails — YAML 模式下渠道编辑器不再覆盖
LITELLM_MODEL/ fallback / Vision;系统配置校验补上全部渠道禁用后的运行时来源检查,并修复vertexai/...这类协议别名模型被重复加前缀的问题 - 🐛 Multi-stock
/askfollow-up regressions — portfolio overlay now shares the same timeout budget as the per-stock phase and is skipped on timeout instead of blocking the bot reply;/historynow stores the readable per-stock summary instead of raw dashboard JSON; condensed multi-stock output now renders numericsniper_pointsvalues - 🐛 Decision dashboard enum compatibility — multi-agent
DecisionAgentnow keepsdecision_typewithin the legacybuy|hold|sellcontract and normalizes straystrong_*outputs before risk override, pipeline conversion, and downstream统计/通知汇总 - 🛟 Multi-Agent partial-result fallback —
IntelAgentnow caches parsed intel for downstream reuse, shared JSON parsing tolerates lightly malformed model output, and the orchestrator preserves/synthesizes a minimal dashboard on timeout or mid-pipeline parse failure instead of always collapsing to50/观望/未知 - 🐛 Shared LiteLLM routing restored — bot NL intent parsing and
ResearchAgentplanning/synthesis now reuse the same LiteLLM adapter / Router / fallback /api_baseinjection path as the main Agent flow, soLLM_CHANNELS/LITELLM_CONFIG/ OpenAI-compatible deployments behave consistently - 🐛 Bot chat session backward compatibility —
/chatnow keeps using the legacy{platform}_{user_id}session id when old history already exists, and/historycan still list / view / clear those pre-migration sessions alongside the new{platform}_{user_id}:chatformat - 🐛 EventMonitor unsupported rule rejection — config validation/runtime loading now reject or skip alert types the monitor cannot actually evaluate yet, so schedule mode no longer silently accepts permanent no-op rules
- 🐛 P0 基本面聚合稳定性修复 (#614) — 修复
get_stock_info板块语义回归(新增belong_boards并保留boards兼容别名)、引入基本面上下文精简返回以控制 token、为基本面缓存增加最大条目淘汰,并补齐 ETF 总体状态聚合与 NaN 板块字段过滤,保证 fail-open 与最小入侵。 - 🔧 GitHub Actions 搜索引擎环境变量补充 — 工作流新增
MINIMAX_API_KEYS、BRAVE_API_KEYS、SEARXNG_BASE_URLS环境变量映射,使 GitHub Actions 用户可配置 MiniMax、Brave、SearXNG 搜索服务(此前 v3.5.0 已添加 provider 实现但缺少工作流配置) - 🤖 Multi-Agent runtime consistency —
AGENT_MAX_STEPSnow propagates to each orchestrated sub-agent; added cooperativeAGENT_ORCHESTRATOR_TIMEOUT_Sbudget to stop overlong pipelines before they cascade further - 🔌 Multi-Agent feature wiring —
AGENT_RISK_OVERRIDEnow actively downgrades final dashboards on hard risk findings;AGENT_MEMORY_ENABLEDnow injects recent analysis memory + confidence calibration into specialised agents; multi-stock/asknow runsPortfolioAgentto add portfolio-level allocation and concentration guidance - 🔔 EventMonitor runtime wiring — schedule mode can now load alert rules from
AGENT_EVENT_ALERT_RULES_JSON, poll them atAGENT_EVENT_MONITOR_INTERVAL_MINUTES, and send triggered alerts through the existing notification service - 🛠️ Follow-up stability fixes — multi-stock
/asknow falls back to usable text output when dashboard JSON parsing fails; EventMonitor skips semantically invalid rules instead of aborting schedule startup; background alert polling now runs independently of the main scheduled analysis loop - 🧪 Multi-Agent regression coverage — added orchestrator execution tests for
run(),chat(), critical-stage failure, graceful degradation, and timeout handling - 🧹 PortfolioAgent cleanup —
post_process()now reuses shared JSON parsing and removed stale unused imports - 🚦 Bot async dispatch —
CommandDispatchernow exposesdispatch_async(); NL intent parsing and default command execution are offloaded from the event loop, DingTalk stream awaits async handlers directly, and Feishu stream processing is moved off the SDK callback thread - 🌐 Async webhook handler — new
handle_webhook_async()function inbot/handler.pyfor use from async contexts (e.g. FastAPI); callsdispatch_async()directly without thread bridging - 🧵 Feishu stream ThreadPoolExecutor — replaced unbounded per-message
Threadspawning with a cappedThreadPoolExecutor(max_workers=8)to prevent thread explosion under message bursts - 🔒 EventMonitor safety —
_check_volume()now safely handlesget_daily_datareturningNone(no tuple-unpacking crash);on_triggercallbacks support both sync and async callables viaasyncio.to_thread/await - 🧹 ResearchAgent dedup —
_filtered_registry()now delegates toBaseAgent._filtered_registry()instead of duplicating the filtering logic - 🧹 Bot trailing whitespace cleanup — removed W291/W293 whitespace issues across
bot/handler.py,bot/dispatcher.py,bot/commands/base.py,bot/platforms/feishu_stream.py,bot/platforms/dingtalk_stream.py - 🐛 Dispatcher
_parse_intent_via_llmsafety — replaced fragile'raw' in dir()with'raw' in locals()for undefined-variable guard inJSONDecodeErrorhandler - 🐛 筹码结构 LLM 未填写时兜底补全 (#589) — DeepSeek 等模型未正确填写
chip_structure时,自动用数据源已获取的筹码数据补全,保证各模型展示一致;普通分析与 Agent 模式均生效 - 🐛 历史报告狙击点位显示原始文本 (#452) — 历史详情页现优先展示
raw_result.dashboard.battle_plan.sniper_points中的原始字符串,避免analysis_history数值列把区间、说明文字或复杂点位压缩成单个数字;保留原有数值列作为回退 - 🐛 Session prefix collision — user ID
123could see sessions of user1234viastartswith; fixed with colon delimiter in session_id format - 🐛 NL pre-filter false positives —
re.IGNORECASEcaused[A-Z]{2,5}to match common English words like "hello"; removed global flag, use inline(?i:...)only for English finance keywords - 🐛 Dotted ticker in strategy args —
_get_strategy_args()didn't recognizeBRK.Bas a stock code, leaving it in strategy text; now acceptsTICKER.CLASSformat - ⏱️ efinance 长调用挂起修复 (#660) — 为所有 efinance API 调用引入
_ef_call_with_timeout()包装(默认 30 秒,可通过EFINANCE_CALL_TIMEOUT配置);使用executor.shutdown(wait=False)确保超时后不再阻塞主线程,彻底消除 81 分钟挂起问题 - 🛡️ 类型安全内容完整性检查 (#660) —
check_content_integrity()现在将非字符串类型的operation_advice/analysis_summary视为缺失字段,避免下游get_emoji()因dict.strip()崩溃 - 📄 报告保存与通知解耦 (#660) —
_save_local_report()不再依赖send_notification标志触发,--no-notify模式下本地报告照常保存 - 🔄 operation_advice 字典归一化 (#660) — Pipeline 和 BacktestEngine 现在将 LLM 返回的
dict格式operation_advice通过decision_type(不区分大小写)映射为标准字符串,防止因模型输出格式变化导致崩溃 - 🛡️ runner.py usage None 防护 (#660) —
response.usage为None时不再抛出AttributeError,回退为 0 token 计数 - 📋 orchestrator 静默失败改为日志警告 (#660) —
IntelAgent/RiskAgent阶段失败现在记录WARNING而非静默跳过,便于诊断
⚠️ Multi-worker auth toggles — runtime auth updates are process-local; multi-worker deployments must restart/roll workers to keep auth state consistent
3.5.0 - 2026-03-12
- 📊 Web UI full report drawer (Fixes #214) — history page adds "Full Report" button to display the complete Markdown analysis report in a side drawer; new
GET /api/v1/history/{record_id}/markdownendpoint - 📊 LLM cost tracking — all LLM calls (analysis, agent, market review) recorded in
llm_usagetable; newGET /api/v1/usage/summary?period=today|month|allendpoint returns aggregated token usage by call type and model - 🔍 SearXNG search provider (Fixes #550) — quota-free self-hosted search fallback; priority: Bocha > Tavily > Brave > SerpAPI > MiniMax > SearXNG
- 🔍 MiniMax web search provider —
MiniMaxSearchProviderwith circuit breaker (3 failures → 300s cooldown) and dual time-filtering; configured viaMINIMAX_API_KEYS - 🤖 Agent models discovery API —
GET /api/v1/agent/modelsreturns available model deployments (primary/fallback/source/api_base) for Web UI model selector - 🤖 Agent chat export & send (#495) — export conversation to .md file; send to configured notification channels; new
POST /api/v1/agent/chat/send - 🤖 Agent background execution (#495) — analysis continues when switching pages; badge notification on completion; auto-cancel in-progress stream on session switch
- 📝 Report Engine P0 — Pydantic schema validation for LLM JSON; Jinja2 templates (markdown/wechat/brief) with legacy fallback; content integrity checks with retry; brief mode (
REPORT_TYPE=brief); history signal comparison - 📦 Smart import — multi-source import from image/CSV/Excel/clipboard; Vision LLM extracts code+name+confidence; name→code resolver (local map + pinyin + AkShare); confidence-tiered confirmation
- ⚙️ GitHub Actions LiteLLM config — workflow supports
LITELLM_CONFIG/LITELLM_CONFIG_YAMLfor flexible AI provider configuration - ⚙️ Config engine refactor & system API (#602) — unified config registry, validation and API exposure
- 📖 LLM configuration guide — new
docs/LLM_CONFIG_GUIDE.mdcovering 3-tier config, quick start, Vision/Agent/troubleshooting
- 🐛 analyze_trend always reports No historical data (#600) — now fetches from DB/DataFetcher instead of broken
get_analysis_context - 🐛 Chip structure fallback when LLM omits it (#589) — auto-fills from data source chip data for consistent display across models
- 🐛 History sniper points show raw text (#452) — prioritizes original strings over compressed numeric values
- 🐛 GitHub Actions ENABLE_CHIP_DISTRIBUTION configurable (#617) — no longer hardcoded, supports vars/secrets override
- 🐛
.envsave preserves comments and blank lines — Web settings no longer destroys.envformatting - 🐛 Agent model discovery fixes — legacy mode includes LiteLLM-native providers; source detection aligned with runtime; fallback deployments no longer expanded per-key
- 🐛 Stooq US stock previous close semantics — no longer misuses open price as previous close
- 🐛 Stock name prefetch regression — prioritizes local
STOCK_NAME_MAPbefore remote queries - 🐛 AkShare limit-up/down calculation (#555) — fixed market analysis statistics
- 🐛 AkShare Tencent source field index & ETF quote mapping (#579)
- 🐛 Pytdx stock name cache pagination (#573) — prevents cache overflow
- 🐛 PushPlus oversized report chunking (#489) — auto-segments long content
- 🐛 Agent chat cancel & switch (#495) — cancel no longer misreports as failure; fast switch no longer overwrites stream state
- 🐛 MiniMax search status in
/statuscommand (#587) - 🐛 config_registry duplicate BOCHA_API_KEYS — removed duplicate dict entry that silently overwrote config
- 🔎 Fetcher failure observability — logs record start/success/failure with elapsed time, failover transitions; Efinance/Akshare include upstream endpoint and classified failure categories
- ♻️ Data source resilience & cleanup (#602) — fallback chain optimization
- ♻️ Image extract API response extension — new
itemsfield (code/name/confidence);codespreserved for backward compatibility - ♻️ Import parse error messages — specific failure reasons for Excel/CSV; improved logging with file type and size
- 📖 LLM config guide refactored for clarity (#583)
- 📖
image-extract-prompt.mdwith full prompt documentation - 📖 AkShare fallback cache TTL documentation
3.4.10 - 2026-03-07
- 🐛 EfinanceFetcher ETF OHLCV data (#541, #527) — switch
_fetch_etf_datafromef.fund.get_quote_history(NAV-only, no OHLCV, nobeg/endparams) toef.stock.get_quote_history; ETFs now return proper open/high/low/close/volume/amount instead of zeros; remove obsolete NAV column mappings from_normalize_data - 🐛 tiktoken 0.12.0
Unknown encoding cl100k_base(#537) — pintiktoken>=0.8.0,<0.12.0in requirements.txt to avoid plugin-registration regression introduced in 0.12.0 - 🐛 Web UI API error classification (#540) — frontend no longer treats every HTTP 400 as the same "server/network" failure; now distinguishes Agent disabled / missing params / model-tool incompatibility / upstream LLM errors / local connection failures
- 🐛 北交所代码识别失败 (#491, #533) — 8/4/92 开头的 6 位代码现正确识别为北交所;Tushare/Akshare/Yfinance 等数据源支持 .BJ 或 bj 前缀;Baostock/Pytdx 对北交所代码显式切换数据源;避免误判上海 B 股 900xxx
- 🐛 狙击点位解析错误 (#488, #532) — 理想买入/二次买入等字段在无「元」字时误提取括号内技术指标数字;现先截去第一个括号后内容再提取
- Markdown-to-image for dashboard report (#455, #535) — 个股日报汇总支持 markdown 转图片推送(Telegram、WeChat、Custom、Email),与大盘复盘行为一致
- markdown-to-file engine (#455) —
MD2IMG_ENGINE=markdown-to-file可选,对 emoji 支持更好,需npm i -g markdown-to-file - PREFETCH_REALTIME_QUOTES (#455) — 设为
false可禁用实时行情预取,避免 efinance/akshare_em 全市场拉取 - Stock name prefetch (#455) — 分析前预取股票名称,减少报告中「股票xxxxx」占位符
- 📊 分析报告模型标记 (#528, #534) — 在分析报告 meta、报告末尾、推送内容中展示
model_used(完整 LLM 模型名);Agent 多轮调用时记录并展示每轮实际使用的模型(支持 fallback 切换)
- Enhanced markdown-to-image failure warning (#455) — 转图失败时提示具体依赖(wkhtmltopdf 或 m2f)
- WeChat-only image routing optimization (#455) — 仅配置企业微信图片时,不再对完整报告做冗余转图,避免误导性失败日志
- Stock name prefetch lightweight mode (#455) — 名称预取阶段跳过 realtime quote 查询,减少额外网络开销
3.4.9 - 2026-03-06
- 🧠 Structured config validation —
ConfigIssuedataclass andvalidate_structured()with severity-aware logging;CONFIG_VALIDATE_MODE=strictaborts startup on errors - 🖼️ Vision model config —
VISION_MODELandVISION_PROVIDER_PRIORITYfor image stock extraction; provider fallback (Gemini → Anthropic → OpenAI → DeepSeek) when primary fails - 🚀 CLI init wizard —
python -m dsa init3-step interactive bootstrap (model → data source → notification), 9 provider presets, incremental merge by default - 🔧 Multi-channel LLM support with visual channel editor (#494)
- ♻️ Vision extraction — migrated from gemini-3 hardcode to
litellm.completion()with configurable model and provider fallback;OPENAI_VISION_MODELdeprecated in favor ofVISION_MODEL - ♻️ Market analyzer — uses
Analyzer.generate_text()for LLM calls; fixes bypass and AnthropicAttributeErrorwhen using non-Router path - ♻️ Config validation refinements — test_env output format syncs with
validate_structured(severity-aware ✓/✗/⚠/·); Vision key warning whenVISION_MODELset but no provider API key; market_analyzer test coversgenerate_market_reviewfallback whengenerate_textreturns None - ⚙️ Auto-tag workflow defaults to NO tag — only tags when commit message explicitly contains
#patch,#minor, or#major - ♻️ Formatter and notification refactor (#516)
- 🐛 STOCK_LIST not refreshed on scheduled runs —
.envor WebUI changes toSTOCK_LISTnow hot-reload before each scheduled analysis (#529) - 🐛 WebUI fails to load with MIME type error — SPA fallback route now resolves correct
Content-Typefor JS/CSS files (#520) - 🐛 AstrBot sender docstring misplaced —
import timeplaced before docstring in_send_astrbot, causing it to become dead code - 🐛 Telegram Markdown link escaping —
_convert_to_telegram_markdownescaped[]()characters, breaking all Markdown links in reports - 🐛 Duplicate
discord_bot_statusfield in Config dataclass — second declaration silently shadowed the first - 🧹 Unused imports — removed
shutil/subprocessfrommain.py - 🔧 Config validation and Vision key check (#525)
- 📝 Clarified GitHub Actions non-trading-day manual run controls (
TRADING_DAY_CHECK_ENABLED+force_run) for Issue #461 / PR #466
3.4.8 - 2026-03-02
- 🐛 Desktop exe crashes on startup with
FileNotFoundError— PyInstaller build was missing litellm's JSON data files (e.g.model_prices_and_context_window_backup.json). Added--collect-data litellmto both Windows and macOS build scripts so the files are correctly bundled in the executable.
- 🔧 Cache Electron binaries on macOS CI runners to prevent intermittent EOF download failures when fetching
electron-vX.Y.Z-darwin-*.zipfrom GitHub CDN - 🔧 Fix macOS DMG
hdiutil Resource busyerror during desktop packaging
- 📝 Clarify non-trading-day manual run controls for GitHub Actions (
TRADING_DAY_CHECK_ENABLED+force_run) (#474)
3.4.7 - 2026-02-28
- 🧠 CN/US Market Strategy Blueprint System (#395) — market review prompt injects region-specific strategy blueprints with position sizing and risk trigger recommendations
- 🐛
TRADING_DAY_CHECK_ENABLEDenv var and--force-runfor GitHub Actions (#466) - 🐛 Agent pipeline preserved resolved stock names (#464) — placeholder names no longer leak into reports
- 🐛 Code cleanup (#462, Fixes #422)
- 🐛 WebUI auto-build on startup (#460)
- 🐛 ARCH_ARGS unbound variable (#458)
- 🐛 Time zone inconsistency & right panel flash (#439)
- 📝 Clarify potential ambiguities in code (#343)
- 📝 ENABLE_EASTMONEY_PATCH guidance for Issue #453 (#456)
3.4.0 - 2026-02-27
- 📡 LiteLLM Direct Integration + Multi API Key Support (#454, Fixes #421 #428)
- Removed native SDKs (google-generativeai, google-genai, anthropic); unified through
litellm>=1.80.10 - New config:
LITELLM_MODEL,LITELLM_FALLBACK_MODELS,GEMINI_API_KEYS,ANTHROPIC_API_KEYS,OPENAI_API_KEYS - Multi-key auto-builds LiteLLM Router (simple-shuffle) with 429 cooldown
- Breaking:
.envGEMINI_MODEL(no prefix) only for fallback; explicit config must include provider prefix
- Removed native SDKs (google-generativeai, google-genai, anthropic); unified through
- ♻️ Notification Refactoring (#435) — extracted 10 sender classes into
src/notification_sender/
- 🐛 LLM NoneType crash, history API 422, sniper points extraction
- 🐛 Auto-build frontend on WebUI startup —
WEBUI_AUTO_BUILDenv var (defaulttrue) - 🐛 Docker explicit project name (#448)
- 🐛 Bocha search SSL retry (#445, #446) — transient errors retry up to 3 times
- 🐛 Gemini google-genai SDK migration (Fixes #440, #444)
- 🐛 Mobile home page scrolling (Fixes #419, #433)
- 🐛 History list scroll reset (#431)
- 🐛 Settings save button false positive (fixes #417, #430)
3.3.22 - 2026-02-26
- 💬 Chat History Persistence (Fixes #400, #414) —
/chatpage survives refresh, sidebar session list - 🎨 Project VI Assets — logo icon set, PSD, vector, banner (#425)
- 🚀 Desktop CI Auto-Release (#426) — Windows + macOS parallel builds
- 🐛 Agent Reasoning 400 & LiteLLM Proxy (fixes #409, #427)
- 🐛 Discord chunked sending (#413) —
DISCORD_MAX_WORDSconfig - 🐛 yfinance shared DataFrame (#412)
- 🐛 sniper_points parsing (#408)
- 🐛 Agent framework category missing (#406)
- 🐛 Date inconsistency & query id (fixes #322, #363)
3.3.12 - 2026-02-24
- 📈 Intraday Realtime Technical Indicators (Issue #234, #397) — MA calculated from realtime price, config:
ENABLE_REALTIME_TECHNICAL_INDICATORS - 🤖 Agent Strategy Chat (#367) — full ReAct pipeline, 11 YAML strategies, SSE streaming, multi-turn chat
- 📢 PushPlus Group Push —
PUSHPLUS_TOPIC(#402) - 📅 Trading Day Check (Issue #373, #375) —
TRADING_DAY_CHECK_ENABLED,--force-run
- 🐛 DeepSeek reasoning mode (Issue #379, #386)
- 🐛 Agent news intel persistence (Fixes #396, #405)
- 🐛 Bare except clauses replaced with
except Exception(#398) - 🐛 UUID fallback for HTTP non-secure context (fixes #377, #381)
- 🐛 Docker DNS resolution (Fixes #372, #374)
- 🐛 Agent session/strategy bugs — multiple follow-up fixes for #367
- 🐛 yfinance parallel download data filtering
- Market review strategy consistency — unified cn/us template
- Agent test assertions updated (
6 -> 11)
3.2.11 - 2026-02-23
- 🐛 StockTrendAnalyzer 从未执行 (Issue #357)
- 根因:
get_analysis_context仅返回 2 天数据且无raw_data,pipeline 中raw_data in context始终为 False - 修复:Step 3 直接调用
get_data_range获取 90 日历天(约 60 交易日)历史数据用于趋势分析 - 改善:趋势分析失败时用
logger.warning(..., exc_info=True)记录完整 traceback
- 根因:
- ⚙️ 支持
RUN_IMMEDIATELY配置项,设为true时定时任务触发后立即执行一次分析,无需等待首个定时点
- 🐛 修复 Web UI 页面居中问题
- 🐛 修复 Settings 返回 500 错误
- 🐛 ETF 分析仅关注指数走势(Issue #274)
- 美股/港股 ETF(如 VOO、QQQ)与 A 股 ETF 不再纳入基金公司层面风险(诉讼、声誉等)
- 搜索维度:ETF/指数专用 risk_check、earnings、industry 查询,避免命中基金管理人新闻
- AI 提示:指数型标的分析约束,
risk_alerts不得出现基金管理人公司经营风险
- 🐛 BOT 与 WEB UI 股票代码大小写统一(Issue #355)
- BOT
/analyze与 WEB UI 触发分析的股票代码统一为大写(如aapl→AAPL) - 新增
canonical_stock_code(),在 BOT、API、Config、CLI、task_queue 入口处规范化 - 历史记录与任务去重逻辑可正确识别同一股票(大小写不再影响)
- BOT
- 🔐 Web 页面密码验证(Issue #320, #349)
- 支持
ADMIN_AUTH_ENABLED=true启用 Web 登录保护 - 首次访问在网页设置初始密码;支持「系统设置 > 修改密码」和 CLI
python -m src.auth reset_password重置
- 支持
- 历史记录 API 变更 (Issue #322)
- 路由变更:
GET /api/v1/history/{query_id}→GET /api/v1/history/{record_id} - 参数变更:
query_id(字符串) →record_id(整数) - 新闻接口变更:
GET /api/v1/history/{query_id}/news→GET /api/v1/history/{record_id}/news - 原因:
query_id在批量分析时可能重复,无法唯一标识单条历史记录。改用数据库主键id确保唯一性 - 影响范围:使用旧版历史详情 API 的所有客户端需同步更新
- 路由变更:
- 修复美股(如 ADBE)技术指标矛盾:akshare 美股复权数据异常,统一美股历史数据源为 YFinance(Issue #311)
- 🐛 历史记录查询和显示问题 (Issue #322)
- 修复历史记录列表查询中日期不一致问题:使用明天作为 endDate,确保包含今天全天的数据
- 修复服务器 UI 报告选择问题:原因是多条记录共享同一
query_id,导致总是显示第一条。现改用analysis_history.id作为唯一标识 - 历史详情、新闻接口及前端组件已全面适配
record_id - 新增后台轮询(每 30s)与页面可见性变更时静默刷新历史列表,确保 CLI 发起的分析完成后前端能及时同步,使用
silent模式避免触发 loading 状态
- 🐛 美股指数实时行情与日线数据 (Issue #273)
- 修复 SPX、DJI、IXIC、NDX、VIX、RUT 等美股指数无法获取实时行情的问题
- 新增
us_index_mapping模块,将用户输入(如 SPX)映射为 Yahoo Finance 符号(如 ^GSPC) - 美股指数与美股股票日线数据直接路由至 YfinanceFetcher,避免遍历不支持的数据源
- 消除重复的美股识别逻辑,统一使用
is_us_stock_code()函数
- 🎨 首页输入栏与 Market Sentiment 布局对齐优化
- 股票代码输入框左缘与历史记录 glass-card 框左对齐
- 分析按钮右缘与 Market Sentiment 外框右对齐
- Market Sentiment 卡片向下拉伸填满格子,消除与 STRATEGY POINTS 之间的空隙
- 窄屏时输入栏填满宽度,响应式对齐保持一致
- 🌍 大盘复盘可选区域(Issue #299)
- 支持
MARKET_REVIEW_REGION环境变量:cn(A股)、us(美股)、both(两者) - us 模式使用 SPX/纳斯达克/道指/VIX 等指数;both 模式可同时复盘 A 股与美股
- 默认
cn,保持向后兼容
- 支持
- 🐛 统一美股数据源为 YFinance(Issue #311)
- akshare 美股复权数据异常,统一美股历史数据源为 YFinance
- 修复 ADBE 等美股股票技术指标矛盾问题
- 🐛 标普500实时数据缺失(Issue #273)
- 修复 SPX、DJI、IXIC、NDX、VIX、RUT 等美股指数无法获取实时行情的问题
- 新增
us_index_mapping模块,将用户输入(如 SPX)映射为 Yahoo Finance 符号(如^GSPC) - 美股指数与美股股票日线数据直接路由至 YfinanceFetcher,避免遍历不支持的数据源
- 📊 PE 指标支持(Issue #296)
- AI System Prompt 增加 PE 估值关注
- 📰 新闻时效性筛查(Issue #296)
NEWS_MAX_AGE_DAYS:新闻最大时效(天),默认 3,避免使用过时信息
- 📈 强势趋势股乖离率放宽(Issue #296)
BIAS_THRESHOLD:乖离率阈值(%),默认 5.0,可配置- 强势趋势股(多头排列且趋势强度 ≥70)自动放宽乖离率到 1.5 倍
- 🔧 东财接口补丁可配置开关
- 支持
EFINANCE_PATCH_ENABLED环境变量开关东财接口补丁(默认true) - 补丁不可用时可降级关闭,避免影响主流程
- 支持
- 🔒 CI 门禁统一(P0)
- 新增
scripts/ci_gate.sh作为后端门禁单一入口 - 主 CI 改为
backend-gate、docker-build、web-gate三段式 - CI 触发改为所有 PR,避免 Required Checks 因路径过滤缺失而卡住合并
web-gate支持前端路径变更按需触发- 新增
network-smoke工作流承载非阻断网络场景回归
- 新增
- 📦 发布链路收敛(P0)
docker-publish调整为 tag 主触发,并增加发布前门禁校验- 手动发布增加
release_tag输入与 semver/changelog 强校验 - 发布前新增 Docker smoke(关键模块导入)
- 📝 PR 模板升级(P0)
- 增加背景、范围、验证命令与结果、回滚方案、Issue 关联等必填项
- 🤖 AI 审查覆盖增强(P0)
pr-review纳入.github/workflows/**范围- 新增
AI_REVIEW_STRICT开关,可选将 AI 审查失败升级为阻断
- 📊 仅分析结果摘要(Issue #262)
- 支持
REPORT_SUMMARY_ONLY环境变量,设为true时只推送汇总,不含个股详情 - 默认
false,多股时适合快速浏览
- 支持
- 📧 个股与大盘复盘合并推送(Issue #190)
- 支持
MERGE_EMAIL_NOTIFICATION环境变量,设为true时将个股分析与大盘复盘合并为一次推送 - 默认
false,减少邮件数量、降低被识别为垃圾邮件的风险
- 支持
- 🤖 Anthropic Claude API 支持(Issue #257)
- 支持
ANTHROPIC_API_KEY、ANTHROPIC_MODEL、ANTHROPIC_TEMPERATURE、ANTHROPIC_MAX_TOKENS - AI 分析优先级:Gemini > Anthropic > OpenAI
- 支持
- 📷 从图片识别股票代码(Issue #257)
- 上传自选股截图,通过 Vision LLM 自动提取股票代码
- API:
POST /api/v1/stocks/extract-from-image;支持 JPEG/PNG/WebP/GIF,最大 5MB - 支持
OPENAI_VISION_MODEL单独配置图片识别模型
- ⚙️ 通达信数据源手动配置(Issue #257)
- 支持
PYTDX_HOST、PYTDX_PORT或PYTDX_SERVERS配置自建通达信服务器
- 支持
- ⚙️ 立即运行配置(Issue #332)
- 支持
RUN_IMMEDIATELY环境变量,true时定时任务启动后立即执行一次
- 支持
- 🐛 修复 Docker 构建问题
- 🔌 东财接口补丁机制
- 新增
patch/eastmoney_patch.py修复 efinance 上游接口变更 - 不影响其他数据源的正常运行
- 新增
- 🔐 Webhook 证书校验开关(Issue #265)
- 支持
WEBHOOK_VERIFY_SSL环境变量,可关闭 HTTPS 证书校验以支持自签名证书 - 默认保持校验,关闭存在 MITM 风险,仅建议在可信内网使用
- 支持
- 🐛 修复包导入错误(package import error)
- 🐛 修复
news_intel中query_id不一致问题
- 📷 Markdown 转图片通知(Issue #289)
- 支持
MARKDOWN_TO_IMAGE_CHANNELS配置,对 Telegram、企业微信、自定义 Webhook(Discord)、邮件发送图片格式报告 - 邮件为内联附件,增强对不支持 HTML 客户端的兼容性
- 需安装
wkhtmltopdf和imgkit
- 支持
- 📧 股票分组发往不同邮箱(Issue #268)
- 支持
STOCK_GROUP_N+EMAIL_GROUP_N配置,不同股票组报告发送到对应邮箱 - 大盘复盘发往所有配置的邮箱
- 支持
- 🐛 修复 Docker 内运行时通过页面修改配置报错
[Errno 16] Device or resource busy的问题
- 🐛 修复 Docker 一致性问题,解决关键批次处理与通知 Bug
- ♻️
API_HOST→WEBUI_HOST:Docker Compose 配置项统一
- 📊 ETF 支持增强与代码规范化
- 统一各数据源 ETF 代码处理逻辑
- 新增
canonical_stock_code()统一代码格式,确保数据源路由正确
- 🐛 修复信号 emoji 与建议不一致的问题(复合建议如"卖出/观望"未正确映射)
- 🐛 修复
*ST股票名在微信/Dashboard 中 markdown 转义问题 - 🐛 修复
idx.amount为 None 时大盘复盘 TypeError - 🐛 修复分析 API 返回
report=None及 ReportStrategy 类型不一致问题 - 🐛 修复 Tushare 返回类型错误(dict → UnifiedRealtimeQuote)及 API 端点指向
- 📊 大盘复盘报告注入结构化数据(涨跌统计、指数表格、板块排名)
- 🔍 搜索结果 TTL 缓存(500 条上限,FIFO 淘汰)
- 🔧 Tushare Token 存在时自动注入实时行情优先级
- 📰 新闻摘要截断长度 50→200 字
- ⚡ 补充行情字段请求限制为最多 1 次,减少无效请求
- 📈 回测引擎 (PR #269)
- 新增基于历史分析记录的回测系统,支持收益率、胜率、最大回撤等指标评估
- WebUI 集成回测结果展示
- 🐛 修复狙击点位数据解析错误问题 (PR #271)
- ✉️ 可配置邮件发送者名称 (PR #272)
- 🌐 外国股票支持英文关键词搜索
- 🐛 修复 ETF 实时行情获取、市场数据回退、企业微信消息分块问题
- 🔧 CI 流程简化
- 🗑️ 移除旧版 WebUI
- 删除基于
http.server.ThreadingHTTPServer的旧版 WebUI(web/包) - 旧版 WebUI 的功能已完全被 FastAPI(
api/)+ React 前端替代 --webui/--webui-only命令行参数标记为弃用,自动重定向到--serve/--serve-onlyWEBUI_ENABLED/WEBUI_HOST/WEBUI_PORT环境变量保持兼容,自动转发到 FastAPI 服务webui.py保留为兼容入口,启动时直接调用 FastAPI 后端- Docker Compose 中移除
webui服务定义,统一使用server服务
- 删除基于
- ♻️ 服务层重构
- 将
web/services.py中的异步任务服务迁移至src/services/task_service.py - Bot 分析命令(
bot/commands/analyze.py)改为使用src.services.task_service - Docker 环境变量
WEBUI_HOST/WEBUI_PORT更名为API_HOST/API_PORT(旧名仍兼容)
- 将
2.3.0 - 2026-02-01
- 🇺🇸 增强美股支持 (Issue #153)
- 实现基于 Akshare 的美股历史数据获取 (
ak.stock_us_daily()) - 实现基于 Yfinance 的美股实时行情获取(优先策略)
- 增加对不支持数据源(Tushare/Baostock/Pytdx/Efinance)的美股代码过滤和快速降级
- 实现基于 Akshare 的美股历史数据获取 (
- 🐛 修复 AMD 等美股代码被误识别为 A 股的问题 (Issue #153)
2.2.5 - 2026-02-01
- 🤖 AstrBot 消息推送 (PR #217)
- 新增 AstrBot 通知渠道,支持推送到 QQ 和微信
- 支持 HMAC SHA256 签名验证,确保通信安全
- 通过
ASTRBOT_URL和ASTRBOT_TOKEN配置
2.2.4 - 2026-02-01
- ⚙️ 可配置数据源优先级 (PR #215)
- 支持通过环境变量(如
YFINANCE_PRIORITY=0)动态调整数据源优先级 - 无需修改代码即可优先使用特定数据源(如 Yahoo Finance)
- 支持通过环境变量(如
2.2.3 - 2026-01-31
- 📦 更新 requirements.txt,增加
lxml_html_clean依赖以解决兼容性问题
2.2.2 - 2026-01-31
- 🐛 修复代理配置区分大小写问题 (fixes #211)
2.2.1 - 2026-01-31
- 🐛 YFinance 兼容性修复 (PR #210, fixes #209)
- 修复新版 yfinance 返回 MultiIndex 列名导致的数据解析错误
2.2.0 - 2026-01-31
- 🔄 多源回退策略增强
- 实现了更健壮的数据获取回退机制 (feat: multi-source fallback strategy)
- 优化了数据源故障时的自动切换逻辑
- 🐛 修复 analyzer 运行后无法通过改 .env 文件的 stock_list 内容调整跟踪的股票
2.1.14 - 2026-01-31
- 📝 更新 README 和优化 auto-tag 规则
2.1.13 - 2026-01-31
- 🐛 Tushare 优先级与实时行情 (Fixed #185)
- 修复 Tushare 数据源优先级设置问题
- 修复 Tushare 实时行情获取功能
2.1.12 - 2026-01-30
- 🌐 修复代理配置在某些情况下的区分大小写问题
- 🌐 修复本地环境禁用代理的逻辑
2.1.11 - 2026-01-30
- 🚀 飞书消息流优化 (PR #192)
- 优化飞书 Stream 模式的消息类型处理
- 修改 Stream 消息模式默认为关闭,防止配置错误运行时报错
2.1.10 - 2026-01-30
- 📦 合并 PR #154 贡献
2.1.9 - 2026-01-30
- 💬 微信文本消息支持 (PR #137)
- 新增微信推送的纯文本消息类型支持
- 添加
WECHAT_MSG_TYPE配置项
2.1.8 - 2026-01-30
- 🐛 修正日志中 API 提供商显示错误 (PR #197)
2.1.7 - 2026-01-30
- 🌐 禁用本地环境的代理设置,避免网络连接问题
2.1.6 - 2026-01-29
- 📡 Pytdx 数据源 (Priority 2)
- 新增通达信数据源,免费无需注册
- 多服务器自动切换
- 支持实时行情和历史数据
- 🏷️ 多源股票名称解析
- DataFetcherManager 新增
get_stock_name()方法 - 新增
batch_get_stock_names()批量查询 - 自动在多数据源间回退
- Tushare 和 Baostock 新增股票名称/列表方法
- DataFetcherManager 新增
- 🔍 增强搜索回退
- 新增
search_stock_price_fallback()用于数据源全部失败时 - 新增搜索维度:市场分析、行业分析
- 最大搜索次数从 3 增加到 5
- 改进搜索结果格式(每维度 4 条结果)
- 新增
- 更新搜索查询模板以提高相关性
- 增强
format_intel_report()输出结构
2.1.5 - 2026-01-29
- 📡 新增 Pytdx 数据源和多源股票名称解析功能
2.1.4 - 2026-01-29
- 📝 更新赞助商信息
2.1.3 - 2026-01-28
- 📝 重构 README 布局
- 🌐 新增繁体中文翻译 (README_CHT.md)
- 🐛 修复 WebUI 无法输入美股代码问题
- 输入框逻辑改成所有字母都转换成大写
- 支持
.的输入(如BRK.B)
2.1.2 - 2026-01-27
- 🐛 修复个股分析推送失败和报告路径问题 (fixes #166)
- 🐛 修改 CR 错误,确保微信消息最大字节配置生效
2.1.1 - 2026-01-26
- 🔧 添加 GitHub Actions auto-tag 工作流
- 📡 添加 yfinance 兜底数据源及数据缺失警告
- 🐳 修复 docker-compose 路径和文档命令
- 🐳 Dockerfile 补充 copy src 文件夹 (fixes #145)
2.1.0 - 2026-01-25
- 🇺🇸 美股分析支持
- 支持美股代码直接输入(如
AAPL,TSLA) - 使用 YFinance 作为美股数据源
- 支持美股代码直接输入(如
- 📈 MACD 和 RSI 技术指标
- MACD:趋势确认、金叉死叉信号(零轴上金叉⭐、金叉✅、死叉❌)
- RSI:超买超卖判断(超卖⭐、强势✅、超买
⚠️ ) - 指标信号纳入综合评分系统
- 🎮 Discord 推送支持 (PR #124, #125, #144)
- 支持 Discord Webhook 和 Bot API 两种方式
- 通过
DISCORD_WEBHOOK_URL或DISCORD_BOT_TOKEN+DISCORD_MAIN_CHANNEL_ID配置
- 🤖 机器人命令交互
- 钉钉机器人支持
/分析 股票代码命令触发分析 - 支持 Stream 长连接模式
- 钉钉机器人支持
- 🌡️ AI 温度参数可配置 (PR #142)
- 支持自定义 AI 模型温度参数
- 🐳 Zeabur 部署支持
- 添加 Zeabur 镜像部署工作流
- 支持 commit hash 和 latest 双标签
- 🏗️ 项目结构优化
- 核心代码移至
src/目录,根目录更清爽 - 文档移至
docs/目录 - Docker 配置移至
docker/目录 - 修复所有 import 路径,保持向后兼容
- 核心代码移至
- 🔄 数据源架构升级
- 新增数据源熔断机制,单数据源连续失败自动切换
- 实时行情缓存优化,批量预取减少 API 调用
- 网络代理智能分流,国内接口自动直连
- 🤖 Discord 机器人重构为平台适配器架构
- 🌐 网络稳定性增强
- 自动检测代理配置,对国内行情接口强制直连
- 修复 EfinanceFetcher 偶发的
ProtocolError - 增加对底层网络错误的捕获和重试机制
- 📧 邮件渲染优化
- 修复邮件中表格不渲染问题 (#134)
- 优化邮件排版,更紧凑美观
- 📢 企业微信推送修复
- 修复大盘复盘推送不完整问题
- 增强消息分割逻辑,支持更多标题格式
- 增加分批发送间隔,避免限流丢失
- 👷 CI/CD 修复
- 修复 GitHub Actions 中路径引用的错误
2.0.0 - 2026-01-24
- 🇺🇸 美股分析支持
- 支持美股代码直接输入(如
AAPL,TSLA) - 使用 YFinance 作为美股数据源
- 支持美股代码直接输入(如
- 🤖 机器人命令交互 (PR #113)
- 钉钉机器人支持
/分析 股票代码命令触发分析 - 支持 Stream 长连接模式
- 支持选择精简报告或完整报告
- 钉钉机器人支持
- 🎮 Discord 推送支持 (PR #124)
- 支持 Discord Webhook 推送
- 添加 Discord 环境变量到工作流
- 🐳 修复 WebUI 在 Docker 中绑定 0.0.0.0 (fixed #118)
- 🔔 修复飞书长连接通知问题
- 🐛 修复
analysis_delay未定义错误 - 🔧 启动时 config.py 检测通知渠道,修复已配置自定义渠道情况下仍然提示未配置问题
- 🔧 优化 Tushare 优先级判断逻辑,提升封装性
- 🔧 修复 Tushare 优先级提升后仍排在 Efinance 之后的问题
- ⚙️ 配置 TUSHARE_TOKEN 时自动提升 Tushare 数据源优先级
- ⚙️ 实现 4 个用户反馈 issue (#112, #128, #38, #119)
1.6.0 - 2026-01-19
- 🖥️ WebUI 管理界面及 API 支持(PR #72)
- 全新 Web 架构:分层设计(Server/Router/Handler/Service)
- 核心 API:支持
/analysis(触发分析),/tasks(查询进度),/health(健康检查) - 交互界面:支持页面直接输入代码并触发分析,实时展示进度
- 运行模式:新增
--webui-only模式,仅启动 Web 服务 - 解决了 #70 的核心需求(提供触发分析的接口)
- ⚙️ GitHub Actions 配置灵活性增强(#79)
- 支持从 Repository Variables 读取非敏感配置(如 STOCK_LIST, GEMINI_MODEL)
- 保持对 Secrets 的向下兼容
- 🐛 修复企业微信/飞书报告截断问题(#73)
- 移除 notification.py 中不必要的长度硬截断逻辑
- 依赖底层自动分片机制处理长消息
- 🐛 修复 GitHub Workflow 环境变量缺失(#80)
- 修复
CUSTOM_WEBHOOK_BEARER_TOKEN未正确传递到 Runner 的问题
- 修复
1.5.0 - 2026-01-17
- 📲 单股推送模式(#55)
- 每分析完一只股票立即推送,不用等全部分析完
- 命令行参数:
--single-notify - 环境变量:
SINGLE_STOCK_NOTIFY=true
- 🔐 自定义 Webhook Bearer Token 认证(#51)
- 支持需要 Token 认证的 Webhook 端点
- 环境变量:
CUSTOM_WEBHOOK_BEARER_TOKEN
1.4.0 - 2026-01-17
- 📱 Pushover 推送支持(PR #26)
- 支持 iOS/Android 跨平台推送
- 通过
PUSHOVER_USER_KEY和PUSHOVER_API_TOKEN配置
- 🔍 博查搜索 API 集成(PR #27)
- 中文搜索优化,支持 AI 摘要
- 通过
BOCHA_API_KEYS配置
- 📊 Efinance 数据源支持(PR #59)
- 新增 efinance 作为数据源选项
- 🇭🇰 港股支持(PR #17)
- 支持 5 位代码或 HK 前缀(如
hk00700、hk1810)
- 支持 5 位代码或 HK 前缀(如
- 🔧 飞书 Markdown 渲染优化(PR #34)
- 使用交互卡片和格式化器修复渲染问题
- ♻️ 股票列表热重载(PR #42 修复)
- 分析前自动重载
STOCK_LIST配置
- 分析前自动重载
- 🐛 钉钉 Webhook 20KB 限制处理
- 长消息自动分块发送,避免被截断
- 🔄 AkShare API 重试机制增强
- 添加失败缓存,避免重复请求失败接口
- 📝 README 精简优化
- 高级配置移至
docs/full-guide.md
- 高级配置移至
1.3.0 - 2026-01-12
- 🔗 自定义 Webhook 支持
- 支持任意 POST JSON 的 Webhook 端点
- 自动识别钉钉、Discord、Slack、Bark 等常见服务格式
- 支持配置多个 Webhook(逗号分隔)
- 通过
CUSTOM_WEBHOOK_URLS环境变量配置
- 📝 企业微信长消息分批发送
- 解决自选股过多时内容超过 4096 字符限制导致推送失败的问题
- 智能按股票分析块分割,每批添加分页标记(如 1/3, 2/3)
- 批次间隔 1 秒,避免触发频率限制
1.2.0 - 2026-01-11
- 📢 多渠道推送支持
- 企业微信 Webhook
- 飞书 Webhook(新增)
- 邮件 SMTP(新增)
- 自动识别渠道类型,配置更简单
- 统一使用
NOTIFICATION_URL配置,兼容旧的WECHAT_WEBHOOK_URL - 邮件支持 Markdown 转 HTML 渲染
1.1.0 - 2026-01-11
- 🤖 OpenAI 兼容 API 支持
- 支持 DeepSeek、通义千问、Moonshot、智谱 GLM 等
- Gemini 和 OpenAI 格式二选一
- 自动降级重试机制
1.0.0 - 2026-01-10
- 🎯 AI 决策仪表盘分析
- 一句话核心结论
- 精确买入/止损/目标点位
- 检查清单(✅
⚠️ ❌) - 分持仓建议(空仓者 vs 持仓者)
- 📊 大盘复盘功能
- 主要指数行情
- 涨跌统计
- 板块涨跌榜
- AI 生成复盘报告
- 🔍 多数据源支持
- AkShare(主数据源,免费)
- Tushare Pro
- Baostock
- YFinance
- 📰 新闻搜索服务
- Tavily API
- SerpAPI
- 💬 企业微信机器人推送
- ⏰ 定时任务调度
- 🐳 Docker 部署支持
- 🚀 GitHub Actions 零成本部署
- Gemini AI 模型(gemini-3-flash-preview)
- 429 限流自动重试 + 模型切换
- 请求间延时防封禁
- 多 API Key 负载均衡
- SQLite 本地数据存储