资源加载中... loading...

多级百分比止盈策略

Author: 扫地僧, Date: 2021-10-26 17:12:49
Tags: 商品期货趋势My语言

摘要

斯坦利·克罗在《克罗谈投资策略》书中提到过他的止盈分为三部分:当达到止盈目标的时候主动平掉三分之一,突破长期阻力位和支撑位的时候再主动平掉三分之一,剩下的三分之一跟随趋势直到止损。本篇文章分享的策略也正是根据这个原理,利用均线作为趋势方向的判断,以收盘价、最高价与最低价的相互关系作为开平仓信号,在价格走势没有明显转向的前提下,提前按照百分比主动分批止盈。

为什么要止盈止损

交易界有句古老的谚语:“会买是徒弟,会卖是师傅”。顾名思义怎么卖比怎么买更难,因为在买入的时候只需要判断行情是否开始就可以了;但是一旦买进之后,不但需要判断行情是否转向,还需要时刻控制风险。相信很多交易者都经历过过山车的行情,明明上车了最后还是以小赚甚至亏损的结果出局。或者本来可以以小亏出局,结果从小亏损积累成大亏损。所以从这点看,卖出比买入更为重要。

简单的说,卖出无非是两种情况:止盈和止损。如果运气很好,买入后价格开始上涨,这时就要考虑止盈的问题,否则可能账面上赚到了钱,没有在合适的位置获利了结,最后平亏出局。如果运气不好,买入后不久价格就开始下跌,这时就要考虑止损了,或者在开仓买入之前就应该考虑好止损的位置,否则小亏损会积累成大亏损。

从统计学的角度看,大部分亏损的单子,在之后的行情里都会回到成本价附近。但是如果遇到一次小概率大幅反向走势,可能会损失之前所有的利润或本金。因此对我们散户来说,可以大赚,可以小赚,也可以小亏,但是永远不能大亏。一句话:止损让你活着,止盈让你活得更好。

策略逻辑

有时候当我们主动止盈的时候,可能会出现一大波行情只赚到了一小部分行情,虽然这一单是不亏的,但是从心态上会有一种踏空的懊悔,所以本篇策略就采用多级止盈的方法,也就是说当浮盈达到5%之后就开启一级主动止盈模式,一旦从浮盈的最高点回撤100%,平仓获利出局;当浮盈达到10%之后就开启二级主动止盈模式,一旦从浮盈的最高点回撤50%,平仓获利出局;当浮盈达到20%之后就开启三级主动止盈模式,一旦从浮盈的最高点回撤20%,平仓获利出局。这样不仅保护了浮盈利润,而且在大行情来的时候,也不至于只赚一点点。下面就是策略的逻辑:

  • 定义上轨

  • 定义下轨

  • 定义均线

  • 多头开仓:收盘价大于上轨,并且上轨大于均线

  • 空头开仓:收盘价小于下轨,并且下轨小于均线

  • 多头平仓:收盘价小于下轨,或者收盘价小于均线

  • 空头平仓:收盘价大于上轨,或者收盘价大于均线

  • 1级多头止盈:开仓后最高价大于等于开仓价位乘以一级止盈启动,并且最低价小于等于开仓后最高价减去浮盈乘以一级止盈触发

  • 2级多头止盈:开仓后最高价大于等于开仓价位乘以二级止盈启动,并且最低价小于等于开仓后最高价减去浮盈乘以二级止盈触发

  • 3级多头止盈:开仓后最高价大于等于开仓价位乘以三级止盈启动,并且最低价小于等于开仓后最高价减去浮盈乘以三级止盈触发

  • 1级空头止盈:开仓后最低价小于等于开仓价位乘以一级止盈启动,并且最高价大于等于开仓后最低价加上浮盈乘以一级止盈触发

  • 2级空头止盈:开仓后最低价小于等于开仓价位乘以二级止盈启动,并且最高价大于等于开仓后最低价加上浮盈乘以二级止盈触发

  • 3级空头止盈:开仓后最低价小于等于开仓价位乘以三级止盈启动,并且最高价大于等于开仓后最低价加上浮盈乘以三级止盈触发

  • 多头止损:收盘价小于等于开仓价位乘以止损系数

  • 空头止损:收盘价大约等于开仓价位乘以止损系数

策略代码

根据上面的策略逻辑,我们可以在优宽量化交易平台上实现交易策略。依次打开:youquant.com > 登录 > 控制中心 > 策略库 > 新建策略 > 点击右上角下拉菜单选择My语言,开始编写策略,注意看下面代码中的注释。

首先,把这些策略需要用到的参数:均线长度、止损幅度、止盈参数等等,定义为外部参数,方便测试调试和优化。

// 定义参数
LENGTH := 100;   // 均线参数
STOP_LOSS := 3;       // 止损幅度

