Banner

vn.py

10小时前

vn.py(VeighNa)上手的核心路径是:先用 VeighNa Studio 把环境装好,再跑通官方双均线 CTA 策略回测,然后连 SimNow 仿真验证下单,最后加风控小资金实盘。 别一上来就啃全栈,很多人卡在环境和策略加载这两步。

一、装环境,优先走一键包

Windows 推荐 VeighNa Studio,它集成 Python 运行环境、VeighNa 框架核心依赖、VeighNa Station 图形化管理工具和 Jupyter Lab,系统要求 Windows 10/11,不支持 Win7。安装时右键以管理员身份运行,选择快速安装,保持默认路径,装完桌面会有 VeighNa Station 图标。安装路径建议选非中文、无空格目录,并勾选添加到系统环境变量,能减少很多依赖报错。

验证是否成功:

python -c "import vnpy; print(vnpy.__version__)"

能打印版本号就没问题。

源码安装要建虚拟环境,从 GitHub 或 Gitee 下载 vnpy 源码解压,进入目录执行对应安装脚本或 pip install .,然后按需安装交易接口 vnpy_ctp、策略应用 vnpy_ctastrategy 和 vnpy_ctabacktester、数据管理 vnpy_datamanager、数据库 vnpy_sqlite 等模块。现在框架是核心加插件模式,装了 vnpy 不等于有 CTP 和回测界面。

Mac 需要手动装,先 brew install ta-lib,再装 numpy,然后 pip 安装 vnpy、vnpy_ctastrategy、vnpy_ctabacktester、vnpy_datamanager、vnpy_sqlite、vnpy_rqdata 等,CTP 接口可能需要克隆 vnpy_ctp 源码用 pip install -e . 编译,编译后还要手动打开 thostmduserapi_se 和 thosttraderapi_se 两个框架文件添加系统信任。

二、启动方式有两种

图形化启动:装好 VeighNa Studio 后启动 VeighNa Station,用社区论坛账号登录,点击 VeighNa Trader 进入交易界面,运行过程中不要关闭 VeighNa Station。

脚本启动更灵活,适合部署:

from vnpy.event import EventEngine
from vnpy.trader.engine import MainEngine
from vnpy.trader.ui import MainWindow, create_qapp
from vnpy_ctp import CtpGateway
from vnpy_ctastrategy import CtaStrategyApp
from vnpy_ctabacktester import CtaBacktesterApp

def main():
    qapp = create_qapp()
    event_engine = EventEngine()
    main_engine = MainEngine(event_engine)
    main_engine.add_gateway(CtpGateway)
    main_engine.add_app(CtaStrategyApp)
    main_engine.add_app(CtaBacktesterApp)
    main_window = MainWindow(main_engine, event_engine)
    main_window.showMaximized()
    qapp.exec()

if __name__ == "__main__":
    main()

也可以直接进源码 examples/veighna_trader 目录运行 python run.py 弹出交易界面。

三、写第一个 CTA 策略

核心是继承 CtaTemplate,用 BarGenerator 把 Tick 合成 K 线,用 ArrayManager 算指标:

from vnpy_ctastrategy import (
    CtaTemplate, TickData, BarData, BarGenerator, ArrayManager
)

class DoubleMaStrategy(CtaTemplate):
    author = "demo"
    fast_window = 10
    slow_window = 30
    fixed_size = 1
    fast_ma = 0.0
    slow_ma = 0.0
    parameters = ["fast_window", "slow_window", "fixed_size"]
    variables = ["fast_ma", "slow_ma"]

    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)
        self.am = ArrayManager()

    def on_init(self):
        self.write_log("策略初始化")
        self.load_bar(10)

    def on_start(self):
        self.write_log("策略启动")

    def on_stop(self):
        self.write_log("策略停止")

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

    def on_bar(self, bar: BarData):
        self.cancel_all()
        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return
        self.fast_ma = am.sma(self.fast_window)
        self.slow_ma = am.sma(self.slow_window)

        if self.pos == 0:
            if self.fast_ma > self.slow_ma:
                self.buy(bar.close_price, self.fixed_size)
            elif self.fast_ma < self.slow_ma:
                self.short(bar.close_price, self.fixed_size)
        elif self.pos > 0:
            if self.fast_ma < self.slow_ma:
                self.sell(bar.close_price, abs(self.pos))
                self.short(bar.close_price, self.fixed_size)
        elif self.pos < 0:
            if self.fast_ma > self.slow_ma:
                self.cover(bar.close_price, abs(self.pos))
                self.buy(bar.close_price, self.fixed_size)
        self.put_event()

