🚀 AI 一键生成 joinquant 策略代码
立即体验

JoinQuant 平台如何使用 StopMarketOrderStyle 设置市价止损单?(附 Python 源码)

joinquant | 发布时间: 2026/7/27
以下内容由 EasyQuant 生成。

问题描述

请根据以下 SEO 主题生成完整页面内容:

Title: joinquant 止损单设置:StopMarketOrderStyle 触发机制与实战

Question: 在 joinquant 中如何使用 StopMarketOrderStyle 设置市价止损单?

解决方案

JoinQuant 止损单设置:StopMarketOrderStyle 触发机制与实战

在量化交易中,及时止损是控制风险和保护本金的核心手段。JoinQuant(聚宽)平台提供了停止单(Stop Order)功能,其中 StopMarketOrderStyle 用于在标的价格突破设定阈值时,自动触发并转换为市价单进行委托。


一、StopMarketOrderStyle 基本概念与语法

StopMarketOrderStyleOrderStyle 的子类,通过在下单函数(如 orderorder_targetorder_valueorder_target_value)中指定 style 参数来使用。

1. 构造函数定义

StopMarketOrderStyle(mode, stop_price)

2. 参数说明

  • mode (str):
    • 'stop_loss':止损模式。
    • 'take_profit':止盈模式。
  • stop_price (float): 触发价格。当市场价格突破该价格时,停止单被激活并转为市价单委托。

二、触发机制与风控规则

1. 止损模式 (stop_loss) 与 止盈模式 (take_profit) 判定

  • 平多 / 卖出 / 开空
    • 止损模式(stop_loss):stop_price 必须小于最新价。当现价跌破 stop_price 时触发卖出。
    • 止盈模式(take_profit):stop_price 必须大于最新价。当现价涨破 stop_price 时触发卖出。
  • 平空 / 买入 / 开多
    • 止损模式(stop_loss):stop_price 必须大于最新价。当现价突破 stop_price 时触发买入。
    • 止盈模式(take_profit):stop_price 必须小于最新价。
  • 注意事项:若设置的 stop_price 不满足上述触发条件,该停止单会立即触发

2. 停止单的运行规则

  1. 不锁资金与持仓:停止单挂出时不会提前冻结账户资金或股票持仓,仅在触发转为市价单时进行验资验券。若触发时资金或持仓不足,委托将直接失败。
  2. 有效期:停止单仅在标的交易时间内生效,未触发的停止单将在当日盘后自动撤销。
  3. 按价值下单委托量计算:使用 order_valueorder_target_value 配合停止单时,实际委托数量根据 stop_price 计算:
    $$\text{实际委托数量} = \frac{\text{value}}{\text{stop_price} \times \text{保证金率} \times \text{合约乘数}}$$

三、实战代码示例:带有市价止损的均线策略

以下是一个完整的 JoinQuant 策略,演示如何在持仓后使用 StopMarketOrderStyle 设置市价止损单:

# 导入聚宽函数库
import jqdata
from jqdata import StopMarketOrderStyle

def initialize(context):
    # 设定标的为平安银行
    g.security = '000001.XSHE'
    # 设定基准
    set_benchmark('000300.XSHG')
    # 开启真实价格模式
    set_option('use_real_price', True)
    # 设定止损比例为 5%
    g.stop_loss_pct = 0.05
    # 每日定时运行
    run_daily(trade, time='9:30')

def trade(context):
    security = g.security
    # 获取过去5日收盘价
    close_data = attribute_history(security, 5, '1d', ['close'])
    ma5 = close_data['close'].mean()
    current_price = close_data['close'][-1]
    
    position = context.portfolio.positions[security]
    cash = context.portfolio.available_cash
    
    # 买入信号:当当前价格高于5日均线1%且无持仓时全仓买入
    if current_price > 1.01 * ma5 and position.total_amount == 0:
        log.info("价格高于均线1%%,执行买入: %s" % security)
        order_value(security, cash)
        
        # 计算止损价(买入价下方5%)
        stop_price = current_price * (1 - g.stop_loss_pct)
        
        # 下达市价止损单:当价格跌破 stop_price 时,清仓卖出
        order_target(
            security, 
            0, 
            style=StopMarketOrderStyle('stop_loss', stop_price)
        )
        log.info("已挂出市价止损单,触发价: %.2f" % stop_price)
        
    # 卖出信号:当价格低于5日均线时主动平仓
    elif current_price < ma5 and position.closeable_amount > 0:
        log.info("价格低于均线,主动卖出平仓: %s" % security)
        order_target(security, 0)

四、常见问题 FAQ

  1. StopMarketOrderStyleStopLimitOrderStyle 有什么区别?

    • StopMarketOrderStyle 在触发后转换为市价单(Market Order),确保快速成交;
    • StopLimitOrderStyle 在触发后转换为限价单(Limit Order),需额外指定 limit_price,能控制成交价格但存在无法成交的风险。
  2. 停止单可以跨日生效吗?

    • 不可以。 JoinQuant 每日结束时会自动撤销所有未完成的订单(包括未触发的停止单)。如果需要跨日止损,需在每日开盘(如 before_trading_startrun_daily)重新计算并挂出停止单。
  3. 为何我的停止单下单后立刻成交了?

    • 请检查 modestop_price 的逻辑关系。例如,在卖出止损(stop_loss)时,如果设定的 stop_price 高于当前市场价格,系统判断条件已满足,会立即触发委托。