11 KiB
11 KiB
vn.py Web Trader 实现方式调研报告
调研结论摘要
根据官方设计,vn.py(VeighNa)的Web Trader采用标准的双进程B-S架构:
- 策略交易进程:运行完整的VeighNa Trader核心(MainEngine、EventEngine、Gateways、Strategies),同时启动RPC服务端
- Web服务进程:运行web_trader模块,基于FastAPI提供REST接口+WebSocket推送,通过RPC客户端与交易进程通信
这是官方推荐的正确架构,之前如果走了"单进程整合"或"前后端不分离"的弯路,需要纠正为这种双进程架构。
1. 官方Web Trader定位与架构
1.1 模块定位
WebTrader是VeighNa框架针对B-S(Browser-Server)架构需求设计的Web服务模块,允许用户通过浏览器(而非PyQt桌面端)来运行管理VeighNa量化策略交易。
核心特点:
- 提供主动函数调用(REST API)
- 支持被动数据推送(WebSocket)
- 基于官方RPC模块实现跨进程通信
1.2 官方架构图
根据官方文档描述,整体架构如下:
┌─────────────────────────────────────────────────────────────┐
│ Browser / Web前端 │
│ (Vue/React/Angular 或 纯HTML前端) │
└─────────────┬───────────────────────────────────────────────┘
│ HTTP / WebSocket
↓
┌─────────────────────────────────────────────────────────────┐
│ Web服务进程 (web_trader模块) │
│ - FastAPI Web服务器 │
│ - REST API 处理请求 │
│ - WebSocket 推送推送数据 │
│ - RPC 客户端 ←───────────┐ │
└─────────────┬───────────────┘ │
│ RPC │
│ TCP │
┌─────────────↓─────────────────┐ │
│ 策略交易进程 (VeighNa Trader) │ │
│ - MainEngine │ │
│ - EventEngine │ │
│ - All Gateways │ │
│ - All Strategies │ │
│ - RPC 服务端 ←────────────────┘ │
└─────────────────────────────────────────────────────────────┘
1.3 核心技术栈
| 层级 | 技术组件 | 作用 |
|---|---|---|
| Web后端 | FastAPI | 提供RESTful API接口 |
| 实时通信 | WebSocket | 主动推送行情、成交、状态更新到前端 |
| 跨进程通信 | vnpy.rpc | Web进程 ↔ 交易进程之间的RPC通信 |
| 身份认证 | OAuth2 JWT | Token认证机制 |
| 前端 | 可选 | 用户可自行选用Vue/React等框架 |
2. 常见弯路分析
根据调研,常见的错误实现方式:
❌ 弯路1:单进程一体化架构
错误做法:
把FastAPI和MainEngine放在同一个进程中启动,依赖asyncio协程调度
问题:
- VeighNa核心是基于多线程事件驱动,与FastAPI的asyncio协程模型冲突
- 容易出现线程安全问题,事件引擎阻塞Web服务响应
- 不好做独立扩展,Web进程和交易进程难以分开部署
- 重启Web服务会中断交易策略
❌ 弯路2:过度拆分微服务
错误做法:
把Gateway、Strategy、Data、Web都拆分成独立服务,引入太多复杂度
问题:
- 增加不必要的分布式复杂度(一致性、网络延迟、运维负担)
- 违背vn.py原生设计理念,难以跟进官方更新
- 对于中小规模量化团队过度设计
❌ 弯路3:前端绑定后端耦合
错误做法:
用Django/Tornado模板引擎渲染页面,前后端强耦合
问题:
- 前端难以独立迭代开发
- 不支持移动端、APP端复用后端API
- 不符合现代Web开发最佳实践
3. 纠正方案:官方标准双进程架构
3.1 推荐架构
按照官方设计,采用:
[进程1] 交易核心进程
- VeighNa Trader (MainEngine + EventEngine)
- 所有交易Gateway (CTP/IB等)
- 所有策略模块
- RPC Service 服务端
[进程2] Web服务进程
- vnpy_webtrader (FastAPI)
- REST API 接口
- WebSocket 推送
- RPC Client 连接交易进程
- CORS 支持跨域访问
[前端] 独立部署
- 基于现代前端框架开发
- 完全独立,通过API调用
- 可单独部署到CDN
3.2 启动流程
-
第一步:启动交易核心进程
from vnpy.trader.main_engine import MainEngine from vnpy.trader.event_engine import EventEngine from vnpy.rpc import RpcServer event_engine = EventEngine() main_engine = MainEngine(event_engine) # 添加gateway、策略... # 启动RPC服务端 rpc_server = RpcServer(main_engine, ("127.0.0.1", 2018)) rpc_server.start() -
第二步:启动Web服务进程
from vnpy_webtrader import run_web_trader # RPC连接配置 rpc_request_address = "tcp://127.0.0.1:2018" rpc_subscribe_address = "tcp://127.0.0.1:4102" # 启动Web Trader run_web_trader( rpc_request_address, rpc_subscribe_address, host="0.0.0.0", port=8000 ) -
第三步:启动前端
- 打包前端静态文件
- 独立部署到Nginx或CDN
- 通过反向代理代理API请求到8000端口
3.3 技术优势
| 优势 | 说明 |
|---|---|
| 解耦 | Web服务和交易核心分离,互不影响 |
| 稳定 | Web服务重启不影响交易进程 |
| 安全 | 交易进程可不暴露公网,只允许Web进程连接 |
| 可扩展 | 支持一个交易进程配多个Web节点,支持多用户并发 |
| 符合官方设计 | 易于跟进社区版本更新 |
4. 具体实施步骤
步骤1:环境准备
# 安装依赖
pip install vnpy_webtrader
# 或
pip install fastapi uvicorn python-jose[cryptography] passlib[bcrypt]
步骤2:启动交易核心RPC服务
创建start_trading_server.py:
from vnpy.trader.event_engine import EventEngine
from vnpy.trader.main_engine import MainEngine
from vnpy.rpc import RpcServer
from vnpy_ctp import CtpGateway
# 其他gateway...
def main():
event_engine = EventEngine()
main_engine = MainEngine(event_engine)
# 添加gateway
main_engine.add_gateway(CtpGateway)
# 添加其他gateway...
# 添加应用模块
# main_engine.add_app(CtaStrategy)
# main_engine.add_app(PortfolioStrategy)
# 启动RPC服务
# 请求端口: 2018,订阅端口: 4102
rpc_server = RpcServer(
main_engine,
("0.0.0.0", 2018),
("0.0.0.0", 4102)
)
rpc_server.start()
print(f"RPC服务已启动")
print(f"- 请求地址: tcp://0.0.0.0:2018")
print(f"- 订阅地址: tcp://0.0.0.0:4102")
# 保持进程运行
input()
if __name__ == "__main__":
main()
步骤3:启动Web Trader服务
创建start_web_trader.py:
from vnpy_webtrader import run_web_trader
def main():
# RPC地址配置
rpc_request_address = "tcp://127.0.0.1:2018"
rpc_subscribe_address = "tcp://127.0.0.1:4102"
# 启动Web服务
run_web_trader(
rpc_request_address,
rpc_subscribe_address,
host="0.0.0.0",
port=8000,
cors_allow_all=True # 开发环境开启CORS
)
if __name__ == "__main__":
main()
步骤4:Nginx配置参考(生产环境)
server {
listen 80;
server_name your-domain.com;
# 前端静态文件
location / {
root /path/to/your/frontend/dist;
try_files $uri $uri/ /index.html;
}
# API反向代理
location /api {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# WebSocket反向代理
location /ws {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
5. 已提供API接口概览
vnpy_webtrader官方已提供:
REST API
POST /token- 获取认证tokenGET /api/accounts- 查询账户信息GET /api/positions- 查询持仓GET /api/orders- 查询订单POST /api/orders- 下单DELETE /api/orders/{orderid}- 撤单- 以及更多...
WebSocket
- 实时推送成交推送
- 实时推送订单更新
- 实时推送账户更新
- 实时推送持仓更新
6. 部署架构建议
开发环境
同一台机器:
- 交易进程 RPC: 127.0.0.1:2018/4102
- Web进程: 0.0.0.0:8000
- 前端开发服务器: 端口5173/3000,通过代理访问API
生产环境
- 交易进程:仅对内网开放RPC端口
- Web进程:和交易进程同机或不同机,监听内网8000
- Nginx:反向代理,暴露HTTPS 443端口
- 前端:打包后由Nginx直接提供静态文件
安全建议
- 不要直接暴露交易RPC端口到公网
- 只允许Web进程连接交易RPC端口
- Web服务启用HTTPS
- 强密码存储,使用JWT过期机制
7. 总结纠正方案
| 项目 | 纠正前(弯路) | 纠正后(正确) |
|---|---|---|
| 进程模型 | 单进程一体化 | 双进程分离架构 |
| 通信方式 | 直接函数调用/协程调度 | RPC跨进程通信 |
| 前后端 | 耦合在一起 | 完全分离独立部署 |
| 架构复杂度 | 要么太简单,要么过度拆分 | 恰到好处的双进程 |
| 稳定性 | Web重启影响交易 | Web重启不影响交易 |
| 安全性 | 交易核心直接暴露 | 分层防护更安全 |
下一步行动建议
- 按照双进程架构重构当前Web Trader实现
- 基于官方vnpy_webtrader模块进行扩展,不重复造轮子
- 前端独立开发,通过REST+WebSocket与后端交互
- 先实现基础功能(登录、账户查询、持仓查询、下单撤单)
- 逐步扩展支持更多策略模块
调研完成时间:2026-03-31 调研人:姜维 伯约