🚀 AI 一键生成 qmt 策略代码

QMT 平台如何实现一篮子股票的批量下单与组合交易?

qmt | 发布时间: 2025/12/5
以下内容由 EasyQuant 生成。

问题描述

如何对一组股票进行批量的买入和卖出操作?

解决方案

在 QMT 中对一组股票进行批量买入和卖出,通常是通过 Python 的循环结构(for 循环)遍历股票列表,并针对每一个标的调用交易函数(如 order_sharesorder_valuepassorder)来实现的。

以下是一个完整的策略示例代码,展示了如何定义一个股票池,并实现“批量买入指定数量”和“批量清仓卖出”的功能。

策略代码示例

# -*- coding: gbk -*-

def init(ContextInfo):
    """
    初始化函数
    """
    # 1. 设置资金账号 (请替换为您的真实账号)
    ContextInfo.accid = '6000000000' 
    ContextInfo.set_account(ContextInfo.accid)
    
    # 2. 定义需要批量操作的股票列表
    ContextInfo.stock_list = ['600000.SH', '000001.SZ', '600519.SH']
    
    # 3. 设置一个标志位,防止在handlebar中重复下单(仅作演示用)
    ContextInfo.has_traded = False
    
    print("策略初始化完成,监控股票列表:", ContextInfo.stock_list)

def handlebar(ContextInfo):
    """
    K线周期运行函数
    """
    # 仅在最后一根K线(实时行情或回测结束点)执行,避免历史K线重复触发
    if not ContextInfo.is_last_bar():
        return

    # 示例:只执行一次
    if not ContextInfo.has_traded:
        
        # --- 执行批量买入操作 ---
        print("开始执行批量买入...")
        batch_buy(ContextInfo, ContextInfo.stock_list, 100) # 每只买入100股
        
        # --- 执行批量卖出操作 (通常根据逻辑触发,这里仅作代码展示,默认注释掉) ---
        # print("开始执行批量卖出...")
        # batch_sell_all(ContextInfo)
        
        ContextInfo.has_traded = True

def batch_buy(ContextInfo, stock_list, volume):
    """
    自定义函数:批量买入
    :param stock_list: 股票代码列表
    :param volume: 每只股票买入的股数
    """
    account_id = ContextInfo.accid
    
    for stock_code in stock_list:
        # 使用 order_shares 按股数下单
        # 参数说明: 代码, 数量, 报价类型('fix'指定价, 'LATEST'最新价), 价格(最新价模式下填-1), ContextInfo, 账号
        # 这里使用 'LATEST' 最新价下单
        order_shares(stock_code, volume, 'LATEST', -1, ContextInfo, account_id)
        print(f"已发送买入指令: {stock_code}, 数量: {volume}")

def batch_sell_all(ContextInfo):
    """
    自定义函数:批量卖出(清仓所有持仓)
    """
    account_id = ContextInfo.accid
    
    # 1. 获取当前持仓信息
    # get_trade_detail_data 获取交易明细,'STOCK'代表股票,'POSITION'代表持仓
    positions = get_trade_detail_data(account_id, 'STOCK', 'POSITION')
    
    for pos in positions:
        stock_code = pos.m_strInstrumentID + "." + pos.m_strExchangeID # 拼接代码,如 600000.SH
        can_use_volume = pos.m_nCanUseVolume # 获取可用持仓(排除冻结)
        
        if can_use_volume > 0:
            # 卖出操作,数量为负数
            order_shares(stock_code, -can_use_volume, 'LATEST', -1, ContextInfo, account_id)
            print(f"已发送卖出指令: {stock_code}, 数量: {can_use_volume}")
        else:
            print(f"股票 {stock_code} 无可用持仓,跳过卖出")

代码逻辑解析

  1. 初始化 (init):

    • 使用 ContextInfo.set_account 绑定交易账号。
    • 定义 ContextInfo.stock_list 列表,存储需要批量操作的股票代码。
  2. 批量买入 (batch_buy):

    • 接收一个股票列表。
    • 使用 for 循环遍历列表。
    • 调用 order_shares 函数进行下单。示例中使用的是 'LATEST'(最新价)模式,也可以改为 'fix'(指定价)并传入具体价格。
  3. 批量卖出 (batch_sell_all):

    • 获取持仓: 卖出前通常需要知道当前持有多少股。使用 get_trade_detail_data(..., 'POSITION') 获取当前账户的所有持仓对象。
    • 遍历持仓: 遍历返回的持仓对象列表。
    • 拼接代码: 返回的对象中,代码(InstrumentID)和市场(ExchangeID)是分开的,需要拼接成 QMT 标准格式(如 600000.SH)。
    • 检查可用: 使用 m_nCanUseVolume 属性获取可用股份(防止卖出已冻结的股份)。
    • 下单: 调用 order_shares,数量传入负数表示卖出。
  4. 执行控制 (handlebar):

    • 使用 ContextInfo.is_last_bar() 确保只在最新的行情切片上执行交易,防止在回测的历史数据加载阶段重复下单。

常用交易函数说明

在批量操作中,您可以根据需求替换 order_shares 为其他函数:

  • order_shares(code, num, ...): 按股数下单(最常用)。
  • order_value(code, value, ...): 按金额下单。例如每只股票买入 10000 元,系统会自动计算股数(向下取整到100股)。
  • order_target_percent(code, percent, ...): 按目标仓位比例下单。例如将某股票调整至总资产的 5%。

Q&A

Q: 如何控制批量下单的速度,避免瞬间发送过多请求?
A: 可以在循环中引入 Python 的 time 模块,使用 time.sleep(0.1) 来在每次下单间增加微小的延迟。但在高频交易场景下不建议阻塞主线程。

Q: 如果我想用指定价格(例如限价)批量买入怎么办?
A: 在 order_shares 函数中,将 'LATEST' 改为 'fix',并将第四个参数 -1 改为您计算出的具体价格(例如 ContextInfo.get_market_data 获取的最新价 * 0.99)。

Q: 批量卖出时,如何只卖出列表中的股票,而不是卖出账户里所有的票?
A: 在 batch_sell_all 函数的循环中增加一个判断:if stock_code in ContextInfo.stock_list:。只有当持仓的股票在您的目标列表中时,才执行卖出操作。

Q: 这种方式支持组合交易(Basket Trading)吗?
A: 上述代码是应用层的批量循环,属于最灵活的方式。QMT 底层 API (passorder) 也支持组合交易指令(如 opType=25),但配置较为复杂,通常建议使用上述 Python 循环方式,便于调试和控制单只股票的逻辑。