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

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)

回测结果:

..

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

Logo

专业量化交易与投资者大本营

更多推荐