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

抛物线转向SAR与价格高低点策略

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

摘要

抛物线转向是一个很奇特的技术分析指标,由美国威尔斯·威尔德(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);                     // 空单止损

策略回测

测试环境

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

结尾

大部分传统的指标都远远滞后于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