以AI量化为生:25.vnpy 4.4升级实战 - 魔改版框架如何安全跟进上游

以AI量化为生:25.vnpy 4.4升级实战 - 魔改版框架如何安全跟进上游

本文是《以AI量化为生》系列的第25篇,我们将从框架版本落后带来的实际困扰出发,把本地深度修改过的vnpy从4.1升级到4.4,聊聊通知系统重构、CTP拒单状态修复这些上游新特性,以及魔改版框架安全升级的一套打法。

写在前面

上一篇讲了回测结果存储与策略参数管理,回测这条线算是闭环了。本来按计划这篇该继续聊AI策略的回测优化,但插了个队------我把vnpy从4.1升到了4.4,折腾了大半天,觉得这个过程本身就很值得写。

为什么突然要升级?直接导火索是通知。第6篇的时候我们做过日志系统和告警机制,邮件、飞书、钉钉都接了。但用下来发现,邮件基本不看,飞书钉钉还得开着对应的APP。vnpy 4.4把原来的邮件引擎重构成了通知系统,新增了WechatEngine,直接往微信推消息。这个对我吸引力太大了------持仓告警、策略异常,推到微信才是最不容易漏的。

但问题来了:我们的vnpy不是pip装的原版,是fork下来深度改过的。第13篇改过BarGenerator支持交易时段小时K线,第8、9篇改过CTA回测引擎加增强指标,策略加载路径也加了core/strategies。直接pip install -U?想都别想,改过的代码全得被覆盖。

所以这次升级的本质,是一次"合并上游改动 + 保留本地定制"的手工操作。这篇文章就聊聊这个过程,以及4.4到底带来了哪些值得升级的东西。

vnpy 4.4到底更新了什么

先说结论:这次升级涉及五个包,vnpy核心(4.1.0→4.4.0)、vnpy_ctp、vnpy_ctastrategy(1.3.3→1.4.1)、vnpy_spreadtrading(1.3.1→1.4.0)、vnpy_ctabacktester(1.2.0→1.3.0)。改动不少,但真正影响日常使用的,我认为是三个。

通知系统重构:从邮件到微信

4.1时代,MainEngine上直接挂着send_email方法,想发通知只能走邮件。4.4把这套拆了:EmailEngine还在,但新增了WechatEngine,MainEngine上统一改成send_notification------一次调用,邮件和微信两个通道一起推。

python 复制代码
def send_notification(self, content: str, subject: str | None = None) -> None:
    """Push notification through all configured channels."""
    if subject is None:
        subject = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    email_engine = cast(EmailEngine, self.get_engine("email"))
    email_engine.send_email(subject, content)

    wechat_engine = cast(WechatEngine, self.get_engine("wechat"))
    wechat_engine.send_wechat(f"{subject}\n{content}")

微信通道的实现挺有意思,走的是微信iLink协议,扫码登录拿到凭证,存在本地的wechat_setting.json里,之后就能直接推文本消息。还做了频率限制,默认60秒最多推一条,防止策略出bug的时候消息轰炸。

用下来的感觉是,这个设计比我自己接的飞书机器人优雅。它是框架级的,CTA策略引擎里也换成了send_notification,意味着策略里的告警通知自动就多了微信这个通道,一行业务代码都不用改。

CTP拒单状态修复:策略终于能感知"被拒"了

这个改动不大,但我觉得是这次升级里对实盘价值最高的一个。

4.1的CTP网关里,报单如果被交易所拒绝(比如资金不足、非交易时段下单),回报的状态是"已撤销"。也就是说,策略看到的跟自己主动撤单是一样的。这时候问题来了:策略以为单子被正常撤掉,可能还在等成交或者准备撤单重报,根本不知道这笔单子压根没报进去。

4.4修了这个映射:

python 复制代码
# 因为报单提交被拒绝导致的撤单状态,需要调整映射为拒单状态
if (
    data["OrderStatus"] == THOST_FTDC_OST_Canceled
    and data["OrderSubmitStatus"] == THOST_FTDC_OSS_InsertRejected
):
    status = Status.REJECTED

同时还加了一条日志:撤单状态但状态信息不是"已撤单"的(比如"非交易时段"、"资金不足"),会输出一条委托状态更新日志。以后下单失败,日志里能直接看到原因,不用再猜了。

价差成交数量的精度修复

vnpy_spreadtrading 1.4.0把腿成交量计算里的普通除法换成了decimal_divide精确除法,还加了round_leg_volume,按每条腿自己的最小变动数量分别取整。

