SPL 量化系列实践:海龟策略

海龟策略:在股价超过过去N个交易日的股价最高点时买入,在股价低于过去N个交易日的股价最低点时卖出(N通常设为20)。上述的若干个最高点和最低点会组成一个通道,称为“唐奇安通道(Donchian Channel)”。

把大于“唐奇安通道”上沿时设为买入信号(1),低于下沿时设为卖出信号(-1),其他时间为不操作(0),据此生成买卖信号(signal)。

当有买入信号且空仓时,下买入订单;有卖出信号且有持仓股票时,下卖出订单。据此生成下单信号(flag),flag=1为买入,flag=-1为卖出,flag=0为不操作。

这里以股票代码为300750为例介绍,交易时段是从202011日到202436日。因为在这期间300750有分红送股等,所以需要对股价复权,回测通常用后复权的方式(后复权的方法见《复权价格》)。

SPL代码


A

1

=file("daily/300750.csv").import@tc()

2

=A1.select(trade_date>=20200101&&trade_date<=20240306)

3

=A2.derive(if(#>1, close/ pre_close *factor[-1], close/pre_close):factor)

4

=hfq_fst=A3(1),A3.derive(round(factor/hfq_fst.factor*hfq_fst.close,2): hfq_close)

5

=ps=0

6

=A4.new(ts_code,trade_date,hfq_close,if(#==1,hfq_close,hfq_close[-20:-1].max()):taq_up,if(#==1,hfq_close,hfq_close[-20:-1].min()):taq_down,if(#>20&&hfq_close>taq_up,1,if(#>20&&hfq_close<taq_down,-1,0)):signal,if(ps==0&&signal==1,(ps=1,1),if(ps!=0&&signal==-1,(ps=0,-1),0)):flag,if(flag!=0,100,0):shares)

A2202011日到202436日的行情数据,下图是部分数据:

..

A3:复权因子

A4:后复权价

A6:生成唐安奇通道(taq_up:通道上限;taq_down: 通道下限)、买卖信号(signal)和下单信号(flag),每次交易股票数是100股。

下图是部分结果:

..

SPL提供了[]来获取当前成员附近的元素,负数表示当前成员前,正数表示当前成员后,比如close[-20:-1]close字段当前成员前边20个到前边第1个的成员集合。如果要用Python完成相同的任务,需要shift(1).rolling(20)shift(1)偏移索引,rolling(20)将之前20个成员打包成一个很难理解的对象,相较之下,SPL的写法更简单明了。

其次A4.new(…)中每个新生成的字段都可以用到后续的计算中,比如taq_uptaq_down可以用在signal的计算中,signal又可以用在flag的计算中,而这是Python所不能的,它只能一个一个计算这些字段的值。

利用A6的数据可以画出这支股票的后复权股价走势、唐安奇通道以及买卖点。画图前需要把trade_date转换成日期格式。trade_date作为横轴,股价作为纵轴。flag=1为买点(红色圆形),flag=-1为卖点(绿色方形)。

买卖示意图如下:

..

之前介绍了回测的例程(《SPL量化系列实践:回测例程》),筛选出A6flag不等于0的数据即为回测的入参数据trade_date,结果如下:

..

再把结束日期设为20240306即可回测。

回测收益率走势图如下:

..

图中纵轴是收益率,红色圆点为买入点,绿色方点为卖出点。

回测指标见下表:

indicators

value

累计收益率 (cumulative rate of return)

25.05%

年化收益率 (annualized rate of return)

6.14%

年化波动率 (annual volatility)

35.77%

夏普比率 (sharpe ratio)

0.09

最大回撤 (maximum drawdown)

37.68%

投入现金 (cash invested)

37916.59

总资产 (total assets)

47416.59

仓位占比 (stock holding ratio)

62.74%

盈利次数 (profit times)

5

亏损次数 (losses times)

11