47 Commits

Author SHA1 Message Date
zhulinsen
bcb7ae4e13 feat: 将参考 AlphaSift 的选股实现纳入主项目 (#2136)
* feat: integrate built-in stock screening engine

* test: verify screening routes via public contract

* refactor: make screening integration fully native

* fix(review-feedback-2136): [Verification blocker] 当前 Head 的阻断型 CI 已最终失败:backend-gate。请在本地运行对应

* feat: persist screening runs and reuse DSA analysis

* fix(review-feedback-2136): 对选股重排应用统一的模型参数兼容逻辑

* fix(review-feedback-2136): 将字段缺失计入数据源失败

* fix(review-feedback-2136): 评审结论 - 代码检查 :当前整个 PR 仍有 3 个未关闭的高置信度代码 blocker。最新复核摘要:当前整个 PR 仍有 3

* fix(review-feedback-2136): 延迟写入候选直到覆盖率通过校验 and 将 DSA 日线成功结果写入 last-good 缓存

* fix(review-feedback-2136): 将直连日线源纳入统一调用超时 and 将新增的选股缓存目录加入桌面更新备份

* fix(review-feedback-2136): 保留完整热点缓存而非请求切片 and 遵守 DSA 上下文声明的候选上限

* fix(review-feedback-2136): 补一条端到端回归:把真实 ScreenResult 经 ScreeningService.screen 落到 /history 和

* fix(review-feedback-2136): 补一个 refresh=true 且 live fetch 失败时返回 stale cache 的回归测试,避免当前只更新 stale
2026-08-01 14:13:23 +08:00
JaxonHu
d13721e817 feat: 新增富途Futu真实持仓导入支持 (#2042)
* feat: add Futu portfolio import support

* docs: condense Futu changelog entry

* fix: tighten Futu portfolio import contracts
2026-07-20 22:45:45 +08:00
zhulinsen
e8a9ca7742 fix: harden release packages and report market context (#1994)
* fix: bundle orjson in release packages

* fix: remove duplicate decision signal excerpts

* feat: add TickFlow sector ranking fallback
2026-07-12 18:56:21 +08:00
zhulinsen
a52c8502d7 fix: harden AlphaSift timeout handling (#1898) 2026-07-03 21:00:12 +08:00
ZhuLinsen
a62fc56a74 fix: restore installable longbridge constraints 2026-06-28 21:29:18 +08:00
zhulinsen
29fa05049d fix: harden AlphaSift source stability (#1832)
* fix: harden AlphaSift source stability

* docs: add data source stability diagrams

* fix(review-feedback-1832): Handle degraded EastMoney failures for the new default

* fix: allow JP KR market light snapshots

* fix(review-feedback-1832): 补充覆盖 alert 创建/校验路径的回归测试,证明 JP/KR 不会被告警路径接受
2026-06-28 20:23:02 +08:00
zariba
94cd2a4d96 feat(data): 接入 TickFlow 核心 A 股数据源 (#1790)
* feat(data): integrate TickFlow core A-share provider

* fix(data): harden TickFlow daily kline contract

* fix(web): localize TickFlow settings and run-flow coverage

* fix(web): clarify TickFlow priority settings

* chore(deps): require verified TickFlow SDK

---------

Co-authored-by: timeance <timeance@users.noreply.github.com>
2026-06-28 17:09:28 +08:00
zhulinsen
7ff3297050 fix: pin longbridge to docker-compatible version (#1811) 2026-06-26 22:28:44 +08:00
mumu
0ed601022f fix: 升级 AlphaSift 并兼容热点详情龙头股字段 (#1714)
* fix: update AlphaSift pin and hotspot detail fields

* fix(review-feedback-1714): fix still returning no concept stocks despite the leaders being
2026-06-19 09:28:32 +08:00
mumu
3b5ef16144 feat: harden AlphaSift data source routing (#1680)
* feat: harden alphasift data source routing

* fix(review-feedback-1680): Keep the sample AlphaSift pin in sync and Avoid circuit-breaking

* fix(review-feedback-1680): Defer half-open health checks until a source is attempted and Treat

* fix(review-feedback-1680): fix only bypasses this branch for fetchers that opt into allow empty

* fix(review-feedback-1680): Avoid accepting truncated Tencent histories

* fix(review-feedback-1680): 修正 .env.example 的 AlphaSift 快照源默认说明,并避免在 docs/CHANGELOG.md

* fix(review-feedback-1680): src/config.py、src/services/alphasift service.py

* fix(review-feedback-1680): requirements.txt、src/config.py、.env.example、src/services/alphasift

* fix(review-feedback-1680): 修复 TencentFetcher 对显式历史窗口的处理问题

* fix(review-feedback-1680): Check the cap was hit before rejecting Tencent history

* fix(review-feedback-1680): Use Tencent's hyphenated date format and Convert Tencent daily volume

* fix(review-feedback-1680): Accept the executor timeout argument and preserve capped windows with

* fix: limit empty daily data opt-in behavior

* docs: restore AlphaSift 3.22 changelog entry
2026-06-14 18:47:41 +08:00
mumu
ecc370e50b feat: adapt AlphaSift hotspot contract (#1675)
* feat: adapt alphasift hotspot contract

* fix(review-feedback-1675): update sample install spec with new allowed pin

* fix(review-feedback-1675): 补充 “revert 本 PR / 恢复旧 AlphaSift pin” 级别的回滚说明,并明确无关联 issue 或补充 Refs

* fix: harden alphasift hotspot metadata migration

* fix(review-feedback-1675): preserve hotspot route events in the new detail path

* fix(review-feedback-1675): 修正旧 AlphaSift pin 回滚/重装路径说明,避免运维按文档操作时被 install allow-list 拒绝

* fix(review-feedback-1675): src/services/alphasift service.py:当 AlphaSift v2 detail payload

* fix(review-feedback-1675): 补对应回归测试
2026-06-13 14:46:18 +08:00
mumu
4b3f679b2d feat: adapt AlphaSift hotspot topics (#1635)
* feat: adapt AlphaSift hotspot topics

* fix(review-feedback-1635): preserve cached hotspots when refresh returns no rows and Avoid

* fix(review-feedback-1635): Reload detail when refreshing the selected hotspot and Fall back when

* fix(review-feedback-1635): update by the requested topic or a request token

* fix(review-feedback-1635): preserve analysis when optional serve startup fails and Fall back when

* fix(review-feedback-1635): 当前 CI 状态为 failure,且 backend-gate 为 cancelled、docker-build 为 skipped

* fix(review-feedback-1635): 让 backend-gate / docker-build 在当前 head 上完成并通过,或给出可接受的维护者级豁免说明

* fix(review-feedback-1635): 当前 CI 仍未闭环:结构化事实显示 backend-gate 被取消、docker-build skipped

* fix(review-feedback-1635): 修复 hotspot detail 的上游 schema 容错问题,并让当前 head 的阻断 CI 重新跑通

* fix(review-feedback-1635): docs/CHANGELOG.md:当前 diff 不是在 [Unreleased] 扁平格式下追加本 PR

* fix(review-feedback-1635): CI 闭环未完成:结构化事实显示当前 CI 状态为 failure,backend-gate cancelled、docker-build

* fix(review-feedback-1635): 让当前 head 的阻断型 CI 完整通过,并修正文档中的 AlphaSift commit hash 不一致

* fix(review-feedback-1635): CI 仍未在当前 head 完整通过:结构化事实显示

* fix(review-feedback-1635): 修复 docs/CHANGELOG.md 对主线既有 [Unreleased] 条目的删除,并补齐 AlphaSift

* fix(review-feedback-1635): Accept slash-containing hotspot topics

* fix(review-feedback-1635): Try industry constituents for industry hotspots

* fix(review-feedback-1635): Clear old hotspot details when loading a new topic and preserve the

* test: isolate main schedule environment

* chore: clean AlphaSift PR scope

* fix: respect AlphaSift hotspot fallbacks
2026-06-12 22:38:42 +08:00
mumu
0ca4e07b0e feat: integrate AlphaSift with DSA runtime enrichment (#1577)
* feat: integrate AlphaSift with DSA runtime enrichment

* feat: pin AlphaSift DSA provider context

* fix: clean up AlphaSift warning display

* fix(review-feedback-1577): pass the headers through a path AlphaSift actually uses, such as a

* fix(review-feedback-1577): 补齐 LLM 运行时桥接兼容性的关键证据

* fix: keep AlphaSift screening lightweight

* fix(review-feedback-1577): Populate DSA news when reusing context

* fix(review-feedback-1577): 补齐外部 LLM/LiteLLM 兼容依据,并修正 docs/CHANGELOG.md 的格式/重复条目问题

* fix(review-feedback-1577): 补齐外部模型/API 兼容依据或在 PR 正文中明确指向已更新文档中的官方来源与迁移/回退边界

* fix(review-feedback-1577): scripts/build-backend.ps1 已随本 PR 调整 AlphaSift 打包/收集逻辑,但完整改动文件列表未包含

* fix(review-feedback-1577): 处理 AlphaSift LLM bridge 对全局 LiteLLM 状态的并发污染风险

* fix: reuse DSA daily history for AlphaSift

* fix(review-feedback-1577): 补齐 --collect-all alphasift 或等价 hidden imports,并增加打包产物级导入验证

* fix(review-feedback-1577): fix the macOS AlphaSift package verifier

* fix(review-feedback-1577): scripts/build-backend-macos.sh 和 scripts/build-backend.ps1

* fix(review-feedback-1577): 处理运行时阻塞风险、CHANGELOG 删除既有条目,以及补齐外部模型/API 兼容证据

* fix(review-feedback-1577): scripts/build-backend-macos.sh:当前“Verifying packaged AlphaSift

* fix(review-feedback-1577): 收敛下面的可用性判断和外部 API/模型兼容证据缺口

* fix(review-feedback-1577): src/config.py、src/core/config registry.py、src/services/alphasift

* fix(review-feedback-1577): scripts/build-backend-macos.sh:新增的 packaged AlphaSift importability

* fix(review-feedback-1577): make the archive fallback require a dsa adapter entry or exercise the

* fix(review-feedback-1577): 处理无关测试改动,并补齐桌面打包文档/验证边界
2026-06-05 08:53:55 +08:00
mumu
5cd968b411 fix: improve Windows first-run encoding compatibility (#1583) 2026-06-03 22:36:50 +08:00
mumu
647b9d24e5 fix: support Longbridge OAuth token cache (#1490)
* fix: support Longbridge OAuth token cache

* fix(review-feedback-1490): bump the runtime dependency minimum or fail with a clear upgrade

* fix(review-feedback-1490): 补充对应回归测试

* fix(review-feedback-1490): Point OAuth cache at the dsa home in Docker

* fix(review-feedback-1490): 修复或给出明确的 CI 重跑通过证据

* fix(review-feedback-1490): 处理 Docker/Actions 持久化 token cache 已损坏时无法被新的 LONGBRIDGE OAUTH TOKEN

* fix: tighten Longbridge OAuth compatibility

* fix: refresh stale Longbridge OAuth cache

* fix: guard Longbridge OAuth SDK availability
2026-05-29 23:08:16 +08:00
mumu
f1fdaaba1b fix: invalid unit abbreviation: T (#1485) (#1489)
* fix(issue-1485): [bug]-invalid-unit-abbreviation:-t

* fix(review-feedback-1489): 补充该命令或等价运行时 smoke 的通过证据后再合入
2026-05-27 22:21:54 +08:00
mumu
88d8ffbf81 Relax LiteLLM version constraint (#1201)
* chore: relax litellm version constraint

* chore: cap litellm constraint to 1.x
2026-05-05 22:49:21 +08:00
Rules
dd89d06a7d feat:修复美股数据丢失,新增长桥数据源 (#981)
* fix:新增长桥数据源,补充美港股数据

* ci: Actions 注入 LONGBRIDGE_* 环境变量并增加数据源检查;full-guide 补充 CI 配置说明

Made-with: Cursor

* fix:长桥参数初始化时机调整

* fix:添加长桥初始化调试日志

* fix:调整数据源优先级

* Update tests/test_search_searxng.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update data_provider/base.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update data_provider/longbridge_fetcher.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update docs/README_CHT.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update docs/README_EN.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update docs/README_EN.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update docs/README_CHT.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(longbridge): 使用 get_config() 替代不存在的 config 导入(_is_available)

* fix:CHANGELOG、联调脚本重命名、繁中 README 英文链接、PRINT_QUOTE_PACKAGES 默认值已对齐。

* fix:调整审核中的问题

---------

Co-authored-by: xuxiong <xiong.xu@xsgames.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-02 23:05:08 +08:00
mumu
a3a820db83 fix: 为 Discord Webhook 请求补充签名验证 (#896) (#934)
* fix(issue-896): [bug]-为-discord-webhook-请求补充签名验证
2026-04-01 11:43:32 +08:00
mumu
e2bff55ce4 fix: restore pypi litellm install path (#858)
* fix: restore pypi litellm install path

* chore: relax litellm lower bound to historical minimum
2026-03-26 00:16:43 +08:00
mumu
c00dff17d3 fix: stabilize backend ci dependency install (#835)
* fix: stabilize backend ci dependency install

* fix: split backend gate workflow phases

* fix: retry backend ci dependency install

* fix: install litellm from github source
2026-03-24 21:42:39 +08:00
Alfred
905b366ef1 feat: integrate TickFlow market review enhancement (#632) (#745)
Co-authored-by: mumu <42829555+ZhuLinsen@users.noreply.github.com>
2026-03-18 19:19:08 +08:00
Alfred
53e3d2dead [Feature] 报告引擎 P0:Schema、模板、完整性校验、Brief 模式、历史对比 (#560) (#561)
* chore(config): add report engine feature flags and template settings

* feat(analyzer): add pydantic schema validation for llm report json

* feat(report): report engine P0 - schema, templates, integrity, brief mode, history comparison

- Pydantic AnalysisReportSchema for LLM JSON validation
- Jinja2 templates (markdown, wechat, brief) with configurable dir
- Content integrity check with retry and placeholder fallback
- Brief mode (REPORT_TYPE=brief) for 3-5 sentence summary
- History comparison service for signal changes across runs
- generate_aggregate_report unified entry, ReportType.from_str(detailed)
- Config: REPORT_TEMPLATES_DIR, REPORT_RENDERER_ENABLED, etc.

Fixes #560
2026-03-09 21:35:55 +08:00
Alfred
633bdda1e2 [feat] 2.2 智能导入 - 名称解析、图片提取、CSV/Excel 导入、预览确认 (#546)
* feat(#455): Markdown-to-image for dashboard, m2f engine, prefetch controls

- Dashboard report supports markdown-to-image (Telegram/WeChat/Custom/Email)
- MD2IMG_ENGINE=markdown-to-file for better emoji support
- PREFETCH_REALTIME_QUOTES to disable full-market quote prefetch
- Stock name prefetch with allow_realtime=False to reduce network overhead
- Email groups and Custom webhook image routing
- Enhanced failure hint (wkhtmltopdf or m2f)
- Docs: README, full-guide, CHANGELOG, .env.example
- Tests: prefetch_stock_names, pipeline notification routing, prefetch dry_run

Fixes #455

* chore: trigger CI and AI review refresh

* feat: intelligent import P1 - name resolver, image extract, CSV/Excel import, preview UI

- Extract STOCK_NAME_MAP to src/data/stock_mapping.py
- Add name_to_code_resolver (local map, pinyin, AkShare, fuzzy match)
- Add stock_code_utils for shared is_code_like/normalize_code
- Enhance image_stock_extractor: code+name+confidence prompt, multi-key, retry
- Add import_parser for CSV/Excel/clipboard with parse-import API
- Add IntelligentImport component (image+file+paste, dedup, confidence-based check)
- Fix single-column code import, preserve name when code dirty
- Deduplicate codes in parse-import response
- Add unit tests for resolver and import_parser

* fix: resolve TS2339 Property 'id' does not exist on type 'never'

In mergeItems when !existing, use fallback id directly instead of existing?.id
to avoid TypeScript narrowing existing to never in that branch.

* chore: address PR review - deps doc, file size check, json_repair, logging, tests

- docs/full-guide: document pypinyin and openpyxl for 智能导入
- api: add file size check before reading in parse-import
- image_stock_extractor: use json_repair fallback for malformed JSON
- import_parser/name_to_code_resolver: add debug logging
- CHANGELOG: add extract-from-image items field compatibility note
- tests: VISION_MODEL priority, json_repair when JSON invalid

* fix(image-extract): markdown strip bug, fake codes filter, EXTRACT_PROMPT doc, parse_import errors

- Fix markdown strip: only remove opening fence to avoid wiping JSON
- Add JSON to _FAKE_CODES; filter field names in fallback
- Add docs/image-extract-prompt.md; PR template EXTRACT_PROMPT block
- Refine parse_import errors: Excel/CSV actionable hints

* chore(parse_import): add detailed error logs, document AkShare cache

- Log file type, size, error on parse_import failures (JSON, file read, parse)
- Add AkShare name resolver 1h TTL cache note to docs/full-guide.md

* fix(import): handle space-separated pairs and confidence upgrade

* fix(import): address PR #546 review - Excel no-header, fuzzy cutoff, code prefix

- fix(import_parser): use header=None for read_excel; detect header row the same
  way as the CSV path to avoid silently consuming first data row as column names
- fix(name_to_code_resolver): raise difflib cutoff 0.6->0.8 and skip fuzzy
  matching for inputs of length <=2 to prevent false-positive short
  matches (e.g. '中国' matching arbitrary stocks in a 5000+ name pool)
- fix(stock_code_utils): normalize_code and is_code_like now recognise
  exchange-prefix formats SH600519, SZ000001, HK00700 (case-insensitive),
  aligning with data_provider/base.py normalize_stock_code behaviour
- tests: add test_parses_xlsx_without_header to TestParseImportFromBytesExcel;
  add tests/test_stock_code_utils.py covering prefix/suffix/plain/edge cases

---------

Co-authored-by: mumu <42829555+ZhuLinsen@users.noreply.github.com>
2026-03-09 19:21:50 +08:00
zhulinsen
43dc266d46 fix(etf+tiktoken): use stock API for ETF OHLCV data, pin tiktoken <0.12 #patch
- EfinanceFetcher: switch ETF from ef.fund.get_quote_history (NAV only)
  to ef.stock.get_quote_history (full OHLCV) so ETFs get proper
  open/high/low/close/volume/amount data instead of zeros
- Remove obsolete NAV column mappings from _normalize_data
- Pin tiktoken>=0.8.0,<0.12.0 to avoid 'Unknown encoding cl100k_base'
  plugin registration issue in tiktoken 0.12.0

Fixes #541
Fixes #527
Fixes #537
2026-03-07 21:06:50 +08:00
mumu
e642f776c8 feat: multi-channel LLM support with visual channel editor (#494)
* feat: multi-channel LLM support with visual channel editor

- Add three-tier LLM config: LITELLM_CONFIG (YAML) > LLM_CHANNELS (env) > legacy keys
- Each channel gets independent base_url / api_key / models (no OPENAI_BASE_URL conflict)
- Support DEEPSEEK_API_KEY as standalone provider (auto-infers deepseek-chat model)
- Add LLMChannelEditor component with 9 presets (AIHubmix/DeepSeek/Dashscope/GLM/Moonshot/SiliconFlow/OpenRouter/Gemini/Custom)
- Expand config_registry with ~50 new fields for web settings coverage
- Rewrite .env.example AI section with clear quick-start guide (Scenario A vs B)
- Add litellm_config.example.yaml template
- Add PyYAML dependency for YAML config support
- Full backward compatibility: existing single-key configs work unchanged

* chore: replace placeholder key values with empty defaults in .env.example

* fix: resolve ESLint errors in LLMChannelEditor and HomePage

* refactor: use native litellm deepseek/ provider and extract shared LLM helpers

- Replace openai/deepseek-* + manual api_base with deepseek/ prefix (litellm
  natively resolves DEEPSEEK_API_KEY and base_url)
- Extract duplicated _get_api_keys_for_model and _extra_litellm_params from
  analyzer.py and llm_adapter.py into shared functions in config.py
- Update litellm_config.example.yaml to use deepseek/ prefix
- Thinking mode (deepseek-chat opt-in, deepseek-reasoner auto) unaffected:
  get_thinking_extra_body uses model short name stripped of provider prefix
2026-03-06 21:14:34 +08:00
Alfred
0154992e18 [feat] LiteLLM 直接集成 + 多 API Key 支持 (Fixes #421 #428, Refs #440) (#454) #minor
* fix: migrate _call_gemini to google-genai SDK for thought_signature support (Fixes #440, Refs #421)

- Replace deprecated google-generativeai with google-genai in llm_adapter.py
- Add base64 round-trip for thought_signature (bytes <-> str) for Gemini 3 multi-turn tool calls
- Fix to_gemini_declaration() to use JSON Schema lowercase types (object/string) for parameters_json_schema
- Add base64 decode error handling for robustness
- Add google-genai>=1.0.0 to requirements.txt; keep google-generativeai for analyzer/image_stock_extractor

* test: update test_gemini_declaration for JSON Schema lowercase types

* fix: use role="tool" for function response per Gemini API docs (review feedback)

* feat: LiteLLM 直接集成 + 多 API Key 支持 (Fixes #421, Refs #440)

- 移除 google-generativeai、google-genai、anthropic 原生 SDK,统一通过 litellm 调用
- 新增 LITELLM_MODEL、LITELLM_FALLBACK_MODELS 配置
- 新增 GEMINI_API_KEYS、ANTHROPIC_API_KEYS、OPENAI_API_KEYS 多 Key 解析
- 多 Key 时自动构建 LiteLLM Router(simple-shuffle)
- 删除 LITELLM_PROXY_SETUP.md、litellm_config.yaml.example
- image_stock_extractor、analyzer、market_analyzer 改用 litellm
- registry 移除 to_gemini_declarations/to_anthropic_tools,统一 OpenAI 格式
- 修复 review 发现:删除 _is_key_valid 死代码,更新错误信息与模块 docstring

* docs: restore AIHubmix recommendation section in .env.example

* docs: expand LITELLM_FALLBACK_MODELS example and add vision model config

* fix: correct _run_loop type hint for tool_decls (Dict -> List)

* style: move inline imports to top of file per PEP 8

- litellm and Router imports moved to module top in llm_adapter.py,
  analyzer.py, image_stock_extractor.py
- Also fixes _run_loop tool_decls type hint (Dict -> List)

* fix: add Config type hints and clarify LLM failure exception (review feedback)

* docs: restore original Chinese comments in config (review feedback)

* fix: deprecation hint for legacy config; fallback to gemini_model_fallback when LITELLM_FALLBACK_MODELS empty (review feedback)

* docs: improve .env.example LLM config clarity (review feedback)

- Consolidate LITELLM_MODEL/FALLBACK explanation at top
- Clarify single primary vs comma-separated fallback
- Rename scheme 3 to OpenAI/DeepSeek/OpenRouter (AIHubmix has own section)
- Add note: AIHUBMIX_KEY requires no OPENAI_BASE_URL
- Add OpenRouter URL in OPENAI_BASE_URL comment
- Clarify openai prefix required for third-party/OpenAI-compatible APIs

* chore: Router log models list; add openai dependency note in full-guide (AI review)
2026-02-28 16:36:34 +08:00
Alfred
38b399143e fix: 迁移 _call_gemini 至 google-genai SDK,修复原生 Gemini thought_signature 支持 (Fixes #440, Refs #421) (#444)
* fix: migrate _call_gemini to google-genai SDK for thought_signature support (Fixes #440, Refs #421)

- Replace deprecated google-generativeai with google-genai in llm_adapter.py
- Add base64 round-trip for thought_signature (bytes <-> str) for Gemini 3 multi-turn tool calls
- Fix to_gemini_declaration() to use JSON Schema lowercase types (object/string) for parameters_json_schema
- Add base64 decode error handling for robustness
- Add google-genai>=1.0.0 to requirements.txt; keep google-generativeai for analyzer/image_stock_extractor

* test: update test_gemini_declaration for JSON Schema lowercase types

* fix: use role="tool" for function response per Gemini API docs (review feedback)
2026-02-27 19:10:29 +08:00
Alfred
0e2e111545 feat: add trading day check (Issue #373) (#375)
- Add trading_calendar module with exchange-calendars for A/HK/US markets
- Per-stock filtering: analyze only stocks whose markets are open today
- Add TRADING_DAY_CHECK_ENABLED config and --force-run CLI override
- Add is_hk_stock_code to data_provider public API
- Update CHANGELOG, full-guide, README, .env.example
2026-02-24 20:12:18 +08:00
mumu
498770616f feat(ci): harden smoke gates and automated release pipeline #minor (#336)
- add scripts/ci_gate.sh as unified backend gate entry

- restructure CI into backend-gate/docker-build/web-gate with frontend path detection

- add network-smoke non-blocking workflow for scheduled/manual network checks

- harden docker-publish with tag/manual release_tag flow, semver + changelog validation, and pre-publish docker smoke

- expand PR review and AI review coverage to code/docs/config/workflow changes

- align PR template and contributor docs with AGENTS.md review requirements

- add pytest markers and python-multipart dependency; restore test setup in get_latest_data tests
2026-02-15 23:05:56 +08:00
Alfred
b19a4d0df9 feat: 支持图片识别股票代码、Anthropic Claude API 及通达信手动配置 (fix #257) (#329)
* feat: Add image stock code extraction, Anthropic API, and Pytdx config (Fixes #257)

- Add POST /api/v1/stocks/extract-from-image with Vision LLM (Gemini/Anthropic/OpenAI)
- Add image_stock_extractor service with 60s timeout, rate limit (10/min), X-Forwarded-For support
- Add ImageStockExtractor UI in Settings for upload and merge-to-watchlist
- Add ANTHROPIC_API_KEY, ANTHROPIC_MODEL to config and analyzer fallback chain
- Add PYTDX_HOST, PYTDX_PORT, PYTDX_SERVERS for custom Pytdx server
- Add OPENAI_VISION_MODEL for image-only models
- Handle 409 conflict in merge flow with user-friendly message

* fix: resolve TypeScript build error in stocks.ts (avoid Record<> generic parsing)

* feat: Redis rate limiter, API field unification, anthropic_max_tokens

- Add rate_limiter.py: Memory + Redis implementations for extract-from-image
- Integrate get_extract_rate_limiter() in stocks.py; remove image param, keep file only
- Add anthropic_max_tokens config for analyzer
- Update .env.example, config_registry, full-guide, CHANGELOG
- Add redis>=5.0 as optional dependency

* refactor: rename GeminiAnalyzer to LLMAnalyzer for multi-backend clarity

* revert: restore GeminiAnalyzer naming (keep original upstream convention)

* docs: add image extraction and from-image-add usage to README

* fix: Anthropic runtime fallback to OpenAI; remove Redis rate limiter

- Init both Anthropic and OpenAI at startup so Anthropic 429/network glitch can fall back to OpenAI
- Check Anthropic before OpenAI in _call_api_with_retry to preserve priority
- Remove Redis rate limiter per review; keep in-memory only

* remove rate limiter for extract-from-image per review

- Delete rate_limiter.py; extract-from-image has no rate limiting
- Remove Request param and 429 response from stocks endpoint
- Update docs to drop rate limit mentions
2026-02-15 19:10:42 +08:00
Alfred
5883dc41bd feat: add Markdown-to-image for notification channels (Fixes #289) (#315)
* feat: add Markdown-to-image for notification channels (Fixes #289)

- Add MARKDOWN_TO_IMAGE_CHANNELS config for telegram, wechat, custom, email
- New src/md2img.py: markdown_to_image() via imgkit/wkhtmltoimage
- Extract markdown_to_html_document to src/formatters.py for reuse
- Implement image sending: Telegram sendPhoto, WeChat base64+md5,
  Discord webhook multipart, email inline attachment
- Add imgkit to requirements, wkhtmltopdf to Dockerfile
- Graceful fallback to text when imgkit/wkhtmltopdf unavailable

* fix(docker): pin to bookworm for wkhtmltopdf, add runtime deps

wkhtmltopdf was removed from Debian testing (2025). Pin base image to
python:3.11-slim-bookworm. Add fontconfig, libjpeg62-turbo, libxrender1,
libxext6 for headless wkhtmltopdf.

* docs(md2img): add security note on command injection and XSS

* refactor(md2img): extract _should_use_image_for_channel, document Fallback rules

* docs: add Markdown-to-image dependency install guide (imgkit, wkhtmltopdf)
2026-02-13 21:16:22 +08:00
Krane
9847157980 Feature/React web support 新的WebUI (#256)
* feat(web): add FastAPI & React web connect

* feat: add FastAPI package

* feat: system base struct

* feat: frontend base struct

* feat: 基础分析接口,历史记录接口

* fix: 使用正确的 FastAPI 方法定义,避免线程阻塞

* fix: 对接历史报告页、详情页

* fix: 修复接口问题

* fix: 网络配置 允许公网访问 跨域配置

* fix: 页面打包 & 提供 Server 静态访问

* fix: 优化dock栏样式

* fix: 优化图标样式

* fix: 修改部分配色

* fix: 删除垃圾文档

* fix: 删除垃圾代码

* fix: 驼峰转换工具

* fix: 历史记录列表滚动加载(分页)

* feat: 显示分析中任务

* fix: 调整布局

* fix: 优化 Market Sentiment 组件动效

* fix: 历史列表组件bug

* fix: FastAPI 日志配置

* feat: 新闻历史接口

* feat: 资讯列表

* feat: 优化布局

* fix: 修复页面元素变宽问题

* fix: 中文标题

* fix: 任务列表状态显示问题

* fix: 抽取日志配置

* fix: 优化报告价格显示

* fix: 修复编译错误

* fix: FastAPI 启动提取到 main.py

* fix: 补充新web-ui启动文档

* fix: 默认发送通知

* fix: FastAPI 模式适配 docker

* fix: FastAPI 模式文档

* Update api/v1/endpoints/stocks.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: package-lock.json

* fix: 修改错别字

* fix: 更新文档说明

* fix: 更新文档说明

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-05 20:56:38 +08:00
litecn
c13da50f2d feat(analyzer): integrate json-repair for JSON string correction (#226)
- requirements: Added `json-repair` dependency for JSON validation and repair.
- analyzer: Utilized `repair_json` function to ensure JSON strings are correctly formatted before processing.

This enhancement improves the robustness of JSON handling in the analysis workflow.
2026-02-02 20:30:41 +08:00
zhulinsen
286f73275e updated requirements.txt to include lxml_html_clean 2026-01-31 23:07:08 +08:00
zhulinsen
c6fc79d9a0 feat: multi-source fallback strategy and data fetching fixes
- Add triple-source fallback for A-share data (EM → Sina → Tencent)
  - Add multi-source fallback for chip distribution (Akshare → Tushare → Efinance)
  - Fix efinance ETF API parameter errors and OHLC data completion
  - Fix tushare index realtime quote code format (sh/sz prefix)
  - Fix stock name display issue showing code instead of name
  - Upgrade SerpAPI to Google search with Knowledge Graph support

  Fixes #206, #171, #139
  Related #207

  #minor
2026-01-31 22:25:11 +08:00
zhulinsen
5bf23c2827 feat: add pytdx data source and multi-source stock name resolution 2026-01-29 22:32:41 +08:00
adminlove520
d2582ed336 Merge upstream/main into feat/discord-bot
Resolve conflicts in config.py and notification.py:
- config.py: Merge realtime quote configuration and Discord bot status
- notification.py: Add markdown2 import and enhance single stock report with risk alerts, catalysts, and operation points
2026-01-25 14:00:22 +08:00
zhulinsen
c9272c55ea fix(notification): 修复邮件中表格不渲染及排版松散问题 (fixes #134)
- 引入 markdown2 库替代简单的正则替换,支持 Markdown 表格渲染
  - 重构邮件 HTML 生成逻辑,添加完整的 CSS 样式支持
  - 优化邮件排版,调整间距使内容更加紧凑易读
  - 增加表格边框、隔行变色等样式,提升数据展示效果
2026-01-25 11:44:47 +08:00
adminlove520
0f2bc0291d Resolve conflicts with upstream/main and update Discord bot configuration 2026-01-24 20:00:35 +08:00
Krane
2fda768cdf feature: 机器人命令交互触发分析功能 2026-01-22 17:52:20 +08:00
adminlove520
e58750eb5d feat: add Discord bot support 2026-01-22 16:38:53 +08:00
Developer
f652638044 feat: 添加 efinance 数据源支持(最高优先级)
- 新增 EfinanceFetcher 数据获取器(Priority 0)
- 数据源:https://github.com/Micro-sheep/efinance
- 支持股票历史K线、ETF数据、实时行情、基本信息等
- 更新 DataFetcherManager 默认数据源顺序
- 添加 efinance>=0.5.5 依赖

数据源优先级顺序:
0. EfinanceFetcher (efinance)
1. AkshareFetcher (akshare)
2. TushareFetcher (tushare)
3. BaostockFetcher (baostock)
4. YfinanceFetcher (yfinance)
2026-01-16 16:26:54 +00:00
zhulinsen
3dded794d7 fix: 修复多个 Issues
- #23 ETF 筹码分布:跳过 ETF/指数的筹码分布调用
- #16 OpenAI SOCKS 代理:改进错误提示,添加 httpx[socks] 依赖
- #15 大盘复盘报告:添加报告文件保存功能
2026-01-14 20:20:51 +08:00
xu.liu
ccd7b2e8d7 添加飞书文档支持 2026-01-13 21:25:36 +08:00
zhulinsen
5d5c095be5 feat: add OpenAI-compatible API support 2026-01-11 15:46:23 +08:00
zhulinsen
4a003c94ea Initial commit: A股智能分析系统 2026-01-10 15:38:56 +08:00