第 13 章 KNN 简单策略

机器学习算法是近年量化策略的热点,我们在这一章中通过一个简单的例子感受一下。

KNN 是机器学习中的一种算法,它的核心思想是:如果一个样本在特征空间中的 K 个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别。更通俗点说,KNN 可以找到和目标样本最相似的 K 个样本,然后根据其中的大多数来预测目标样本。

我们也可以用这种方法来预测股票的涨跌,构造一个特征空间然后在历史数据中找到和当日特征最相似的 K 个交易日数据,然后根据这 K 个交易日第二天的涨跌情况来预测第二天的涨跌(大多数涨就预测为涨,大多数跌就预测为跌)。

KNN 简单策略的具体方法如下:

1. 将第二天是否上涨作为预测目标,即计算收盘 [1]- 收盘,大于 0 时目标值为 1,小于 0 时为 -1,其余为 0。

2. 增加两个特征,最高价 - 最低价和收盘价 - 开盘价作为特征空间

3. 计算历史数据和当日样本特征之间的距离,距离越近越相似。具体为:计算当天样本特征和之前 n 个交易日的特征距离,找到距离最近的 m 个交易日数据,把这 m 个交易日目标值的众数作为第二天的预测结果。

计算距离的常用的方法有欧式距离和马氏距离,在 SPL 里有现成的函数 dis()和 dism(),这里我们用欧式距离来计算。

需要注意的是,在使用一些比较专业的数学函数时,需要打开 SPL 里的数学库。

工具→选项:

..

可以在文档外部库 -Math里查看数学库有哪些函数。

言归正传,我们同样先将 KNN 的计算方便编写为指标,再用指标写策略。

定义指标参数:

A

序表,K线数据

y

指标返回列。1上涨信号,-1下跌信号

n

数字,计算和前n个交易日的特征距离

m

数字,前m个距离最近的数据

indicator.splx中编写指标函数:


A

B

……

……

47

func KNNDIF(A, $y, n, m)

=A.derive@o( [最高-最低,收盘-开盘]:KNNDIF1, sign(收盘[1]-收盘):KNNDIF2)

48


=A.run(${y}=~[-n:-1].top(m; dis( KNNDIF1, A.KNNDIF1) ).(KNNDIF2).mode() )

49


=A.alter(; KNNDIF1, KNNDIF2)

当 KNN 指标结果为 1 且空仓时,下买入订单;指标结果为 -1 且有持仓股票时,下卖出订单。n 和 m 分别取 100 和 20:


A

B

1

>call("init.splx")


2

2024

=date(A2,1,1)

3

=workday(B2,-110,HOLIDAY)

=date(A2,12,31)

4

600690

=Load@C(A4, A3,B3)

5



6

=B4.derive(:KNN)


7

=KNNDIF(A6, KNN, 100, 20)

8



9

=Begin(A6)


10

=A9.select(日期>=B2)

11

for A10

=H=昨日.持仓

12


=卖出=if(昨日.KNN==-1,SellOff( ~, H,收盘 ) )

13


=if(昨日.KNN==1 && H.len()<=0, 买入|=Buy( ~,100,收盘))

14


=Loop()

15

=Summary(A10)

=Display(A15)

回测结果:

..

看起来先进技术的效果也不见得更好。