第 1 章 · 03 从 run.py 看七步装配与首次运行


文档摘要

第 1 章 · 03 从 run.py 看七步装配与首次运行 本节摘要:本节精读 ——这份仅 87 行的脚本是理解 VeighNa 架构的最佳入口。它演示了一个完整的 VeighNa 交易程序怎么从零搭起来:七步装配(建 QApplication → 建 EventEngine → 建 MainEngine → 装网关 ×N → 装应用 ×N → 建主窗口 → 进 Qt 主循环)。更妙的是,文件里大量注释掉的网关和应用 import 清单,本身就是 VeighNa 插件生态的"菜单"。读完本节,你会理解 MainEngine 这副空壳是怎么被插件一点点填满的,为第 4 章精读 MainEngine 源码打下直觉。 内容来源:原项目源码 ,精读并套用体系化模板。

第 1 章 · 03 从 run.py 看七步装配与首次运行

本节摘要:本节精读 examples/veighna_trader/run.py——这份仅 87 行的脚本是理解 VeighNa 架构的最佳入口。它演示了一个完整的 VeighNa 交易程序怎么从零搭起来:七步装配(建 QApplication → 建 EventEngine → 建 MainEngine → 装网关 ×N → 装应用 ×N → 建主窗口 → 进 Qt 主循环)。更妙的是,文件里大量注释掉的网关和应用 import 清单,本身就是 VeighNa 插件生态的"菜单"。读完本节,你会理解 MainEngine 这副空壳是怎么被插件一点点填满的,为第 4 章精读 MainEngine 源码打下直觉。

内容来源:原项目源码 examples/veighna_trader/run.py,精读并套用体系化模板。

学习目标

阅读完本节,你应当能够:

  1. 背出 VeighNa 启动的七步装配流程
  2. 说清每一步创建了什么、为什么这一步不能省
  3. 读懂 run.py 里注释掉的网关/应用清单,认识 VeighNa 的插件生态全貌
  4. 区分 EventEngine / MainEngine / MainWindow 三者的职责。
  5. 知道怎么把 run.py 改造成自己的启动脚本(加/减网关应用)。

一、run.py 全貌

examples/veighna_trader/run.py 全文 87 行,核心的 main() 函数只有 40 多行(run.py:38-86):

38 def main(): 39 """""" 40 qapp = create_qapp() 41 42 event_engine = EventEngine() 43 44 main_engine = MainEngine(event_engine) 45 46 main_engine.add_gateway(CtpGateway) 63 main_engine.add_app(CtaStrategyApp) 64 main_engine.add_app(CtaBacktesterApp) 73 main_engine.add_app(DataManagerApp) 74 79 main_window = MainWindow(main_engine, event_engine) 80 main_window.showMaximized() 81 82 qapp.exec() 83 84 85 if __name__ == "__main__": 86 main()

(中间省略的都是注释掉的其他网关/应用。)这 40 行就是整个 VeighNa GUI 程序的启动逻辑。

二、七步装配逐行解读

第 1 步:建 QApplication(run.py:40)

40 qapp = create_qapp()

create_qapp() 来自 vnpy.trader.ui,它会创建一个全局的 QApplication 实例,并配置好字体、国际化翻译、HiDPI 缩放等 Qt 环境细节。

💡 核心心法:Qt 是 GUI 框架,任何带界面的 Qt 程序必须先有一个 QApplication。它管理 GUI 程序的控制流和主设置,是所有 Qt 窗口的"根"。VeighNa 的界面基于 PySide6(Qt6 的 Python 绑定),所以这一步不可省。如果你做无界面部署(服务器跑策略),则不需要这一步——见第 12 章的 no_ui/run.py

第 2 步:建事件引擎(run.py:42)

42 event_engine = EventEngine()

EventEngine 来自 vnpy.event,是整个框架的通信总线。所有组件(网关、策略、UI)都通过它收发事件:网关收到行情 → put 一个 eTick 事件 → 策略和 UI 各自订阅处理。

注意:这里创建的 event_engine 后面会传给 MainEngine 和 MainWindow 两个地方(run.py:44run.py:79)——所有组件共享同一个事件总线。这是 VeighNa 解耦的关键。

