闫斌
武汉学院信息工程学院
【摘要】:形态分析是一种重要的技术分析方法, 如何在不同板块众多种类的股票中挑选出具有投资价值的股票已经成为一个亟待解决的问题。道氏理论认为市场波动具有某种趋势,不同时期多空双方力量对比的大小决定了股票价格时间序列是向上还是向下运行。找到对盈利有益的形态,是投资者关心的目标。本章方法提供的程序经过适当的修改,便可以对以上提出的问题进行进一步的检验。
关键词:股票市场;聚类分析;主成分分析
依托项目:教育部科技发展中心项目高校产学研创新基金项目-新一代信息技术创新项目2018A02016基于大数据的行业系统推荐研究,B2018361基于大数据挖掘的企业决策系统研究,
指导教师:李琼 龚鸣敏
1引言
中国股市从无到有,发展至今日渐完善,现已颇具规模。目前,一些经典的分析形态,比如双重顶、三重顶、双重底、三重底、上升三角、下降三角、头肩顶等已广为投资者熟知,这些形态是否还有指导意义值得商榷,更重要的是这些形态需要人工处理,在交易大数据的今天显然很难实施。近几年偏股类基金保有量持续提升。从2019年起偏股类公募基金保有量有所上行,占比从2018年的40%提升至2020年11月的54%,提升近14个百分点。债券基金保有量占比有所下降,从2018年的42%下降至23%。
面对股票的大量数据信息,财务数据、基本面数据、价格数据,如何从这些大数据高纬度的信息中找到有用的数据是一个值得研究的问题。我们已经步入了大数据的时代数据挖掘等与之相关名词越来越多的出现在我们的视野中。在数据挖掘的众多方法中,聚类分析的应用极其广泛,它的基本思想是根据数据之间的相似性度量来把数据分类,一般相似矩阵构造的好坏会决定聚类效果的好坏。这从直观上也很容易理解,如果把一个衡量数据之间关系的度量刻画的越精确,结果当然就越能反映数据之间的关系。我们会发现对数据进行分类之后仍然有很多问题需要解决,因为股票分类完成后还需要筛选出真正具有投资价值的股票。
2 案例背景
投资者通过实战经验,总结出了各种各样的股票价格走势形态以辅助投资决策。比如常见的头肩形、倒头肩形、三重顶、三重底、M头、W底等。
然而投资者的经验是有限的,特别是新进股市的投资者。进一步地,常用的股票形态已经为广大投资者熟知,一定程度上降低了这些形态的有效性。同时,一些新的形态或许隐藏在其中而没有被发现。本案例通过实际的股票交易数据,提取价格形态特征,采用聚类分析的方法,对其形态特征数据进行自动聚类分析,并根据聚类的结果计算每类股票未来持有期为一个月的平均收益率。然后将类平均收益率排名前5的股票记为+1类,其余股票记为-1类,作为训练样本,采用支持向量机模型进行训练。最后,利用训练好的支持向量机模型对新的股票价格形态特征数据进行预测。如果预测结果为+1,表示该只股票在未来一个月内会得到较好的投资回报率,即设计一个量化投资策略:以未来一个月为持有周期,以期初收盘价买入,期末收盘价卖出,计算其收益率。这里采用第8章中基于总体规模与投资效率指标的综合评价方法,获取其排名前400的股票作为研究样本;用于聚类的股票价格数据周期取三个月,每类股票平均收益率=该类中各个股票收益率之和/该类股票总数,单只股票的收益率=(该股票期末收盘价-该股票期初收盘价)/该股票期初收盘价。
3案例目标及实现思路
案例主要目标是采用数量化的方法,找出未来具有较好投资回报率的股票价格走势形态,从而为投资者提供一定的参考价值。案例实现的思路及流程如下:
3.1数据获取
案例获取的数据包括中国股票市场A股2017年度日行情交易数据(DA.xlsx,、交易日历数据表.xlsx、沪深300指数交易数据表。
3.2关键价格点概念及提取算法
通过分析我们可以发现,股票价格走势主要由一些关键价格点构成,因为我们选择其关键的价格点作为聚类特征即可。由文献[14],构成的序列模式,越大,成为关键点的可能性就大。下面我们给出关键价格点提取算法。
关键价格点提取算法:
输入:原始价格序列x=(x1,x2,……,xp),提取关键点个数num
输出:关键价格点序列、对应下标序列
step1:对x2,……,x(p-1),按公式计算其与相邻两个价格点均值的绝对值大小,并按从大到小进行排序,取排名前num-2对应的价格点,记为L1,对应的下标序列记为S1.
step2:记x1,xp对应的价格点记为L2,对应的下标序列记为S2;
step3:记L=L1L2,S=S1S2,并按S进行从小到大进行排序,则L即为关键价格点序列,S即为对应的下标序列。
关键点提取算法函数如下(函数定义在df.py文件中):
def get_keydata(x,num):
import pandas as pd
import numpy as np
#计算x2,……,x(p-1)各点减去相邻两点平均值的绝对值
d=abs(x[1:len(x)-1].values-(x[0:len(x)-2].values+x[2:len(x)].values)/2)
#以d为值,对应的下标为index,构建序列,并按降序排序
Sd=pd.Series(d,index=np.arange(1,len(x)-1)).sort_values(ascending=False)
L1=Sd[0:num-2]
L2=pd.Series([x[0],x[len(x)-1]],index=[0,len(x)-1])
L=L1.append(L2)
keydata=x[L.index].sort_index()
return keydata
其中函数输入参数为价格数组X、提取的关键点个数num,返回值为关键点序列(index为下标、value为对应的关键点价格点)。作为一个例子,取股票代码600000,2017年6月1日至2017年8月31日的收盘价数据,提取10个关键点,并在同一坐标轴上绘制原始价格点与关键价格点拟合图,示例代码如下:
import pandas as pd
import df
import matplotlib.pyplot as plt
data=pd.read_excel('DA.xlsx')
#提取满足日期条件的数据
I1=data['Trddt'].values>='2017-06-01'
I2=data['Trddt'].values=<'2017-08-31'
I=I1&I2
data1=data.iloc[I,:]
#提取代码600000的收盘价
dt=data1.loc[data1['Stkcd']==600000,['Clsprc']]['Clsprc']
#收盘价序列的index重排,从0开始
dt=pd.Series(dt.values,index=range(len(dt)))
#调用关键点获取函数
keydata=df.get_keydata(dt,10)
#绘图
plt.plot(dt.index,dt.values)
plt.plot(keydata.index,keydata.values,'r*--')
最终得到拟合效果图如图10-1及关键点如下。
关键价格点(keydata.values)为:
[ 12.92 12.53 12.86 13.76 13.55 13.45 13.67 13.44 12.47 12.71]
对应的下标(keydata.index)为:
[0, 27, 29, 32, 33, 36, 37, 44, 60, 65]
从拟合的效果可以看出,关键点基本能表示原来的价格走势,因此采用关键点进行分析即可。
3.3 K-最频繁值聚类算法
由于K-均值聚类算法主要适用于数值特征数据,而本章10.4.2中提取的股票价格形态特征数据是经过离散化的离散变量(名义变量),因此经典的K-均值聚类算法不再适用。本节借鉴K-均值聚类算法的思想,给出K-最频繁值聚类算法,该算法与K-均值聚类算法不同之处主要体现在距离度量和类中心的更新方法上,其中距离度量函数采用海明距离,类中心的更新方法则选择类样本特征向量分量出现最多的值(最频繁值,经典的K-均值聚类算法采用的是平均值)作为类中心特征向量的分量。具体算法如下:
输入:特征数据集,聚类个数K。
输出:特征数据集及其类标签。
Step1. 随机初始化K个聚类中心,即K个类中心向量。
Step2. 对每个样本,计算其与各个类中心向量的距离,并将该样本指派给距离最小的类,这里的距离采用海明距离,其计算公式如下:
Step3. 更新每个类的中心向量,更新的方法为取该类所有样本的特征向量的最频繁值。
Step4. 直到各个类的中心向量不再发生变化为止,并输出类标签。
在Python中没有现成的函数可以调用,故本节给出其函数的具体定义。事实上该函数与5.7.1定义的函数非常类似,下面给出其具体的定义。
def K_mean(data,knum):
#输入:data--聚类特征数据集,要求为数据结构要求为numpy数值数组
#输入:knum--聚类个数
#返回值,data后面加一列类别,显示类别
import pandas as pd
import numpy as np
p=len(data[0,:]) #聚类数据维度
cluscenter=np.zeros((knum,p)) #定预定义元素为全0的初始聚类中心
lastcluscenter=np.zeros((knum,p)) #定预定义元素为全0的旧聚类中心
#初始聚类中心和旧聚类中心初始化,取数据的前knum行作为初始值
ss=pd.DataFrame(data)
ss=ss.drop_duplicates()
ss=ss.as_matrix()
for i in range(knum):
cluscenter[i,:]=ss[i,:]
lastcluscenter[i,:]=ss[i,:]
#预定义聚类类别一维数组,用于存放每次计算样本的所属类别
clusindex=np.zeros((len(data)))
count=0
while 1:
count=count+1
for i in range(len(data)):
#计算第i个样本到各个聚类中心的欧式距离
#预定义sumsquare,用于存放第i个样本到各个聚类中心的欧式距离
sumsquare=np.zeros((knum))
for k in range(knum):
s=data[i,:]-cluscenter[k,:]
sumsquare[k]=len(s[s!=0])
# sumsquare[k]=sum((data[i,:]-cluscenter[k,:])**2)
#sumsquare=np.sqrt(sumsquare)
#第i个样本到各个聚类中心的欧式距离进行升序排序
s=pd.Series(sumsquare).sort_values()
#判断第i个样本的类归属(距离最小,即s序列中第0个位置的index)
clusindex[i]=s.index[0]
#将聚类结果添加到聚类数据最后一列
clusdata=np.hstack((data,clusindex.reshape((len(data),1))))
#更新聚类中心,新的聚类中心为对应类别样本特征的均值
for i in range(knum):
ci=clusdata[clusdata[:,p]==i,:-1]
for j in range(p):
s1=pd.Series(ci[:,j]).value_counts()
cluscenter[i,j] =s1.index[0]
#cluscenter[i,:]=np.mean(clusdata[clusdata[:,p]==i,:-1],0).reshape(1,p)
#新的聚类中心与旧的聚类中心相减
t=abs(lastcluscenter-cluscenter)
#如果新的聚类中心与旧的聚类中心一致,
#即聚类中心不发生变化,返回聚类结果,并退出循环
if sum(sum(t))==0:
return clusdata[:,p]
break
#如果更新的聚类中心与旧的聚类中心不一致,
#将更新的聚类中心赋给旧的聚类中心,进入下一次循环
else:
for k in range(knum):
lastcluscenter[k,:]=cluscenter[k,:]
if count==10000:
return clusdata[:,p]
break
该函数的输入参数为特征数据data(要求为数据结构要求为numpy数值数组)、聚类个数knum。返回值为带类别标签的特征数据集,即在data后面加一列类别标签。
4结论
形态分析也是技术分析的常用手段,也存在众多投资者总结出来的投资形态。通过数据挖掘方法自动找到对投资者有价值的形态。为了降低股票价格维度,给出了关键价格点的概念和提取方法,通过关键价格点来描述原来的股票形态走势。进一步地,利用关键价格点提取股票形态特征进行自动聚类,并对每类股票计算未来一定持有期的平均收益率,在此基础上对每个类别的股票按收益率高低(排名前5作为界限)分为两类来构建训练样本。最后,根据训练样本训练支持向量机模型,并利用支持向量机模型自动寻找高收益率的股票形态。为了检验方法的有效性,设计了其量化投资策略,也获得了较好的效果。需要说明的是本章方法其稳定性和应用还需要作进一步的研究,关键点的提取个数、聚类的个数、交易周期的选择等相关问题还需要进一步研究及检验,这里仅提供一个思路及实现方法。
参考文献:
[1]面向股票交易分析场景的流式大数据系统测试框架,史凌云;郑莹莹;谭励,许利杰;王伟,
计算机系统应用,2020-04-15
[2]面向大数据的并行聚类算法在股票板块划分中的应海沫;牛怡晗;张悦今,大数据,2015-11-20