基于vnpy的量化交易系统架构与策略分类

系统架构 系统架构 基于 vnpy 4.1.0 构建的生产级量化交易平台,采用分层架构设计: 数据层 Wind API: 历史行情获取与实时数据推送 SQLite: 本地数据存储与索引优化 数据验证: 缺失值检测、异常值过滤、时间序列对齐 交易层 CTP网关: 东方证券期货接口,支持实盘交易 订单管理: 订单验证、重复检测、撤单管理 风控系统: 保证金实时监控 最大持仓限制 单笔订单金额限制 策略层 CTA引擎: 基于vnpy_ctastrategy的策略框架 回测引擎: 支持参数优化和多策略组合 性能分析: 夏普比率、最大回撤、盈亏比、胜率等 监控层 Rich终端: 实时持仓、PnL、订单状态 日志系统: 分级日志记录和错误追踪 可视化: Plotly交互式图表 + Matplotlib静态图表 策略分类体系 量化策略按交易逻辑可分为四大类: 1. 趋势跟踪策略 核心思想: 识别趋势方向,顺势交易。 策略 信号来源 适用市场 ATR波动率突破 价格突破 + ATR过滤 趋势初期、波动率扩大 动量反转组合 短期动量 + 长期反转 趋势延续但有回调 均线交叉 快慢均线金叉/死叉 明确趋势行情 通道突破 唐奇安通道/布林带上下轨 区间震荡后的突破 国债期货特点: 趋势持续性强(政策驱动) 单日波动小,需持仓数日至数周 适合中长期趋势策略 2. 均值回归策略 核心思想: 价格偏离均值后会回归。 ...

November 15, 2025 · 3 min · LexHsu

策略解析:BasicSpreadStrategy (基础价差交易)

源码文件:vnpy_spreadtrading.strategies.basic_spread_strategy 1. 策略概述 BasicSpreadStrategy 与其说是一个自动策略,不如说是一个智能执行工具。 它不包含任何指标计算或预测逻辑,而是完全按照用户在参数中指定的固定价格进行挂单交易。它适合那些通过主观判断或外部计算得出目标价差,然后希望程序自动完成“腿A+腿B”复杂下单过程的交易员。 基类:SpreadStrategyTemplate 核心逻辑:固定点位开平 + 时间过滤 适用场景:主观套利、跨期移仓 2. 核心参数 参数名 含义 buy_price 买入开仓触发价 sell_price 卖出平仓触发价 short_price 卖出开仓触发价 cover_price 买入平仓触发价 max_pos 目标持仓量 start_time 每日开始交易时间 (如 “9:00:00”) end_time 每日停止交易时间 (如 “15:00:00”) 3. 策略逻辑详解 3.1 时间过滤器 策略首先检查当前时间是否在允许的交易时段内。如果不在,会强制停止所有正在运行的算法。 1 2 3 4 5 self.update_time = self.spread.datetime.time() if self.update_time < self.start_t or self.update_time >= self.end_t: self.stop_open_algos() self.stop_close_algos() return 3.2 状态机逻辑 策略根据当前的持仓状态 (spread_pos) 决定启动哪种算法。 空仓 (spread_pos == 0): 检查是否已启动买入算法 (buy_algoid),若无则启动。 检查是否已启动卖出算法 (short_algoid),若无则启动。 注意:这里是同时监控双向开仓机会。 持有多头 (spread_pos > 0): 停止开仓算法。 启动卖出平仓算法 (sell_algoid),目标价为 sell_price。 持有空头 (spread_pos < 0): ...

May 13, 2025 · 1 min

策略解析:StatisticalArbitrageStrategy (统计套利)

