Commit Graph
15 Commits
Author SHA1 Message Date
GitHub 33d44ba5d6 feat(webui)!: 行情终端重大升级——市场看板/自选/个股与板块弹窗 + SSE 实时推送
展示层对标专业看盘终端(tick-stock-panel 模式),数据全部来自通达信协议直连:

- 市场看板:五大指数实时条(迷你分时)、涨跌统计、四维情绪雷达、
  全市场涨跌分布直方图(约 5500 只 22 桶、鼠标跟随浮窗)、涨停雷达、
  行业/概念热冷榜(可下钻)、涨幅/跌幅/成交额/换手四联排行榜、异动雷达
- 自选行情:6 位代码即加(symbol-info 自动取名)、SSE 实时全表刷新、
  行内迷你分时;SQLite 持久化(watchlist.db,幂等加删)
- 个股弹窗:五档盘口 + 1/3/5 日分时 + 日K(MA/BOLL/EMA + MACD/KDJ/RSI
  前端本地计算)+ 一键加自选 + 一键全策略寻优
- 板块弹窗:板块分时/日K + 成分股涨跌榜直达个股
- SSE 架构:QuoteStreamer 单循环轮询 fan-out(独立队列 + 背压丢旧、
  无订阅休眠、盘中 8s/盘外 60s 降频);前端 pinia 单连接指数退避重连
- fix(codec): SH 000 系大盘指数与 881/885 板块指数报价按 2 位小数解析
  (曾缩小 10 倍:科创50 1647.53→164.753);880 统计指数保持 3 位
- fix: 前端批量五档路径 /security/quotes→/quotes、SSE 五档白名单
  bid1_vol→bid_vol1、MAC 排行 close 列归一化、日K v-if 撑满、
  寻优查看跳转 /→/backtest、FastAPI 0.141 _IncludedRouter 测试适配

新增 27 个单测(streamer/自选/小数位语义),全套 1078 passed
2026-09-01 17:45:07 +08:00
GitHub d0d65d64b8 feat: v1.20.0 服务器失败自动 ping 切换(无需手动 easy-tdx ping)
服务器连不上或返回空数据时,自动测速切到延迟最低的可用服务器再试,
Python API / CLI / Web API 三入口全部自动生效。

核心改动:
- _reconnect.py 新增 select_best_host_sync/async(连接失败 failover)
  和 find_working_host_sync/async(空数据逐台实测)
- 8 个 client 的 _execute 注入跨主机故障转移(复用 auto_reconnect 开关)
- get_market_stat 空数据时按延迟顺序逐台实测找返回数据的服务器
- 新增 _reconnect/_areconnect helper 收敛重建连接副本
- MacClient failover 用 save_best_mac_host(延续 v1.19.4 不污染 best_host)
- 顺手修复 test_commands_offline 未使用 import(main CI failure 根因)

测试:925 passed(新增 18 个 failover 测试),ruff/mypy 零新增错误。
2026-07-08 18:07:37 +08:00
Justin Gu 032f5a40c0 fix(web): v1.19.3 K线空body不再500 + SPA路由刷新404
两个独立问题(日志证据):

1. K线空body 500:SH600519 等正常股票偶发请求时,通达信返回
   ret_count>0 但 body 完全为空(偏移2 剩余0)。v1.18.3 的容错有
   'if bars:' 条件,bars 为空时 raise → 500。移除该条件,始终 return
   (空列表让前端分页重试比 500 友好)。GetIndexBarsCmd 同改。

2. SPA fallback 缺失:/optimize /portfolio 等前端路由刷新时 404。
   子类化 StaticFiles 为 SPAStaticFiles,404 时返回 index.html。
   API 路径不受影响。

测试:更新 test_security_bars_truncated_first_record(原断言 raise,
现断言返回空列表)+ 新增空 body 回归测试。902 全过。
2026-07-07 20:13:39 +08:00
GitHub e3e8dd492e fix: K线响应截断容错 + 一键寻优并发默认8进程
- security_bars: parse_response 遇末尾残缺记录时丢弃并返回前 N-1 条,
  避免 TDX 服务端截断响应导致整页 500(如 000408 count=800 日线)
- OptimizeView: 一键寻优并发默认 8 进程,用户选择持久化到 localStorage

