大数跨境

为什么QMT回测效果好,实盘却不理想?猫哥教你看懂6个关键差异

为什么QMT回测效果好,实盘却不理想?猫哥教你看懂6个关键差异 lucky出海
2025-09-19
198
文/猫哥AI量化
ps:3500字


大家好,我是猫哥。今天跟大家聊聊QMT量化交易中一个非常重要的话题:回测和实盘的差异

前几天有一篇关于ETF动量轮动的策略,回测效果比较好,以这篇文章为例,进行演示(不构成投资建议):

回测十年26倍,ETF乖离动量轮动策略详解

相信很多朋友都有这样的经历:回测的时候策略表现亮眼,收益率杠杠的,但一上实盘就各种翻车。所以说,回测和实盘之间,是有巨大差异的,今天猫哥就把这些经验分享给大家,希望能帮大家避开一些常见的坑。

一、数据获取:回测用历史,实盘靠实时

这是最核心的差异,也是很多人容易忽视的地方。回测的时候,是用历史数据,QMT是将数据下载到本地,然后回测的时候去调用;而实盘是需要接收服务器的实时数据,两者的函数接口是不同的。

回测模式

# 回测使用本地历史数据,速度快,数据完整
price_dict = ContextInfo.get_market_data_ex(
    fields=['close'],
    stock_code=CODE_LIST,
    period='1d',
    end_time=previous_date,
    count=BIAS_N + MOMENTUM_DAY,
    dividend_type='back',
    fill_data=True,
    subscribe=False  # 重点:不订阅实时数据
)

实盘模式

# 实盘使用实时tick数据,更贴近真实情况
price_dict = ContextInfo.get_full_tick(CODE_LIST)

猫哥提醒

  • 回测时要设置subscribe=False,这样速度更快,不会影响实时行情
  • 实盘必须订阅实时数据,get_full_tick能获取最新的买卖价、成交量等信息
  • 注意数据的时效性,实盘中可能遇到停牌、临时停牌等特殊情况

二、交易执行:回测看K线,实盘抢时间

这个差异直接影响到策略的执行效果。例如在这个策略中,回测是逐个K线去运行,以开盘价成交;实盘的时候,可以指定任意时间去下单。

回测模式

def handlebar(ContextInfo):
    # 每根K线都会调用,可以模拟逐K线交易
    today = timetag_to_datetime(ContextInfo.get_bar_timetag(ContextInfo.barpos), '%Y%m%d')
    execute_rotation_trade(ContextInfo)

# 使用固定价格下单,比如开盘价
passorder(OPTYPE_BUY, ORDER_TYPE_VOLUME, ACCOUNT_ID, code,
         PRTYPE_FIXED, price, volume, STRATEGY_NAME, 0, uoi, ContextInfo)

实盘模式

# 设置定时任务,在指定时间执行
ContextInfo.run_time('execute_rotation_trade''1nDay', stg_run_time)

# 使用对手价下单,确保成交
passorder(OPTYPE_BUY, ORDER_TYPE_VOLUME, ACCOUNT_ID, code,
         PRTYPE_OPPOSITEBEST, -1, volume, STRATEGY_NAME, 1, uoi, ContextInfo)

关键差异

  • 回测用quick_trade=0(逐K线模式),实盘用quick_trade=1(立即下单)
  • 回测可以用固定价格,实盘建议用对手价确保成交
  • 实盘需要考虑开盘集合竞价、涨跌停等实际情况

三、状态管理:回测简单,实盘复杂

这是最容易被忽视,但又最重要的一个差异。实盘的时候,尽量做一下持仓隔离,区分不同策略的持仓,或者策略与手工下单的持仓。

回测模式

# 简单的全局变量就够了
strategy_state.target_holdings = []
strategy_state.current_holding = None

实盘模式

# 需要完整的文件管理系统
def init_strategy_files():
    gvar.strategy_folder = os.path.join(STRATEGY_PATH, STRATEGY_NAME)
    gvar.position_file = os.path.join(gvar.strategy_folder, 'position.json')
    gvar.tradelog_file = os.path.join(gvar.strategy_folder, 'tradelog.txt')