第 2 章会逐行精读 EventEngine 的 145 行源码,讲清 Queue+Thread 发布订阅怎么实现。

第 3 步:建主引擎(run.py:44)

44 main_engine = MainEngine(event_engine)

MainEngine 来自 vnpy.trader.engine,是整个平台的装配中枢。它本身不实现任何交易逻辑——它只是一个"容器",持有所有网关、应用、子引擎,并提供统一的对外 API(connect/subscribe/send_order 等,实际都委托给具体网关)。

构造时把第 2 步的 event_engine 传进去,MainEngine 内部会:

  • 启动事件引擎的后台线程;
  • 自动装配四个内置子引擎(LogEngine/OmsEngine/EmailEngine/WechatEngine)。

第 4 章会逐行精读 engine.py 的 838 行,讲清装配中枢的"Facade 模式"。

第 4 步:装配网关(run.py:46)

46 main_engine.add_gateway(CtpGateway)

add_gateway 接收一个网关类(这里是 CtpGateway,来自 vnpy_ctp 包),实例化它并注册到 MainEngine 的 gateways 字典。从此 MainEngine 就"认识"了 CTP 这个交易接口,可以 connect/send_order 了。

第 6 行 from vnpy_ctp import CtpGateway 是关键——你必须先 pip install vnpy_ctp 才能 import 它。如果没装,这一行会 ModuleNotFoundError

第 5 步:装配应用(run.py:63-73)

63 main_engine.add_app(CtaStrategyApp) 64 main_engine.add_app(CtaBacktesterApp) 73 main_engine.add_app(DataManagerApp)

add_app 接收一个应用类(继承 BaseApp),实例化后从中取出 engine_class,再装配成一个子引擎。比如:

  • CtaStrategyApp → 装配出 CtaEngine(CTA 策略引擎,管理策略实例、加载历史数据、触发 on_bar);
  • CtaBacktesterApp → 装配出回测引擎;
  • DataManagerApp → 装配出数据管理引擎。

应用和网关的区别:网关对接交易所(数据/订单通道),应用实现业务逻辑(策略/回测/风控)。

第 6 步:建主窗口(run.py:79-80)

79 main_window = MainWindow(main_engine, event_engine) 80 main_window.showMaximized()

MainWindow 来自 vnpy.trader.ui,是 VeighNa Studio 的主界面。它接收 main_engineevent_engine,据此构建菜单栏、工具栏、各种监控面板(行情/订单/成交/持仓/账户/日志)。showMaximized() 让窗口最大化显示。

第 7 步:进 Qt 主循环(run.py:82)

82 qapp.exec()

qapp.exec() 进入 Qt 的事件主循环——从此程序阻塞在这里,处理鼠标键盘事件、定时器、窗口重绘,直到用户关闭窗口。这一行之后的所有逻辑都由 Qt 事件驱动(比如你点"连接"按钮,会触发 connect 流程)。

这就是为什么 GUI 程序的最后一行总是 app.exec()——它把控制权交给 Qt,程序从"顺序执行"模式切换到"事件驱动"模式。

三、装配清单:VeighNa 插件生态全貌

run.py 里注释掉的网关和应用 import,本身就是 VeighNa 生态的"菜单"。把它们整理出来,你能看清整个框架的能力边界。

网关清单(run.py:7-18)

包名 网关类 对接的市场
vnpy_ctp CtpGateway 期货(中金所/上期所/大商所/郑商所/广期所)
vnpy_ctptest CtptestGateway CTP 测试环境(OpenCTP 模拟)
vnpy_mini MiniGateway 飞马 Mini(中金所)
vnpy_femas FemasGateway 中金所 Femas
vnpy_sopt SoptGateway 股票期权
vnpy_esunny EsunnyGateway 鼎信 Esunny
vnpy_xtp XtpGateway 中泰证券 XTP(A 股)
vnpy_tora ToraStockGateway / ToraOptionGateway 鑫管家股票/期权
vnpy_ib IbGateway 盈透证券(全球股期期权)
vnpy_tap TapGateway 易盛 Tap
vnpy_da DaGateway 达钱 DA
vnpy_rohon RohonGateway 融航 Rohon(期货资管)
vnpy_tts TtsGateway TTS(OpenCTP 模拟)

