教程 · 单套解锁 教程 · EA量化教学

EA10 Python/vnpy 策略

使用手册 + 操作教程 共 16 章全部免费开放,一步一步把软件用起来;核心知识点 11 章,¥69 一次解锁讲透原理。

作者 枢汇安全课堂 更新 2026-10-13 阅读 45 收录 EA量化教学 · 27 章
本课程 · 单套解锁
¥69¥104
单品永久解锁 · 会员可阅 · 一次购买终身使用
✓使用手册 + 操作教程 共 16 章全文免费 ✓核心知识点 11 章,¥69 一次解锁 ✓支持电脑 / 手机 · 永久免费更新
注册后解锁核心知识点
免费学习区 使用手册 + 操作教程 共 16 章全部免费开放 · 核心知识点 11 章为付费内容 ¥69 解锁核心知识点
PART ONE

使用手册

功能在哪 · 是什么 · 怎么调出来

一、vn.py 是什么

vn.py(现名 VeighNa)是国内最流行的开源量化交易框架:

  • Python 编写,开源免费(MIT 协议)
  • 模块化架构:核心引擎 + 按需安装的应用模块(CTA 策略、价差交易、算法交易等)
  • 覆盖全流程:行情网关 → 事件引擎 → 策略引擎 → 回测 → 实盘
  • 国内期货 CTP 实盘的事实标准之一
白话注解:如果把量化交易比作开餐厅,vn.py 就是"精装修的厨房"——水电煤气(行情/交易通道)都接好了,你只管炒菜(写策略逻辑)。TqSdk 是"半成品厨房"(更简单),Backtrader 是"只练菜不营业"(只回测)。

二、安装与环境

# 方式一:官方推荐,图形化 VeighNa Station(Windows)自动装好一切
# 到 www.vnpy.com 下载 VeighNa Station

# 方式二:pip 手动安装核心 + CTA 应用
pip install vnpy
pip install vnpy_ctastrategy # CTA 策略模块(本教程主角)
pip install vnpy_ctabacktester # CTA 回测工具(可选)
pip install vnpy_ctp # CTP 期货柜台网关(实盘需要,仅 Windows)
  • 建议 Python 3.10 左右版本(个别网关对过新/过旧的 Python 支持滞后)
  • Windows 实盘 CTP 最省事;Linux 跑回测/研究很稳
  • 验证:python -c "import vnpy; print(vnpy.__version__)"

vn.py 3.x 之后把功能拆成了独立包(vnpy_ctastrategy、vnpy_ctp…)。只装 pip install vnpy 只有核心引擎,CTA 策略要用必须另装 vnpy_ctastrategy——报 No module named 'vnpy_ctastrategy' 就是这个原因。

PART TWO

操作教程

一步一步 · 跟着做完一件事

三、核心架构与 vt_symbol 规则

组件作用
EventEngine 事件引擎框架心脏:所有行情/成交/委托都是事件,分发给订阅者
MainEngine 主引擎总管家:管理网关、应用模块、事件转发
Gateway 网关对接一个交易所/柜台(CTP、CTP MINI 等),统一转成 vn.py 数据格式
应用模块vnpy_ctastrategy(CTA)、vnpy_spreadtrading(价差)、vnpy_portfoliostrategy(组合)等

vt_symbol 合约代码规则:合约.交易所,注意与 TqSdk 顺序相反:

示例含义
rb2410.SHFE上期所螺纹钢
IF2406.CFFEX中金所股指
TA409.CZCE郑商所 PTA
sc2407.INE上期能源原油
白话注解:日常写策略时你基本不直接碰 MainEngine/EventEngine——VeighNa Trader 图形界面或回测引擎都替你管了。但理解"一切都是事件"这个模型,能帮你明白为什么策略类里全是 on_xxx 回调。

四、数据对象:TickData / BarData / OrderData / TradeData

策略回调收到的都是 vn.py 统一的数据对象,常用字段:

对象常用字段
BarDataopen_price / high_price / low_price / close_price / volume / datetime / vt_symbol
TickDatalast_price / ask_price_1 / bid_price_1 / ask_volume_1 / bid_volume_1 / volume / limit_up / limit_down / datetime
OrderDatavt_orderid / direction / offset / price / volume / traded / status
TradeDatavt_tradeid / vt_orderid / direction / offset / price / volume / datetime

