VeighNa ScriptTrader 脚本策略交易模块:从交互式下单到多标的组合策略的完整实践指南
2026/9/19 1:35:27 网站建设 项目流程

VeighNa ScriptTrader 脚本策略交易模块:从交互式下单到多标的组合策略的完整实践指南

【免费下载链接】vnpy基于Python的开源量化交易平台开发框架项目地址: https://gitcode.com/vnpy/vnpy

导读

ScriptTrader 是 VeighNa 面向脚本策略交易场景设计的功能模块,它把交易客户端直接暴露给 Python,让开发者既能像使用命令行一样交互式地完成下单、撤单、查持仓等操作,也能把一段持续运行的脚本当作策略来执行。本文以社区版文档为骨架,结合仓库中的 演示脚本 与 Notebook 示例 进行纵深讲解,读完你将掌握 ScriptTrader 的加载启动方式、脚本策略文件的标准写法、脚本引擎(ScriptEngine)全部查询与交易函数,以及如何用它搭建跨品种对冲、一篮子委托、行情监控通知等多标的量化任务。

功能简介:直接拿 Python 操作交易客户端

ScriptTrader 提供了两类能力:

  • 交互式的量化分析与程序化交易:以类似 REPL(Read-Eval-Print Loop)指令的形式在命令行中完成行情查询、委托下单等操作;
  • 脚本策略功能:以整个策略连续运行的方式执行一段 Python 脚本。

因此,它可以视为“直接利用 Python 对交易客户端进行操作”的通道。与 CTA 策略模块相比,ScriptTrader 的定位有明显区别:

  • 突破了单交易所、单标的的限制,可以在一个策略中同时操作多个交易所、多个品种;
  • 可以较方便地实现股指期货和一篮子股票之间的对冲策略、跨品种套利、股票市场扫描自动化选股等复杂组合类任务。

在 README.md 中对它的定位是:“脚本策略模块,面向多标的类量化策略和计算任务设计,同时也可以在命令行中实现 REPL 指令形式的交易,不支持回测功能”。需要注意的是:ScriptTrader不支持回测,历史数据验证请配合 CTA 回测等模块使用;它更擅长的是把已经成型的思路直接投放到实盘环境中去执行。

加载启动

通过 VeighNa Station 加载

启动登录 VeighNa Station 后,点击【交易】按钮,在配置对话框中的【应用模块】栏勾选【ScriptTrader】,保存配置后进入主界面即可使用该模块。

通过启动脚本加载

在启动脚本中添加如下代码:

# 写在顶部 from vnpy_scripttrader import ScriptTraderApp # 写在创建main_engine对象后 main_engine.add_app(ScriptTraderApp)

仓库中的 run.py 给出了同一写法的参考:顶部from vnpy_scripttrader import ScriptTraderApp,随后在main_engine.add_app(ScriptTraderApp)处注册应用。值得注意的是,ScriptTraderApp 属于独立发布的扩展包vnpy_scripttrader,因此除本仓库外还需通过pip install vnpy_scripttrader安装该应用(同理,其依赖的交易接口如vnpy_ctp也需单独安装)。

启动模块

在启动模块之前,请先连接交易接口。看到 VeighNa Trader 主界面【日志】栏输出“合约信息查询成功”之后再启动模块。

一个需要特别留意的例外是IB 接口:它因为登录时无法自动获取所有的合约信息,只有在用户手动订阅行情时才能获取。因此使用 IB 接口时,需要先在主界面上手动订阅合约行情,再启动模块。

成功连接交易接口后,在菜单栏中点击【功能】→【脚本策略】,或者点击左侧按钮栏的对应图标,即可进入脚本交易模块的 UI 界面。

如果配置了数据服务(配置方法见 全局配置说明 中的全局配置部分),打开脚本交易模块时会自动执行数据服务登录初始化。若成功登录,则会输出“数据服务初始化成功”的日志。

进入界面后,可以通过以下按钮管理脚本策略:

  • 启动:脚本策略需要事先编写好脚本策略文件(如 test_strategy.py),点击【打开】按钮指定该脚本策略文件的路径,随后点击【启动】按钮启动脚本策略,并在下方界面输出相关信息;
  • 停止:点击【停止】按钮,策略随即停止,通知会在下方界面输出“策略交易脚本停止”的日志;
  • 清空:点击【清空】按钮,下方显示界面的所有信息都会被清空,方便开启新的脚本策略。

脚本策略模板

脚本策略文件需要遵循一定格式。下面给出官方模板,其作用为:

  • 订阅两个品种的行情;
  • 打印合约信息;
  • 每隔 3 秒获取最新行情。
