Strasmore Research
学习 Matt Connor作者: Matt Connor

自托管A股量化工作台:架构与四项检查

了解自托管A股量化工作台如何运行:网页、数据服务、本地存储与回测引擎分别承担什么职责,以及开始前应检查的四项基础条件。

自托管的A股量化工作台是一个网页应用。它可以筛选市场、监控自选股、运行回测,并撰写盘后复盘。该应用运行在您控制的设备上,而不是券商终端中。一个采用MIT许可证的项目tickflow-stock-panel将这些功能整合到同一个端口下。截至2026年8月,该项目在GitHub上已获得约2,800颗星。功能列表容易读懂。真正决定这些功能下个季度能否继续运行的,是底层架构。

自托管 A 股量化工作台由哪些部分构成

其架构足够简短,便于在脑中建立整体认识。根据 2026 年 8 月提交版本中的代码和文档,架构包括:

  • 使用 React 和 TypeScript 构建的网页。
  • 使用 FastAPI 的 Python 服务,以及按定时计划刷新数据的调度器。
  • 本地存储:将数据保存为磁盘上的 Parquet 文件,使用 DuckDB 查询,并使用 Polars 计算。
  • 使用 vectorbt 的回测引擎,读取这些文件中的数据。
  • 用于获取面板所显示每个价格的供应商 SDK。

请注意其中没有什么。这个技术栈没有任何组件连接交易所。面板负责计算,供应商负责提供数据。“自托管”描述的是代码运行的位置,并不说明数字来自哪里。持有原始行情数据属于下一层,即本地 A 股市场数据湖的职责。这一层使上面的所有组件都可以替换。

数据源免费层涵盖的内容

一个环境变量决定面板可以查看哪些数据。将供应商密钥留空后,项目会进入其文档所称的 None 模式:通过免费端点获取历史日线数据,当前交易日的数据会在收盘后一至两个小时到账。填入密钥后,便可按付费层级开通访问权限。对于日终分析,这是一个可用的免费层;对于任何盘中需求,则构成明确限制。供应商可在续约时重新说明这些条款。

维护者明确说明了这一安排:

本项目仅供学习与量化研究,不构成任何投资建议。回测结果不代表未来收益。
本项目个人开源,基于 TickFlow 数据源,非 TickFlow 官方项目。
README,shy3130/tickflow-stock-panel,读取于 2026 年 8 月 13 日

换言之,该项目用于学习和量化研究,“不构成任何投资建议”;回测结果不代表未来收益;它是“个人开源项目,并非 TickFlow 官方产品”。这也是整个项目类型中最值得长期注意的一点。Zero-ops 可以替您承担运维工作,但依赖关系并未改变:您仍在向一家从未承诺支持该面板的公司租用数据。README 还将使用范围限定为学习和研究,而许可证文件采用 MIT 许可证。

为什么要固定提交 SHA,而不是版本号

提交 SHA 是 git 为每次保存的更改分配的 40 位字符指纹。它永久指向代码的一个确切状态。

截至 2026 年 8 月 13 日,该仓库的 GitHub Releases 页面没有任何内容。仓库确实有 31 个版本标签,从 v0.1.31 到 v0.1.88,但编号存在跳跃,且没有附带说明。最新标签指向 2026 年 7 月 31 日提交的代码,而默认分支已经推进到 2026 年 8 月 6 日的工作状态。一个落后于分支且没有说明的标签,无法告诉您实际获取的是什么。

因此,请记下 SHA。2026 年 8 月 6 日默认分支的最新提交是 ecfddb451e97f6fc9a7e43ac33e4ef0e69933b33。检出该提交,并将其记录在您根据回测得出的任何结论旁边。六周后,“我运行的是最新版本”并不能说明任何问题。

文档规定的启动步骤只有两行:将示例环境文件复制为 .env,然后运行 docker compose up --build。该命令会在 3018 端口提供面板服务。这些是该提交中维护者提供的说明,并不代表经过测试的运行路径;构建过程会拉取镜像,需要网络访问,而本文并未测试这一点。开发环境路径(./dev.sh,Windows 下为 .\dev.ps1)需要 Python 3.11 或更高版本、Node 20 或更高版本,以及 uvpnpm 包管理器。

LLM策略功能发送什么,以及发送到哪里