这个修复解决的是浮点误差导致的成交数量对不齐。比如两条腿配比1:3,浮点除法算出来可能是2.9999999,取整后变成2,两条腿成交量就差了一手。做价差套利的,这种舍入误差积累下来,腿就瘸了。我们目前价差用得不多,但这个修复说明官方对细节的打磨在持续。

魔改版怎么升级:合并而不是覆盖

好,新特性说完了,回到最现实的问题:我们改过源码,怎么升?

我的做法分三步。

第一步,盘家底。 先把本地所有改过的点列出来。咱们这个仓库的定制主要有三处:BarGenerator加了hour_sessions和half_hour_sessions参数(第13、19篇的交易时段K线)、CtaEngine的策略加载加了core/strategies路径、回测引擎的enhanced_backtesting增强。这些是必须保住的底线。

第二步,拉上游新版本逐文件对比。 把4.4的源码拉下来,跟本地文件一个个diff。原则是:上游改过的文件,如果本地也改过,手工合并;本地没改过的,直接用新版。这次运气不错,几个改动大的上游文件跟我们本地改的位置基本不冲突。比如上游给ArrayManager加了一堆@overload类型声明,而我们的BarGenerator在文件另一头,合并很顺滑。

第三步,全量跑一遍。 合并完别急着上实盘,先把回测跑起来,再开模拟盘挂着。我这次合并完先跑了几个老策略的回测,结果跟升级前完全一致,才敢提交。

对了,还有个意外收获。合并完清理venv里残留的dist-info时,顺手发现了enhanced_chart_widget.py里candlestick_patterns的一个空指针------图表在不启用K线形态识别的情况下会崩。这个问题存在挺久了,只是平时都开着形态识别没触发。升级逼着把代码整体过一遍,顺手就修了。

升级后的实际体验

升完用了一段时间,几个感受。

微信通知确实香。策略启动、停止、异常,直接推到微信,基本不会漏。60秒的频率限制刚开始觉得碍事,后来遇到一次策略循环报错,看着被限流拦住的消息队列,觉得这个设计是救过我命的。

拒单状态的修复立竿见影。升级后没几天就碰到一次夜盘开盘瞬间下单被拒,日志里清清楚楚写着"委托状态更新,非交易时段",策略侧也收到了REJECTED状态。搁在4.1,这就是一笔"已撤销",我得翻CTP原始日志才能搞明白发生了什么。

类型声明的完善也是个隐性福利。ArrayManager的指标方法都加了@overload,传array=True返回np.ndarray,默认返回float,IDE终于能正确推断了。写策略的时候自动补全和类型检查都好用不少。

写在最后

下一篇回到主线,讲讲AI策略的回测和优化。AI策略回测跟传统策略差别挺大的------传统策略每次运行结果一样,AI策略得靠缓存才有可复现性,API调用费用也是个绕不开的问题。这些坑值得单独写一篇。

先写到这,有问题欢迎留言交流。


本文是《以AI量化为生》系列文章的第25篇,ATMQuant量化交易系统已开源至GitHub:https://github.com/seasonstar/atmquant

本文内容仅供学习交流,不构成任何投资建议。交易有风险,投资需谨慎。


往期文章回顾

量化策略开发系列

以AI量化为生系列

量化指标解码系列


相关推荐
Raas1001 小时前
MAIGateway,魔芋企业级AI网关的FinAPI成本归因设计
大数据·人工智能·网关·api网关·finapi
啾啾Fun1 小时前
【AI原生组织】2-从L0到L6:Agent自治等级与组织成熟度地图
人工智能·ai-native
LaughingZhu1 小时前
Product Hunt 每日热榜 | 2026-08-04
人工智能·经验分享·深度学习·神经网络·产品运营
阿里云云原生1 小时前
金融级 AI 原生架构:FinXScope 如何解决智能体从 Demo 到生产的“最后一公里”?
人工智能·金融·架构·agentscope·finxscope
蓝速科技1 小时前
蓝速科技 AI 双屏翻译机商务选购与实测避坑指南
人工智能·科技
小彤花园1 小时前
和 AI 结对写网站:从 JSON 到一整个工具集
前端·人工智能·程序员
BerryS3N2 小时前
Java在人工智能与大模型时代的深度演进:从工程落地、高性能计算到企业级Agent与RAG架构实战指南
java·人工智能·架构
小白说大模型2 小时前
AI Agent 调试实战:从 Prompt 追踪到执行回放的系统化排障方法
人工智能·prompt
科研小刘带你玩学术2 小时前
【学术干货】CVPR论文解析:扩散模型如何推动生成式人工智能进入新时代?
人工智能·深度学习·计算机视觉·生成式ai·扩散模型