斯坦利·克罗在《克罗谈投资策略》书中提到过他的止盈分为三部分:当达到止盈目标的时候主动平掉三分之一,突破长期阻力位和支撑位的时候再主动平掉三分之一,剩下的三分之一跟随趋势直到止损。本篇文章分享的策略也正是根据这个原理,利用均线作为趋势方向的判断,以收盘价、最高价与最低价的相互关系作为开平仓信号,在价格走势没有明显转向的前提下,提前按照百分比主动分批止盈。
交易界有句古老的谚语:“会买是徒弟,会卖是师傅”。顾名思义怎么卖比怎么买更难,因为在买入的时候只需要判断行情是否开始就可以了;但是一旦买进之后,不但需要判断行情是否转向,还需要时刻控制风险。相信很多交易者都经历过过山车的行情,明明上车了最后还是以小赚甚至亏损的结果出局。或者本来可以以小亏出局,结果从小亏损积累成大亏损。所以从这点看,卖出比买入更为重要。
简单的说,卖出无非是两种情况:止盈和止损。如果运气很好,买入后价格开始上涨,这时就要考虑止盈的问题,否则可能账面上赚到了钱,没有在合适的位置获利了结,最后平亏出局。如果运气不好,买入后不久价格就开始下跌,这时就要考虑止损了,或者在开仓买入之前就应该考虑好止损的位置,否则小亏损会积累成大亏损。
从统计学的角度看,大部分亏损的单子,在之后的行情里都会回到成本价附近。但是如果遇到一次小概率大幅反向走势,可能会损失之前所有的利润或本金。因此对我们散户来说,可以大赚,可以小赚,也可以小亏,但是永远不能大亏。一句话:止损让你活着,止盈让你活得更好。
有时候当我们主动止盈的时候,可能会出现一大波行情只赚到了一小部分行情,虽然这一单是不亏的,但是从心态上会有一种踏空的懊悔,所以本篇策略就采用多级止盈的方法,也就是说当浮盈达到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;
测试环境
绩效报告
资金曲线
交易是一种正确思维和行为的提炼,从最开始如何做到少亏钱,到如何做到不亏钱,到如何做到赚钱并把钱留住,这中间的每一阶段都是上一个阶段的升华。截断亏损,让利润奔跑!一直华尔街的名言和交易者的作用铭。尽管每个人的认知各有不同,方法各有千秋,但到最后真正盈利的交易思维是相通的。
(*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