策略生成、个股点评和复盘文章均为可选功能。AI_API_KEY留空时,整个功能界面会保持关闭。填写该字段后,您还需设置AI_PROVIDER(兼容 OpenAI 的端点或 Ollama)、AI_BASE_URLAI_MODELAI_DAILY_TOKEN_BUDGET。当日令牌额度用尽后,系统将停止调用。

数据发送方向很重要。您的提示词以及面板附加的相关上下文,会离开本机并发送至您配置的端点。若将基础 URL 指向托管 API,请求会发送给相应公司;若将其指向您自有网络中的运行时环境,数据则会留在本地。在本地托管面板,并不等于在本地托管模型。密钥以明文形式存放在项目根目录下的.env中,也可以在设置页面编辑;设置页面受仪表盘密码保护,密码至少须包含六个字符。我们的LLM生成的阿尔法因子说明了机器生成的策略通常会在哪些方面失效。

回测器是否建模交易成本?

回测器声称支持 T+1 处理、佣金、滑点和止损。但存在这些开关,并不等于它们已被设置。若回测按收盘价成交且成本设为零,就等于声称交易是免费的。事实并非如此。一个基点是百分之一个百分点。下方面板统计了 2026 年 6 月 17 日午间一小时内,六只美国上市证券的最优买价与最优卖价之间平均价差,单位为基点。

查询跨越买卖价差的成本:平均报价价差,六个美国上市标的,2026年6月17日午间
每个数字背后的完整 SQL
SELECT
    ticker                                                                       AS symbol,
    round(avg(toFloat64(ask_price) - toFloat64(bid_price))
          / avg((toFloat64(ask_price) + toFloat64(bid_price)) / 2) * 10000, 2)   AS spread_bps
FROM global_markets.cache_stocks_quotes
WHERE ticker IN ('SPY', 'AAPL', 'MSFT', 'NVDA', 'KO', 'F')
  AND sip_timestamp >= toDateTime('2026-06-17 15:00:00', 'UTC')
  AND sip_timestamp <  toDateTime('2026-06-17 16:00:00', 'UTC')
  AND bid_price > 0
  AND ask_price > bid_price
GROUP BY ticker
ORDER BY spread_bps
Run this yourself

面板中价差最小的证券是 SPY,该时段的平均报价价差为 0.29 个基点。价差最大的证券是 F,报价价差为 6.98 个基点。买入时要跨越一次价差,卖出时还要跨越一次。这样一来,往返交易的成本约为图中数值的两倍,且尚未计入佣金。

交易时点与标的选择同样重要。下一个面板选取其中一只证券,测量其价格在单分钟内的波动幅度,并将同一天的数据按半小时分组取平均。

查询一分钟内价格的波动幅度:KO,按纽约时间,2026年6月17日
每个数字背后的完整 SQL
SELECT
    formatDateTime(
        toStartOfInterval(toTimeZone(window_start, 'America/New_York'), INTERVAL 30 MINUTE),
        '%H:%i')                                                                 AS et_time,
    round(avg((toFloat64(high) - toFloat64(low)) / toFloat64(close)) * 10000, 1)  AS range_bps
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'KO'
  AND window_start >= toDateTime('2026-06-17 12:00:00', 'UTC')
  AND window_start <  toDateTime('2026-06-17 21:00:00', 'UTC')
  AND volume > 0
  AND close > 0
GROUP BY et_time
ORDER BY et_time
Run this yourself

面板从 08:00 开始,即常规交易时段前。此时平均一分钟K线的波动幅度为 0 个基点:实际发生交易的分钟内,价格都停留在同一水平。最后一个时间段 16:30 位于收盘后,平均波动幅度为 4.2 个基点。回测会从每个区间中选取一个点,并将其视为成交价。应关注曲线,而不是端点:同一项假设在某些时段偏宽松,在另一些时段则过于严苛。A股规则还会带来额外约束,因为 T+1 规定当日买入的股票要到下一交易日才能卖出,日涨跌停也可能使模型中的卖出交易根本无法执行。我们关于可复现回测的演示说明了稳健设置应记录哪些内容;而前视偏差则介绍了另一种会让曲线看似漂亮、实际却失真的原因。

调整还是未调整:数据来源问题

