3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
您好!在 QMT 平台的回测模式下,遇到 get_trade_detail_data 获取的 order 对象部分属性(如证券名称 m_strInstrumentName、市场名称 m_strExchangeName、投资备注 m_strRemark)为空字符串,这并非您的代码错误或单纯的版本问题,而是 QMT 回测引擎的底层机制决定的。
根据 QMT 的运行机制,回测模式和实盘/模拟模式使用的是两套不同的撮合引擎:
order(委托)和 deal(成交)对象时,只保留了计算净值和回测指标最核心的数值型字段(如 m_strInstrumentID 证券代码、m_nVolumeTotalOriginal 委托量、m_dLimitPrice 委托价、买卖方向等)。对于描述性的中文字段(证券名称、市场名称)以及用户自定义的透传字段(投资备注),回测引擎通常会省略赋值,因此读取到的是空字符串。虽然回测引擎没有直接在 order 对象中填充这些属性,但我们可以通过 QMT 提供的其他 API 或 Python 的数据结构来轻松实现相同的功能。
既然 order 对象中已经有了证券代码 (m_strInstrumentID),您可以直接调用 ContextInfo.get_stock_name() 函数来动态获取证券名称。
def handlebar(ContextInfo):
# 获取委托列表
order_list = get_trade_detail_data(ContextInfo.accid, 'stock', 'order')
for order in order_list:
stock_code = order.m_strInstrumentID
# 替代方案:通过代码获取名称
stock_name = ContextInfo.get_stock_name(stock_code)
print(f"委托代码: {stock_code}, 证券名称: {stock_name}")
在回测中,如果需要追踪某笔订单的自定义备注(例如区分是哪个子策略触发的下单),建议在 ContextInfo 中维护一个全局字典,将委托号或股票代码+时间映射到您的备注信息上。
def init(ContextInfo):
ContextInfo.accid = '您的测试账号'
# 初始化一个字典用于记录投资备注
ContextInfo.order_remarks = {}
def handlebar(ContextInfo):
stock_code = '000001.SZ'
remark = '均线金叉买入策略'
# 下单
passorder(23, 1101, ContextInfo.accid, stock_code, 5, -1, 100, ContextInfo)
# 获取最新委托号并记录备注
order_id = get_last_order_id(ContextInfo.accid, 'stock', 'order')
if order_id != '-1':
ContextInfo.order_remarks[order_id] = remark
# 遍历委托对象时读取备注
order_list = get_trade_detail_data(ContextInfo.accid, 'stock', 'order')
for order in order_list:
sys_id = order.m_strOrderSysID
# 从自定义字典中获取备注,如果不存在则返回默认值
my_remark = ContextInfo.order_remarks.get(sys_id, '无备注')
print(f"委托号: {sys_id}, 投资备注: {my_remark}")
在 QMT 编写策略时,建议核心逻辑依赖于代码(Code)、价格(Price)、数量(Volume)和状态(Status)等硬核字段。对于名称、备注等辅助性字段,在回测阶段可以通过 ContextInfo 的辅助函数或全局变量自行映射解决。当您的策略切换到实盘模式时,order.m_strRemark 等字段自然就会有值了。