源码文件:vnpy_spreadtrading.strategies.statistical_arbitrage_strategy 1. 策略概述 StatisticalArbitrageStrategy 是一个经典的 均值回归 (Mean Reversion) 策略,应用于价差交易。 其核心假设是:两个相关性极高的品种(如豆油/棕榈油,螺纹/热卷),它们的价差会围绕一个均值波动。当价差偏离均值过大(突破布林带上轨/下轨)时,大概率会回归。 基类:SpreadStrategyTemplate 核心指标:Bollinger Bands (布林带) 交易逻辑:逆势交易(高抛低吸) 2. 核心参数 参数名 默认值 含义 boll_window 20 布林带均线周期 boll_dev 2 布林带标准差倍数 max_pos 10 最大持仓量 payup 10 算法执行时的超价跳数 interval 5 算法撤单重发间隔(秒) 3. 策略逻辑详解 3.1 K 线合成与指标计算 策略使用 BarGenerator 合成价差的 K 线(注意:是价差本身的 K 线,不是单腿的)。 在 on_spread_bar 中计算布林带: 1 2 self.boll_mid = self.am.sma(self.boll_window) self.boll_up, self.boll_down = self.am.boll(self.boll_window, self.boll_dev) 3.2 交易信号 策略逻辑非常清晰,分为三种状态: 空仓时 (spread_pos == 0): 做空价差:价差 > 上轨 (boll_up)。预期价差回归下跌。 做多价差:价差 < 下轨 (boll_down)。预期价差回归上涨。 1 2 3 4 if bar.close_price >= self.boll_up: self.start_short_algo(bar.close_price - 10, self.max_pos, ...) elif bar.close_price <= self.boll_down: self.start_long_algo(bar.close_price + 10, self.max_pos, ...) 持有空头 (spread_pos < 0): ...

May 12, 2025 · 1 min

VN.PY SpreadTrading 策略模板与通用接口详解

在进行价差交易(套利)开发前,必须理解 vnpy_spreadtrading.template 提供的基础框架。与 CTA 策略不同,价差交易涉及多条腿(Legs)的同步操作,因此引入了“算法执行”的概念。 1. SpreadStrategyTemplate:策略的大脑 所有价差策略都继承自 SpreadStrategyTemplate。 1.1 核心回调函数 回调函数 触发时机 典型用途 on_init 策略初始化 初始化变量,加载历史数据 on_start 策略启动 标记状态 on_spread_data 价差行情更新 核心逻辑区:判断价差是否满足开平仓条件 on_spread_pos 价差持仓更新 监听持仓变化,决定下一步动作 on_spread_algo 算法状态更新 监听算法执行进度(如算法完成、停止) 1.2 算法启动接口 价差交易不直接发单(不调用 buy/sell),而是启动一个算法 (Algo) 来负责执行。 这是因为买入一个价差通常意味着“买入腿A + 卖出腿B”,必须保证原子性或滑点控制。 买入价差 (Long Spread): 1 self.start_long_algo(price, volume, payup, interval, lock) price: 价差限价 volume: 数量 payup: 超价跳数(用于保证成交) interval: 撤单重发间隔 lock: 是否锁仓(针对上期所) 卖出价差 (Short Spread): 1 self.start_short_algo(price, volume, payup, interval, lock) 1.3 停止算法 stop_algo(algoid): 停止特定算法 stop_all_algos(): 停止所有正在运行的算法 2. SpreadAlgoTemplate:执行的手脚 策略只负责“决定要做什么”,而 SpreadAlgoTemplate 负责“具体怎么做”。 ...

May 11, 2025 · 1 min

策略解析:TestStrategy (功能测试工具)

源码文件:vnpy_ctastrategy.strategies.test_strategy 1. 策略概述 TestStrategy 并不是一个用于实盘获利的交易策略,而是一个调试工具。 它的主要作用是帮助开发者验证: 交易接口(Gateway)是否连接正常。 策略引擎(CtaEngine)是否能正确收发订单。 测试下单函数的执行耗时。 基类:CtaTemplate 触发机制:基于 Tick 计数,每隔 N 个 Tick 执行一个测试动作。 2. 测试流程 策略内部维护了一个函数列表 self.test_funcs,按顺序存放了要测试的动作: 市价单测试 (test_market_order): 以涨停价 (limit_up) 发出买单,模拟市价成交(在期货中通常用对手价或超价模拟市价)。 限价单测试 (test_limit_order): 以跌停价 (limit_down) 发出买单,模拟挂单(通常不会立即成交)。 全撤测试 (test_cancel_all): 调用 cancel_all() 撤销之前挂出的所有未成交订单。 停止单测试 (test_stop_order): 发出本地停止单(Stop Order),验证策略引擎的触发机制。 3. 核心代码逻辑 在 on_tick 中,每收到 test_trigger (默认10) 个 Tick,就弹出一个测试函数执行,并计算耗时。 1 2 3 4 5 6 7 8 9 10 11 self.tick_count += 1 if self.tick_count >= self.test_trigger: self.tick_count = 0 if self.test_funcs: test_func = self.test_funcs.pop(0) # 取出下一个测试任务 start = time() test_func() # 执行 time_cost = (time() - start) * 1000 # 计算耗时(ms) self.write_log(f"耗时{time_cost}毫秒") 4. 使用场景 当你刚配置好一个新的交易接口(比如连接到一个新的仿真环境),或者修改了底层引擎代码后,可以先运行这个策略: ...