from time import sleep from vnpy_scripttrader import ScriptEngine def run(engine: ScriptEngine): """""" vt_symbols = ["sc2209.INE", "sc2203.INE"] # 订阅行情 engine.subscribe(vt_symbols) # 获取合约信息 for vt_symbol in vt_symbols: contract = engine.get_contract(vt_symbol) msg = f"合约信息,{contract}" engine.write_log(msg) # 持续运行,使用strategy_active来判断是否要退出程序 while engine.strategy_active: # 轮询获取行情 for vt_symbol in vt_symbols: tick = engine.get_tick(vt_symbol) msg = f"最新行情, {tick}" engine.write_log(msg) # 等待3秒进入下一轮 sleep(3)

仓库中的 demo_script.py 与该模板同源,并把脚本策略的主函数约束写得很清楚:

  1. 唯一入参是脚本引擎 ScriptEngine 对象,通过它来完成查询和请求操作;
  2. 该函数会通过一个独立的线程来启动运行,区别于其他策略模块(如 CTA)的事件驱动机制——这也解释了为什么模板中使用while循环配合sleep做轮询,而不是依赖事件回调;
  3. while 循环的维护请通过engine.strategy_active状态来判断,实现可控退出。

其中engine.strategy_active可视作脚本策略的开关:点击【启动】按钮,启动 While 循环,执行脚本策略;点击【停止】按钮,退出 While 循环,停止脚本策略。

run()函数的 docstring 中还列举了脚本策略的典型应用场景,可作为选题参考:

  1. 自定义篮子委托执行算法;
  2. 股指期货和一篮子股票之间的对冲策略;
  3. 国内外商品跨交易所的套利;
  4. 自定义组合指数行情监控以及消息通知;
  5. 股票市场扫描选股类交易策略(龙一、龙二)。

功能函数:ScriptEngine 引擎全解

ScriptTrader 的 Jupyter/交互式模式基于脚本引擎(ScriptEngine)驱动。下面通过 Jupyter Notebook 来说明 ScriptEngine 的各功能函数。

首先打开 Jupyter notebook,然后加载组件、初始化脚本引擎:

from vnpy_scripttrader import init_cli_trading from vnpy_ctp import CtpGateway engine = init_cli_trading([CtpGateway])

其中:

  • 脚本引擎支持同时连接多个接口
  • init_cli_trading(gateways: Sequence[BaseGateway])可以将多个接口类以列表的形式传递给它;
  • init_cli_trading可视为 vnpy 封装好的初始化启动函数,对主引擎(MainEngine)、事件引擎(EventEngine)、脚本引擎等各种对象进行了整体封装。

仓库中的 demo_notebook.ipynb 展示了完整的交互式工作流:先init_cli_trading([CtpGateway])初始化引擎,再engine.connect_gateway(setting, "CTP")连接柜台,随后即可依次执行查询合约、查询资金、查询持仓、查询活动委托、订阅行情、查询行情、委托下单、查询委托、委托撤单等指令。

连接接口

connect_gateway

  • 入参:setting: dict,gateway_name: str
  • 出参:无

不同接口需要不同的配置参数,SimNow 仿真环境的配置如下:

setting = { "用户名": "xxxx", "密码": "xxxx", "经纪商代码": "9999", "交易服务器":"180.168.146.187:10202", "行情服务器":"180.168.146.187:10212", "产品名称":"simnow_client_test", "授权编码":"0000000000000000" } engine.connect_gateway(setting,"CTP")

其他接口的配置可以参考 site-packages 目录下不同接口模块类(如vnpy_ctp.gateway.ctp_gateway)中的default_setting字段来填写。在 Notebook 实战中,也常用from vnpy.trader.utility import load_json配合load_json("connect_ctp.json")从本地 JSON 配置文件加载连接参数,避免在代码中硬编码账号密码。

订阅行情

subscribe

  • 入参:vt_symbols: Sequence[str]
  • 出参:无

subscribe()函数用于订阅行情信息,若需要订阅一篮子合约的行情,可以使用列表格式:

engine.subscribe(vt_symbols = ["rb2209.SHFE","rb2210.SHFE"])

查询数据

连接上交易接口并成功订阅数据后,数据存储的流转逻辑如下:

  • 底层接口不停向主引擎(MainEngine)推送新的数据;
  • 主引擎里维护着一个ticks 字典用于缓存不同标的的最新 tick 数据(仅能缓存最新数据);
  • use_df的作用是转换为 DataFrame 格式,便于数据分析。
单条查询

get_tick

  • 入参:vt_symbol: str,use_df: bool = False
  • 出参:TickData

查询单个标的最新 tick,use_df为可选参数,用于把返回的类对象转化为 DataFrame 格式,便于数据分析。

tick = engine.get_tick(vt_symbol="rb2210.SHFE",use_df=False)