注意字段命名与 TqSdk 不同:vn.py 是 close_price 不是 close,是 ask_price_1 不是 ask_price1。混用两个框架时最容易写串。

五、生命周期回调全集

CtaTemplate 的全部回调(官方 template.py 源码确认):

回调触发时机典型用途
on_init()策略初始化(抽象方法,必须实现)load_bar 预热指标
on_start()点"启动"后写日志、恢复状态
on_stop()点"停止"后put_event、记录状态
on_tick(tick)每笔 tick喂给 BarGenerator
on_bar(bar)每根 1 分钟 K 线主策略逻辑(多数策略写在这)
on_order(order)委托状态更新跟踪挂单
on_trade(trade)成交回报记录开仓价、打日志
on_stop_order(stop_order)本地停止单状态更新跟踪停止单(见第十六章)

配套工具方法(同样是源码确认):

方法作用
self.buy/sell/short/cover(price, volume, stop, lock, net)四向下单(见第九章)
self.cancel_order(vt_orderid) / self.cancel_all()撤单 / 撤掉本策略全部挂单
self.write_log(msg)写日志
self.put_event()刷新界面显示(on_bar 结尾习惯调一次)
self.load_bar(days, interval, callback, use_database)加载历史数据预热指标
self.load_tick(days)加载历史 tick 预热
self.get_engine_type()判断当前是回测还是实盘(BACKTESTING/LIVE)
self.get_pricetick() / self.get_size()合约最小变动价 / 合约乘数
self.sync_data()把 variables 持久化到磁盘(重启恢复现场)
self.send_notification(msg)(别名 send_email)推送通知(实盘告警)

CtaTemplate 没有 set_target 和 close_all 方法——网上部分老教程写错了,直接调用会报 AttributeError。想"一键平仓":判断 self.pos 后调用对应的 sell/cover;或者干脆继承 TargetPosTemplate 用 set_target_pos(0)(第十四章)。

六、BarGenerator:K 线合成器

国内期货 CTP 推送的是 tick 和 1 分钟线,BarGenerator 负责把它们合成你要的周期:

from vnpy.trader.utility import BarGenerator
from vnpy.trader.constant import Interval

def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
    super().__init__(cta_engine, strategy_name, vt_symbol, setting)
    # 1分钟K线 → 合成 15分钟K线,推给 on_15min_bar
    self.bg = BarGenerator(self.on_bar, 15, self.on_15min_bar)
    # 小时线:window 配合 Interval.HOUR
    self.bg_hour = BarGenerator(self.on_bar, 2, self.on_2hour_bar, Interval.HOUR)

def on_tick(self, tick: TickData):
self.bg.update_tick(tick) # tick 灌进合成器

def on_bar(self, bar: BarData):
self.bg.update_bar(bar) # 1分钟线再灌进15分钟合成器

def on_15min_bar(self, bar: BarData):
    # 你的主逻辑写在这(15分钟级别)
    ...
  • BarGenerator(on_bar, window, on_window_bar, interval):默认把 tick 合成 1 分钟线推给 on_bar
  • window=N 再把 N 根合成一根推给 on_window_bar;小时线要配 Interval.HOUR
  • chain 起来就是:tick → 1分钟 → 15分钟,层层灌
白话注解:注意信号只会在 K 线走完时触发一次(合成器是收满 N 根才切一刀),天然规避了"K线没走完反复交易"的问题——这点 vn.py 帮你处理好了。

七、下单函数:buy / sell / short / cover(含 stop/lock/net)

四个下单函数,源码签名完全一致:

def buy(self, price: float, volume: float, stop: bool = False,
        lock: bool = False, net: bool = False) -> list:
    """买入开多"""

# 四个方向
self.buy(price, volume) # 买开(做多)
self.sell(price, volume) # 卖平(平多仓)
self.short(price, volume) # 卖开(做空)
self.cover(price, volume) # 买平(平空仓)
参数作用细节
stop=True本地停止单价格触线才转限价单发出,不占交易所挂单(见第十六章)
lock=True锁仓代替平仓上期所平今手续费贵时,反手开仓锁仓、次日再解(见第十七章)
net=True净持仓下单直接指定目标净持仓方向和数量,交易所自动处理开平

