抛物线转向是一个很奇特的技术分析指标,由美国威尔斯·威尔德(Welles Wilder)发明,英文名字叫“Stop and Reverse”,简称“SAR”。这是一种使用非常简单,同时也非常流行的中低频趋势性技术分析工具。本篇文章的策略根据这个技术指标,并结合价格高低点的相对位置关系来开发策略。
抛物线转向之所以奇特,是因为它的外在图形与其他指标不同,它是以红点或绿点组成,以弧形的方式跟随价格移动,由于在图表上它的形状像是一个抛物线,因此称之为抛物线转向,实际上其并不涉及抛物线的数学计算。它构建于价格图表之上,主要用来分析价格的趋势变化,这一点与均线类似,唯一的区别就是它附带加速因子,会随着价格变化速度来调整自己的运行速度。
另外,均线会始终贯穿价格,但当价格穿越抛物线时,那么该指标就反转切换,同时它的指示价格会出现在价格水平的另一面,并会提示交易者的止损位置,直到趋势行情的结束。当价格在抛物线之上时,交易者应该持有多单,当价格在抛物线之下时,交易者应该持有空单。
抛物线转向的计算非常复杂,首先需要确定极值点(最高价或最低价 EP)。然后在它的基础上加上从 0.02 起步的加速因子(AF),然后每当触及下一个极值点时,再加 0.02。AF的最高为 0.20。然后用极点价与前一时段 SAR 之间的差值乘以加速因子,然后再加上前一时段的 SAR。
上涨算法 第一步:假设时间段是t。SAR(t)等于前面N个时间段的最低价格。Af(t)的初始值为0.02。
如果SAR(t)大于t时间段的最低价L(t),则发生跳转,在下一个时间段时进入跌势;
如果SAR(t)不大于t时间段的最低价L(t),在下一个时间段时进入涨势;
极值Ep(t)等于最近N个时间段的最高价格;
第二步:时间段是t+1,即:
SAR(t+1)=SAR(t)+Af(t)*(Ep(t) – SAR(t))
如果SAR(t+1)大于t+1时间段的最低价L(t+1),则发生跳转,在下一个时间段时进入跌势;
如果SAR(t+1)不大于t+1时间段的最低价L(t+1),进入涨势下一步;并且,极值Ep(t+1)等于最近N个时间段的最高价格;
如果该时间段的最高价,即H(t+1)比前面N个时间段的最高价高,则AF(t+1)=AF(t)+0.02,否则,AF(t+1)=AF(t)。
第三步:在后面的时间段t+2,t+3,……,上重复涨势第二步中的算法,直到发生跳转为止。另外,AF的最大值是0.2。
下跌算法
第一步:假设时间段是t。SAR(t)等于前面N个时间段的最高价格。Af(t)的初始值为0.02。
如果SAR(t)小于t时间段的最高价H(t),则发生跳转,在下一个时间段时进入涨势;
如果SAR(t)不小于t时间段的最高价H(t),在下一个时间段时进入跌势;
极值Ep(t)等于最近N个时间段的最低价格;
第二步:时间段是t+1,即:
SAR(t+1)=SAR(t)+Af(t)*(Ep(t) – SAR(t))
如果SAR(t+1)小于t+1时间段的最高价H(t+1),则发生跳转,在下一个时间段时进入涨势;
如果SAR(t+1)不小于t+1时间段的最高价L(t+1),进入跌势下一步;并且,极值Ep(t+1)等于最近N个时间段的最低价格;
如果该时间段的 最低价 L(t+1),比前面N个时间段的最低价低,则AF(t+1)=AF(t)+0.02,否则,AF(t+1)=AF(t)。
第三步:在后面的时间段t+2,t+3,……,上重复涨势第二步中的算法,直到发生跳转为止。另外,AF的最大值是0.2。
关于SAR的算法,有很多种版本,上面这种算法只是其中之一,算法结构都差不多,区别是在细节上,比如:加速因子的触发条件、Ep(t)的确定算法等,会有所区别。我们可以看到抛物线转向的特点:在行情上涨走势中,每根K线的SAR 都高于上一根K线的SAR,止损点在逐步上移,从而保证浮盈也在逐步上移,这就是典型的移动止损。 在行情加速上涨走势中,AF 加大,EP 增大,从而进一步加速止损点上移的速度,保证在强势情况下,止损点能紧密跟随股价的走势,并锁定更多的收益。
单独抛物线转向是一个反转策略,当价格在抛物线之上时多头持仓,价格在抛物线之下时空头持仓,这种非空即多的策略能够很好的适应趋势行情,在行情走势流畅时能赚很多钱。但是做过交易的人都知道,市场在大多时候是震荡行情,因此如果贸然单独使用抛物线转向,可能会在长期震荡行情中,损失掉很多之前得来的利润,甚至会损失本金。那么,我们就有必要加一个滤网,当震荡行情来的时候,可以过滤一部分震荡行情,从而降低交易频率,同时增加胜率或盈亏比,这样即使在长期震荡行情中,也能有效的减少净值回撤。
根据上面的策略逻辑,我们可以在优宽量化交易平台上实现交易策略。依次打开:youquant.com > 登录 > 控制中心 > 策略库 > 新建策略 > 点击右上角下拉菜单选择My语言,开始编写策略,注意看下面代码中的注释。
首先,把这些策略需要用到的参数:均线长度、止损幅度、止盈参数等等,定义为外部参数,方便测试调试和优化:
N:=30; // 最高/低价参数
SLOSS:=1; // 止盈止损系数
FUND:=100000; // 初始资金
接着,计算策略所用的必要数据:首先计算下单量,然后计算抛物线转向指标,并判断其是上涨状态还是下跌状态,最后计算最高价最低价与前期高低点位置关系:
LOTS:=MAX(1,INTPART(FUND/(O*UNIT*0.1))); // 计算下单量
SARLINE:=SAR(4,2,20); // 计算抛物线转向指标
B1:=SARLINE>0; // 判断是否上涨趋势
S1:=SARLINE<0; // 判断是否下跌趋势
B2:=HIGH>=HHV(CLOSE,N); // 判断最高价是否大于前期高点
S2:=LOW<=LLV(CLOSE,N); // 判断最低价是否小于前期低点
代码的最后是开仓和止盈止损部分:
BARPOS>N AND B1 AND B2,BK(LOTS); // 开多单
BARPOS>N AND S1 AND S2,SK(LOTS); // 开空单
S1 AND S2 AND BKHIGH>BKPRICE*(1+0.01*SLOSS),SP(BKVOL); // 多单止盈
B1 AND B2 AND SKLOW<SKPRICE*(1-0.01*SLOSS),BP(SKVOL); // 空单止盈
C<BKPRICE*(1-SLOSS*0.01),SP(BKVOL); // 多单止损
C>SKPRICE*(1+SLOSS*0.01),BP(SKVOL); // 空单止损
测试环境
大部分传统的指标都远远滞后于K线,但是抛物线转向可以根据内置加速因子的特性与K线紧密贴合,又不至于太过灵活,可以使策略做到攻防兼备。虽然其计算方式很复杂,但现有的指标可以直接使用,这对量化交易初学者来说非常友好。但需要注意的是,当市场进入窄幅震荡行情时,抛物线转向会经常出现无效的买入卖出信号,这将导致其暂时或者相当长时间内失效。
(*backtest start: 2015-02-22 00:00:00 end: 2019-09-27 00:00:00 period: 1h exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] args: [["ContractType","rb000",126961]] *) N:=30; // 最高/低价参数 SLOSS:=1; // 止盈止损系数 FUND:=100000; // 初始资金 LOTS:=MAX(1,INTPART(FUND/(O*UNIT*0.1))); // 计算下单量 SARLINE:=SAR(4,2,20); // 计算抛物线转向指标 B1:=SARLINE>0; // 判断是否上涨趋势 S1:=SARLINE<0; // 判断是否下跌趋势 B2:=HIGH>=HHV(CLOSE,N); // 判断最高价是否大于前期高点 S2:=LOW<=LLV(CLOSE,N); // 判断最低价是否小于前期低点 BARPOS>N AND B1 AND B2,BK(LOTS); // 开多单 BARPOS>N AND S1 AND S2,SK(LOTS); // 开空单 S1 AND S2 AND BKHIGH>BKPRICE*(1+0.01*SLOSS),SP(BKVOL); // 多单止盈 B1 AND B2 AND SKLOW<SKPRICE*(1-0.01*SLOSS),BP(SKVOL); // 空单止盈 C<BKPRICE*(1-SLOSS*0.01),SP(BKVOL); // 多单止损 C>SKPRICE*(1+SLOSS*0.01),BP(SKVOL); // 空单止损template: strategy.tpl:40:21: executing "strategy.tpl" at <.api.GetStrategyListByName>: wrong number of args for GetStrategyListByName: want 7 got 6