其中:

  • vt_symbol:为本地合约代码,格式是合约品种+交易所,如rb2210.SHFE(合约代码.交易所代码);
  • use_df:为 bool 变量,默认False,返回 TickData 类对象,否则返回相应 DataFrame。

get_order

  • 入参:vt_orderid: str,use_df: bool = False
  • 出参:OrderData

根据vt_orderid查询委托单的详细信息。

order = engine.get_order(vt_orderid="CTP.3_-1795780178_1",use_df=False)

其中,vt_orderid为本地委托号(在委托下单时,会自动返回该委托的 vt_orderid),格式形如“接口名.编号”。

get_contract

  • 入参:vt_symbol,use_df: bool = False
  • 出参:ContractData

根据本地vt_symbol来查询对应合约对象的详细信息,包括合约乘数、最小变动价位、涨跌停板等。

contract = engine.get_contract(vt_symbol="rb2210.SHFE",use_df=False)

get_account

  • 入参:vt_accountid: str,use_df: bool = False
  • 出参:AccountData

根据本地vt_accountid来查询对应资金信息(可用资金、冻结资金、动态权益等)。

account = engine.get_account(vt_accountid="CTP.189672",use_df=False)

get_position

  • 入参:vt_positionid: str,use_df: bool = False
  • 出参:PositionData

根据vt_positionid来查询持仓情况,返回对象包含接口名称、交易所、合约代码、数量、冻结数量等。

position = engine.get_position(vt_positionid='CTP.hc2305.SHFE.多')

注意,vt_positionid为 vnpy 内部对一笔特定持仓的唯一持仓编号,格式为"gateway_name.vt_symbol.Direction.value",其中持仓方向可选“多”、“空”和“净”

多条查询

get_ticks

  • 入参:vt_symbols: Sequence[str],use_df: bool = False
  • 出参:Sequence[TickData]

查询多个合约最新 tick,vt_symbols是列表格式,里面包含多个vt_symbol

ticks = engine.get_ticks(vt_symbols=['rb2209.SHFE','rb2210.SHFE'],use_df=True)

get_orders

  • 入参:vt_orderids: Sequence[str],use_df: bool = False
  • 出参:Sequence[OrderData]

根据多个vt_orderid查询其详细信息。vt_orderids为列表,里面包含多个vt_orderid

orders = engine.get_orders([orderid_one,orderid_two],use_df=True)

get_trades

  • 入参:vt_orderid: str,use_df: bool = False
  • 出参:Sequence[TradeData]

根据给定的一个vt_orderid返回这次报单过程中的所有 TradeData 对象。vt_orderid是本地委托号,每一个委托 OrderData 由于部分成交关系,可以对应多笔成交 TradeData。

trades = engine.get_trades(vt_orderid=your_vt_orderid,use_df=True)

get_bars

  • 入参:vt_symbol: str,start_date: str,interval: Interval,use_df: bool = False
  • 出参:Sequence[BarData]

通过配置的数据服务查询历史数据:

bars = engine.get_bars(vt_symbol="rb2210.SHFE",start_date="20211201", interval=Interval.MINUTE,use_df=False)

其中:

  • vt_symbol:本地合约代码,格式为合约代码 + 交易所名称;
  • start_date:起始日期,格式为"%Y%m%d"
  • interval:K 线周期,包括分钟、小时、日、周(对应Interval.MINUTEInterval.HOURInterval.DAILYInterval.WEEKLY等枚举);
  • bars:包含了一系列 BarData 数据的列表对象,其 BarData 的定义如下:
@dataclass class BarData(BaseData): symbol: str exchange: Exchange datetime: datetime interval: Interval = None volume: float = 0 turnover: float = 0 open_interest: float = 0 open_price: float = 0 high_price: float = 0 low_price: float = 0 close_price: float = 0 def __post_init__(self): self.vt_symbol = f"{self.symbol}.{self.exchange.value}"

BarData的定义位于仓库 vnpy/trader/object.py,从中可以看到 K 线对象除 OHLC 价格外,还包含成交量、成交额、持仓量等字段,并会在初始化时自动拼出vt_symbol

全量查询

在全量查询中,唯一参数是use_df,默认为False。返回的是一个包含相应数据的 List 对象,例如 ContractData、AccountData 和 PositionData。

get_all_contracts

  • 入参:use_df: bool = False
  • 出参:Sequence[ContractData]

默认返回一个 list,包含了全市场的 ContractData;如果use_df=True则返回相应的 DataFrame。可用于在交互式会话中快速浏览市场合约结构。

get_all_active_orders

  • 入参:use_df: bool = False
  • 出参:Sequence[OrderData]

活动委托指的是尚未完全成交的委托,其状态包含“已提交、未成交、部分成交”;函数将返回包含一系列 OrderData 的列表对象。在风控与撤单逻辑中常配合使用。

