Commit Graph
101 Commits
Author SHA1 Message Date
Justin Gu 29b6ca33aa feat(cli): 新增 finance-info / company-info / company-info-content 命令
把 TdxClient 上已封装但未暴露给 CLI 的三个 F10/财务方法做成命令,
数据源走通达信原生协议(与 Web 层 /finance /company/* 同源),
覆盖 f10(新浪三表)之外的 F10 全文板块。

- finance-info: 最新财务快照(37 字段单期指标),与 f10 多期三表互补
- company-info: F10 板块目录(最新提示/公司概况/财务分析/... 等 16 板块)
- company-info-content: 读 F10 正文,支持板块名(自动解析)或文件名
  --offset 语义随入参而定:板块名=板块内相对偏移,文件名=绝对偏移
- conn.py: 新增 get_tdx_client() 上下文管理器

补 README 命令表与 CHANGELOG。
2026-06-27 04:02:09 +08:00
Justin Gu 77104a32e3 fix(ci): mypy python_version 3.10 → 3.12 修复 numpy stub 语法错误
根因:CI 的 mypy job 在 Python 3.13 下运行,安装的 numpy 2.x stub
使用 PEP 695 type 语句(3.12+ 语法),但 pyproject.toml 的
python_version="3.10" 让 mypy 按 3.10 语义解析,报
'Type statement is only supported in Python 3.12 and greater'。

修复:
- python_version 提升到 3.12(CI mypy job 实际跑 3.13,开发目标版本对齐)
- mypy/ruff 同步排除 gitignored 的 exchange_margin.py 本地脚本
- 顺带修复 market.py / test_screen.py 的 ruff format 漂移
2026-06-25 03:46:57 +08:00
Justin Gu f36e2d6a6c feat(screen): v1.15.0 — 强势股排名 + 修复证券类型识别与名称分批查询
新增:强势股排名(screen strength)
- 全市场按 5/20/60 日涨幅加权合成强势分,纯离线扫描
- 三种预设:steady(稳健)/breakout(妖股)/balanced(均衡)
- CLI: easy-tdx screen strength --preset steady --top 50 --table
- Web API: GET /api/v1/market/strength
- 支持自定义权重、成交额过滤、并发扫描

修复:
- _detect_security_type 代码段不全,ETF/基金/科创板/逆回购被误判为 A 股
- screen strength/rank 名称补齐超 80 只时末尾被丢弃(分批查询)

详见 CHANGELOG.md
2026-06-25 03:33:13 +08:00
Justin Gu 85e0f8a65f feat(chanlun): 分钟级别日期自适应输出时分 YYYY-MM-DD HH:MM 2026-06-17 18:17:32 +08:00
Justin Gu 87f11e409c release: v1.14.4 — 修复 cmd_chanlun.py ruff format CI 失败 2026-06-16 10:03:48 +08:00
Justin Gu 1945fa1261 feat(chanlun): CLI table 模式 zss/mmds/bcs 显示日期字段 2026-06-16 03:00:08 +08:00
Justin Gu 28aad8a84c release: v1.14.2 — 缠论 JSON 可视化字段增强(中枢/买卖点/背驰补日期) 2026-06-16 02:51:52 +08:00
GitHubandClaude c54071e85e release: v1.14.1 — 高级回测 ExecutionModel 路径 3 个真实数据兼容 Bug 修复
- datetime 类型分歧(致命):Trade.datetime 转 int 与 PortfolioTracker 的 Timestamp key 失配,TWAP/VWAP/Limit 路径交易全部静默丢失、权益曲线恒定、收益归零
- volume 列名分歧:回测认 volume 而真实行情为 vol,滑点 volume 恒 0 退化百分比模式,VWAP 退化为等权
- date/datetime 列名分歧:日线返回 date 列引擎要 datetime,run() 入口由 date 派生下游无感兼容
新增 3 个回归测试(均红灯验证)。650 单测通过,backtest 模块 ruff + mypy strict 清洁。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 20:50:49 +08:00
Justin Gu b49cfd66f8 feat(sina): 新增新浪财报三表 — 三层接入(API/CLI/Web),独立数据源 2026-06-15 00:31:13 +08:00
Justin Gu 574b284dd5 fix(cninfo): URL 404 + type null + 表格截断 + PDF 下载(实测 601088 暴露) 2026-06-14 23:58:24 +08:00
Justin Gu 4b439920fc feat(cninfo): 新增巨潮公告检索 — 三层接入(API/CLI/Web),独立数据源 2026-06-14 23:29:19 +08:00
Justin Gu a12c2122fc feat(indicator): 新增 SAR/VWAP/AROON 三指标 + 注册 FK(30 → 34) 2026-06-14 18:46:02 +08:00
Justin Gu 5fc398255d fix(types): 修复 CI mypy strict + ruff format 失败
mypy (13 errors → 0):
- portfolio/optimizer: register_optimizer 返回类型改为 Callable 装饰器签名
  (原标注 type[WeightOptimizer] 导致 4 个子类 Too many arguments)
- factor/engine: _datetime_to_int 用 isinstance 收窄替代 object→int 强转
- factor/analysis: 删多余 type:ignore(改由 mypy override 统一处理 scipy)
- backtest/orders, execution: np.sqrt 表达式用 float() 包裹消除 no-any-return
- MyTT.pyi: MACD 签名删除错误的 LOW/HIGH 参数(与 MyTT.py 实际签名对齐)
- pyproject: 新增 scipy mypy override (ignore_missing_imports)

ruff format: 8 个 test 文件格式化

验证: 564 passed, mypy 192 文件零错误, ruff check/format 全绿
2026-06-13 21:21:33 +08:00
Justin Gu 88638e82ad release: v1.11.5 — scipy 依赖声明 + 文档同步 + 工程化清理
- pyproject: 新增 science 可选依赖组(scipy),dev 纳入 scipy;版本号 1.11.5
- factor/analysis: spearman 分支加 scipy 软依赖保护,缺失时友好报错
- mac/client: 板块排行吞异常处补 logger.debug
- CLAUDE.md: 架构章节补全 mac/ex/unified/portfolio/factor/offline/screen 子包
- .gitignore: 补全 .coverage、signals.json
- README: 补 1.11.5 changelog
2026-06-13 21:10:35 +08:00
Justin Gu be41746aa9 fix(backtest): _find_bar_index 用 to_numpy().argmax() 取真实位置
idxmax() 返回 index label,后续 iloc[] 按位置取行;当 df.index 非默认
RangeIndex 时 label != position,撮合会取错 K 线。两处分支统一改为位置索引。
新增 2 例非连续 index 回归测试。
2026-06-13 21:10:15 +08:00
Justin Gu 095c88f735 fix(transport): ping 容错 TdxConnectionError,避免单台服务器拖垮测速
ping_host 仅 except OSError,但握手期 _recv_exact_sock 抛的 TdxConnectionError
继承自 TdxError(Exception) 而非 OSError,逃出捕获后经 ping_all 的 fut.result()
重新抛出,导致非交易时间服务器 accept 后立即 FIN 时整个 easy-tdx ping 崩溃。
- ping_host: except (OSError, TdxConnectionError),对齐 docstring 返回 None
- ping_all: fut.result() 加 try/except 防御层,单 host 失败只跳过不崩
- 新增 2 例回归测试
2026-06-13 21:09:55 +08:00
GitHubandClaude a6ed0eac16 docs: add quantitative guide, update README + CHANGELOG, bump v1.11.1
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 22:12:19 +08:00
GitHubandClaude 06f2e1f1a2 feat(backtest): add AttributionAnalyzer with Brinson, factor, cost attribution
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 21:10:50 +08:00
GitHub 0945e47990 feat(backtest): integrate SlippageModel + ExecutionModel into BacktestEngine 2026-06-12 21:04:24 +08:00
GitHub d18af98855 feat(backtest): add LimitExecution 2026-06-12 20:59:59 +08:00
GitHub fe68d9da95 feat(backtest): add TWAPExecution + VWAPExecution 2026-06-12 20:56:57 +08:00
GitHub 0772666be3 feat(backtest): add ExecutionModel ABC + ImmediateExecution 2026-06-12 20:53:07 +08:00
GitHub 6414c2cc11 feat(backtest): integrate SlippageModel into OrderSimulator 2026-06-12 20:50:42 +08:00
GitHub d081eeb265 feat(backtest): add SquareRootSlippage + VolumeSlippage 2026-06-12 20:47:03 +08:00
GitHub 4098af02bf feat(backtest): add SlippageModel ABC + FixedSlippage + PercentSlippage 2026-06-12 20:44:28 +08:00
GitHub b7b72b10d1 feat(portfolio): add optimizer, risk model, rebalance engine, CLI pfactor command, bump v1.13.0 2026-06-12 20:25:50 +08:00
GitHubandClaude e6a69d51e4 feat(portfolio): add optimizer, risk model, and rebalance engine
- WeightOptimizer base class with registry (equal, factor_weighted, risk_parity, mean_variance)
- RiskModel with shrinkage covariance estimation and portfolio risk metrics
- RebalanceEngine for multi-period backtesting with commission/slippage
- 20 unit tests covering all components

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 20:22:31 +08:00
GitHub 303964ea67 feat(factor): add analysis/transform exports, CLI analyze command, bump v1.12.0 2026-06-12 20:11:28 +08:00
GitHub 9d7bf84d5d feat(factor): add FactorAnalyzer with IC/quantile/turnover/decay analysis 2026-06-12 20:09:08 +08:00
GitHub c6f2580b73 feat(factor): add factor preprocessing pipeline (winsorize/zscore/rank/fill/orthogonalize) 2026-06-12 20:08:10 +08:00
GitHubandClaude d5fa572a43 style: ruff format factor module
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 19:58:34 +08:00
GitHub f47a6df776 feat(cli): add 'easy-tdx factor list' command 2026-06-12 19:55:40 +08:00
GitHub d9bb37f750 feat(factor): wire up builtin factor auto-registration and export 2026-06-12 19:53:18 +08:00
GitHubandClaude c9be1f85d9 feat(factor): add 19 builtin factors (momentum/volatility/quality/volume/technical/chanlun/value)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 19:50:05 +08:00
GitHubandClaude e766cace73 feat(factor): add FactorEngine with single/cross-section/forward-return compute
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 19:47:08 +08:00
GitHub 67d9963f20 feat(factor): add Factor base class and registry 2026-06-12 19:43:54 +08:00
GitHubandClaude de2b37e1e3 fix(web): use redoc@2.2.0 standalone bundle (v3 is ESM-only)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 17:06:54 +08:00
GitHubandClaude 79c81cc3b6 fix(web): override redoc endpoint with pinned JS v3.0.0-rc.0
FastAPI does not accept redoc_js_url as a constructor param — the old
approach silently ignored it, leaving the default redoc@next CDN URL
(which returns 404). Manually register /redoc with get_redoc_html()
using the fixed v3.0.0-rc.0 bundle URL.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 17:05:25 +08:00
GitHubandClaude 9848d754a8 fix(web): use redoc@3.0.0-rc.0 bundle
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 16:55:21 +08:00
GitHubandClaude 0d673f1972 fix(web): pin ReDoc JS to v2.1.3 (cdn redoc@next returns 404)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 16:54:03 +08:00
GitHubandClaude 46c5d3cc05 fix(web): guard MAC client None + filter _raw bytes from Ex responses
- get_mac_client() now raises TdxConnectionError (503) when MAC client
  is None, matching get_ex_client() behavior. Previously returned None
  causing AttributeError (500) on all 12 MAC endpoints.
- _records_to_df_resp() filters out internal _raw: bytes fields from
  Ex dataclass models. Previously asdict() included binary protocol
  data that is not JSON-serializable and would cause 500 errors.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 16:51:47 +08:00
GitHubandClaude d17895e92b feat(web): full Web API parity with CLI — 18 new endpoints (v1.10.2)
- Board analysis: list/members/belong/summary/ranking/change-ranking (6)
- Capital flow, symbol info, server info (3)
- Quote list, auction, unusual (3)
- Extended market: bars/quote/minute/transaction (4)
- Technical indicators: list + compute (2)
- Multi-client DI: AsyncMacClient + AsyncExTdxClient lifecycle
- 6 MAC enum converters, DictResponse, ComputeIndicatorsRequest schemas
- Web API endpoints: 22 → 40

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 16:46:48 +08:00
Justin Gu 0e74752701 fix(web): validate market/category input — support lowercase, reject invalid with 400
Root cause: _market_from_str/_market/_category in routers used bare
MarketEnum[key]/Market[key] without .upper() or try/except, so
lowercase or invalid values (sz, ZZZ) threw uncaught KeyError → 500.

Fix: extract shared convert.py with market_from_str/category_from_str
that do .upper() + ValueError on invalid input.  All 4 routers updated.
4 regression tests added for case-insensitive and invalid input.
2026-06-12 03:26:29 +08:00
Justin Gu 9d7a9161f7 fix(web): remove TYPE_CHECKING guard for AsyncTdxClient in deps.py
The typing.cast(AsyncTdxClient, ...) evaluated AsyncTdxClient at
runtime, but the import was gated behind TYPE_CHECKING, causing
NameError in production.  Direct import is safe here — web module
already depends on easy_tdx core.
2026-06-12 03:21:39 +08:00
Justin Gu eb8a7a5675 feat(web): add FastAPI app factory, all routers, CLI serve command, and tests
- App factory with lifespan management and CORS middleware
- Market router: security list, quotes, market stat, fund-flow
- Bars router: kline, index kline, minute, transaction
- Finance router: xdxr, finance, company info, financial records
- Block router: block file parsing
- Chanlun router: POST /chanlun/analyze
- Realtime router: WebSocket /ws/realtime/{symbol}
- CLI: easy-tdx serve command
- 16 unit tests, all passing offline (no network)
2026-06-12 03:08:12 +08:00
Justin Gu 9dc70566a5 feat(web): add Pydantic schemas and error handling 2026-06-12 03:02:04 +08:00
Justin Gu 7f44ba1d06 feat(web): scaffold web API module with [web] optional dependency 2026-06-12 03:00:49 +08:00
GitHubandClaude Opus 4.8 fd03e2a334 fix: ruff format compliance for CI
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 22:56:23 +08:00
GitHubandClaude Opus 4.8 e290ea3f21 feat: add board N-day change ranking (v1.9.10)
- Add get_board_change_ranking() to MacClient and AsyncMacClient
- Add 'board-change-ranking' CLI command (--type/--date/--days/--top/--asc)
- Calculate N-day price change from board index K-lines directly
- Default to listing all boards; --top N to truncate
- 12 unit tests covering calculation, edges, sorting

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 17:40:51 +08:00
Justin Gu 786c7e3619 fix: remove unused type: ignore comments for mypy strict 2026-06-11 04:30:39 +08:00