量化投资学习笔记121——股票实盘练习12实现程序判断K线顶底形态

主要参考了:
ANDREW W. LO, HARRY MAMAYSKY, AND JIANG WANG.Foundations of Technical Analysis:Computational Algorithms, Statistical Inference, and Empirical Implementation.TEIE JOURNAL OF FINANCE VOL. LV. NO. 4 AUGUST 2000.
技术分析的一般目标是从有噪音的数据中提取出非线性模式,以在价格的时间序列数据中找到规律。这个目标意味着一些价格运动很重要,而其它的价格运动则为随机波动,应该被忽略。使用平滑估计(Smoothing Estimators)适合于该项任务。
先假设t时刻的价格Pt = m(Xt) + ε,其中m(Xt)是未知的非线性函数,ε是白噪声。
设Xt = t。
估计非线性关系最普遍的方法是平滑,估计误差可以用各种方法来估计。基本思想:在时间序列某点附近进行多次观测,将所得结果取平均值,就可以将误差抵消,从而获得对该时间序列的非线性估计。观测点与目标点距离越远,权重越小。反之权重越大。选取的点离目标点太远或太近都不好。
核回归
权重按照某种随机概率密度分布函数来分布,这也叫核(kernel)。通过调整核的带宽(bandwidth)来调整取样的距离。最常用的核函数是高斯核函数。

选择带宽
很关键,取值较小,波动较剧烈。取值较大,波动较平滑。
找到一个库,叫pyGRNN,是实现Nadaraya-Watson Estimator。试了一下复现论文中的正弦函数的例子。



可以看到带宽太大或太小,效果都不好。
用网格搜索,最佳参数为0.24。

可以看到对于技术分析来说,用网格搜索出来的参数“太光滑”了。作者考虑用最佳参数的0.3倍作为实际使用的参数。
下面就开始进行自动技术分析。
算法分三步:
①从技术形态的几何性质方面对其进行定义,例如,局部极值(极大或极小值)。
②对于一个给定的时间序列数据,进行核估计,这样可以得到其极值的数值。
③检查估计的曲线是否包含相应的技术特征。
后两步是核回归的直接应用。
第一步是考验专业技术分析人员技能和判断的时候。没有一个算法能完全掌握一位有经验的技术分析人员的技能。但如果技术分析是一门可以被教授的艺术,那在某种程度上它就可以被定量和程序化。
定义五对(十个)技术形态。
在股价时间序列的核估计函数中可以找到一系列极值点(极大值或极小值),依次标记为E1,E2,E3,…,En。
下面对几个技术形态进行定义:
定义1:头肩顶(Head-and-Shoulders, HS)和头肩顶(inverted head-and-shoulders, IHS)。
由5个极值点定义。
HS:
①E1是一个极大值。
②E3>E1,E3>E5。
③E1和E5在其平均值的1.5倍范围内。
④E2和E4在其平均值的1.5倍范围内。
IHS:
①E1是一个极小值。
②E3<E1,E3<E5。
③E1和E5在其平均值的1.5倍范围内。
④E2和E4在其平均值的1.5倍范围内。
原论文没图,我画一个吧。