返回值是 vt_orderid 列表(本地停止单返回 STOP.前缀 的虚拟单号),撤单用:

self.cancel_order(vt_orderid) # 撤指定单
self.cancel_all() # 撤本策略全部挂单(含停止单)
白话注解:新手最容易混 buy/cover 和 sell/short。口诀:开仓看方向(买开 buy、卖开 short),平仓反着来(平多用 sell、平空用 cover)。平仓手数超过实际持仓会被拒单——平之前看一眼 self.pos。

八、TargetPosTemplate:目标持仓模板

vn.py 内置了"目标持仓"式策略模板(继承自 CtaTemplate):你不写买卖方向,只声明目标净持仓,框架自动算差额、自动撤旧单、自动按多空方向下单(实盘自动处理平今平昨的组合):

from vnpy_ctastrategy import TargetPosTemplate, BarData
from vnpy.trader.utility import BarGenerator, ArrayManager

class TargetMaStrategy(TargetPosTemplate):
    """注意:继承 TargetPosTemplate,不是 CtaTemplate"""
    fast_window = 10
    slow_window = 30
    target_pos_size = 1

target_pos = 0 # 模板内置变量:目标净持仓(正=多,负=空,0=空仓)

    parameters = ["fast_window", "slow_window", "target_pos_size"]
    variables = ["fast_ma0", "slow_ma0"]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar, 15, self.on_15min_bar)
        self.am = ArrayManager(100)

    def on_init(self):
        self.load_bar(10)

    def on_tick(self, tick):
        self.bg.update_tick(tick)

    def on_bar(self, bar):
        self.bg.update_bar(bar)

    def on_15min_bar(self, bar: BarData):
        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return

        fast = am.sma(self.fast_window, array=True)
        slow = am.sma(self.slow_window, array=True)

        if fast[-1] > slow[-1]:
self.set_target_pos(self.target_pos_size) # 目标:多头1手
        elif fast[-1] < slow[-1]:
self.set_target_pos(-self.target_pos_size) # 目标:空头1手
        else:
self.set_target_pos(0) # 目标:空仓

        self.put_event()

    def on_stop(self):
        # 停止前把目标清零,框架会自动平掉所有持仓
        self.set_target_pos(0)
        self.put_event()

与手写 buy/sell/short/cover 对比:

维度手写四函数TargetPosTemplate
表达方式一笔笔委托只声明目标净持仓
反手/平今平昨自己拼单模板自动拆单组合
未成交旧单自己撤自动撤旧单再发新单(check_order_finished/cancel_old_order)
下单价格自己给自动对价 ± tick_add(类属性,默认 1,可改)
适合精细控制趋势/调仓类策略
白话注解:set_target_pos(n) 的 n 是手数:正数持多、负数持空、0 平光。它内部逻辑(官方 template.py)就是"目标减现有 = 差额",差额为正 buy/cover、为负 sell/short,且实盘会根据你的持仓方向自动选对平仓函数。和 TqSdk 的 TargetPosTask 一个思想——"声明目标,框架干活"。

旧教程里在 CtaTemplate 上调 self.set_target(...) 是错误写法(不存在该方法)。目标持仓的正确入口是继承 TargetPosTemplate 并调用 self.set_target_pos(...)。

九、停止单(stop)机制

buy/sell/short/cover(price, volume, stop=True) 发出的是本地停止单:

  • 不发给交易所,存在 vn.py 引擎里,用 STOP. 开头的虚拟单号
  • 每个 tick 到来时检查:价格触及触发价 → 自动转成限价单发出
  • 触发后走 on_stop_order() 回调
  • cancel_all() 会一并撤掉所有本地停止单
# 跌破 stop_price 止损(本地停止单)
self.sell(stop_price, abs(self.pos), stop=True)

def on_stop_order(self, stop_order):
    self.write_log(f"停止单更新: {stop_order.status}")
白话注解:本地停止单的好处是不占交易所挂单、不暴露意图;代价是vn.py 程序挂了停止单就失效——断线期间价格穿透止损线,没有任何保护。实盘要么保证程序 7×24 稳定,要么用交易所条件单。

十、锁仓(lock)与净持仓(net)模式