get_all_accounts

  • 入参:use_df: bool = False
  • 出参:Sequence[AccountData]

默认返回包含 AccountData 的列表对象,用于多账户场景下统一查看资金状况。

get_all_positions

  • 入参:use_df: bool = False
  • 出参:Sequence[PositionData]

默认返回包含 PositionData 的列表对象,可一次性获取当前所有持仓。

交易委托

脚本引擎提供四个方向/开平组合的快捷委托函数:

  • buy:买入开仓(Direction:LONG,Offset:OPEN)

  • sell:卖出平仓(Direction:SHORT,Offset:CLOSE)

  • short:卖出开仓(Direction:SHORT,Offset:OPEN)

  • cover:买入平仓(Direction:LONG,Offset:CLOSE)

  • 入参:vt_symbol: str,price: float,volume: float,order_type: OrderType = OrderType.LIMIT

  • 出参:str

以委托买入为例,engine.buy()函数入参包括:

  • vt_symbol:本地合约代码(字符串格式);
  • price:报单价格(浮点数类型);
  • volume:报单数量(浮点数类型);
  • order_type:OrderType 枚举常量,默认为限价单(OrderType.LIMIT),同时支持停止单(OrderType.STOP)、FAK(OrderType.FAK)、FOK(OrderType.FOK)、市价单(OrderType.MARKET)。不同交易所支持的报单方式不完全一致。
engine.buy(vt_symbol="rb2210.SHFE", price=4200, volume=1, order_type=OrderType.LIMIT)

执行交易委托后会返回本地委托号vt_orderid,可将其保存后用于后续的get_order查询与cancel_order撤单。在 demo_notebook.ipynb 中即演示了vt_orderid = engine.buy("sc2209.INE", 32, 1000)后,用返回的vt_orderid依次执行查询委托、撤单的完整链路。

send_order

  • 入参:vt_symbol: str,price: float,volume: float,direction: Direction,offset: Offset,order_type: OrderType
  • 出参:str

send_order函数是脚本交易引擎调用的发送委托的底层函数。一般在策略编写时不需要单独调用,通过 buy/sell/short/cover 函数发送委托即可(四个快捷函数内部最终都会汇聚到 send_order 完成报单)。

cancel_order

  • 入参:vt_orderid: str
  • 出参:无

基于本地委托号撤销委托:

engine.cancel_order(vt_orderid='CTP.3_-1795780178_1')

信息输出

write_log

  • 入参:msg: str
  • 出参:无

在策略中调用write_log函数,可以进行指定内容的日志输出。脚本策略模板中大量使用它打印合约信息与最新行情;在 GUI 模式下日志会显示在脚本模块下方的信息界面中。

send_email

  • 入参:msg: str
  • 出参:无

配置好邮箱相关信息之后(配置方法见 全局配置说明 中的全局配置部分),调用send_email函数可以发送标题为“脚本策略引擎通知”的邮件到自己的邮箱。配合行情监控循环使用,即可实现“组合指数行情监控以及消息通知”这一典型应用——当监控条件触发时把告警内容实时推送到邮箱。

实战小结:把脚本策略跑起来的完整步骤

综合官方文档与仓库示例,一个完整的 ScriptTrader 落地流程可以归纳为:

  1. 安装依赖pip install vnpy_scripttrader,并安装所需交易接口(如vnpy_ctp);
  2. 加载应用:在 run.py 中main_engine.add_app(ScriptTraderApp),或在 VeighNa Station 的应用模块中勾选 ScriptTrader;
  3. 连接接口:先连接交易接口,等待日志输出“合约信息查询成功”;IB 接口需先手动订阅合约行情;
  4. 编写脚本:参照模板新建脚本策略文件,run(engine: ScriptEngine)为唯一入口,用engine.strategy_active控制 while 循环的生命周期;
  5. 启动运行:在模块界面【打开】选择脚本文件,点击【启动】开始执行,点击【停止】结束;
  6. 交互式扩展:若要在 Jupyter 中做数据探索与临时交易,用init_cli_trading([CtpGateway])初始化引擎,再按查询 → 订阅 → 委托 → 撤单的链路自由调用。

总体而言,ScriptTrader 的价值在于把 VeighNa 的主引擎能力以极低的门槛开放给 Python 脚本:既有 CTA 模块不具备的跨交易所、跨品种组合操作能力,又有比图形界面更灵活、可编程、可复用的执行方式。对于对冲策略、跨品种套利、篮子委托执行、市场扫描选股等“非典型 CTA”需求,它是当前仓库生态中直接的解决方案。

【免费下载链接】vnpy基于Python的开源量化交易平台开发框架项目地址: https://gitcode.com/vnpy/vnpy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询