news 2026/9/29 5:31:47

tick-stock-panel 实时行情流架构:档位节流、订阅池与盘中突发故障隔离,新手也能看懂的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
tick-stock-panel 实时行情流架构:档位节流、订阅池与盘中突发故障隔离,新手也能看懂的完整指南

tick-stock-panel 实时行情流架构:档位节流、订阅池与盘中突发故障隔离,新手也能看懂的完整指南

【免费下载链接】tick-stock-panelTSP自托管、零运维的 A 股「选股 + 监控 + 回测」量化工作台 | LLM能力驱使策略定制+个股分析+复盘 | 自由接入第三方数据源与个性化扩展数据 | 个人开源项目地址: https://gitcode.com/GitHub_Trending/ti/tick-stock-panel

📊 tick-stock-panel 是一款自托管、零运维的 A 股「选股 + 监控 + 回测」量化工作台。它的实时行情流由后台轮询线程驱动,通过档位节流控制拉取频率、SSE 订阅池向多端广播事件、盘中突发故障隔离保证单次失败不拖垮整轮行情。本文带你从架构全景到关键源码,5 分钟看懂这套实时数据管道如何做到又快又稳。

一、架构全景:一根线程撑起整条行情流水线

tick-stock-panel 的实时行情核心是一个后台轮询线程(单例QuoteService),每 15 秒左右跑一轮,数据流如下:

  1. 调用数据源 API 拉取全市场行情(股票 + ETF + 核心指数)
  2. 原始价格写入kline_daily(不复权日K)
  3. 增量计算全套技术指标,写入 enriched 缓存与磁盘
  4. 通过 SSE(Server-Sent Events)把更新广播到所有前端连接

这套设计的关键点:内存中的 enriched 缓存是盘中唯一数据源,所有页面(选股、自选、监控)都读同一份缓存,而不是各自请求数据源——这既省配额又保证各页面数据口径一致。

核心文件:quote_service.py

二、档位节流:不同套餐,不同节奏

自托管最怕把数据源配额打爆。tick-stock-panel 的做法是按档位设最小轮询间隔,在 quote_service.py 中一目了然:

档位最小轮询间隔
expert1 秒
pro3 秒
starter / free6 秒
  • 默认间隔 6 秒,上限 60 秒,用户设置值会被_clamp_interval()强制夹在档位下限与上限之间;
  • 接入自定义数据源时不走档位限速(中立能力原则),只保留通用 1 秒下限;
  • 档位本身由 policy.py 中的能力探测自动判定:没有复权因子是免费档,拥有批量分时/五档等能力签名才归入付费档,单个能力探测失败不会把整体档位误降。
TIER_MIN_INTERVAL = { "expert": 1.0, "pro": 3.0, "starter": 6.0, "free": 6.0, }

除轮询间隔外,批量拉取还有一层进程级共享限速器:rate_limits.py 按 rpm 分桶维护「下一个可用发包时刻」,并刻意按套餐标称 rpm 的80% 安全系数(SAFETY_RPM_FACTOR = 0.8)执行,给偶发抖动留足余量。

三、SSE 订阅池:每个连接一个独立订阅者

前端页面、告警推送、复盘进度都走同一条 SSE 通道。早期的常见坑是多个客户端共享一个事件队列——「取走」语义下,先醒来的标签页消费掉告警,其余设备永远收不到。

tick-stock-panel 的解法在 api/intraday.py:每个/stream连接注册一个独立的QuoteSubscriber(独立事件 + 独立队列),事件由QuoteService广播给所有人,多标签页、多设备各自收到全量事件。

QuoteSubscriber还有两个精巧的细节(quote_service.py):

  • 背压保护:告警队列上限 1000 条,复盘事件上限 200 条,超限时丢弃最旧,慢客户端不会拖垮服务端内存;
  • 通道隔离:行情刷新、策略结果、五档盘口、告警、复盘进度各自独立标志位,五档修正只会触发连板梯队刷新,不连带刷新自选列表。

推送侧同样做了隔离:飞书等 webhook 投递放在独立的 2 线程池中 fire-and-forget(quote_service.py),即使推送目标宕机,也绝不会阻塞行情热路径。

四、盘中突发故障隔离:一块失败不拖垮整轮

