龙哥量化:国外著名交易策略:R-Breaker日内交易策略
龙哥微信:Long622889
代写技术指标_选股公式: 通达信,同花顺,东方财富,大智慧,文华,博易,KT交易师
代写期货量化策略:TB交易开拓者,文华8,金字塔量化
本篇是我研究策略的时候, 找到的一篇写的高质量文章,策略思路说的非常清晰明了,值得学习,R-Breaker策略也很经典, 转载收藏学习 ,
本篇,我用TBquant3,交易开拓者软件
我计划研究三个版本,原版, 国内期货版,etf版T+1
原文地址:https://www.vnpy.com/forum/topic/1597?page=1
原文,及策略思路:
R-Breaker是一种中高频的日内交易策略,这个策略也长期被Future Truth杂志评为最赚钱的策略之一。R-Breaker策略结合了趋势和反转两种交易方式,所以交易机会相对较多,比较适合日内1分钟K线或者5分钟K线级别的数据。
R-Breaker的策略逻辑由以下4部分构成:
1)计算6个目标价位
根据昨日的开高低收价位计算出今日的6个目标价位,按照价格高低依次是:
- 突破买入价(Bbreak)
- 观察卖出价(Ssetup)
- 反转卖出价(Senter)
- 反转买入价(Benter)
- 观察买入价(Bsetup)
- 突破卖出价(Sbreak)
他们的计算方法如下:(其中a、b、c、d为策略参数)
- 观察卖出价(Ssetup)= High + a * (Close – Low)
- 观察买入价(Bsetup)= Low – a * (High – Close)
- 反转卖出价(Senter) = (High + Low)/ 2 *b – c * Low
- 反转买入价(Benter)= (High + Low)/ 2 *b – c * High
- 突破卖出价(Sbreak)= Ssetup - d * (Ssetup – Bsetup)
- 突破买入价(Bbreak)= Bsetup + d * (Ssetup – Bsetup)
其中a、b、c、d为参数,满足 b - c =1,并且b越大,Senter越大,Benter越小;d越大,Bbreak越大,Sbreak越小。可以通过调整参数改变价位,从而调整交易频率,但注意不能改变6个价格的相对大小。
2)策略逻辑
趋势策略
该策略主要在没有持仓情况下,判断是否有上涨(下跌)的趋势,从而实现多头(空头)开仓。
- 当前价格>突破买入价(Bbreak),开仓做多;
- 当前价格<突破卖出家(Sbreak),开仓做空。

反转策略
反转策略包括在持仓与没有持仓的情况下的交易,根据走势进行反转。
- 若当日最高价>观察卖出价(Ssetup),然后下跌导致当前价格<反转卖出价(Senter),没有持仓时则开仓做空,有多头持仓时则先平仓再反向开仓做空;
- 若当日最低价<观察买入价(Bsetup),然后上涨导致当前价格>反转买入价(Senter),没有持仓时则开仓做多,有空头持仓时则先平仓再反向开仓做多。

3)设定相应的止盈止损。
4)日内策略要求收盘前平仓。
上面是原版R-Breaker策略逻辑,但是使用RQData从2010年至今(即2019年10月)的1分钟沪深300股指期货主力连续合约(IF88)测试,效果并不理想。
大概回测几个指数合约,效果不好

原版的R-Breaker策略
TBquant3,完整代码,运行在5分钟K线,完全交易时段,应用结束时间