参数机制什么时候用
lock=True不直接平仓,反向开仓锁住仓位,之后合适时机再解锁平仓上期所平今手续费贵、想避开平今单的场景
net=True按净持仓报单:直接报"最终要持有多少",交易所/柜台自动拆成开平支持净持仓模式的柜台,简化策略代码
# 上期所:用锁仓代替平今
self.short(price, volume, lock=True) # 不平多单,直接反手开空锁仓

# 净持仓模式(柜台支持时)
self.buy(price, 5, net=True) # 目标净多头5手,自动处理开平
白话注解:这三个参数(stop/lock/net)是 vn.py 实盘的"隐藏考点"。回测里它们都被正确模拟,但行为差异只有实盘才感受得到——特别是上期所的平今手续费,能让一个高频策略从微赚变微亏。

十一、参数优化:穷举与遗传算法

from vnpy_ctastrategy.backtesting import BacktestingEngine, OptimizationSetting

engine = BacktestingEngine()
engine.set_parameters(...) # 同第十一章

setting = OptimizationSetting()
setting.set_target("sharpe_ratio") # 优化目标(统计字段名)
setting.add_parameter("fast_window", 5, 25, 5) # 参数名, 起始, 结束, 步长
setting.add_parameter("slow_window", 20, 60, 10)

# 穷举优化(run_optimization 是它的别名)
result = engine.run_bf_optimization(setting)

# 遗传算法优化(参数多、空间大时更快)
result = engine.run_ga_optimization(setting, pop_size=100, ngen=30)
  • set_target 填第十二章统计字段名(如 total_return、sharpe_ratio、return_drawdown_ratio)
  • 返回结果按目标值排序的参数组合列表

优化结果只挑"最优一组"就是过拟合:那组参数大概率只是刚好贴合历史。正确姿势:看最优附近一组参数是否普遍不错(参数平原),再用样本外数据验证(参见本站 Backtrader 教程的防过拟合章节,原理通用)。

十二、实盘部署:VeighNa Trader + CTP

  1. 启动 VeighNa Station → 打开 VeighNa Trader(或自己写 run.py 加载应用)
  2. 登录界面连接 CTP:填期货公司给的服务器地址、账号、密码、产品信息、授权码
  3. 菜单栏"功能 → CTA 策略":添加策略实例(选策略类、绑定合约、填参数)
  4. 点"初始化"(on_init 加载历史预热)→ 点"启动"(on_start 开始交易)
  5. 策略配置自动持久化为 json,重启后恢复实例;sync_data() 同步 variables 现场数据
# 自定义启动脚本 run.py:
# 各版本 MainEngine 初始化与应用注册的写法略有差异。
# 最可靠做法:直接抄本机安装目录自带的 run.py(官方模板),
# 在其中加载 cta_strategy 应用即可,模板本身就是最好的文档。

vn.py 版本迭代较快,MainEngine/应用初始化的具体写法请以本机安装版本自带的 run.py 官方模板为准——模板本身就是最好的文档。CTP 实盘前先连SimNow 模拟环境(上期所官方仿真)验证全流程。

十三、风控与通知

  • self.send_notification(msg):策略里推送告警(配合 vnpy 的通知渠道配置)
  • 风控模块:安装 vnpy_riskmanager 后可在交易前做委托流控(单笔上限/总委托上限/活跃委托上限),实盘防手滑
  • 策略内风控底线(自己写):单笔手数上限、当日最大亏损熔断(用 on_trade 累计盈亏触发 self.set_target_pos(0) + on_stop)、风险度监控
  • 日志:write_log 输出到 VeighNa Trader 日志界面与文件,实盘务必落盘留痕
白话注解:实盘第一原则——程序会出错,所以要有"双保险":框架层风控(riskmanager)管住量,策略层熔断管住钱。任何一条触发就停,宁可少赚不可爆仓。

十四、VPS 部署注意事项

vn.py 实盘 24 小时跑建议用 VPS:

  1. 选离期货公司机房近的服务器(比如上海)
  2. CTP 网关(vnpy_ctp)目前仅 Windows;Linux 上可考虑其他兼容柜台网关
  3. 用 systemd / 任务计划守护进程;程序崩溃自动拉起后,策略实例和 variables 会从 json 恢复
  4. 夜盘时段(21:00 起)确保 VPS 不断电不断网
  5. 本地停止单(stop=True)依赖程序存活——见第十六章的风险提示