May 10, 2025 · 1 min

策略解析:TurtleSignalStrategy (海龟交易法则)

源码文件:vnpy_ctastrategy.strategies.turtle_signal_strategy 1. 策略概述 TurtleSignalStrategy 是大名鼎鼎的 海龟交易法则 (Turtle Trading Rules) 的完整复现。 它不仅仅是一个简单的突破策略,而是一套完整的资金管理系统,包含了: 入场:唐奇安通道 (Donchian Channel) 突破。 仓位管理:基于 ATR (N值) 的加仓 (Pyramiding)。 止损:基于 ATR 的移动止损。 离场:反向通道突破。 基类:CtaTemplate 核心指标:Donchian Channel, ATR 复杂度:高(涉及分批加仓逻辑) 2. 核心参数 参数名 默认值 含义 entry_window 20 入场通道周期 (20日高点) exit_window 10 离场通道周期 (10日低点) atr_window 20 ATR 计算周期 3. 策略逻辑详解 3.1 信号计算 策略使用 am.donchian 计算唐奇安通道,使用 am.atr 计算波动率 N 值。 1 2 3 self.entry_up, self.entry_down = self.am.donchian(self.entry_window) # 20日 self.exit_up, self.exit_down = self.am.donchian(self.exit_window) # 10日 self.atr_value = self.am.atr(self.atr_window) 3.2 初始入场 当空仓时,在 20 日高点挂买入停止单,在 20 日低点挂卖出停止单。 ...

May 9, 2025 · 2 min

策略解析:MultiTimeframeStrategy (多周期共振)

源码文件:vnpy_ctastrategy.strategies.multi_timeframe_strategy 1. 策略概述 MultiTimeframeStrategy 展示了如何在 CTA 策略中同时处理两个不同频率的时间序列。 通常策略只关注单一 K 线周期(如 15 分钟),但本策略同时订阅并合成: 15 分钟 K 线:用于判断大趋势(Trend)。 5 分钟 K 线:用于寻找具体的入场点(Timing)。 这种“大周期定方向,小周期找买点”的方法是手工交易中非常经典的多周期共振思路。 基类:CtaTemplate 核心机制:双 BarGenerator (5m + 15m) 核心指标:MA (趋势), RSI (择时) 2. 核心参数 参数名 默认值 含义 rsi_window 14 RSI 计算周期 (基于 5 分钟) rsi_signal 20 RSI 阈值偏移 (50 ± 20) fast_window 5 快线周期 (基于 15 分钟) slow_window 20 慢线周期 (基于 15 分钟) 3. 策略逻辑详解 3.1 双周期 K 线合成 策略在 on_init 中初始化了两个 K 线生成器: ...

May 8, 2025 · 2 min

策略解析:KingKeltnerStrategy (肯特纳通道突破)