bump version to 1.18.3
2026-07-06 13:23:37 +08:00
Justin Gu 56153eeb97 release: v1.17.7 — 修复 Windows CI fixture 读取编码
1.17.5 引入的 tests/fixtures/ex_history_transaction.json 含中文注释,Windows CI
默认用 cp1252 解码 UTF-8 文件触发 UnicodeDecodeError: 'charmap' codec can't
decode byte 0x8f,导致 3 个 Windows 矩阵的 test_parse_ex_history_transaction_hk
失败(Linux 矩阵因默认 utf-8 不受影响)。

修复:所有 fixture 读取显式指定 encoding='utf-8':
- test_hk_transaction.py 的 load_hex/load_json(直接触发点)
- test_commands_offline.py 的 load_hex(纯 ASCII hex,当前未触发但一并统一)
- test_decode_errors.py 的 _load_hex(同上)

867 单测全绿,ruff format/check / mypy strict 通过。
2026-07-04 02:11:27 +08:00
GitHub db83e7505d fix(security_quotes): 修复 ETF/指数实时行情价格被放大10倍 (Issue #8) 2026-06-29 22:15:28 +08:00
GitHubandClaude Opus 4.8 8d68e9c094 docs: add backtest engine design spec
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 16:05:17 +08:00
Justin Gu 02701952ca feat: merge datetime fields in DataFrame output, hide MinuteBar internal fields
- K-line: daily+ periods output 'date' only, minute periods output 'datetime'
- Transactions (tick-by-tick): combine date param + hour/minute into 'datetime'
- XdxrRecord, HistoricalFundFlow: year/month/day merged to 'date'
- MinuteBar: rename unknown_1 to _unknown_1 (hidden from DataFrame)
- MinuteBar: add datetime column computed from bar index (A-share 240-bar pattern)
- get_minute_time_data: use history endpoint only (current-day endpoint broken in pytdx too)
- Update all examples to reflect new DataFrame column names
2026-05-22 04:19:07 +08:00
GitHubandClaude Opus 4.7 50491f9aae feat!: rename project from xmtdx to easy-tdx
- Package directory: src/xmtdx/ -> src/easy_tdx/
- Import path: from easy_tdx import ...
- pip install easy-tdx
- Add LICENSE (MIT) with upstream attribution (pytdx, xmtdx)
- Add NOTICE with detailed attribution
- Update all examples, tests, scripts, docs
- Bump version to 1.0.0

BREAKING CHANGE: import path changed from `xmtdx` to `easy_tdx`

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 23:21:21 +08:00
minionszyw 7c085f7537 Normalize xdxr per-share fields 2026-04-22 19:42:34 +08:00
minionszyw 91f6a884d5 Fix security list pre-close decoding 2026-04-22 18:50:07 +08:00
M 96f14f70bc Fix protocol regressions and clarify experimental APIs 2026-04-15 21:02:26 +08:00
MandClaude Sonnet 4.6 74ae6b6975 fix: xdxr_info 股本字段改用 _decode_volume 解码,单位万股
股本字段(category 2–10 的 panqian_liutong / panhou_liutong /
qian_zongguben / hou_zongguben)与成交量字段使用相同的通达信自定义
4 字节浮点格式;原 float(uint32) 直解差约 374 倍。

改用 _decode_volume 后,最近一条 hou_zongguben(3,330,583.75 万股)
与 FinanceInfo.zong_guben / 10000(3,330,583.75 万股)完全吻合。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 14:38:45 +08:00
minionszyw 16c237d5a0 Harden transport and decode paths 2026-04-11 21:47:08 +08:00
minionszywandClaude Sonnet 4.6 0fa685dbdd feat: 离线 fixture 测试、unknown 字段探测脚本、高可用传输层
- tests/fixtures/:录制 12 条命令真实响应 body(hex),配套 json 预期值
- tests/unit/test_commands_offline.py:13 个离线 pytest,无需网络,验证
  各命令解析正确性及所有已知 bug 修复(#1~#5)
- scripts/probe_unknowns.py:对比 unknown_1/2/3/5~8 与均价、涨停价等假设,
  输出相关性分析报告,供后续字段逆向使用
- transport/sync.py:新增 ping_host()、ping_all()(并发测速)、KNOWN_HOSTS
- client.py:TdxClient.from_best_host() 工厂方法(自动优选最低延迟服务器)、
  TdxClient.ping_all() 静态代理、_execute() 断线自动重连(重试一次)
- 修复 GetTransactionDataCmd.parse_response 多余 skip 参数调用

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 20:33:41 +08:00