3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
R-Breaker 是一种经典的日内交易策略,结合了趋势跟随(Trend)和反转(Reversal)两种逻辑。它在量化交易中非常流行,尤其适用于期货市场,也可以用于波动较大的股票。
该策略的核心在于根据前一个交易日的最高价(High)、最低价(Low)和收盘价(Close)计算出 6 个关键价位(3 个阻力位和 3 个支撑位),并结合当日盘中的价格走势来触发交易信号。
以下是基于 PTrade 框架实现的 R-Breaker 策略代码及详细说明。
基准价(Pivot):
$$Pivot = (High_{prev} + Low_{prev} + Close_{prev}) / 3$$
六个关键价位:
交易逻辑:
以下代码可以直接复制到 PTrade 的策略编辑器中运行。为了演示方便,这里以股指期货(如 IF 主连)为例,因为 R-Breaker 需要做空机制才能发挥最大效用。如果是股票,只能做多和平仓。
import numpy as np
def initialize(context):
"""
初始化函数,设置策略参数
"""
# 设置标的:这里以沪深300股指期货主力合约为例
# 如果是股票回测,请修改为具体股票代码,如 '600519.SS'
g.security = 'IF2312.CCFX'
# 设置股票池
set_universe([g.security])
# 设置手续费(根据实际情况调整,期货通常按手或万分比)
# set_commission(commission_ratio=0.0001, min_commission=5.0, type='FUTURE')
# 策略参数
g.open_position = 0 # 持仓状态:0空仓,1多仓,-1空仓
# 每日盘前计算的关键价位
g.R3 = 0 # 突破买入价
g.R2 = 0 # 反转卖出价
g.R1 = 0 # 观察卖出价
g.S1 = 0 # 观察买入价
g.S2 = 0 # 反转买入价
g.S3 = 0 # 突破卖出价
# 记录当日盘中的最高价和最低价
g.high_today = 0
g.low_today = 0
# 设定每日收盘平仓时间
run_daily(context, close_all_positions, time='14:55')
def before_trading_start(context, data):
"""
盘前处理:获取昨日数据,计算 R-Breaker 的 6 个价位
"""
# 获取过去 1 天的日线数据(不包含当天)
# 注意:get_history 返回的是 DataFrame
hist = get_history(1, frequency='1d', field=['high', 'low', 'close'], security_list=g.security, include=False)
if len(hist) > 0:
# 提取昨日数据
# 注意:get_history 返回的 DataFrame 索引可能是时间,或者是多级索引,需根据 PTrade 版本处理
# 这里假设返回的是标准 DataFrame,直接取最后一行
high_prev = hist['high'].values[-1]
low_prev = hist['low'].values[-1]
close_prev = hist['close'].values[-1]
# 计算 Pivot
pivot = (high_prev + low_prev + close_prev) / 3.0
# 计算 6 个关键价位
g.R3 = high_prev + 2 * (pivot - low_prev) # 突破买入
g.S3 = low_prev - 2 * (high_prev - pivot) # 突破卖出
g.R1 = 2 * pivot - low_prev # 观察卖出
g.S1 = 2 * pivot - high_prev # 观察买入
g.R2 = pivot + (high_prev - low_prev) # 反转卖出
g.S2 = pivot - (high_prev - low_prev) # 反转买入
# 打印日志方便调试
log.info("R-Breaker Levels for {}: R3={:.2f}, R2={:.2f}, R1={:.2f}, S1={:.2f}, S2={:.2f}, S3={:.2f}".format(
g.security, g.R3, g.R2, g.R1, g.S1, g.S2, g.S3))
# 重置当日最高最低价记录
g.high_today = 0
g.low_today = 1000000 # 设置一个极大值初始值
def handle_data(context, data):
"""
盘中处理:每分钟运行一次,判断信号并交易
"""
# 获取当前时间,如果是收盘平仓时间段则跳过逻辑
current_hour = context.blotter.current_dt.hour
current_minute = context.blotter.current_dt.minute
if current_hour == 14 and current_minute >= 55:
return
security = g.security
# 获取当前分钟的最新价、最高价、最低价
# 注意:data[security] 获取的是当前分钟 Bar 的数据
current_price = data[security]['close']
current_high = data[security]['high']
current_low = data[security]['low']
# 更新当日盘中最高价和最低价
# 如果是开盘第一分钟,直接赋值
if g.high_today == 0:
g.high_today = current_high
g.low_today = current_low
else:
g.high_today = max(g.high_today, current_high)
g.low_today = min(g.low_today, current_low)
# 获取当前持仓数量
position = get_position(security).amount
# --- 交易逻辑 ---
# 1. 趋势突破逻辑
# 突破 R3,且空仓或持有空单 -> 做多
if current_price > g.R3:
if g.open_position <= 0:
log.info("触发趋势买入信号:价格 {:.2f} > R3 {:.2f}".format(current_price, g.R3))
order_target(security, 1) # 这里的 1 代表 1手,如果是股票代表 100股,需根据实际调整
g.open_position = 1
# 跌破 S3,且空仓或持有多单 -> 做空
elif current_price < g.S3:
if g.open_position >= 0:
log.info("触发趋势卖出信号:价格 {:.2f} < S3 {:.2f}".format(current_price, g.S3))
order_target(security, -1) # -1 代表持有空单 1手
g.open_position = -1
# 2. 反转逻辑
# 做空反转:当日最高价超过 R1 (观察卖出价),且当前价格跌破 R2 (反转卖出价)
elif g.high_today > g.R1 and current_price < g.R2:
if g.open_position >= 0:
log.info("触发反转卖出信号:最高价 {:.2f} > R1, 现价 {:.2f} < R2".format(g.high_today, current_price))
order_target(security, -1)
g.open_position = -1
# 做多反转:当日最低价低于 S1 (观察买入价),且当前价格突破 S2 (反转买入价)
elif g.low_today < g.S1 and current_price > g.S2:
if g.open_position <= 0:
log.info("触发反转买入信号:最低价 {:.2f} < S1, 现价 {:.2f} > S2".format(g.low_today, current_price))
order_target(security, 1)
g.open_position = 1
def close_all_positions(context):
"""
收盘前强制平仓
"""
security = g.security
position = get_position(security).amount
if position != 0:
log.info("收盘前强制平仓")
order_target(security, 0)
g.open_position = 0
数据获取 (get_history):
before_trading_start 中调用 get_history 获取前一天的日线数据。include=False 确保不包含当天的数据,避免未来函数。盘中高低点追踪:
handle_data 中使用 g.high_today 和 g.low_today 实时更新当日的最高和最低价。交易执行 (order_target):
order_target(security, amount) 是最方便的调仓函数。amount=1 表示目标持仓为多头 1 手(或 100 股)。amount=-1 表示目标持仓为空头 1 手。amount=0 表示平仓。日内平仓:
run_daily 在 14:55 触发 close_all_positions 函数清空仓位。order_target 设为负数)。如果你在做纯股票策略,请将所有涉及做空的代码(order_target(security, -1))改为 order_target(security, 0)(仅平仓),或者删除做空逻辑。handle_data 需要在盘中实时监控价格突破情况。Q: 为什么我的策略在股票回测中报错?
A: 股票通常不能直接做空。如果代码中执行了 order_target(security, -1) 而账户没有融券权限或回测不支持融券,会报错或忽略。请将做空逻辑改为平仓逻辑。
Q: 如何在实盘中使用?
A: 实盘中需要确保 g.security 是正确的合约代码(期货合约通常有月份后缀,如 IF2312.CCFX)。此外,实盘建议增加滑点控制和订单状态检查。
Q: 可以在 tick 级别运行吗?
A: 可以。PTrade 支持 tick_data 函数。你可以将 handle_data 中的逻辑迁移到 tick_data 中,以获得更快的响应速度(3秒一次),逻辑基本一致。