Skip to content

fix(trading): make equity heartbeats reliable#10

Merged
kunkundi merged 4 commits into
kunkundi:mainfrom
CyrusAuyeung:codex/equity-heartbeat
Jul 17, 2026
Merged

fix(trading): make equity heartbeats reliable#10
kunkundi merged 4 commits into
kunkundi:mainfrom
CyrusAuyeung:codex/equity-heartbeat

Conversation

@CyrusAuyeung

@CyrusAuyeung CyrusAuyeung commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

修改内容

  • 在 Dashboard 启动时创建独立的模拟账户权益心跳线程,不再依赖浏览器或完整账户 API 请求。
  • 使用非阻塞锁协调后台心跳与保留的请求侧兼容入口,避免多个生产者并发写入。
  • 新点写入后同时失效完整账户和快速账户快照缓存,使前端能及时读取最新曲线。
  • 将权益采样改为自然分钟分桶,并把写入时间规范化为分钟的 :00
  • 修正心跳中不存在的 refresh_position_quotes() 调用,改用项目已有的 refresh_realtime_prices()
  • 让权益记录与心跳返回真实写入状态,避免未写入时错误失效缓存或报告成功。
  • 增加独立心跳、单例后台线程、缓存失效、跨分钟记录及同分钟去重的回归测试。

问题原因

现有实时权益心跳只在 get_practice_payload() 处理完整 Dashboard 请求时触发。页面关闭、请求较少或运行在无头服务器上时,服务没有独立生产者继续写入分钟权益点。

原有时间判断比较距上一点经过的秒数。若上一点记录在 10:00:59,即使当前已经进入 10:01,在 10:01:01 仍会因为不足 60 秒而跳过;长期运行后采样秒数也会持续漂移。

此外,持仓刷新调用了项目中不存在的 refresh_position_quotes()。该异常会被降级处理捕获,因此任务表面可继续运行,但权益可能基于旧持仓价格写入。

Closes #9

兼容性与影响范围

  • 不新增依赖或必填配置,旧部署可直接升级。
  • 保留请求侧心跳作为未启动后台工作线程的历史入口兼容方案。
  • 仅在 A 股既有会话时段内写入到期分钟;同一分钟不会重复写入。
  • 不重建或覆盖已有真实历史点,只影响后续实时采样。
  • 不修改选股、买卖决策、仓位、交易执行或风控规则。
  • fix: recover post-trade intraday equity curves #4 的成交后历史追加恢复互补:fix: recover post-trade intraday equity curves #4 修复重启后的历史缺口,本 PR 修复运行期间的实时采样。

验证结果

python -m unittest tests.test_sell_strategy_rules
Ran 86 tests
OK

新增的 3 项 Dashboard 心跳定向测试全部通过:

python -m unittest tests.test_dashboard_auth.DashboardAuthTests.test_equity_heartbeat_records_without_dashboard_requests_and_invalidates_snapshots tests.test_dashboard_auth.DashboardAuthTests.test_equity_heartbeat_loop_polls_independently_of_http_requests tests.test_dashboard_auth.DashboardAuthTests.test_equity_heartbeat_starts_as_single_daemon_worker
Ran 3 tests
OK
git diff --check origin/main..HEAD
OK

完整验证共运行 467 项 Python 测试,其中 462 项通过;其余 5 项均可在未修改的 main 上复现,属于 Windows 路径分隔符、POSIX 权限位和子进程中文编码差异,与本次修改无关。完整验证同时通过了受影响的 Python 编译检查及 JavaScript、Shell、Windows BAT 语法检查。

@kunkundi kunkundi left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

再次评审 PR #10 的最新版本。

此前评审中发现了两个需要处理的问题:

  • P1:权益心跳刷新行情期间若发生并发成交,旧账户状态可能覆盖成交后的持仓和同分钟权益点。
  • P2:后台任务每 5 秒轮询,但原时间判断只接受 15:00:00,可能错过当天收盘权益点。

相关修复已补充到该 PR 分支:

  • 行情请求移到状态锁之外,写入前在跨进程锁内重新读取最新账户状态,只合并行情字段,避免覆盖并发成交结果。
  • SQLite 权益同步延后到 JSON 状态完成合并之后,确保两处保存的是同一个最终权益点。
  • 权益心跳使用独立的采样时段,覆盖整个 15:00 分钟,并继续将记录时间规范化为 15:00:00
  • 原有交易执行时段没有放宽。
  • 增加并发成交和 15:00:01 / 15:00:59 / 15:01:00 边界回归测试。

结合 Issue #9 重新核对后,独立后台采样、自然分钟分桶、实时行情刷新和缓存失效等目标均已覆盖。相关测试及 GitHub Validate 均通过,当前 PR 状态为 CLEAN / MERGEABLE。

未发现新的阻塞问题,建议批准合并。

@kunkundi
kunkundi merged commit 640fd29 into kunkundi:main Jul 17, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 模拟账户收益心跳依赖 Dashboard 请求且无法稳定按分钟采样

2 participants