全市场约 5500+ 只股票的分钟数据脉冲拉取,是故障隔离设计的重点场景,实现在 kline_sync.py 的fetch_intraday_full_market_burst:

  1. 切块并发:按 batch_size=200 把全市场切成约 28 块,用 32 线程的线程池一次打出,60 秒滑动窗口内至多一个脉冲,天然不超安全 rpm;
  2. 单块独立容错:每块把异常作为返回值上交而不是抛出——一个块失败,其余成功块照常落盘(线程池map迭代中抛异常会废弃全部已收数据,这是旧实现的教训);
  3. 分级重试:
    • 失败块 ≤ 4 个 → 逐个单独重试一次,仍失败则跳过该块(下一轮拉全天数据,天然自愈);
    • 失败块 > 4 个 → 判定为系统性故障/限流风暴,直接跳过重试,避免向已过载的服务端加压。

这套契约有专门的单测保证(test_intraday_burst_fault_isolation.py):瞬时失败重试后 6 只全在、恒失败只跳过该块其余 4 只照常返回、系统性故障不重试。

稳态场景还有一招省流量:fetch_intraday_universe_increment用单请求返回全市场最新 3 根分钟K,替代 28 块并发脉冲,请求量 28→1、传输量约 40 倍下降,缺口回补才走突发脉冲。

五、配套细节:标的池缓存与定版保护

  • 标的池(Universe):沪深300/中证500/上证50/全A/自选五种池,拉取后以 parquet 原子写缓存,避免半截文件导致每次读取报错(pools.py);
  • 午休/收盘定版确认:只有快照时间戳越过 11:30 / 15:00 边界(含 5 秒容差)才允许落盘,防止数据源收盘后仍返回竞价前旧价,把陈旧收盘价固化进当日分区(quote_service.py);
  • 管道互斥:盘后管道运行期间行情轮询临时pause()(线程存活、只跳过取数),杜绝实时写入与管道重建互相覆盖同一批 parquet。

六、上手体验

在数据页开启实时行情后,看板与监控中心即按档位节奏自动刷新,SSE 断线会自动重连。想深入了解,推荐阅读:

  • docs/features.md:功能全景
  • docs/secondary-development.md:自定义数据源接入
  • docs/deployment.md:部署指南

tick-stock-panel 用一根轮询线程、一层档位节流、一个订阅池和一套分块容错,把「全市场实时行情」这件难事做得又快又稳。自托管部署、零运维,把精力留给策略本身。🚀

【免费下载链接】tick-stock-panelTSP自托管、零运维的 A 股「选股 + 监控 + 回测」量化工作台 | LLM能力驱使策略定制+个股分析+复盘 | 自由接入第三方数据源与个性化扩展数据 | 个人开源项目地址: https://gitcode.com/GitHub_Trending/ti/tick-stock-panel

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 5:30:57

MoviePy批量调整视频音量

在数字视频创作中,音频质量直接影响着观众的观看体验。音量过大或过小,或者音量不一致,都会导致观众频繁调整音量,影响观看效果。手动调整每个视频的音量是一项繁琐的任务,而借助Python的MoviePy库,可以快速对多个视频的音量进行批量调整。这不仅适用于内容创作者和视频编…

作者头像 李华
网站建设 2026/9/29 5:30:50

【Codex智慧中医系统】配置后台菜单与管理站点

后台管理模块配置不当时,最先暴露的问题通常不是业务代码异常,而是菜单入口缺失、模型维护入口不可见、主题和站点信息没有按预期生效,进而影响中医问诊系统的数据维护链路。 本文围绕 Django 项目中的 home 应用整理后台菜单与站点配置,读完后可以独立检查应用是否启用、…

作者头像 李华
网站建设 2026/9/29 5:30:26

深入剖析Rundll32.exe:从代理执行到攻防对抗

Rundll32.exe 这个名字,Windows 用户可能一辈子都不会正眼瞧它一下,但在我们做安全的人眼里,这家伙简直是个宝藏男孩。平时它就安静地躺在 C:\Windows\System32 下面,但进入实战对抗的时候,它几乎是被使用频率最高的系…

作者头像 李华
网站建设 2026/9/29 5:29:21

弯曲传感器Arduino实战:从电阻变化到稳定信号调理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 5:29:19

H3C路由交换毕业设计:从配置到诊断的工程化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华