欢迎大家订阅《教你用 Python 进阶量化交易》专栏!为了能够提供给大家更轻松的学习过程,笔者在专栏内容之外已陆续推出一些手记来辅助同学们学习本专栏内容,目前已推出如下扩展篇:
在第一篇《管理概率==理性交易》中笔者结合一个简单的市场模型介绍了为什么在没有概率优势的前提下参与交易会亏钱,其实股票交易和玩一个游戏、做一个项目理念是相通的,需要章法、需要制定策略,否则就和抛硬币赌博一样一样的,用量化交易可以帮助我们管理好概率,更理性的去下单。
在第二篇《线性回归拟合股价沉浮》中笔者在专栏《股票交易策略开发:走势线性回归选股策略》小节的基础上对线性回归方法的策略应用做进一步的扩展介绍。由于线性回归作用于股票收盘价的整个周期,前后两段完全相反的周期会彼此作用,最终影响拟合的角度值,于是笔者设定窗口期用移动窗口的方式拟合股价的走势,寻找角度曲线的拐点以预示新一轮的反转走势,给大家提供一个衍生的策略思路。
在第三篇《最大回撤评价策略风险》中笔者在专栏
《股票交易数据可视化:买卖区间下策略收益绘制》的基础上对策略的最大回撤指标做一定的扩展介绍。投资是有风险的,那么如何去衡量这个风险呢?最大回撤率就是一种直观的将风险切实量化的指标,它描述了买入股票后,在策略出现最糟糕的情况下会损失多少钱,这也直接关系到了风险策略中止损因子的设定。
在第四篇《寻找最优化策略参数》中笔者在专栏
《股票交易策略开发:趋势突破择时策略》的基础上对寻找最优化策略参数的方法做一些扩展介绍。对于寻找最优化参数的方法可以选择枚举法或者蒙特卡洛法。枚举法适用于解决效率要求不高,样本规模小的问题。蒙特卡洛法得到的结果并不一定是最优的,但是在大规模样品的场合下可以更快地找到近似最优结果。
在第五篇《标记A股市场涨跌周期》中笔者在专栏
《股票交易数据的自动下载》的基础上对matplotlib绘图工具的使用方法做一些扩展介绍,在A股历史走势图中标记出市场涨跌周期。
在第六篇《Tushare Pro接口介绍》中笔者在《股票交易数据的自动下载》的基础上扩展介绍使用Tushare Pro版本获取财经和股票交易数据的方法。
在第七篇《装饰器计算代码时间》中笔者在《用装饰器注册股票池》的基础上对装饰器的进行扩展介绍,通过装饰器方式实现timeit测试函数执行时间功能。
本次场外篇笔者在《技术分析常用指标绘制》的基础上对KDJ指标的计算进行扩展介绍,由之前for…in循环遍历方式升级为矢量化方式,并且用自制的@timeit装饰器对比两种方式的效率。
KDJ指标在各大股票行情软件中都会体现,一般在股票K线图下方,如下图所示:
关于KDJ指标的特点和它的来龙去脉,笔者在专栏中有具体的介绍。在专栏中KDJ指标的实现是采用for…in循环遍历的方式,目的是让同学们更容易理解,但是在效率上并不是最佳的。先看下当前实现KDJ指标的数值,如下所示:
print(df_stockload.loc[:,['K', 'D','J']].head(20))
print(df_stockload.loc[:,['K', 'D','J']].tail(10))
K D J
Date
2018-01-02 NaN NaN NaN
2018-01-03 NaN NaN NaN
2018-01-04 NaN NaN NaN
2018-01-05 NaN NaN NaN
2018-01-08 NaN NaN NaN
2018-01-09 NaN NaN NaN
2018-01-10 NaN NaN NaN
2018-01-11 NaN NaN NaN
2018-01-12 50.000000 50.000000 50.000000
2018-01-15 43.006532 47.668844 33.681909
2018-01-16 43.311542 46.216410 37.501805
2018-01-17 35.018155 42.483658 20.087149
2018-01-18 28.835633 37.934317 10.638267
2018-01-19 21.474105 32.447580 -0.472844
2018-01-22 21.143383 28.679514 6.071121
2018-01-23 20.387414 25.915481 9.331281
2018-01-24 26.739757 26.190239 27.838792
2018-01-25 34.780534 29.053671 46.234261
2018-01-26 43.876661 33.994668 63.640648
2018-01-29 41.339019 36.442785 51.131487
K D J
Date
2018-12-18 22.180222 30.130738 6.279189
2018-12-19 15.725781 25.329086 -3.480829
2018-12-20 14.709213 21.789128 0.549383
2018-12-21 13.972795 19.183684 3.551017
2018-12-24 19.037423 19.134930 18.842410
2018-12-25 22.215432 20.161764 26.322768
2018-12-26 25.336607 21.886712 32.236398
2018-12-27 19.391069 21.054831 16.063544
2018-12-28 16.260719 19.456794 9.868570
2019-01-02 20.035902 19.649830 20.808046
将KDJ实现部分的代码封装为函数cal_kdj_loop(),并用装饰器@timer_para打印该函数执行的时间,运行时间如下所示:
Time of %s used: %s 0 0.28521588100000006
接下来介绍下矢量化实现的方法,仅仅只要6行代码即可,减少了一半以上,如下所示:
def cal_kdj_vector(df_data):
low_list = df_data['Low'].rolling(9, min_periods=1).min()
high_list = df_data['High'].rolling(9, min_periods=1).max()
rsv = (df_data['Close'] - low_list) / (high_list - low_list) * 100
df_data['K'] = rsv.ewm(com=2, adjust=False).mean()
df_data['D'] = df_data['K'].ewm(com=2, adjust=False).mean()
df_data['J'] = 3 * df_data['K'] - 2 * df_data['D']
return df_data
此处使用了pandas.DataFrame.ewm()函数平滑KD值,该函数提供指数加权平滑功能,函数原型如下所示:
DataFrame.ewm(com=None, span=None, halflife=None, alpha=None, min_periods=0, adjust=True, ignore_na=False, axis=0)
当adjust为False时,以递归方式计算加权平均值:
weighted_average[0] = arg[0]
weighted_average[i] = (1-alpha)*weighted_average[i-1] + alpha*arg[i]
com为2则alpha为1/3,于是K值为(2/3*前一日K值 + 1/3 当日RSV值),不过此处K值初值为rsv[0],而专栏中默认设定为50,因此计算得到的具体数值在开始阶段会有所不同。
计算得到的KDJ指标的数值,如下所示:
print(df_stockload.loc[:,['K', 'D','J']].head(20))
print(df_stockload.loc[:,['K', 'D','J']].tail(10))
K D J
Date
2018-01-02 66.666490 66.666490 66.666490
2018-01-03 71.895300 68.409427 78.867046
2018-01-04 70.152422 68.990425 72.476416
2018-01-05 62.112192 66.697681 52.941214
2018-01-08 65.721838 66.372400 64.420714
2018-01-09 60.677308 64.474036 53.083853
2018-01-10 71.076537 66.674870 79.879872
2018-01-11 73.920300 69.090013 83.580874
2018-01-12 66.273665 68.151231 62.518535
2018-01-15 53.855643 63.386035 34.794858
2018-01-16 50.544282 59.105450 33.421945
2018-01-17 39.839982 52.683628 14.152691
2018-01-18 32.050185 45.805813 4.538927
2018-01-19 23.617139 38.409589 -5.967759
2018-01-22 22.572072 33.130417 1.455384
2018-01-23 21.339874 29.200236 5.619150
2018-01-24 27.374730 28.591734 24.940722
2018-01-25 35.203850 30.795772 44.020004
2018-01-26 44.158871 35.250139 61.976336
2018-01-29 41.527159 37.342479 49.896519
K D J
Date
2018-12-18 22.180222 30.130738 6.279189
2018-12-19 15.725781 25.329086 -3.480829
2018-12-20 14.709213 21.789128 0.549383
2018-12-21 13.972795 19.183684 3.551017
2018-12-24 19.037423 19.134930 18.842410
2018-12-25 22.215432 20.161764 26.322768
2018-12-26 25.336607 21.886712 32.236398
2018-12-27 19.391069 21.054831 16.063544
2018-12-28 16.260719 19.456794 9.868570
2019-01-02 20.035902 19.649830 20.808046
代码量减少了,那么效率是否提高了呢?将函数cal_kdj_vector()用装饰器@timer_para打印该函数执行的时间,运行时间如下所示:
Time of %s used: %s 0 0.03495547999999982
矢量化方式计算KDJ指标相比于使用for…in循环方式效率提高了12倍!!!以下为两种方式实现的KDJ指标可视化绘制:
关于完整代码可以加入专栏交流群获取。更多的量化交易内容欢迎大家订阅专栏阅读!!
热门评论
元宵大师,你好,请问可以给我这篇的完整代码吗,谢谢