策略简介
R-Breaker是一种短线日内交易策略,该策略已经在市场上存活了二十年之久,尤其当指数波动较大时,该策略表现越好,根据S&P至2011年底的统计,R-Break也多次名列前十,由于进入榜单的交易系统业绩并不稳定,尤其是一年业绩榜单,时常会发生变化,因此模型的稳定性和一致性其实比短期排名更加关键,杂志给出了长期来看一致性最好的十大交易模型,其中就包括 R-Breaker 等模型,它们的业绩不一定总是能排进前十名的榜单,但长期以来具有较高的一致性。
前十大S&P 交易系统排名 | |
排名交易系统名称 | 年收益率 % |
1 FT Classic | 107.30% |
2 TSL_SP_1.0Z | 76.90% |
3 TSL_CEL_SP1 | 74.50% |
4 Keystone | 54.10% |
5 Impetus SP | 50.50% |
6 Big Blue 2 | 49.60% |
7 Strategic 500 | 45.50% |
8 STC SP Daytrader | 42.00% |
9 R-Breaker | 37.10% |
10 %C Daybreaker | 36.30% |
资料来源:https://blog.csdn.net/The_Time_Runner/article/details/88762963
策略的基本原理
- 根据前一个交易日的收盘价、最高价和最低价数据通过一定方式计算出六个价位,从大到小依次为:突破买入价、观察卖出价、反转卖出价、反转买入、观察买入价、突破卖出价。以此来形成当前交易日盘中交易的触发条件。(策略源码在文章最后)
def get_index_line(klines): '''计算指标线''' high = klines.high.iloc[-2] # 前一日的最高价 low = klines.low.iloc[-2] # 前一日的最低价 close = klines.close.iloc[-2] # 前一日的收盘价 pivot = (high + low + close) / 3 # 枢轴点 bBreak = high + 2 * (pivot - low) # 突破买入价 sSetup = pivot + (high - low) # 观察卖出价 sEnter = 2 * pivot - low # 反转卖出价 bEnter = 2 * pivot - high # 反转买入价 bSetup = pivot - (high - low) # 观察买入价 sBreak = low - 2 * (high - pivot) # 突破卖出价 print("已计算新标志线, 枢轴点: %f, 突破买入价: %f, 观察卖出价: %f, 反转卖出价: %f, 反转买入价: %f, 观察买入价: %f, 突破卖出价: %f" % (pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak)) return pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak
- 追踪盘中价格走势,实时判断触发条件。具体条件如下:
- 突破
- 在空仓条件下,如果盘中价格超过突破买入价,则采取趋势策略,即在该点位开仓做多。
- 在空仓条件下,如果盘中价格跌破突破卖出价,则采取趋势策略,即在该点位开仓做空。
- 反转
- 持多单,当日内最高价超过观察卖出价后,盘中价格出现回落,且进一步跌破反转卖出价构成的支撑线时,采取反转策略,即在该点位反手做空。
- 持空单,当日内最低价低于观察买入价后,盘中价格出现反弹,且进一步超过反转买入价构成的阻力线时,采取反转策略,即在该点位反手做多。
- 突破
- 设定止损条件。当亏损达到设定值后,平仓。
- 设定是否隔夜留仓。
代码实现逻辑
实现步骤
只要新产生一条日线,即可判断为新交易日的开始,则重新计算七条指标线;
if api.is_changing(klines.iloc[-1], "datetime"): # 产生新k线,则重新计算7条指标线 pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak = get_index_line(klines)
根据策略的交易规则,依据当前的持仓信息以及行情最新价突破信息进行加减仓操作;
如果设置了非隔夜留仓,在策略进行过程中判断当前时间是否临近交易日结束,即当前行情时间已到达设定的平仓时间,若是则平仓;
if api.is_changing(quote, "datetime"): now = datetime.strptime(quote.datetime, "%Y-%m-%d %H:%M:%S.%f") if now.hour == CLOSE_HOUR and now.minute >= CLOSE_MINUTE: # 到达平仓时间: 平仓 print("临近本交易日收盘: 平仓") target_pos_value = 0 # 平仓 pivot = bBreak = sSetup = sEnter = bEnter = bSetup = sBreak = float("nan") # 修改各指标线的值, 避免平仓后再次触发
设置止损点,每次调仓后记录调仓时的行情价,当调仓价与当前行情价之差大于止损点则平仓止损。
STOP_LOSS_PRICE = 10 # 止损点(价格) target_pos_value = position.pos_long - position.pos_short # 净目标净持仓数 open_position_price = position.open_price_long if target_pos_value > 0 else position.open_price_short # 开仓价 # 开仓价与当前行情价之差大于止损点则止损 if (target_pos_value > 0 and open_position_price - quote.last_price >= STOP_LOSS_PRICE) or (target_pos_value < 0 and quote.last_price - open_position_price >= STOP_LOSS_PRICE): target_pos_value = 0 # 平仓
策略代码实现工具
免费期货模拟、实盘天勤量化软件:https://www.shinnytech.com/tianqin/
回测
回测初始设置
初始账户资金:100万
回测日期:2018.11.14 —— 2018.12.25
策略参数:平仓时间:14:50 ;止损点:35
多、空头开仓手数:20手
合约:INE.sc1905
是否隔夜留仓:隔夜不留仓: 在每日收盘前,对所持合约进行平仓
回测时盘口行情quote的更新频率:和K线分钟线的更新频率一致
回测结果
R-Breaker策略回测结果 | |||||
合约代码 | 合约品种 | 收益率 | 风险度 | 最大回撤 | 年化夏普率 |
INE.sc1905 | 原油 | 37.32% | 0.00% | 2.78% | 6.1229 |
上表回测结果中累计收益走势图
天勤内策略源码:
非隔夜留仓(收盘前平仓):
# !/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'limin' ''' R-Breaker策略(非隔夜留仓: 在每日收盘前,对所持合约进行平仓) 参考: https://www.shinnytech.com/blog/r-breaker 注: 该示例策略仅用于功能示范, 实盘时请根据自己的策略/经验进行修改 ''' from datetime import datetime from tqsdk import TqApi, TargetPosTask SYMBOL = "SHFE.au1912" # 合约代码 CLOSE_HOUR, CLOSE_MINUTE = 14, 50 # 平仓时间 STOP_LOSS_PRICE = 10 # 止损点(价格) api = TqApi() print("策略开始运行") def get_index_line(klines): '''计算指标线''' high = klines.high.iloc[-2] # 前一日的最高价 low = klines.low.iloc[-2] # 前一日的最低价 close = klines.close.iloc[-2] # 前一日的收盘价 pivot = (high + low + close) / 3 # 枢轴点 bBreak = high + 2 * (pivot - low) # 突破买入价 sSetup = pivot + (high - low) # 观察卖出价 sEnter = 2 * pivot - low # 反转卖出价 bEnter = 2 * pivot - high # 反转买入价 bSetup = pivot - (high - low) # 观察买入价 sBreak = low - 2 * (high - pivot) # 突破卖出价 print("已计算新标志线, 枢轴点: %f, 突破买入价: %f, 观察卖出价: %f, 反转卖出价: %f, 反转买入价: %f, 观察买入价: %f, 突破卖出价: %f" % (pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak)) return pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak quote = api.get_quote(SYMBOL) klines = api.get_kline_serial(SYMBOL, 24 * 60 * 60) # 86400: 使用日线 position = api.get_position(SYMBOL) target_pos = TargetPosTask(api, SYMBOL) target_pos_value = position.pos_long - position.pos_short # 净目标净持仓数 open_position_price = position.open_price_long if target_pos_value > 0 else position.open_price_short # 开仓价 pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak = get_index_line(klines) # 七条标准线 while True: target_pos.set_target_volume(target_pos_value) api.wait_update() if api.is_changing(klines.iloc[-1], "datetime"): # 产生新k线,则重新计算7条指标线 pivot, bBreak, sSetup, sEnter, bEnter, bSetup, sBreak = get_index_line(klines) if api.is_changing(quote, "datetime"): now = datetime.strptime(quote.datetime, "%Y-%m-%d %H:%M:%S.%f") if now.hour == CLOSE_HOUR and now.minute >= CLOSE_MINUTE: # 到达平仓时间: 平仓 print("临近本交易日收盘: 平仓") target_pos_value = 0 # 平仓 pivot = bBreak = sSetup = sEnter = bEnter = bSetup = sBreak = float("nan") # 修改各指标线的值, 避免平仓后再次触发 '''交易规则''' if api.is_changing(quote, "last_price"): print("最新价: %f" % quote.last_price) # 开仓价与当前行情价之差大于止损点则止损 if (target_pos_value > 0 and open_position_price - quote.last_price >= STOP_LOSS_PRICE) or \ (target_pos_value < 0 and quote.last_price - open_position_price >= STOP_LOSS_PRICE): target_pos_value = 0 # 平仓 # 反转: if target_pos_value > 0: # 多头持仓 if quote.highest > sSetup and quote.last_price < sEnter: # 多头持仓,当日内最高价超过观察卖出价后, # 盘中价格出现回落,且进一步跌破反转卖出价构成的支撑线时, # 采取反转策略,即在该点位反手做空 print("多头持仓,当日内最高价超过观察卖出价后跌破反转卖出价: 反手做空") target_pos_value = -3 # 做空 open_position_price = quote.last_price elif target_pos_value < 0: # 空头持仓 if quote.lowest < bSetup and quote.last_price > bEnter: # 空头持仓,当日内最低价低于观察买入价后, # 盘中价格出现反弹,且进一步超过反转买入价构成的阻力线时, # 采取反转策略,即在该点位反手做多 print("空头持仓,当日最低价低于观察买入价后超过反转买入价: 反手做多") target_pos_value = 3 # 做多 open_position_price = quote.last_price # 突破: elif target_pos_value == 0: # 空仓条件 if quote.last_price > bBreak: # 在空仓的情况下,如果盘中价格超过突破买入价, # 则采取趋势策略,即在该点位开仓做多 print("空仓,盘中价格超过突破买入价: 开仓做多") target_pos_value = 3 # 做多 open_position_price = quote.last_price elif quote.last_price < sBreak: # 在空仓的情况下,如果盘中价格跌破突破卖出价, # 则采取趋势策略,即在该点位开仓做空 print("空仓,盘中价格跌破突破卖出价: 开仓做空") target_pos_value = -3 # 做空 open_position_price = quote.last_price
点击查看天勤量化程序