定义2:顶部扩散(Broadening tops,BTOP),底部扩散(Broadening bottoms,BBOT)
由五个极值定义。
BTOP
①E1是极大值。
②E1<E3<E5
③E2>E4
BBOT
①E1是极小值。
②E1>E3>E5
③E2<E4
定义3:三角顶(Triangle tops, TTOP)和三角底(Triangle bottoms, TBOT)
由五个极值定义
TTOP
①E1是极大值。
②E1>E3>E5
③E2<E4
TBOT
①E1是极小值。
②E1<E3<E5
③E2>E4
定义4:矩形顶(Rectangle tops,RTOP)和矩形底(Rectangle bottoms, RBOT)
由五个极值组成。
RTOP
①E1是极大值。
②顶和底与它们的均值偏离均在75%以内。
③最低的高点>最高的低点。
RBOT
①E1是极小值。
②顶和底与它们的均值偏离均在75%以内。
③最低的高点>最高的低点。
定义五:双顶(Double tops, DTOP)和双底(Double bottoms, DBOT)
由一个极值E1和后续的极大值Ea和极小值Eb组成。
DTOP
①E1是极大值。
②E1和Ea位于其均值的150%的范围内。
③Ea和E1的间隔在22个交易日以上。
DTOP
①E1是极小值。
②E1和Eb位于其均值的150%的范围内。
③Eb和E1的间隔在22个交易日以上。
来看具体的算法。
对于一个价格序列{Pt},定义子集或窗口从t到t+l+d-1,这里l和d为固定参数。在论文中l=35,d=3。因此每个窗口包含38个交易数据。这使我们能把注意力集中在窗口内,避免出现较多的技术形态。但这也有个缺陷:它只能识别完整发生在窗口以内的技术形态。这一点在使用时需要牢记。
设定参数d的原因是在实操中我们并不会在形态刚刚发生的时候就能识别出形态来。在形态完成和我们能识别出形态来之间有个间隔。因此最后一个极值点应在t+l-1之内。这确保了我们实操时不会使用未来数据。
在每个窗口内,使用核回归进行估计。然后对估计结果求导,如果前后两个导数值符号相反,这就是一个极值点。
一个有用的结果是算法产生的极值都是间隔的,即一个极大值后面一定跟着的是极小值,反之亦然。使用和回归的好处是可以避免陷入局部极值。在找到窗口中的所有极值后,就可以按照技术形态的定义进行判断了。然后滑动到下一个窗口。
下面写代码,随便找了只股票,先下载最近六个月的数据。k线图是这样的。

然后用收盘价作为原始数据,用pyGRNN做核回归,网格搜索,然后用最佳参数结果作图:

最佳参数: {‘calibration’: ‘None’, ‘kernel’: ‘RBF’, ‘sigma’: 4.589999999999997}
好像太光滑了……
然后尝试用论文里的最佳参数的0.3倍作为实际使用的参数。

这就差不多了。用肉眼可以看到一些技术形态了,但关键问题是用程序找出来。
接下来进入到识别阶段,先划分窗口,按照论文,窗口宽度为从t到t+l+d-1,l=35,d=3,在t到t+l-1这个范围内找技术形态。
写了两天,终于折腾得差不多了。我就不堆代码了,在这儿https://github.com/zwdnet/stockpractice/blob/main/shape/shape.py
先找头肩底。在筛选出来的600多只股票的股票池里找,服务器上跑了一个多小时(因为每只股票都要用核回归拟合出其参数)。运行结果:

从底向上在股票软件里打开人肉看。
怎么找到的都不太像啊,最后选定一只,目标价(所谓颈线),4.11。

再找一下其它形态。
三角底

感觉都很小,找了一只,目标价4.0

矩形底没有,看看底部扩散。

随便选几只吧,这个到历史最低价了。

这个也差不多

到开盘看买哪只吧

今天大盘大跌,我选定这几只也在跌。于是一直观望。到了收盘前最后两分钟,我看60分钟线已经有反转了,于是以3.67入了一手嘉泽新能(601619),止损价3.3。应该会持有的久一点,因为是按做波段的逻辑买入的。
目前的实操账户情况。

接下来想改一下监控程序,增加到达止损价格就报警的功能。

声明:本文为个人学习记录,不构成投资建议!股市有风险,入市需谨慎!

我发文章的三个地方,欢迎大家在朋友圈等地方分享,欢迎点“在看”。
我的个人博客地址:https://zwdnet.github.io
我的知乎文章地址: https://www.zhihu.com/people/zhao-you-min/posts
我的微信个人订阅号:赵瑜敏的口腔医学学习园地

欢迎打赏!感谢支持!