def save_strategy_position():
    # 持仓数据必须持久化保存
    with open(gvar.position_file, 'w', encoding='utf-8'as f:
        json.dump(gvar.strategy_position, f)

猫哥经验

  • 实盘中程序可能意外重启,持仓信息必须保存到文件
  • 要做持仓校验,防止手工干预导致的数据不一致
  • 日志文件是排查问题的重要工具,千万别省

四、订单管理:回测一步到位,实盘步步惊心

回测中的下单是理想化的,实盘中各种意外情况层出不穷。回测的时候,订单是全部成交的;但是实盘的时候,出于种种原因,可能未成交,或者部分成交,这时候就需要做相应的处理。

实盘中的复杂情况

def handle_pending_orders(ContextInfo):
    # 检查超时订单,自动撤单
    for order in order_list:
        if order.m_nOrderStatus in [未成交状态] and 超时:
            cancel(order.m_strOrderSysID, ACCOUNT_ID, ACCOUNT_TYPE, ContextInfo)

def handle_canceling_orders(ContextInfo):
    # 撤单成功后,重新下单未成交部分
    remaining_volume = order.m_nVolumeTotalOriginal - order.m_nVolumeTraded
    if remaining_volume >= 100:
        passorder(...)  # 重新下单

需要处理的情况

  • 订单超时未成交 → 撤单重新下单
  • 部分成交 → 继续等待或撤单剩余部分
  • 网络异常 → 订单状态不明,需要查询确认
  • 程序重启 → 清理历史未完成订单

五、资金管理:回测满仓,实盘要保守

回测中的时候,是直接满仓运行;实盘的时候,因为账户可能是多策略运行,或者有一些手工下单的持仓,所以需要设置给这个策略分配多少资金,或者按照总资产的一定比例去设置策略运行的金额。

回测中的理想做法

# 回测中可以基本满仓
cash = 0.999 * account.m_dAvailable
cash_per_code = cash / len(buy_list)

实盘中的现实做法

# 实盘中要设定专用资金
if ACCOUNT_MODE.upper() == 'MONEY':
    cash = 0.999 * ACCOUNT_MONEY  # 固定金额
else:
    cash = 0.999 * account.m_dBalance * ACCOUNT_RATIO  # 比例分配

实盘资金管理原则

  • 不要把所有资金都给策略用,留点备用金
  • 考虑手续费、滑点等成本,实际可用资金要打折
  • 多策略运行时,要做好资金隔离

六、异常处理:回测不用愁,实盘防万一

实盘中的异常情况比回测多得多:

def deal_callback(ContextInfo, dealInfo):
    # 成交回报处理,可能收到重复或延迟的回报
    if dealInfo.m_strTradeTime < gvar.stg_start_dt.strftime('%H%M%S'):
        return  # 过滤程序启动前的历史成交

    try:
        update_strategy_position(code, direction, volume)
    except Exception as e:
        log_info(f'处理成交回报异常: {e}')

常见异常情况

  • 网络断线重连
  • 程序意外退出重启
  • 交易所临时停牌
  • 账户余额不足
  • 价格超出涨跌停限制

七、猫哥总结

回测和实盘的差异远比表面看起来复杂。回测是在理想环境下的模拟,而实盘是在真实市场中的博弈。

几个关键建议

  1. 先回测,再实盘:任何策略都要先经过充分回测验证
  2. 小资金试错:实盘初期用小资金测试,或者使用QMT的模拟运行
  3. 完善监控:实盘中要有完善的日志和监控机制
  4. 预案准备:对各种异常情况要有预案和处理机制
  5. 持续优化:根据实盘表现不断优化策略参数

记住,量化交易不是印钞机,而是一个需要不断学习和完善的过程。希望这篇文章能帮大家在QMT量化之路上少踩一些坑!

如果这篇文章对你有帮助,记得点赞转发哦!有问题欢迎在评论区交流~

PS:策略源代码已同步知识星球,三天不满意可退款。新星球限时优惠中,后面随人数增加会随时调价。

猫哥精心整理了AI+量化的入门资料,如需可私信‘量化’获取。

想开通量化交易的朋友可联系我,备注开户或交流群一起学习。



免责声明:本内容为个人业余研究,所有股票代码和策略代码仅作示例,不构成任何投资建议。本公众号仅做知识整理,对信息的准确性及完整性不做保证,亦不用于商业用途。投资有风险,入市需谨慎。



推荐阅读:
8张图告诉你,量化是投资者最值得掌握的终身技能

国内首个开源金融K线基础模型Kronos(附教程和A股实测)

Claude Code 开发100个量化策略:全天候策略

Claude Code 开发100个量化策略:海龟交易策略

从零开始掌握 Claude Code 的Sub Agent机制,如何让AI工作效率翻倍(建议收藏)

【声明】内容源于网络
0
0
lucky出海
跨境分享圈 | 每天分享跨境干货
内容 44213
粉丝 18
lucky出海 跨境分享圈 | 每天分享跨境干货
总阅读668.0k
粉丝18
内容44.2k