3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在量化交易中,“头七战法”(即标的跌停后,在第五个交易日寻找超跌反弹机会买入)是一种典型的逆势均值回归策略。这类策略经常面临**“高胜率、低盈亏比”**的窘境:虽然多数交易能微利止盈,但极少数持续暴跌的极端案例(如连续一字跌停、退市整理等)会产生巨大亏损,直接将策略的整体期望收益拉低至负数。
要在聚宽(JoinQuant)平台中解决这一痛点,必须从数据防真、动态止损、仓位控制三个维度进行深度优化。以下是具体的优化方案及聚宽实现代码:
set_option('use_real_price', True),回测可能会使用未来的复权因子,导致历史跌停价格不准确,产生回测幻觉。买入价 - N * ATR。对于高波动股票给予更宽的容忍度,对于低波动股票则快速止损。get_current_data() 动态过滤 ST、*ST 以及退市整理期的股票,从源头上规避连续无量一字跌停无法卖出的风险。以下代码展示了如何在聚宽中实现跌停计数、第五日买入,并结合 ATR 动态止损 + 时间硬止损 的完整逻辑:
import jqdata
import numpy as np
import talib
def initialize(context):
# 1. 开启真实价格模式,防范未来函数
set_option('use_real_price', True)
set_benchmark('000300.XSHG')
# 交易税费设置
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
# 策略参数
g.target_hold_days = 5 # 跌停后第5个交易日买入
g.max_hold_days = 3 # 买入后最大持有天数(时间止损)
g.atr_period = 14 # ATR计算周期
g.atr_multiplier = 1.5 # ATR止损倍数
g.profit_target = 0.08 # 8%止盈线
# 记录持仓信息 {stock: {'buy_price': price, 'hold_days': 0, 'stop_loss': price}}
g.tracker = {}
# 每日运行
run_daily(market_open, time='every_bar')
def before_trading_start(context):
# 过滤ST和退市股
current_data = get_current_data()
g.all_stocks = [s for s in get_all_securities(['stock'], context.current_dt).index
if not current_data[s].is_st and not current_data[s].paused]
def market_open(context):
# 1. 处理已有持仓的止盈止损
handle_exits(context)
# 2. 寻找符合“头七战法”的股票并买入
check_and_buy(context)
def handle_exits(context):
current_data = get_current_data()
positions = context.portfolio.positions
for stock in list(positions.keys()):
if stock not in g.tracker:
continue
current_price = current_data[stock].last_price
buy_price = g.tracker[stock]['buy_price']
stop_loss = g.tracker[stock]['stop_loss']
g.tracker[stock]['hold_days'] += 1
# 止损触发:跌破 ATR 动态止损线
if current_price <= stop_loss:
order_target(stock, 0)
log.info(f"[止损卖出] {stock},当前价: {current_price},止损价: {stop_loss}")
g.tracker.pop(stock, None)
continue
# 止盈触发:达到目标收益
if current_price >= buy_price * (1 + g.profit_target):
order_target(stock, 0)
log.info(f"[止盈卖出] {stock},当前价: {current_price},买入价: {buy_price}")
g.tracker.pop(stock, None)
continue
# 时间止损触发:持有超过最大天数
if g.tracker[stock]['hold_days'] >= g.max_hold_days:
order_target(stock, 0)
log.info(f"[时间止损] {stock} 持有达 {g.max_hold_days} 天,强行平仓")
g.tracker.pop(stock, None)
def check_and_buy(context):
# 避免重复买入
available_cash = context.portfolio.available_cash
if available_cash < 20000: # 剩余资金不足
return
for stock in g.all_stocks:
if stock in context.portfolio.positions:
continue
# 获取过去6天的数据(判断5天前是否跌停)
hist = attribute_history(stock, 6, '1d', ['close', 'high_limit', 'low_limit'])
if len(hist) < 6:
continue
# 5天前的K线索引为 hist.iloc[0]
was_limit_down = (hist['close'].iloc[0] <= hist['low_limit'].iloc[0] * 1.005) # 允许0.5%的误差
# 确保中间4天没有大幅反弹(维持超跌状态)
no_rebound = all(hist['close'].iloc[1:5] < hist['close'].iloc[0] * 1.05)
if was_limit_down and no_rebound:
# 计算 ATR 用于设置止损线
prices = attribute_history(stock, g.atr_period + 5, '1d', ['high', 'low', 'close'])
atr = talib.ATR(prices['high'].values, prices['low'].values, prices['close'].values, timeperiod=g.atr_period)[-1]
if np.isnan(atr):
continue
# 执行买入
current_price = get_current_data()[stock].last_price
order_value(stock, 20000) # 均分仓位,每只买入2万
# 记录买入信息与动态 ATR 止损线
g.tracker[stock] = {
'buy_price': current_price,
'hold_days': 0,
'stop_loss': current_price - (g.atr_multiplier * atr)
}
log.info(f"[头七买入] {stock},买入价: {current_price},动态止损价: {g.tracker[stock]['stop_loss']}")