🚀 AI 一键生成 joinquant 策略代码

JoinQuant 篮子下单教程:如何实现多只股票的批量同步交易?

joinquant | 发布时间: 2025/11/26
以下内容由 EasyQuant 生成。

问题描述

如何同时对一个股票列表里的所有股票进行下单操作?

解决方案

在 JoinQuant 聚宽平台上,对一个股票列表里的所有股票进行下单,主要有两种常见的方法:

  1. 使用循环遍历(推荐):通过 for 循环遍历股票列表,逐个调用下单函数(如 order_valueorder_target_value)。这种方法最灵活,适合资金分配和调仓。
  2. 使用篮子下单 API:使用 batch_submit_orders 函数。这种方法适合需要批量委托且对执行效率有特定要求的场景(如一篮子股票同时买入)。

以下是具体的代码实现示例:

方法一:使用循环遍历(最常用)

这种方法适合大多数策略,特别是需要根据资金等比例分配(Equal Weight)或调整仓位时。

# -*- coding: utf-8 -*-
def initialize(context):
    # 定义股票列表
    g.stock_list = ['000001.XSHE', '600000.XSHG', '000002.XSHE']
    # 设定基准
    set_benchmark('000300.XSHG')
    # 开启动态复权
    set_option('use_real_price', True)
    # 每天开盘时运行
    run_daily(market_open, time='09:30')

def market_open(context):
    # 获取当前可用资金
    cash = context.portfolio.available_cash
    
    # 计算每只股票分配的资金(例如:等权重分配)
    # 注意:实际交易中可能需要考虑手续费预留
    if len(g.stock_list) > 0:
        cash_per_stock = cash / len(g.stock_list)
    else:
        return

    # 遍历股票列表进行下单
    for stock in g.stock_list:
        # 过滤掉停牌的股票(可选,但推荐)
        current_data = get_current_data()
        if current_data[stock].paused:
            log.info(f"股票 {stock} 停牌,跳过下单")
            continue
            
        # 下单:按价值买入
        # order_value 会自动计算股数(向下取整到100股)
        order_value(stock, cash_per_stock)
        
        # 或者使用 order_target_value 进行调仓(调整到目标价值)
        # order_target_value(stock, cash_per_stock)
        
        log.info(f"对 {stock} 下单,金额: {cash_per_stock}")

方法二:使用 batch_submit_orders 批量下单

如果你已经计算好了每只股票需要买入的股数(amount),可以使用此 API 进行批量提交。注意,此函数需要传入具体的股数,而不是金额。

# -*- coding: utf-8 -*-
def initialize(context):
    g.stock_list = ['000001.XSHE', '600000.XSHG']
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    run_daily(trade_batch, time='09:30')

def trade_batch(context):
    orders_info = []
    
    # 假设我们要对列表里的每只股票买入 100 股
    for stock in g.stock_list:
        # 构建订单字典
        order_dict = {
            'security': stock,
            'amount': 100,       # 正数买入,负数卖出
            'style': MarketOrderStyle(), # 市价单,也可以用 LimitOrderStyle(price)
            'side': 'long'       # 多单
        }
        orders_info.append(order_dict)
    
    # 批量提交订单
    # 注意:会对每一个委托进行验资验券,若其中任一个委托校验失败,则整个委托将会失败
    if len(orders_info) > 0:
        batch_submit_orders(orders_info)
        log.info("批量订单已提交")

关键区别与建议

  1. 资金计算

    • 循环法:可以使用 order_value(按金额下单)或 order_target_value(按目标市值调仓),系统会自动根据当前股价计算需要买卖多少股,非常方便。
    • 批量法batch_submit_orders 需要传入具体的 amount(股数)。如果你只知道要买多少钱,你需要自己先获取股价,计算出股数,再构建订单字典。
  2. 容错性

    • 循环法:如果列表里某一只股票下单失败(例如资金不足或停牌),不会影响循环中后续股票的下单。
    • 批量法:根据文档,若其中任一个委托校验失败(如验资验券失败),则整个委托将会失败。

总结:对于大多数趋势跟踪、轮动或多因子策略,建议使用 方法一(循环遍历 + order_value/order_target_value,因为它处理资金分配更简单,且容错率更高。


Q&A

Q: 使用循环下单时,如何避免资金不足导致排在后面的股票买不进去?
A: 在计算 cash_per_stock 时,不要简单地用 available_cash / count。建议预留一小部分资金(例如乘以 0.98)用于支付手续费和滑点成本。即 cash_per_stock = (cash * 0.98) / len(g.stock_list)

Q: order_target_valueorder_value 有什么区别?
A: order_value(stock, 10000)买入价值 10000 元的股票(在现有持仓基础上增加)。order_target_value(stock, 10000) 是将该股票的持仓调整到 10000 元。如果当前持仓 0 元,它买入 10000;如果当前持仓 15000 元,它会卖出 5000 元。做定期调仓策略时,通常使用 order_target_value

Q: 批量下单 batch_submit_orders 支持限价单吗?
A: 支持。在构建订单字典时,将 'style' 字段设置为 LimitOrderStyle(price) 即可,其中 price 是你指定的限价价格。