白话注解:vn.py 是个 Python 程序,你电脑关了它就停了。VPS 是远程 24 小时不关机的服务器,放在期货公司机房旁边,下单延迟比家里低。

十五、vn.py vs TqSdk vs Backtrader

对比项vn.pyTqSdkBacktrader
入门难度中等(概念多、模块多)最简单(pip 装完即用)简单
国内期货实盘支持 CTP(本机直连,需装 vnpy_ctp)支持 CTP(云端中继)核心定位回测,可经 Store 扩展
回测内置引擎 + 优化器内置,与实盘同代码内置,分析维度最全
目标持仓工具TargetPosTemplateTargetPosTaskorder_target_\* 族
图形界面完整 VeighNa Trader 客户端web_gui 网页matplotlib 静态图
适合专业期货量化、多市场多模块国内期货入门与中低频回测研究与学习
白话注解:国内期货从零起步,TqSdk 上手最快;要完整平台(界面、风控、多模块、多网关)选 vn.py;纯研究回测用 Backtrader。三者不冲突,很多团队回测用 Backtrader、实盘用 vn.py/TqSdk。

十六、本课小结

  • vn.py = 核心引擎 + 应用模块;CTA 策略装 vnpy_ctastrategy
  • 策略继承 CtaTemplate:parameters/variables + on_init/on_start/on_stop + on_tick/on_bar 回调
  • BarGenerator 合成周期 K 线,ArrayManager 管指标(sma/ema/atr/rsi/macd/boll…,dir(am) 查全部)
  • 下单四函数 buy/sell/short/cover,关键参数 stop(本地停止单)/lock(锁仓)/net(净持仓)
  • 一切持仓状态看 self.pos;平仓前先看它
  • 目标持仓用 TargetPosTemplate.set_target_pos(正多/负空/0 清仓),不是 set_target
  • 回测 BacktestingEngine:interval 用 Interval 枚举;统计 28 字段无胜率,用 get_all_trades 自算
  • 优化有穷举和遗传算法两种,警惕过拟合
  • 实盘走 VeighNa Trader + vnpy_ctp,先 SimNow 模拟后实盘,VPS 24 小时运行
  • 回测 ≠ 实盘,业绩不代表未来收益
本站固定免责声明:本教程仅讲解软件编程与操作方法,不构成投资建议或策略推荐。回测业绩不代表未来收益,EA自动交易风险大,请谨慎决策。
付费专享 · 核心知识点 11 章

继续阅读:核心知识点,搞懂原理

EA10 Python/vnpy 策略 — 共 27 章,已免费阅读 16 章,剩余 11 章核心知识点讲透「为什么这样、点了会怎样」。

十七、第一个 CTA 策略:CtaTemplate 结构
十八、ArrayManager:指标数组
十九、完整实战案例:双均线策略
二十、回测:BacktestingEngine 全解
二十一、回测统计字段表(28 项)
二十二、回测结果怎么看
…等共 11 章核心内容
✍️ 注册后扫码购买 🔐 已有账号,去登录 单套 ¥69 永久 · 会员可阅
SERVICE & PRICING
服务收费说明 · 明码标价,无隐藏收费
全部课程统一 ¥39-69,买一套永久使用。以下为购买与使用的完整流程。
01先免费试读

每套教程的「使用手册」部分均可免费阅读,先确认内容是否适合自己再决定,不必盲买。

02扫码付款

选定课程后点「立即解锁」,页面展示收款二维码与客服微信,扫码转账即可,无需注册海外支付。

03获取卡密

付款完成后客服第一时间发送卡密号与卡密密码,站内消息与微信同步通知。

04兑换解锁

在用户中心「兑换卡密」输入卡密号与密码,系统即时解锁全部章节,无需二次付款。

一次付费,终身可用 · 解锁后课程永久留在账号里,不限次数、不限时间阅读 持续免费更新 · 平台改版、规则变化时课程同步修订
RECOMMEND
相关教程推荐 · 同栏目更多上手机会

💬 用户评价 (0)

🔒 登录并成为会员后可发表评价
还没有评价 · 成为第一个评价的人吧 🎯