🚀 AI 一键生成 joinquant 策略代码

如何在 JoinQuant 中编写分级止盈与超时清仓策略?

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

问题描述

如果想在5天内分级止盈,按不同价格卖出部分股票,该怎么实现??需要加一个计时器吗?

我想测试下一个策略,但是不太会写卖出策略。想求教下:
比如:我买了“平安银行”的100手股票,然后要在5天内卖完。我要每10分钟获取下当前时间,如果高于买入价格的1.3倍,就买10手,如果高于1.5倍就卖30手,如果高于1.8倍就卖80手,如果高于2倍,就卖完100手。持有到了5天,不管价格如何,就全都抛出。
请问大家能不能给我指点下???非常感谢!!

解决方案

在 JoinQuant(聚宽)平台上实现这种分级止盈超时强制清仓的策略,不需要额外引入外部的计时器。你可以直接使用分钟级回测,并在 handle_data 函数中通过判断当前时间的分钟数(如 context.current_dt.minute % 10 == 0)来实现每 10 分钟检查一次的逻辑。

下面是为你编写的完整策略代码示例。代码中包含了初始买入、每 10 分钟监控价格、阶梯式卖出以及持有满 5 个交易日强制清仓的逻辑。

Python 策略源码

import jqdata

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    # 设置手续费
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 定义全局变量
    g.security = '000001.XSHE'  # 平安银行
    g.buy_price = 0             # 记录买入价格
    g.buy_date = None           # 记录买入日期
    g.has_bought = False        # 是否已经初始买入
    
    # 记录各阶梯是否已经触发过,防止重复卖出
    g.level_1_3_triggered = False
    g.level_1_5_triggered = False
    g.level_1_8_triggered = False

def handle_data(context, data):
    dt = context.current_dt
    
    # 1. 初始买入逻辑(仅作为测试,在策略启动的第一天买入100手)
    if not g.has_bought:
        # 100手 = 10000股
        order(g.security, 10000)
        g.buy_price = data[g.security].close
        g.buy_date = dt.date()
        g.has_bought = True
        log.info("【初始建仓】买入 %s 100手,买入价: %.2f" % (g.security, g.buy_price))
        return
        
    # 2. 每10分钟执行一次检查 (例如 9:30, 9:40, 9:50...)
    if dt.minute % 10 != 0:
        return
        
    # 获取当前持仓
    position = context.portfolio.positions[g.security]
    
    # 如果还有可用持仓,则进行止盈和清仓判断
    if position.closeable_amount > 0:
        current_price = data[g.security].close
        
        # 计算持有天数(按交易日计算)
        trade_days = get_trade_days(start_date=g.buy_date, end_date=dt.date())
        days_held = len(trade_days) - 1
        
        # 3. 超时清仓逻辑:持有达到或超过5天,全部抛出
        if days_held >= 5:
            order_target(g.security, 0)
            log.info("【超时清仓】持有达到5天,全部清仓!当前价格: %.2f" % current_price)
            return
            
        # 4. 分级止盈逻辑
        # 注意:从最高倍数开始判断,满足条件即执行
        if current_price >= 2.0 * g.buy_price:
            order_target(g.security, 0)
            log.info("【分级止盈】价格超过2倍,全部清仓!当前价格: %.2f" % current_price)
            
        elif current_price >= 1.8 * g.buy_price and not g.level_1_8_triggered:
            # 卖出80手(8000股),如果持仓不足8000股,系统会自动按最大可卖数量卖出
            order(g.security, -8000)
            g.level_1_8_triggered = True
            log.info("【分级止盈】价格超过1.8倍,卖出80手。当前价格: %.2f" % current_price)
            
        elif current_price >= 1.5 * g.buy_price and not g.level_1_5_triggered:
            # 卖出30手(3000股)
            order(g.security, -3000)
            g.level_1_5_triggered = True
            log.info("【分级止盈】价格超过1.5倍,卖出30手。当前价格: %.2f" % current_price)
            
        elif current_price >= 1.3 * g.buy_price and not g.level_1_3_triggered:
            # 卖出10手(1000股)
            order(g.security, -1000)
            g.level_1_3_triggered = True
            log.info("【分级止盈】价格超过1.3倍,卖出10手。当前价格: %.2f" % current_price)

策略原理解析

  1. 运行频率设置:在聚宽的回测界面,请务必将运行频率设置为“分钟”。这样 handle_data 才会每分钟被调用一次。
  2. 每 10 分钟触发:通过 if dt.minute % 10 != 0: return 这行代码,过滤掉了不符合条件的分钟,使得核心的卖出判断逻辑严格按照每 10 分钟执行一次。
  3. 持有天数计算:使用了聚宽 API get_trade_days() 来获取买入日到当前日期的交易日列表,从而准确计算出持有了几个交易日,避免了周末和节假日带来的干扰。
  4. 阶梯触发标志位:使用了 g.level_1_3_triggered 等布尔变量。这是为了防止在价格持续高于 1.3 倍时,每 10 分钟都重复卖出 10 手。触发一次后将其置为 True 即可。
  5. 卖出数量限制:聚宽的 order(security, amount) 函数在执行卖出(负数)时,如果指定的卖出数量大于当前实际可用持仓,系统会自动将其调整为卖出全部可用持仓,因此不用担心“超卖”报错。