← 返回文章列表

AKQuant 最小实测:费用和 T+1 怎样改变同一组交易

作者:杨轩

同一段回测,为什么配置不同结果就变了?

两天八根人工 K 线,四组配置与逐笔核账。提供脚本、合成样本、版本锁和结果;只验证本例费用与订单行为。

栏目:量化工具研究 · 最小样例已跑通

测试日期:2026-10-29。AKQuant 0.3.75,macOS arm64,Python 3.12.2。本文使用人工合成价格,不是真实行情,也不是策略收益评测。

先说结论:在这次小实验中,费用配置改变了实际扣款,T+1 改变了卖单能否成交;不传撮合配置时,订单按下一根 K 线开盘价成交。三件事都可以从逐笔记录中核对,而不必猜测一条收益曲线为什么变化。

为什么先测这个

AKQuant 是一个 Rust 引擎配合 Python 接口的量化框架。对准备上手的人来说,先确认一笔交易怎样发生,比马上做一个复杂策略更有帮助。

官方快速开始已经提醒:没有指定相关配置时,回测不计成本、不开 T+1。这不是发现了一个隐藏缺陷,而是要验证:文档里的设置,在实际运行时怎样影响订单。项目说明

这次只做一个可以手算的小例子,不比较速度,不训练模型,也不接券商账户。

实验:两天、八根人工 K 线、四组配置

样本只有两个日期,每天四根盘中 K 线,不是完整交易日行情。虚构标的名为 SYNTH,起始资金 10,000,买卖数量都是 100。显式指定时区、两日交易日历和每手 100 的设置;未单独验证手数限制。

所有组使用同一段逻辑:

  1. 第一天 09:31 提交买入 100 的市价单。
  2. 第一天 09:33 若仍持仓,提交卖出 100 的市价单。
  3. 第二天 09:31 若仍持仓,再提交一张新的卖单。

这里的“第二天再提交”很重要:被拒的订单不是自动等到次日成交,而是脚本主动重新发单。

为了容易核算,费用组只设置双边佣金 0.1%,最低佣金、印花税与过户费都设为零。这是实验参数,不是实际券商报价或现行税费说明。其他组不传费用参数,也不使用券商配置模板。

组别 费用设置 T+1 本例累计费用 结束时资金(已无持仓)
A 不传,沿用默认 不传,沿用默认 0.00 10,100.00
B 双边佣金 0.1% 不传,沿用默认 2.10 10,097.90
C 不传,沿用默认 显式开启 0.00 9,950.00
D 双边佣金 0.1% 显式开启 1.95 9,948.05

“默认”只指本次留空的费用、T+1 与撮合配置,不表示整次运行没有显式设置其他参数。

逐笔看,比只看最后的数字清楚

以下时间均为 Asia/Shanghai;原始记录同时保存 UTC 时间。

订单 提交时间 A/B 组处理结果 C/D 组处理结果
买入 100 10 月 26 日 09:31 09:32,以 10.00 成交 同左
当日卖出 100 10 月 26 日 09:33 09:34,以 11.00 成交 09:34,被拒,成交量为零
次日新卖单 10 月 27 日 09:31 已无持仓,不提交 09:32,以 9.50 成交

开启 T+1 的两组,当日卖单留下的状态是 rejected。原因原文为:

Risk: Insufficient available position for SYNTH at execution. Available: 0, Required: 100

当时账户仍有 100 的持仓,但可用于这笔卖单的数量为零。隔日重新提交后卖出成功。这个结果支持的是“本例的同日新增持仓卖出限制有效”,并不覆盖完整市场规则。

费用也能手算:

  • B 组:买入扣 100 × 10 × 0.001 = 1.00,卖出扣 100 × 11 × 0.001 = 1.10,合计 2.10。
  • D 组:买入扣 1.00,次日卖出扣 100 × 9.5 × 0.001 = 0.95,合计 1.95。被拒的那笔单没有成交,也没有扣佣金。

本例特意设置了次日下跌,所以延后卖出降低了余额。它说明交易约束会改变交易路径,不能据此得出“T+1 总会让结果变差”的结论。

另一个重要细节:信号时间不等于成交时间

09:31 的买单没有按该根 K 线的收盘价成交,而是在 09:32 以其开盘价成交。卖单也遵循相同规律。

测试脚本把每笔成交的价格和时间,与下一根样本 K 线逐项比对;安装包中的默认撮合定义也是 NextOpen。这个机制值得先弄清楚,否则一套策略即使逻辑没变,只因对成交时点理解不同,也会出现无法解释的结果。

不过,“下一根开盘撮合”并不会自动消除所有未来信息问题。数据如何生成、因子是否提前读到未来,仍是策略代码自己的责任。

对 AKQuant 的第一轮评价

值得继续研究。此次在 macOS arm64 独立环境使用基础发行包的预编译 wheel 即可运行,没有额外编译 Rust;短脚本就能拿到订单、成交和费用记录。对于入门研究,容易定位“交易究竟怎么发生”是实用优点。

暂时不能评价的部分也很明确:这次没有验证大数据性能、机器学习功能、实盘接入、不同资产类型,也没有测试停牌、涨跌停、节假日、部分成交、最低佣金和卖出税费。八根合成 K 线能验证几个配置分支,不能证明整个框架在复杂市场环境中可靠。

运行中出现了 pandas 3.1.0 的弃用警告,来自依赖包的结果排序代码;本次七项测试仍然通过。它不是这次计算失败,但说明升级依赖时应重新测试,不能只锁主框架版本。

怎样复现

下载完整复现包(不含运行环境),或逐个查看以下文件。压缩包包含完整脚本、人工样本、依赖版本锁和原始输出:

在包含上述文件的实验目录,新建隔离环境后运行:

uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python --only-binary :all: -r requirements.lock.txt
.venv/bin/python experiment.py
.venv/bin/python test_experiment.py

实验只使用本地合成数据,不需要行情接口或模型密钥。安装依赖需要联网;上述命令只在本次 macOS arm64 环境验证,Linux 和 Windows 未实测。订单和成交 ID 每次随机生成,因此不能要求整份结果文件哈希每次相同;重复测试比较的是去掉这些 ID 后的完整业务记录。

如果只带走一条经验:先用能手算的样本核对一笔交易,再把更多数据、因子和模型加进来。这样得到的不是一张更漂亮的图,而是对工具行为更明确的认识。

相关阅读:首批 18 个项目短评 · 专题总览

本文代码与样本:资料与下载 →

让分享,成为交流的开始。

关于文章、AI 实践或阅读,有想法欢迎来信。