官方示例里判断金叉死叉通常取数组最后两个值比较,避免用单点值误判,可以参考 ADemo 里 fast_ma0、fast_ma1 的写法。

四、跑回测

from vnpy_ctastrategy.backtesting import BacktestingEngine
from datetime import datetime

engine = BacktestingEngine()
engine.set_parameters(
    vt_symbol="rb888.SHFE",
    interval="1m",
    start=datetime(2024, 1, 1),
    end=datetime(2025, 12, 31),
    rate=0.3/10000,
    slippage=1,
    size=10,
    pricetick=1,
    capital=100_000,
)
engine.add_strategy(DoubleMaStrategy, {"fast_window": 10, "slow_window": 30, "fixed_size": 1})
engine.load_data()
engine.run_backtesting()
engine.calculate_result()
engine.calculate_statistics()
engine.show_chart()

也可以用 CTA 回测图形界面,配置本地代码、K线周期、起止日期、起始资金、手续费率、交易滑点、合约乘数、价格跳动等参数后点击回测。

五、连 SimNow 仿真

先在 SimNow 注册 CTP 仿真账号,拿到经纪商代码和服务器地址,在 VeighNa Trader 或配置文件里填入账号、密码和服务器信息。

有个很容易踩的坑:SimNow 账户需要手动激活,注册后要登录官网找到激活仿真交易的选项,未激活连接时会直接报密码错误或未登录。

环境选择上,7x24 小时环境全天候开放,适合开发调试和配置验证,服务器端口通常是交易 40001、行情 40011;交易时段环境严格模拟实盘时间,端口通常是 30001 和 30011,适合感受开盘收盘和集合竞价行为。建议先用 7x24 把连接和下单跑通,再切交易时段环境。

如果一直连不上报 4097,常见原因是 CTP 接口版本和 SimNow 要求不匹配、同时加载了多个交易接口导致资源冲突、网络对金融端口有限制,可以优先更新 CTP 交易库、只启用 CTP 接口、确认在测试时段内并核对 brokerID。

六、把策略跑起来前必查的几件事

策略在列表里找不到:自己写的策略要放到 VN Trader 运行时目录下的 strategies 文件夹才能被识别,运行时目录可以在主界面标题栏查看,Windows 默认常见路径类似 C:\Users\用户名\strategies。另外 vnpy 加载的是 py 文件里的类名而不是文件名,导入语句写漏也可能导致加载失败。

回测和实盘差距大:滑点建议按 1 到 3 个最小变动单位保守设置,低流动性合约取上限;手续费要区分平今平昨,比如郑商所棉花开仓万分之 0.5、平今万分之 3,没配置好会严重高估收益。还要检查是否用了未来函数、数据频率和下单触发时机是否匹配、是否做过样本外验证和参数扰动测试。

数据质量:最好用 data_recorder 自己录行情入库,外部数据缺漏会直接污染回测结果。

Linux 权限问题:vn.py 首次运行会在用户家目录创建 .vntrade 配置目录,如果被 root 创建过,普通用户启动会报 Permission denied,可以用 sudo chown -R $USER:$USER ~/.vntrade 和 chmod 700 ~/.vntrade 修复。

编译报错:Linux 下 gcc failed 常见是缺 python3-dev 或 build-essential,建议先装 build-essential、python3-dev、libssl-dev、libffi-dev,再用 conda 做环境隔离,避免全局 pip 污染。

七、建议的练习路线

  1. 装好 Studio,确认 import vnpy 正常
  2. 启动 VeighNa Trader,熟悉行情、委托、成交、日志、持仓面板
  3. 跑通官方双均线回测,看懂夏普、最大回撤、日盈亏
  4. 改参数做优化,观察是不是明显过拟合
  5. 注册 SimNow 并激活,用 7x24 环境连上 CTP
  6. 用本地仿真或模拟账户跑至少一个月,观察滑点和成交质量
  7. 配置风控,设单日亏损熔断,再考虑小资金实盘

框架再完善也解决不了策略本身不赚钱的问题,行情没清洗干净、复权没处理好、滑点手续费没模拟真实,回测再漂亮实盘都会打回原形。另外实盘一定要加单日亏损自动停机,别完全依赖策略自身逻辑。

6