这个策略的核心思想是:利用昨日巨大的振幅和价格变动,来预测未来一天到几天的短期趋势,并在第二天开盘附近买入,在后续的日子里卖出。

A.策略逻辑

前一天出现异常大的振幅,通常意味着市场出现了激烈的多空博弈。如果股价最终收在高位(形成一根坚挺的阳线),可能预示着多方获胜,上涨势头有望延续。我们的策略就是在信号出现后,第二天跟进,并持有一定时间。

B.买入信号条件

    ~今日振幅巨大: (今日最高价 - 今日最低价) / 昨日收盘价 > 阈值A

公式解释:今日的振幅超过了正常水平。阈值A 是一个可调参数,例如可以设为 5%(0.05)。这意味着振幅要大于5%才算异常。

   ~收阳线且涨幅可观: (今日收盘价 - 今日开盘价) / 今日开盘价 > 阈值B

公式解释:虽然是巨大振幅,但最终是多方力量更强,收出了一根实体阳线。阈值B 可以设为 2%(0.02)或 3%(0.03)。

C.买入时机:

在信号日出现的第二天(T+1日),以昨日收盘价买入。

D.卖出时机:

买入后,设置一个目标盈利点和止损点。

  • 止盈:当股价从买入价上涨达到 X% 时,卖出。例如 X = 5%。
  • 止损:当股价从买入价下跌达到 Y% 时,坚决卖出止损。例如 Y = 3%。
  • 补充条件:如果一直没达到止盈或止损,则在买入后的第M天(例如第5天)无条件卖出。

根据上述描述,我们来实现此策略:

第一步定义买入信号列:

买卖信号列的输出规则是这样:1表示第二天执行买入;-1表示第二天执行卖出;0表示不操作。需要再次说明的是,这里设计的是离线策略,也就是用截止到昨日的收盘数据算出的买卖信号列值,来决定第二天的买卖操作

指标类型选SPL公式,输出列名填买入信号,输出列类型选信号,表达式为if((最高-最低)/收盘[-1]>0.05 && (收盘-开盘)/开盘>0.02,1,0),点提交

~SPL公式:列名引用

SPL公式中可以直接引用数据窗口中显示的列名:

比如上例中的开盘、收盘、最高、最低就是数据显示窗口中的列名。

~SPL公式:四则运算符

说明:SPL的四则运算符大体和excel一致,少量会有不同,这里列出excel和SPL的异同:

相同之处

  1. 基本运算符相同:+-*/ > >= < <=
  2. 运算优先级相同:乘除法优先于加减法,可用 () 改变顺序

不同之处

特性

Excel

SPL公式

幂运算

^

 power(),如power(2,3)

取模运算

 MOD()

 %  (如 5%2 返回 1)

布尔值

 TRUE/FALSE

 true/false(小写)

比较运算

<> 

!= 

空值

用 NA() 或空单元格或NULL

 null(小写)

大小写

大小写不敏感

大小写敏感,大部分函数和关键词小写,少数大写

逻辑运算符与

AND()

&& (如收盘>=5 && 收盘<=10)

OR()

|| (如收盘<=5 || 收盘>=10)

NOT()

! (如买卖信号列!=0)

~SPL公式:什么是收盘[-1]?

收盘[-1]表示引用当前行的前一行中的收盘列值;相应地,收盘[1] 表示引用当前行的后一行中的 收盘列值。这是SPL语言中特有的相对位置引用语法,常用于需要访问相邻行数据的计算场景。

基本特性:

  • 相对定位:基于当前行的相对位置访问
  • 动态计算:引用的具体值取决于当前处理的行位置
  • 边界处理:当引用超出序列范围时(如第一行的前一行,或最后一行的后一行),返回null

典型应用场景

  • 计算涨幅
  • 查找相邻行
  • 实现滑动窗口计算

图示说明

  • 示例数据表
  • 收盘[-1]和收盘[1] 运算过程

日期

收盘

2022-01-04

29.15

2022-01-05

29.09

2022-01-06

29.26

2022-01-07

29.48

当前处理行

收盘[-1]取值

收盘[1]取值

收盘[-1]计算逻辑

收盘[1]计算逻辑

2022-01-04

null(无前一行)

29.09

[无前一行]

取2022-01-05收盘

2022-01-05

29.15

29.26

取2022-01-05收盘值

取2022-01-06收盘值

2022-01-06

29.09

29.48

取2022-01-05收盘

取2022-01-07收盘

2022-01-07

29.26

null(无后一行)

取2022-01-06收盘值

[无后一行]

边界情况处理

  • 首行:收盘[-1] 返回 null
  • 尾行:收盘[1] 返回 null
  • 跨组分引用:在分组计算中,相对引用不会跨组
  • 多行偏移:也支持如 收盘[-2] (前两行)、收盘[3] (后三行)等写法

这种相对位置引用机制使得时间序列计算、滑动窗口分析等场景的表达式非常简洁直观。

~SPL公式:if()函数

函数说明:

       条件判断函数,根据条件表达式的真假,返回不同分支的计算结果

函数语法:

       if(a)                      当条件a为真时,返回true,否则返回false

if(a,b,c)                 当条件a为真时,返回b的计算结果,否则返回c的计算结果

if(x1:y1,…,xk:yk;y)   当条件x1为真时,返回y1的计算结果;否则当条件x2为真时返回y2的计算结果;否则……依此类推,如果所有xk均为假,则返回y的计算结果。

用法示例:

  1. if((收盘-开盘)/开盘>0.02)

表达式含义:当(收盘-开盘)/开盘>0.02满足时返回true,否则返回false

  1. if((最高-最低)/收盘[-1]>0.05 && (收盘-开盘)/开盘>0.02,1,0)

表达式含义:当(最高-最低)/收盘[-1]>0.05 && (收盘-开盘)/开盘>0.02满足时返回1,否则返回0

  1. if(收盘<23:1,收盘>28:-1;0)

表达式的含义:当收盘<23满足时返回1,当收盘>28满足时返回-1,否则返回0


第二步定义策略:买入信号列选买入信号,买入价格选昨日收盘价,卖出信号列不选(意思是不按此操作),止盈填5,止损填3,最长持仓日填5,平仓缺省价格选昨日收盘价,最后提交:

提交后,可看到回测结果如下:

可以看出,当涨幅超过5%或跌幅超过3%时,会自动卖出。

前面定义策略时,把最大持仓数置空,表示回测时只要信号列返回1,第二天就执行买入操作;如果设为数字n,则只要当前持仓笔数等于n,即使信号列返回1,第二天也不会操作。我们可以把上面的策略按最大持仓数为空和为1做个对比:

从上面两图可以看出,如果最大持仓数为空,则只要满足买入条件,就会持续买入;反之,只要当前持仓数等于最大持仓数,即使满足买入条件,也不会再次买入。

Logo

加入社区!打开量化的大门,首批课程上线啦!

更多推荐