// 定义止盈参数
STARTPER1 := 5;  // 1级跟踪止盈,盈利5%启动
STOPPER1 := 100; // 1级跟踪止盈,盈利回撤100%触发    
STARTPER2 := 10; // 2级跟踪止盈,盈利10%启动
STOPPER2 := 50;  // 2级跟踪止盈,盈利回撤50%触发	
STARTPER3 := 20; // 3级跟踪止盈,盈利20%启动
STOPPER3 := 20;  // 3级跟踪止盈,盈利回撤20%触发

接着,根据当天价格和昨天价格,以及昨天价格的波动幅度,设置一个价格区间。通过这个价格区间以及与均线的相对位置关系,做出买入和卖出开仓信号,这样不仅可以很好的跟踪到市场行情,也能在市场处于震荡时期,减少一定的开仓次数,降低回撤幅度。

// 定义上下区间
NN := BARSLAST(DATE <> REF(DATE, 1)) + 1;  // 当天开盘到当前周期数
TODAY_OPEN := VALUEWHEN(NN = 1, O);        // 当天开盘价
TODAY_HIGH := HHV(H, NN);                  // 当天最高价
TODAY_LOW := LLV(L, NN);                   // 当天最低价
YESTERDAY_HIGH := REF(TODAY_HIGH, NN);     // 昨天最高价
YESTERDAY_LOW := REF(TODAY_LOW, NN);       // 昨天最低价
BAND := YESTERDAY_HIGH - YESTERDAY_LOW;    // 昨天振幅
UPPERLINE : TODAY_OPEN + BAND;             // 上线
LOWERLINE : TODAY_OPEN - BAND;             // 下线
MYMA:MA(CLOSE, LENGTH);                    // 均线

然后,就是开仓和平台的逻辑代码。当收盘价大于上轨,并且上轨大于均线,就开多单;当收盘价小于下轨,并且下轨小于均线,就开空单;平仓条件刚好与开仓条件相反:当收盘价小于下轨,或者收盘价小于均线,就平多单;当收盘价大于上轨,或者收盘价大于均线,就平空单。

// 开仓
C > UPPERLINE AND UPPERLINE > MYMA, BK;   // 开多
C < LOWERLINE AND LOWERLINE < MYMA, SK;   // 开空

// 平仓
C < LOWERLINE OR C < MYMA, SP;  // 平多
C > UPPERLINE OR C > MYMA, BP;  // 平空

最后,就是本文中所说的止盈止损部分了,无论是多单止盈还是空单止盈,都分为三个阶段,每个阶段都根据当前市场价格波动,以及盈利状况来自动调整,并且这个调整设置为外部参数,你可以根据不同的市场行情和品种状态来进行精细化调整。止损也是我们写策略需要考虑的一部分,因为不可能一开仓就能赚钱,有时候市场就是与我们的预期反着来,所以止损也绝对有必要的。本文策略在止损处理上简单暴力,即当浮亏到一定程度时全部平仓。

// 多单止盈
BKHIGH >= BKPRICE * (1 + 0.01 * STARTPER1) AND LOW <= BKHIGH - (BKHIGH - BKPRICE) * 0.01 * STOPPER1, SP;  // 一级
BKHIGH >= BKPRICE * (1 + 0.01 * STARTPER2) AND LOW <= BKHIGH - (BKHIGH - BKPRICE) * 0.01 * STOPPER2, SP;  // 二级
BKHIGH >= BKPRICE * (1 + 0.01 * STARTPER3) AND LOW <= BKHIGH - (BKHIGH - BKPRICE) * 0.01 * STOPPER3, SP;  // 三级

// 空单止盈
SKLOW <= SKPRICE * (1 - 0.01 * STARTPER1) AND HIGH >= SKLOW + (SKPRICE - SKLOW) * 0.01 * STOPPER1, BP;  // 一级
SKLOW <= SKPRICE * (1 - 0.01 * STARTPER2) AND HIGH >= SKLOW + (SKPRICE - SKLOW) * 0.01 * STOPPER2, BP;  // 二级
SKLOW <= SKPRICE * (1 - 0.01 * STARTPER3) AND HIGH >= SKLOW + (SKPRICE - SKLOW) * 0.01 * STOPPER3, BP;  // 三级

//止损
C <= BKPRICE * (1 - STOP_LOSS * 0.01), SP;  // 多头
C >= SKPRICE * (1 + STOP_LOSS * 0.01), BP;  // 空头

另外,我们还设置了下单委托方式,以及信号过滤方式,使处理更加完整。

// 设置下单委托方式
SETSIGPRICETYPE(BK,NEW_ORDER);
SETSIGPRICETYPE(SK,NEW_ORDER);
SETSIGPRICETYPE(BP,NEW_ORDER);
SETSIGPRICETYPE(SP,NEW_ORDER);

