halo 的技术博客

返回

从回测到实盘:量化策略的”最后一公里”#

无数量化研究员在回测中取得了令人瞩目的夏普比率,却在实盘上线后发现业绩大幅缩水。其中的罪魁祸首往往不是策略逻辑本身,而是交易执行环节的隐形成本

一个完善的实盘交易系统,需要将策略信号转化为实际收益,这个过程涉及:

  • 订单生成:如何将阿尔法信号转化为具体订单
  • 交易执行:如何以最优价格成交
  • 滑点控制:如何应对市场冲击和流动性风险
  • 订单管理:如何处理部分成交、撤单、异常

本文将深入探讨实盘交易系统的核心模块,帮你跨越”回测完美、实盘拉胯”的鸿沟。

交易执行架构:从信号到成交的完整链路#

1. 订单生成的三个层次#

实盘交易系统的第一环是将策略信号转化为可执行订单。这需要分层次处理:

层次一:信号标准化

# 将不同策略的信号统一为标准格式
class Signal:
    symbol: str          # 股票代码
    direction: int       # 1买入, -1卖出, 0平仓
    strength: float      # 信号强度 (0-1)
    timeframe: str      # 持有周期
    strategy_id: str    # 策略标识
python

层次二:组合优化 多个策略的信号需要聚合,通过风险模型计算目标仓位:

  • 市值加权 vs 等权 vs 风险平价
  • 单票仓位上限(如不超过5%)
  • 行业/风格暴露约束

层次三:订单切分 大单需要切分为小单,避免市场冲击:

def split_order(total_quantity, avg_daily_volume):
    """根据流动性切分订单"""
    max_participation = 0.1  # 最大参与率10%
    max_single_order = avg_daily_volume * max_participation / 20
    
    if total_quantity <= max_single_order:
        return [total_quantity]
    else:
        num_splits = math.ceil(total_quantity / max_single_order)
        base_size = total_quantity // num_splits
        remainder = total_quantity % num_splits
        return [base_size + 1] * remainder + [base_size] * (num_splits - remainder)
python

2. 执行算法:VWAP与TWAP的实战应用#

TWAP (Time Weighted Average Price)

  • 在固定时间间隔内均匀下单
  • 适合流动性好的大盘股
  • 实现简单,但无法适应市场变化

VWAP (Volume Weighted Average Price)

  • 根据成交量分布下单(开盘、收盘成交量大)
  • 更适合A股的”开盘抢筹、收盘偷袭”特性
  • 需要预测当日成交量分布

POV (Percentage of Volume)

  • 按照市场成交量的固定比例参与
  • 动态调整下单速度,流动性差时自动减速
  • 机构最常用的执行算法

交易执行算法对比

图1:TWAP、VWAP、POV三种执行算法的优劣势对比

滑点控制:量化实盘的最大隐形成本#

什么是滑点(Slippage)?#

滑点 = 实际成交价 - 信号触发价

正向滑点:成交价比你预期的更好(幸运) 负向滑点:成交价比你预期的更差(悲剧)

在A股市场,负向滑点尤为严重:

  • 涨停板抢筹:滑点可达2-5%
  • 跌停板出逃:滑点可达3-7%
  • 小盘股交易:流动性不足导致滑点1-3%

滑点的四大来源#

  1. 延迟滑点

    • 行情延迟:券商行情比交易所慢100-500ms
    • 决策延迟:策略计算需要时间
    • 下单延迟:从发单到交易所需要时间
  2. 市场冲击

    • 你的订单改变了买卖盘口
    • 大单吃掉流动性,推价格朝不利方向走
    • 回归分析:订单规模 vs 价格影响
  3. 逆选择(Adverse Selection)

    • 你以为在买便宜货,其实是”接飞刀”
    • 信息不对称:大资金提前知道坏消息
    • 解决方法:避免交易异常放量个股
  4. 流动性黑洞

    • 极端行情下,买一卖一盘口消失
    • 2015年股灾、2016年熔断都出现过
    • 必须对流动性实时监控

滑点控制的实战技巧#

技巧1:智能路由

def smart_order_routing(symbol, quantity, side):
    """智能选择交易通道"""
    # 1. 检查多个交易通道的延迟和费用
    routes = [
        {'channel': 'exchange_direct', 'latency': 5, 'cost': 0.0001},
        {'channel': 'broker_1', 'latency': 15, 'cost': 0.0002},
        {'channel': 'broker_2', 'latency': 20, 'cost': 0.00015},
    ]
    
    # 2. 根据策略类型选择
    if strategy_type == 'high_frequency':
        return min(routes, key=lambda x: x['latency'])
    else:
        return min(routes, key=lambda x: x['cost'])
python

技巧2:限价单 vs 市价单的动态选择

  • 流动性好时(买一卖一价差≤2档):用市价单快速成交
  • 流动性差时:用限价单,避免滑点过大
  • 盘口深度监控:如果买一有100手,你只买10手,滑点很小

技巧3:盘口预测 利用机器学习预测未来1-5秒的盘口变化:

  • 特征:当前买卖盘口、成交量、大单流入
  • 模型:LightGBM或简单LSTM
  • 输出:未来价格变动方向和幅度
  • 应用:预测价格上涨,推迟买入;预测价格下跌,加速卖出

技巧4:交易时间选择

  • 开盘前15分钟:波动大,滑点高,避免交易
  • 收盘前15分钟:机构调仓,滑点高,谨慎交易
  • 最佳时段:10:30-11:30, 14:00-14:30(流动性稳定)

滑点成本分析

图2:不同订单规模和市场环境下的滑点成本分析

订单管理系统(OMS):实盘交易的”中枢神经系统”#

OMS的核心功能#

一个成熟的订单管理系统需要处理以下场景:

1. 订单状态管理

订单生命周期:
待提交 → 已提交 → 部分成交 → 全部成交

         已撤单/拒单
plaintext

每个状态转换都需要记录:

  • 时间戳(精确到毫秒)
  • 交易所返回的委托号
  • 成交数量、价格、手续费

2. 异常处理 实盘环境充满意外:

  • 网络断开:需要重连后查询订单状态
  • 交易所拒单:价格超出涨跌幅、仓位不足
  • 部分成交:原计划买1000手,只成交500手,怎么办?

3. 风控拦截 在订单发出前进行最后检查:

实盘交易系统搭建:交易执行、滑点控制与订单管理全解析
https://blog.halo26812.eu.org/blog/2026-06-15-execution-slippage-control
Author halo
Published at 2026年6月15日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