
在量化交易领域从策略构思到实盘执行之间往往横亘着一条技术鸿沟。许多交易者熟悉Python和策略逻辑却对如何将代码安全、稳定、合规地部署到券商交易系统感到无从下手。迅投QMTQuantitative Market Trading正是为了解决这一痛点而设计的券商端量化实盘交易系统它通过提供内置的Python环境、策略编写框架和风控接口让开发者能够在一个受控的环境内直接运行自动化交易程序。本文面向已经具备基础Python编程能力并希望将个人交易策略转化为实盘操作的投资者。我们将以一个完整的流程从零开始讲解如何在QMT中搭建策略开发环境、编写一个简单的双均线策略、进行历史回测并最终部署到模拟或实盘环境中。整个过程将聚焦于QMT的核心使用逻辑、常见陷阱以及从开发到实盘必须关注的工程细节确保你能获得一个可复现、可排查、可直接用于实战的指南。1. 理解迅投QMT定位、架构与核心概念在开始安装和编码之前必须先理解QMT是什么以及它在整个量化交易链条中扮演的角色。这有助于你建立正确的预期并理解后续所有操作的设计原理。1.1 QMT的定位券商端的策略执行容器QMT并非一个独立的、像Backtrader或Zipline那样的开源回测框架。它是由券商如中信建投、国金证券等提供给合格投资者的客户端实盘交易软件。其核心定位是一个策略执行容器和交易网关。策略执行容器它提供了一个内置的Python解释器通常是特定版本如Python 3.6/3.7和一系列预装的量化库如numpy,pandas。你的策略代码在这个容器内运行保证了运行环境的一致性并隔离了策略对本地系统的潜在影响。交易网关它封装了券商交易系统的底层协议如柜台API提供了标准化的Python函数如order_volume,get_market_data供你调用。你无需关心如何连接柜台、如何维护心跳、如何打包订单报文只需调用这些函数即可完成下单、撤单、查询等操作。这种设计带来了一个关键约束你的策略开发和运行环境被锁定在QMT客户端内。你不能随意使用pip install安装任意第三方库也不能直接操作本地文件系统有特定限制。理解这一点是避免后续无数坑的第一步。1.2 QMT的核心工作流程从事件驱动到订单流QMT的策略模型通常是事件驱动型。你的策略主函数会被系统在特定事件如行情推送、定时器触发下回调。一个典型的策略生命周期包含以下环节初始化 (initialize): 策略启动时执行一次用于订阅行情、设置定时器、初始化全局变量。事件处理 (handle_data): 当订阅的行情到达或定时器触发时此函数被调用。在这里编写你的核心交易逻辑计算指标、判断买卖点。订单管理: 在事件处理函数中根据逻辑调用下单函数。QMT会管理订单状态已报、已成、部成、已撤等。风险控制: QMT客户端和券商服务器端均设有风控如单笔最大金额、持仓比例、撤单频率等。你的策略也需要考虑自身的逻辑风控。日志与监控: 通过print或日志函数输出信息到QMT的日志窗口这是你排查策略问题的唯一途径。整个订单流为你的策略逻辑 - 调用QMT的order_volumeAPI - QMT客户端风控 - 券商柜台风控 - 交易所。1.3 关键对象与API速览在编码前需要熟悉几个最核心的对象和函数ContextInfo: 上下文对象通常作为参数传入事件处理函数。它包含了当前时间、账户信息、持仓数据等。在策略中常以context命名。get_market_data: 获取历史行情数据的函数。这是策略进行指标计算的基础。order_volume: 按数量下单函数。你需要指定证券代码、买卖方向、订单类型市价/限价、数量等。get_portfolio: 获取当前账户的持仓、资金信息。订阅行情: 通过subscribe_quote或类似函数告诉QMT你需要实时接收哪些标的的行情。2. 环境准备与策略创建假设你已通过券商开通了QMT权限并成功安装了客户端软件。不同券商的QMT界面可能略有差异但核心功能模块一致。2.1 客户端界面与策略编辑器启动QMT后你需要找到“量化策略”或“策略交易”相关模块。通常会有以下几个关键子模块策略列表/管理: 查看、创建、编辑、删除策略。策略编辑器: 一个内置的代码编辑器可能功能较简单用于编写和修改Python策略文件。回测模块: 提供界面化参数用于对策略进行历史数据回测并生成绩效报告。实盘监控: 查看正在运行的实盘策略状态、日志、订单和持仓。第一步是创建一个新的策略。点击“新建策略”系统会提示你选择策略类型如Python策略、输入策略名称并生成一个基础的策略模板文件通常是一个.py文件。2.2 理解策略模板结构QMT生成的策略模板是你学习的起点。一个典型的模板如下所示# codingutf-8 from qmt import * import pandas as pd import numpy as np # 策略初始化函数只在策略启动时执行一次 def initialize(context): 初始化函数设定基准、交易费用、滑点等。 # 设置基准合约用于回测分析 set_benchmark(‘000300.SH‘) # 沪深300指数 # 设置交易费用印花税卖出收取佣金双边收取 set_commission(open_tax0, close_tax0.001, open_commission0.0003, close_commission0.0003, close_today_commission0, min_commission5) # 设置滑点单位价格最小变动单位 set_slippage(0.01) # 订阅行情这里订阅了沪深300指数的1分钟K线 subscribe_quote(‘000300.SH‘, ‘1m‘) # 设置定时任务每天开盘后运行这里只是示例具体时间需调整 # run_daily(market_open, time‘09:35‘) # 行情事件处理函数每次订阅的行情更新都会触发 def handle_data(context): 核心交易逻辑。 context: 上下文对象包含账户、时间等信息。 # 获取当前时间 now context.now symbol ‘000300.SH‘ # 获取历史数据用于计算指标 # 获取最近100根1分钟K线 hist_data get_market_data([‘close‘], symbol, ‘1m‘, 100) if hist_data is None or len(hist_data) 100: # 数据不足不进行交易 return close_prices hist_data[‘close‘].values # 计算简单移动平均线 ma_short np.mean(close_prices[-10:]) # 10周期均线 ma_long np.mean(close_prices[-30:]) # 30周期均线 # 获取当前持仓 portfolio get_portfolio() position portfolio.get(symbol, 0) # 获取该标的的持仓数量默认为0 # 双均线策略逻辑 if ma_short ma_long and position 0: # 短线上穿长线且当前无持仓或空仓执行买入 # 计算可买数量示例使用可用资金的50% cash portfolio[‘available_cash‘] last_price close_prices[-1] volume_to_buy int((cash * 0.5) / last_price / 100) * 100 # 按手数100股取整 if volume_to_buy 0: order_volume(symbol, volume_to_buy, side‘buy‘, order_typeOrderType.Market) print(f‘{now} 买入 {symbol} {volume_to_buy}股短均{ma_short:.2f}长均{ma_long:.2f}‘) elif ma_short ma_long and position 0: # 短线下穿长线且当前有持仓执行卖出 order_volume(symbol, position, side‘sell‘, order_typeOrderType.Market) print(f‘{now} 卖出 {symbol} {position}股短均{ma_short:.2f}长均{ma_long:.2f}‘) # 其他情况持仓不动 # 定时任务函数示例 def market_open(context): 每天开盘后执行的任务 print(‘市场开盘‘, context.now)关键点解释initialize(context): 这是你的策略配置中心。除了设置基准和费用最重要的是在这里订阅行情和设置定时器。订阅错误或频率过高会影响性能。handle_data(context): 这是策略的“心脏”。它被行情事件反复调用。所有获取数据、计算指标、判断买卖、下单的操作都应在此函数或其调用的函数中完成。注意函数体内部必须高效避免复杂循环否则可能错过行情事件。get_market_data: 注意其参数。[‘close‘]表示获取哪些字段开盘open、最高high等。100是获取的K线数量。确保获取的数据量足够你计算最长的指标例如计算30日均线至少需要30根K线。order_volume:side参数可以是‘buy‘或‘sell‘。OrderType.Market是市价单还有OrderType.Limit限价单。实盘中慎用市价单尤其是在流动性差的标的。打印日志print语句是调试和监控策略运行的唯一可靠手段。务必在关键逻辑点如开仓、平仓、遇到异常打印信息。2.3 依赖管理与模块导入QMT内置了常见的科学计算库但版本可能较旧。切勿尝试在策略代码中使用pip install。如果你需要某个特定库如ta-lib用于技术指标通常需要联系券商客服询问是否支持安装。或将库的纯Python源码文件.py直接放在策略同一目录下通过import导入。但这仅适用于不依赖C扩展的纯Python库。更安全的做法是尽量使用QMT已内置的numpy和pandas来实现计算逻辑。例如上面的双均线就是用np.mean手动计算的。3. 策略回测验证逻辑与调整参数在投入实盘前必须进行充分的历史回测。QMT的回测引擎会将你的策略代码在指定的历史时间段内模拟事件驱动的方式运行一遍。3.1 回测配置要点在回测界面你需要配置以下关键参数参数项说明与注意事项回测时间范围选择足够长的周期应包含牛市、熊市、震荡市。避免过拟合某个特定阶段。初始资金设置与计划实盘资金量级相当的金额。回测中的复利效应会影响结果。行情频率与策略中subscribe_quote的频率一致。例如策略基于1分钟K线这里就选1分钟。回测精度越高如tick级速度越慢。复权方式股票策略通常选择“后复权”以消除分红送股对价格的影响。手续费与滑点务必与initialize函数中set_commission和set_slippage的设置保持一致或者直接在回测界面设置让系统覆盖代码中的设置。这是回测是否接近现实的关键。3.2 分析回测报告回测完成后QMT会生成一份报告。你需要重点关注以下指标而不仅仅是总收益率年化收益率 / 总收益率: 策略的赚钱能力。最大回撤: 资产从峰值到谷底的最大跌幅。这是衡量策略风险承受能力的最重要指标之一。一个高收益但回撤超过50%的策略实盘中很难坚持。夏普比率: 衡量每承受一单位风险能获得多少超额回报。通常大于1为可接受大于2为优秀。胜率: 盈利交易次数占总交易次数的比例。高频策略可能胜率低但盈亏比高趋势策略可能胜率高。交易次数: 过于频繁的交易可能导致收益被手续费侵蚀过于稀疏的交易可能样本不足策略稳定性存疑。收益曲线: 观察曲线是否平滑上升。剧烈震荡或长期横盘的曲线需要警惕。回测的局限性回测是“过去已知信息”的模拟无法预测未来。它无法模拟市场冲击、流动性枯竭、极端行情下的订单成交情况尤其是限价单。因此回测成功只是实盘的必要不充分条件。3.3 参数优化与过拟合陷阱你可能会想调整双均线策略中的周期参数如将10/30改为5/20。QMT可能提供参数优化功能。但必须警惕过拟合即策略参数在历史数据上表现完美但仅仅是因为巧合地“拟合”了历史噪声在未来实盘中失效。避免过拟合的实践样本外测试将历史数据分为两部分一部分如70%用于参数优化训练集另一部分30%用于验证优化后的策略测试集。确保策略在测试集上依然有效。参数敏感性分析观察策略绩效在参数小幅变动时是否剧烈变化。如果变化剧烈说明策略不稳定过拟合风险高。保持策略逻辑简单复杂的策略有更多参数更容易过拟合。先从简单的经典策略如双均线、海龟开始理解市场。4. 模拟交易与实盘部署回测通过后切勿直接投入实盘。模拟交易Paper Trading是连接回测和实盘的桥梁。4.1 模拟交易的重要性模拟交易使用实时的行情数据和模拟的订单簿来运行你的策略。它与回测的关键区别在于实时性检验策略事件处理逻辑在真实时间流下的性能是否有延迟、丢事件。订单成交模拟检验你的下单价格、数量在模拟的实时盘口下能否成交这对于限价单策略至关重要。系统稳定性长时间运行数日甚至数周观察策略是否存在内存泄漏、逻辑错误累积等问题。在QMT中通常有独立的“模拟交易”账户或模式。用模拟账户运行你的策略至少一到两周完整经历多个交易日。4.2 部署实盘前的最终检查清单当模拟交易表现稳定后可以准备实盘。以下是一份部署前检查清单检查类别具体项目代码逻辑1. 确认所有print日志清晰可读能反映策略状态。2. 确认异常处理完善如get_market_data返回None。3. 确认没有使用未来函数例如在handle_data中使用了当前K线还未收盘的最高价。4. 确认仓位计算、资金计算逻辑正确无整数溢出或除零风险。风险控制1. 策略内部是否有最大持仓比例、单笔最大亏损止损2. 是否考虑了交易费用和滑点对盈利的侵蚀3. 是否设置了每日最大交易次数或交易金额限制运行环境1. 运行QMT的电脑是否稳定、网络是否可靠是否设置了断电、断网重启机制2. QMT客户端版本是否最新是否有已知bug3. 策略文件的路径是否固定是否会因误操作被移动或重命名账户与合规1. 实盘账户资金是否足额2. 所交易标的是否在账户权限范围内如创业板、科创板需额外开通3. 策略交易频率是否可能触发交易所的异常交易监管4.3 启动实盘与监控小资金试运行首次实盘使用极小一部分资金例如计划资金的10%。运行至少一个完整周期对于趋势策略可能是几周甚至一个月。严密监控实盘初期必须人工盯盘。关注QMT的日志输出、订单状态、成交回报是否与预期一致。对比策略信号与实际行情。记录交易日志不仅依赖QMT的打印日志建议策略自动将关键事件信号产生、订单发出、成交回报记录到文件如果QMT文件权限允许或至少定期截图保存。5. 常见问题排查与调试技巧在QMT中开发策略你一定会遇到各种问题。以下是典型问题的排查路径。5.1 策略不触发交易现象策略运行无报错但始终不发出订单。排查步骤查日志检查initialize和handle_data函数中的print是否正常输出。如果没有说明策略可能未正确启动或事件未触发。查订阅确认initialize中subscribe_quote的标的代码和周期是否正确。错误的代码会导致handle_data不被触发。查数据在handle_data开头打印get_market_data返回的数据形状和最新值。确认数据不为空且长度足够计算指标。查逻辑条件打印计算出的指标值如ma_short,ma_long和当前持仓position。确认你的买卖条件if ma_short ma_long在历史时点是否真的满足。查风控是否因为可用资金不足、不在交易时间段内、标的停牌等原因被QMT或券商的风控拦截检查账户状态和标的交易状态。5.2 订单状态异常现象订单长时间处于“已报”状态未成交或立即变成“已撤”、“废单”。排查步骤查订单类型如果是限价单OrderType.Limit你的报价是否偏离市价太远打印下单时的价格和当时的市价进行对比。查市场流动性对于小盘股或非活跃合约盘口买卖价差大市价单或限价单都可能难以成交。查数量下单数量是否小于最小交易单位A股为100股是否因为资金不足导致部分成交查规则是否触发了交易所的涨跌停板限制、T1规则对于股票查回报QMT的订单列表和成交列表会显示详细状态和原因。仔细阅读“备注”或“状态说明”字段。5.3 策略运行缓慢或卡顿现象日志输出间隔变长行情响应延迟。排查步骤查数据量是否在handle_data中请求了过长的历史数据例如get_market_data(..., count10000)或者订阅了过多标的的过高频率行情减少数据请求范围和频率。查循环计算是否在handle_data中使用了低效的Python循环进行计算尽量使用numpy和pandas的向量化操作。查外部调用策略是否尝试访问网络或本地大型文件这在QMT环境中可能被限制或极慢。清空策略创建一个最简单的、只打印时间的策略看是否依然卡顿。如果是可能是QMT客户端本身或电脑资源问题。5.4 回测与实盘业绩差异巨大这是量化交易中最常见也最棘手的问题。除了过拟合还有以下原因差异原因回测中的假设实盘中的现实应对措施成交价格通常以K线收盘价或均价成交忽略盘口。市价单成交在买一/卖一限价单可能无法成交。回测中加入滑点模型。实盘优先使用限价单并考虑订单簿深度。交易费用使用固定费率计算。有最低佣金如5元印花税仅卖出收取。在set_commission中精确设置并考虑最低佣金的影响。数据质量使用清洗过的后复权数据。实时行情有噪声、断点、快照延迟。模拟交易验证。策略逻辑对数据噪声要有鲁棒性。市场冲击忽略自身交易对市场的影响。大额订单会推动价格产生冲击成本。大资金策略需拆分订单使用TWAP/VWAP算法。6. 进阶实践与策略优化建议当你的第一个策略稳定运行后可以考虑以下方向进行深化。6.1 策略组件化与代码复用不要将所有逻辑都堆在handle_data里。将功能模块化data_manager.py: 封装数据获取和清洗逻辑。indicator_calculator.py: 封装所有技术指标计算。risk_manager.py: 封装风控逻辑如止损、止盈、仓位控制。order_executor.py: 封装下单、撤单、订单状态查询逻辑。在主策略文件中import这些模块。这样不仅代码清晰也便于单独测试和复用组件。6.2 实现更稳健的风控基础风控包括仓位风控单标的持仓上限、总仓位上限。止损风控基于亏损金额或亏损比例的硬止损。交易频率风控单位时间内最大交易次数防止程序失控。时间风控避免在开盘、收盘等波动剧烈时段交易或设定每日自动清仓时间。这些风控应作为独立模块在每次下单前被调用检查。6.3 策略性能分析除了QMT提供的报告可以自己记录更详细的交易记录用于深入分析每笔交易的盈亏分析盈利交易和亏损交易的分布。持仓时间策略是短线还是长线持仓时间与胜率、盈亏比的关系。市场状态适应性策略在上涨、下跌、震荡市中表现如何是否需要根据市场状态切换参数或开关策略6.4 关于“未来函数”与模型量化在搜索热词中出现了“.onnx量化int8”和“模型量化”这指的是深度学习模型的压缩技术与交易策略的“未来函数”是两回事但容易混淆。未来函数 (Look-ahead Bias)在策略中使用了在交易当时还无法知道的信息。例如在handle_data处理09:31的K线时使用了09:31这根K线的收盘价该价格在09:31这一刻并未确定。这是策略开发的大忌必须杜绝。确保所有计算使用的数据都是已经发生的、闭合的K线。模型量化 (Model Quantization)指将深度学习模型的权重从高精度如FP32转换为低精度如INT8以减小模型体积、提升推理速度。这在将AI模型部署到资源受限的设备时常用。这与金融量化交易无直接关系。在QMT中运行复杂的深度学习模型通常是不现实的应专注于逻辑清晰的规则型策略。从入门到熟练使用QMT进行实盘交易核心在于转变思维从“写出能跑的策略”到“写出能在生产环境稳定运行的策略”。这要求开发者不仅关注策略逻辑本身更要深刻理解交易系统的运行机制、风险所在以及如何通过工程化的方法如模块化、日志、风控、监控来管理不确定性。建议从最小化的策略开始每增加一个功能都经过回测、模拟、小实盘的完整验证循环逐步构建你对系统和市场的认知。