// 设置信号过滤方式
AUTOFILTER;

策略回测

测试环境

  • 交易品种:螺纹钢指数
  • 时间:2015年02月22日~2019年09月18日
  • 周期:一小时
  • 滑点:开平仓各2跳
  • 手续费:交易所2倍 img

绩效报告 img

资金曲线 img

结尾

交易是一种正确思维和行为的提炼,从最开始如何做到少亏钱,到如何做到不亏钱,到如何做到赚钱并把钱留住,这中间的每一阶段都是上一个阶段的升华。截断亏损,让利润奔跑!一直华尔街的名言和交易者的作用铭。尽管每个人的认知各有不同,方法各有千秋,但到最后真正盈利的交易思维是相通的。


(*backtest
start: 2015-02-22 00:00:00
end: 2019-09-18 00:00:00
period: 1h
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
args: [["SlideTick",2,126961],["ContractType","rb000",126961]]
*)

// 定义参数
LENGTH := 100;   // 均线参数
STOP_LOSS := 3;       // 止损幅度

// 定义止盈参数
STARTPER1 := 5;  // 1级跟踪止盈,盈利5%启动
STOPPER1 := 100; // 1级跟踪止盈,盈利回撤100%触发    
STARTPER2 := 10; // 2级跟踪止盈,盈利10%启动
STOPPER2 := 50;  // 2级跟踪止盈,盈利回撤50%触发	
STARTPER3 := 20; // 3级跟踪止盈,盈利20%启动
STOPPER3 := 20;  // 3级跟踪止盈,盈利回撤20%触发

// 定义上下区间
NN := BARSLAST(DATE <> REF(DATE, 1)) + 1;  // 当天开盘到当前周期数
TODAY_OPEN := VALUEWHEN(NN = 1, O);        // 当天开盘价
TODAY_HIGH := HHV(H, NN);                  // 当天最高价
TODAY_LOW := LLV(L, NN);                   // 当天最低价
YESTERDAY_HIGH := REF(TODAY_HIGH, NN);     // 昨天最高价
YESTERDAY_LOW := REF(TODAY_LOW, NN);       // 昨天最低价
BAND := YESTERDAY_HIGH - YESTERDAY_LOW;    // 昨天振幅
UPPERLINE : TODAY_OPEN + BAND;             // 上线
LOWERLINE : TODAY_OPEN - BAND;             // 下线
MYMA:MA(CLOSE, LENGTH);                    // 均线

// 开仓
C > UPPERLINE AND UPPERLINE > MYMA, BK;   // 开多
C < LOWERLINE AND LOWERLINE < MYMA, SK;   // 开空

// 平仓
C < LOWERLINE OR C < MYMA, SP;  // 平多
C > UPPERLINE OR C > MYMA, BP;  // 平空

// 多单止盈
BKHIGH >= BKPRICE * (1 + 0.01 * STARTPER1) AND LOW <= BKHIGH - (BKHIGH - BKPRICE) * 0.01 * STOPPER1, SP;  // 一级
BKHIGH >= BKPRICE * (1 + 0.01 * STARTPER2) AND LOW <= BKHIGH - (BKHIGH - BKPRICE) * 0.01 * STOPPER2, SP;  // 二级
BKHIGH >= BKPRICE * (1 + 0.01 * STARTPER3) AND LOW <= BKHIGH - (BKHIGH - BKPRICE) * 0.01 * STOPPER3, SP;  // 三级

// 空单止盈
SKLOW <= SKPRICE * (1 - 0.01 * STARTPER1) AND HIGH >= SKLOW + (SKPRICE - SKLOW) * 0.01 * STOPPER1, BP;  // 一级
SKLOW <= SKPRICE * (1 - 0.01 * STARTPER2) AND HIGH >= SKLOW + (SKPRICE - SKLOW) * 0.01 * STOPPER2, BP;  // 二级
SKLOW <= SKPRICE * (1 - 0.01 * STARTPER3) AND HIGH >= SKLOW + (SKPRICE - SKLOW) * 0.01 * STOPPER3, BP;  // 三级


//止损
C <= BKPRICE * (1 - STOP_LOSS * 0.01), SP;  // 多头
C >= SKPRICE * (1 + STOP_LOSS * 0.01), BP;  // 空头

// 设置下单委托方式
SETSIGPRICETYPE(BK,NEW_ORDER);
SETSIGPRICETYPE(SK,NEW_ORDER);
SETSIGPRICETYPE(BP,NEW_ORDER);
SETSIGPRICETYPE(SP,NEW_ORDER);

// 设置信号过滤方式
AUTOFILTER;
template: strategy.tpl:40:21: executing "strategy.tpl" at <.api.GetStrategyListByName>: wrong number of args for GetStrategyListByName: want 7 got 6