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