Params
Numeric qty(1);
Numeric aa(0.01);
Numeric bb(1.3);
Numeric cc(0.3);
Numeric dd(0.4);
Numeric StopLossSet(50); // 固定止损跳数
//其中a、b、c、d为参数,满足 b - c =1,并且b越大,Senter越大,Benter越小;d越大,Bbreak越大,Sbreak越小。
//可以通过调整参数改变价位,从而调整交易频率,但注意不能改变6个价格的相对大小。
Vars
Series<Numeric> guancha_buy;
Series<Numeric> guancha_sell;
Series<Numeric> fanzhuan_buy;
Series<Numeric> fanzhuan_sell;
Series<Numeric> tupo_buy;
Series<Numeric> tupo_sell;
Series<Numeric> timecha;
natural numeric tiao;
Series<Bool> time2;
Series<Numeric> hh;
Series<Numeric> ll;
Series<Numeric> zhouqi;
Series<Numeric> shu;
Natural Numeric dianshu;
Events
onBar(ArrayRef<Integer> indexs)
{
tiao = minmove * pricescale;
Commentary("High "+Text(HighD(1)));
Commentary("lowd "+Text(lowd(1)));
Commentary("closed "+Text(closed(1)));
guancha_sell=HighD(1)+aa*(closed(1)-lowd(1));
guancha_buy=lowd(1)-aa*(HighD(1)-closed(1));
fanzhuan_sell= bb/2*(HighD(1)+lowd(1))-cc*lowd(1);
fanzhuan_buy=bb/2*(HighD(1)+lowd(1))-cc*highd(1);
tupo_sell= guancha_buy-dd*(guancha_sell-guancha_buy);
tupo_buy=guancha_sell+dd*(guancha_sell-guancha_buy);
PlotAuto("突破买入价",tupo_buy,tupo_buy);
PlotAuto("观察卖出价",guancha_sell,guancha_sell);
PlotAuto("反转卖出价",fanzhuan_sell,fanzhuan_sell);
PlotAuto("反转买入价",fanzhuan_buy,fanzhuan_buy);
PlotAuto("观察买入价",guancha_buy,guancha_buy);
PlotAuto("突破卖出价",tupo_sell,tupo_sell);
zhouqi=nthcon(time2,1)+1;
hh=highest(high,zhouqi);
ll=lowest(low,zhouqi);
//趋势策略, 开仓
if (longCurrentContracts==0 and shortCurrentContracts==0 and high>tupo_buy)
{
Buy(qty, max(open,tupo_buy+tiao*1));
PlotAuto("开多1", "趋势突破买入价,开多", high + tiao*5, yellow);
}
if (longCurrentContracts==0 and shortCurrentContracts==0 and low<tupo_sell)
{
SellShort(qty, min(open,tupo_sell-tiao*1));
PlotAuto("开空1", "趋势突破卖出价,开空", high + tiao*5, yellow);
}
//反转策略, 平仓
if (longCurrentContracts==0 and shortCurrentContracts>0 and ll<guancha_buy and high>fanzhuan_buy and shu[1]==0)
{
buytocover(qty, max(open,fanzhuan_buy+tiao*1));
PlotAuto("平多2", "反转买入价平空", high + tiao*10, yellow);
shu=1;
}
if (longCurrentContracts>0 and shortCurrentContracts==0 and hh>guancha_sell and low<fanzhuan_sell and shu[1]==0)
{
sell(qty, min(open,fanzhuan_sell-tiao*1));
PlotAuto("平空2", "反转卖出价平多", high + tiao*10, yellow);
shu=1;
}
//反转策略, 开仓
if (longCurrentContracts==0 and shortCurrentContracts==0 and ll<guancha_buy and high>fanzhuan_buy and shu[1]<=1)
{
Buy(qty, max(open,fanzhuan_buy+tiao*1));
PlotAuto("开多2", "反转买入价,开多", high + tiao*5, yellow);
shu=2;
}
if (longCurrentContracts==0 and shortCurrentContracts==0 and hh>guancha_sell and low<fanzhuan_sell and shu[1]<=1)
{
SellShort(qty, min(open,fanzhuan_sell-tiao*1));
PlotAuto("开空2", "反转卖出价,开空", high + tiao*5, yellow);
shu=2;
}
//固定止损
dianshu=StopLossSet *MinMove * PriceScale;
if(longCurrentContracts > 0 and BarsSinceEntry > 0 and Low < longAvgEntryPrice - dianshu )
{
Sell(qty, min(open, longAvgEntryPrice - dianshu ));
PlotAuto("固定止损", "固定止损", close, green);
}
if(shortCurrentContracts > 0 and BarsSinceEntry > 0 and High > shortAvgEntryPrice + dianshu)
{
BuyToCover(qty, max(open, shortAvgEntryPrice + dianshu));
PlotAuto("固定止损", "固定止损", close, green);
}
}
OnBarClose(ArrayRef<Integer> indexes)
{
//日内策略要求收盘前平仓。
time2 = time == 0.1500;
Commentary("时间: " + text(Time));
if(time2)
{
shu=0;
if (longCurrentContracts > 0 )
{
Sell(qty, close);
PlotAuto("清仓", "清仓1", high + tiao * 5, yellow);
}
if (shortCurrentContracts > 0)
{
buytocover(qty, close);
PlotAuto("清仓", "清仓1", high + tiao * 5, yellow);
}
}
}
实际上R-Breaker策略可以拆分成趋势策略和反转策略。下面分别对这对2种策略逻辑进行优化:
1)趋势策略:
- 若当前x分钟的最高价>观察卖出价,认为它具有上升趋势,在突破买入价挂上买入开仓的停止单;
- 若当前x分钟的最低价<观察买入价,认为它具有下跌趋势,在突破卖出价挂上买入开仓的停止单;
- 开仓后,使用固定百分比移动止损离场;
- 增加过滤条件:为防止横盘行情导致不断的开平仓,日内每次开仓买入开仓(卖出开仓)委托的价位都比上一次更高(更低);
- 收盘前,必须平调所持有的仓位。
2)反转策略:
- 若当前x分钟的最高价>观察卖出价,认为它已经到了当日阻力位,可能发生行情反转,在反转卖出价挂上卖出开仓的停止单;
- 若当前x分钟的最低价>观察买入价,认为它已经到了当日支撑位,可能发生行情反转,在反转买入价挂上买入开仓的停止单;
- 开仓后,使用固定百分比移动止损离场;
- 收盘前,必须平调所持有的仓位
其代码实现逻辑如下:
代码---
明天继续研究
以下文字是
策略效果
同样使用10年的1分钟IF88数据进行回测。不过,在展示强化版R-Breaker策略效果前,先分别展示一下拆分后的趋势策略和反转策略。
1)趋势策略:
- 趋势策略夏普比率1.96,日均成交2.6笔,资金曲线是整体上扬的;
- 但是在2017~2018年的盘整阶段,具有较大并且持续时间较长的回撤;
- 这凸显出趋势类策略自身无法规避的缺点:在趋势行情中盈利,意味着震荡行情必然亏损。
2)反转策略
- 反转策略夏普比率0.75,日均成交0.4笔,资金曲线缓慢上扬;
- 但是在2017~2018年的盘整阶段,资金曲线上扬最快,而且这个阶段是最平滑的;
- 这凸显出反转类策略优点:尽管在趋势行情亏损,在震荡行情必然能盈利。
综合对比2种策略的日均成交笔数和资金曲线,我们可以知道:
- 由于趋势策略日均交易笔数较多(2.6笔),它主要负责贡献R-Breaker策略的alpha;
- 趋势策略的亏损也是主要导致R-Breaker策略亏损的原因,但这时候的亏损由反转策略的盈利来填补。
由于趋势策略和反转策略是互斥的,在某些方面呈现出此消彼长的特点。那么,根据投资组合理论,可以把反转策略看作是看跌期权,买入一定规模的看跌期权来对消非系统性风险,那么组合的收益会更加稳健,即夏普比率更高。
由于趋势策略和反转策略日均成交手数比是2.6:0.4,若它们都只委托1手的话,反转策略的对冲效果微乎其微。
为了方便演示,我们设置趋势策略每次交易1手;反转策略则是3手。然后合成R-Breaker策略。发现夏普比率提高到2,资金曲线整体上扬,而且没有较大且持续时间较长的回撤。
结论
R-Breaker策略成功之处在于它并不是纯粹的趋势类策略,它属于复合型策略,它的alpha由2部分构成:趋势策略alpha;反转策略alpha。
这类复合型策略可以看作是轻量级的投资组合,因为它的交易标的只有一个:沪深300股指期货的主力合约。
更复杂的话,可以交易多个标的,如在商品期货做虚拟钢厂套利(同时交易螺纹钢、铁矿石、焦炭),在IF股指期货上做日内CTA策略。考虑到市场容量不同,价差套利能分配更多的资金。这样在价差套利提供稳定收益率基础上,CTA策略能在行情好的时候贡献更多alpha(高盈亏比特征导致的)。
从上面例子可以看出,一个合理的投资组合,往往比单个策略具有更高的夏普比率。因为夏普比率=超额收益/风险。夏普比率高意味着资金曲线非常平滑;这也意味着我们可以有效控制使用杠杆的风险。
当某个投资组合策略夏普足够高,而且策略资金容量允许,交易成本能有效控制等情况下,就可以通过杠杆来提升组合收益了。例如向银行贷款或者发放债券,这时候交易团队是债务人角色,即在承担更大风险同时,追求更到收益。债权人享受利息收益(类无风险收益)。
向公众发产品是另一种增加杠杆的方式,但此时投资组合风险已经转移到了客户这方,交易团队可以享受着管理费收益(类无风险收益)。根据目标客户的不同:
- 私募基金面向高净值客户,这些客户群体风险承受能力较高;并且私募监管比较放松,能使用的衍生品较多,有提升业绩的自由度。故私募基金除了管理费,更追求业绩提成。
- 公募基金面向普通群众,他们风险承受能力较低;并且公募监管非常严格,投资约束非常多,提升业绩难度较大。但是公募牌照的稀缺性必然导致该行业是盈利的。如万亿级别的管理规模,其管理费的收益,也不是一般的自营交易公司或者私募基金比得上的。
附录
最后附上策略源代码:

浙公网安备 33010602011771号