源码文件:vnpy_ctastrategy.strategies.king_keltner_strategy 1. 策略概述 KingKeltnerStrategy 是一个基于 肯特纳通道 (Keltner Channel) 的趋势突破策略。 肯特纳通道与布林带类似,都是“均线 + 带宽”的结构,但肯特纳通道使用 ATR (平均真实波幅) 来计算带宽,而不是标准差。这使得它对波动率的反应更加平滑。 基类:CtaTemplate 周期:5分钟 K 线 核心指标:Keltner Channel (MA ± N * ATR) 订单管理:OCO (One Cancels Other) —— 双向挂单 2. 核心参数 参数名 默认值 含义 kk_length 11 计算均线和 ATR 的周期 kk_dev 1.6 通道宽度倍数 (MA ± 1.6 * ATR) trailing_percent 0.8 移动止损百分比 3. 策略逻辑详解 3.1 指标计算 策略在 5 分钟 K 线 (on_5min_bar) 上计算通道。 1 self.kk_up, self.kk_down = am.keltner(self.kk_length, self.kk_dev) 上轨 = MA + 1.6 * ATR 下轨 = MA - 1.6 * ATR 3.2 入场逻辑:OCO 双向挂单 这是该策略最独特的实现细节。 当空仓时,策略同时在上方挂买入停止单,在下方挂卖出停止单。 ...

May 7, 2025 · 1 min

策略解析:DualThrustStrategy (Dual Thrust 区间突破)

源码文件:vnpy_ctastrategy.strategies.dual_thrust_strategy 1. 策略概述 DualThrustStrategy 是 Michael Chalek 在 20 世纪 80 年代开发的著名策略,曾被 Future Truth 杂志评为最赚钱的策略之一。 它是一个典型的 日内突破策略。核心逻辑是利用前 N 日(这里简化为前 1 日)的最高价、最低价、收盘价计算出一个“波动区间 (Range)”,然后以今日开盘价为锚点,加上/减去这个区间的倍数,形成上轨和下轨。 基类:CtaTemplate 核心逻辑:Range Breakout (区间突破) 交易时段:日内交易,收盘前强制平仓 2. 核心参数 参数名 默认值 含义 k1 0.4 上轨系数 (用于做多) k2 0.6 下轨系数 (用于做空) fixed_size 1 每次下单手数 注意:k1 和 k2 可以不对称。如果 k1 < k2,说明做多更容易触发,适合多头市场;反之适合空头市场。 3. 策略逻辑详解 3.1 计算 Range (波动区间) 策略在每天开盘时(检测到日期变化),利用前一日的数据计算 Range。 1 2 3 4 5 6 7 if last_bar.datetime.date() != bar.datetime.date(): if self.day_high: self.day_range = self.day_high - self.day_low # 前一日振幅 # 计算今日突破轨 self.long_entry = bar.open_price + self.k1 * self.day_range self.short_entry = bar.open_price - self.k2 * self.day_range 上轨 (Long Entry) = 今日开盘价 + K1 * 昨日振幅 下轨 (Short Entry) = 今日开盘价 - K2 * 昨日振幅 3.2 盘中突破交易 在收盘时间 (exit_time, 14:55) 之前,策略持续监控价格是否突破上下轨。 ...

May 6, 2025 · 1 min

策略解析:DoubleMaStrategy (双均线交叉)

源码文件:vnpy_ctastrategy.strategies.double_ma_strategy 1. 策略概述 DoubleMaStrategy 是量化交易中最经典的入门策略——双均线策略。 逻辑极其简单:快线向上穿过慢线(金叉)做多,快线向下穿过慢线(死叉)做空。虽然简单,但它是理解趋势跟踪逻辑的最佳起点。 基类:CtaTemplate 核心指标:SMA (Simple Moving Average) 交易方式:信号触发后立即市价(或限价)成交 2. 核心参数 参数名 默认值 含义 fast_window 10 快线周期 (如 10 日均线) slow_window 20 慢线周期 (如 20 日均线) 3. 策略逻辑详解 3.1 指标计算 策略计算了两条均线的当前值 (ma0) 和上一根 K 线的值 (ma1),用于判断交叉。 1 2 3 4 5 6 7 fast_ma = am.sma(self.fast_window, array=True) self.fast_ma0 = fast_ma[-1] # 当前 K 线快线 self.fast_ma1 = fast_ma[-2] # 上一根 K 线快线 slow_ma = am.sma(self.slow_window, array=True) self.slow_ma0 = slow_ma[-1] self.slow_ma1 = slow_ma[-2] 3.2 交叉判断 金叉 (Cross Over): 上一刻:快线 < 慢线 当前:快线 > 慢线 1 cross_over = self.fast_ma0 > self.slow_ma0 and self.fast_ma1 < self.slow_ma1 死叉 (Cross Below): ...

May 5, 2025 · 1 min