公司行动是筛选器悄然误导投资者的地方。一只股票按十比一拆分后,当天会显示下跌90%,但没有人因此损失一分钱。下表列出2026年1月1日至8月13日期间,美国上市股票中规模最大的十二次正向拆分。

查询美国上市标的中规模最大的十二次正向股票拆分,2026年1月1日至8月13日
每个数字背后的完整 SQL
SELECT
    ticker                                                            AS symbol,
    formatDateTime(execution_date, '%b %e, %Y')                       AS effective_on,
    round(any(toFloat64(split_to)) / any(toFloat64(split_from)), 2)   AS shares_after_per_share
FROM global_markets.stocks_splits
WHERE execution_date >= toDate('2026-01-01')
  AND execution_date <= toDate('2026-08-13')
  AND split_from > 0
  AND split_to > split_from
  AND ticker NOT IN ('SPCX')
GROUP BY ticker, execution_date
ORDER BY shares_after_per_share DESC, execution_date DESC
LIMIT 12
Run this yourself

规模最大的一次将一股变为10000,于Feb 10, 2026生效。这样的拆分比例并非普通的四比一;公司行动数据源会在同一列中涵盖整个范围。十二次拆分中规模最小的一次,也会将一股变为20,足以让未调整图表看起来像发生了暴跌。读取原始价格的动量筛选器会将它们全部标记为崩盘。中国数据源也存在同样的问题,只是使用不同术语,为每个序列提供三种版本:未调整、前复权和后复权。请确认您的面板加载的是哪一种。拆分调整后的价格历史将详细说明计算方法。

自行托管此类工具前需要检查的事项

  • 数据来源。确认供应商、适用许可,以及免费层级是否涵盖您的使用目的。
  • 密钥管理。确认 API 密钥保存在哪个磁盘位置、谁可以访问设置页面,以及这台机器是否暴露在您自有网络之外。
  • 成本建模。确认回测器是否计入佣金、滑点和市场自身的规则,并了解您不作调整时这些字段采用什么值。
  • 更新路径。记录您部署的确切 commit,并与结果放在一起,以便数月后仍能复现。

常见问题

自建 A 股量化工作台可以免费运行吗?

代码采用 MIT 许可证,可免费使用。数据则是另一回事:如果不填写供应商密钥,本项目会回退到免费的历史日线数据,当前交易日的数据会在收盘后一到两个小时到达。更快或更深度的数据需要使用供应商的付费层级。

这里所说的“自建”具体是什么意思?

网页、调度器、存储文件和回测器都运行在您自己的电脑或服务器上,不需要在他人的平台上开设账户。这并不意味着数据归您所有;除非您将可选的 AI 功能指向自己网络中的模型,否则这些功能仍会在远程运行。

LLM 功能会将我的数据发送给第三方吗?

启用后会。数据会发送至您配置的 OpenAI 兼容端点。该功能默认关闭:如果不填写 AI 密钥,任何数据都不会离开本机。

为什么要固定 commit SHA,而不是版本标签?

截至 2026 年 8 月 13 日,该代码库没有正式发布版本,也没有发布说明;其最新标签对应的代码还旧于默认分支。“最新”在这种情况下意味着您克隆代码当天分支所包含的内容,而 commit SHA 则是精确的。相同的原则也适用于 开源量化交易资料:固定您实际运行的版本。

核验说明

以上所有架构和配置细节均来自 2026 年 8 月 13 日公开代码库中的内容,具体对应 commit ecfddb451e97f6fc9a7e43ac33e4ef0e69933b33。该 commit 是默认分支的最新提交,日期为 2026 年 8 月 6 日。Releases 页面没有列出任何内容;标签列表包含从 v0.1.31 到 v0.1.88 的 31 个版本标签,最新标签对应的提交日期为 2026 年 7 月 31 日。文中的引述均为维护者原话,直接摘自 README,而非转述。容器启动命令也引自该 README,本文未执行该命令。

市场面板展示的是美国上市证券,并固定在过去的特定日期,以保持数据不变。它们用于说明适用于任何市场的两项核查:交易执行成本和公司行动调整,而不是用于描述中国市场。


这里的每个面板都附有生成数据的 SQL,可在下方展开查看。如果您想在将某个标的接入筛选器前,对自己的标的列表执行相同的 spread 检查,可以在 Strasmore 终端中用自然语言提出请求。

#open-source#backtesting#screening#a-shares#self-hosted