应用清单(run.py:20-35)

包名 App 类 功能
vnpy_paperaccount PaperAccountApp 模拟成交(无实盘时记录成交)
vnpy_ctastrategy CtaStrategyApp CTA 策略(趋势跟踪)
vnpy_ctabacktester CtaBacktesterApp CTA 策略回测
vnpy_spreadtrading SpreadTradingApp 价差交易
vnpy_algotrading AlgoTradingApp 算法交易(TWAP/VWAP)
vnpy_optionmaster OptionMasterApp 期权交易/波动率
vnpy_portfoliostrategy PortfolioStrategyApp 组合策略
vnpy_scripttrader ScriptTraderApp 脚本交易(交互式)
vnpy_chartwizard ChartWizardApp K 线图表向导
vnpy_rpcservice RpcServiceApp RPC 服务(分布式)
vnpy_excelrtd ExcelRtdApp Excel 实时数据
vnpy_datamanager DataManagerApp 数据管理(下载/导入/导出)
vnpy_datarecorder DataRecorderApp 行情录制
vnpy_riskmanager RiskManagerApp 风控
vnpy_webtrader WebTraderApp Web 交易
vnpy_portfoliomanager PortfolioManagerApp 组合管理

(✅ = run.py 默认开启的)

四、改造成你自己的启动脚本

理解了七步装配,改造 run.py 就很直观了。常见场景:

场景一:只做国内期货 CTA(默认配置)
保持现状即可——CTP + CtaStrategy + 回测 + 数据管理。

场景二:加美股期权
解开两行注释:

from vnpy_ib import IbGateway from vnpy_optionmaster import OptionMasterApp # ... main_engine.add_gateway(IbGateway) main_engine.add_app(OptionMasterApp)

场景三:服务器无界面跑 CTA
参考 examples/no_ui/run.py(第 12 章详讲):去掉 create_qapp/MainWindow/qapp.exec(),改成 connect → sleep → init → start → while 循环监听,用父子双进程守护。

场景四:做 AI 量化选股
不需要改 run.py——vnpy.alpha 是内置的,直接在 Jupyter Notebook 里 from vnpy.alpha import AlphaLab, ... 即可(见 examples/alpha_research/ 的 notebook)。

五、首次运行的典型流程

启动 run.py 后,VeighNa Studio 的典型使用流程:

  1. 连接 CTP:菜单"接口" → 选 CTP → 填账号密码 → 连接。MainEngine.connect 委托给 CtpGateway。
  2. 订阅行情:合约查询出来后,订阅 rb2401 等。CtpGateway 收到 tick → on_tick → 事件总线 → UI 行情面板刷新。
  3. 加载 CTA 策略:打开 CTA 策略应用 → 添加策略类 → 初始化(加载历史 bar)→ 启动。CtaEngine 开始在每个 bar 回调策略的 on_bar。
  4. 监控:订单/成交/持仓/账户/日志面板实时刷新(都靠事件总线驱动)。

每一步背后都是"事件驱动 + 装配"这套架构在工作。

本节要点回顾

  1. 七步装配:create_qappEventEngineMainEngineadd_gateway ×Nadd_app ×NMainWindowqapp.exec()
  2. EventEngine 是共享总线,同时传给 MainEngine 和 MainWindow。
  3. MainEngine 是装配中枢,本身不实现交易逻辑,只装不实现。
  4. 网关对接交易所,应用实现业务,都靠 add_gateway/add_app 装配。
  5. 注释清单即生态菜单:12 个网关覆盖国内外市场,16 个应用覆盖 CTA/价差/期权/算法/AI 等业务。
  6. 改造直观:加减业务只需解开/注释对应行,这是"核心 + 插件"在用户体验上的体现。

第 1 章结束。我们知道了 VeighNa 是什么、为什么这样拆、怎么跑起来。下一章(第 2 章)开始钻进源码——精读框架的心脏:EventEngine 事件引擎,看看 145 行怎么搭起一个发布订阅总线。


发布者: 作者: 灏天文库 转发
评论区 (0)
U