从本文开始准备写写关于股票量化交易的连载博客,重点记录自己对于量化交易平台实现的学习路径,针对一些重点第三方库以及重点知识做个备忘录。
我要实现的量化交易框架只是一个针对金融数据获取、清洗、整合及一些量化策略的实现、回测等功能,并不会实现股票真实的程序化交易功能,所有在实现量化交易框架必须先掌握一些第三方库的知识,这里给出涉及到的相关库,需要提前安装并对库的使用知识提前储备.
NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
可以通过安装Anaconda3来实现NumPy、Pandas等基础库的安装,也可以使用下面命令安装Numpy:
pip3 install numpy scipy matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
默认情况使用国外线路,国外太慢,我们使用清华的镜像。
关于Numpy的教程可以单击《Numpy教程》链接进行学习。
Pandas 是 Python 的核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。Pandas 的目标是成为 Python 数据分析实践与实战的必备高级工具,其长远目标是成为最强大、最灵活、可以支持任何语言的开源数据分析工具。
同样Pandas可以通过安装Anaconda3来实现统一安装,如果需要单独安装可以使用下面的命令:
conda install Pandas
如果要安装指定版本的pandas使用下面命令
conda install Pandas=0.20.3
pip3 install Pandas
股市金融数据获取我主要通过两个平台,一个是tushare,一个是聚宽,两个平台都可以注册后免费使用,国泰君安的量化交易库也是使用的聚宽平台的jqdata库,有兴趣可以搜索了解一下,如果有交易账号的话可以自己直接实现程序化交易的部分。
pip3 install tushare
注意该平台现有新旧两个接口文档,新接口将一些功能从旧接口中迁移了,使用时要注意看文档。
新接口文档链接
导入包方式
import tushare as ts
pip3 install jqdatasdk
或者下面的,速度能快点:
pip3 install jqdatasdk -i https://mirrors.aliyun.com/pypi/simple/
升级:
pip3 install -U jqdatasdk
导入jqdatasdk包方式
import jqdatasdk as jq
TA-Lib,全称“Technical Analysis Library”, 即技术分析库,是Python金融量化的高级库,涵盖了150多种股票、期货交易软件中常用的技术分析指标,如MACD、RSI、KDJ、动量指标、布林带等等。TA-Lib可分为10个子板块:Overlap Studies(重叠指标),Momentum Indicators(动量指标),Volume Indicators(交易量指标),Cycle Indicators(周期指标),Price Transform(价格变换),Volatility Indicators(波动率指标),Pattern Recognition(模式识别),Statistic Functions(统计函数),Math Transform(数学变换)和Math Operators(数学运算),见下图。
安装与使用
安装:在cmd上使用“pip install talib”命令一般会报错,正确安装方法是,进入https://www.lfd.uci.edu/~gohlke/pythonlibs/,下拉选择TA_Lib-0.4.19-cp38-cp38-win_amd64.whl(win系统64位,python3.8版本,根据自己系统和python版本选择相应的安装包),将下载包放在某一路径中,然后在Anaconda Prompt(或windows的cmd)里面输入命令:
pip install [文件全路径名]
安装效果(TA_Lib-0.4.19-cp38-cp38-win_amd64.whl文件放在C:\Users\ml\Desktop\Python路径下)
安装后登录Python测试:
由于talib库没有中文文档,此处给出两个参考链接,深入学习还请自行搜索吧。链接一、链接二。
连接二是比较全的翻译文档。
Matplotlib 是 Python 的绘图库。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。
可以通过anaconda3进行安装也可以用下面方式:
pip3 install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
使用镜像地址安装速度块。
学习文档链接。
使用Python的matplotlib库,可以快速创建高质量的图形,绘制金融类图形建议使用mplfinance模块,mplfinance原本是Matplotlib的子模块,现被剥离成为一个独立的库。对于绘制K线图等金融领域常用的可视化图形建议使用mplfinance模块。
mplfinance模块是在2020年初开始频繁更新的,在此之前最常用的是旧版mpl_finance模块,别看名字只差一点,但用法还是象成很大的。现在使用旧版已经会提示:
WARNING: `mpl_finance` is deprecated:
Please use `mplfinance` instead (no hyphen, no underscore).
To install: `pip install --upgrade mplfinance`
For more information, see: https://pypi.org/project/mplfinance/
旧版说不定哪天就停用了。而新版mplfinance比旧版使用起来更加方便,使得创建金融图表变得更加容易,并且新版能很好的直接与pandas数据接口对接。两个版本的模块都脱胎于经典的数据可视化模块matplotlib,但重要的是新的API自动完成用户以前必须用旧API“手动”完成的额外matplotlib工作。
mplfinance模块安装
pip3 install mplfinance
Backtrader是一个基于Python的自动化回溯测试框架,作者是德国人 Daniel Rodriguez,是一个易懂、易上手的量化投资框架。后面进行策略回测时用Backtrader进行简单的量化策略回溯。
backtrader的安装:
pip3 install backtrader
Backtrader有几个要掌握的核心概念:
# 设置经纪人初始交易资金额
cerebro.broker.setcash(100000.0)
backtrader框架的中文文档
Scikit-learn(sklearn)是机器学习中常用的第三方模块,对常用的机器学习方法进行了封装,包括回归(Regression)、降维(Dimensionality Reduction)、分类(Classfication)、聚类(Clustering)等方法。当我们面临机器学习问题时,便可根据下图来选择相应的方法。Sklearn具有以下特点:
sklearn的安装:
Sklearn安装要求Python(>=2.7 or >=3.3)、NumPy (>= 1.8.2)、SciPy (>= 0.13.3)。如果已经安装NumPy和SciPy,安装scikit-learn可以使用
pip3 install -U scikit-learn
scikit-learn (sklearn) 官方文档中文版
均线是指股价在一定交易时间内的算术平均数的连线,反映了一段时间内持股者的平均成本价。例如5日均线,就是将最近的5个交易日的收盘价相加,再除以5,就是5日的算术平均数。
在talib中,移动平均线系列指标包括:SMA简单移动平均线、EMA指数移动平均线、WMA加权移动平均线、DEMA双移动平均线、TEMA三重指数移动平均线、TRIMA三角移动平均线、KAMA考夫曼自适应移动平均线、MAMA为MESA自适应移动平均线、T3三重指数移动平均线。
通用函数名:MA
调用代码:ta.MA(close,timeperiod=30,matype=0)
参数说明:
import numpy as np
import talib as ta
from talib import MA_Type
import pandas as pd
close = np.array([1, 2, 3, 4, 5, 6], dtype='f8')
se = pd.Series(close, dtype='f8')
# 方法一使用通用函数MA计算5日算术均线,传入matype参数调用简单移动平均线
# 如果调用指数移动平均线则参数matype=MA_Type.EMA
# 第一个参数可以传入close,也可以传入se
output = ta.MA(se, timeperiod=5, matype=MA_Type.SMA)
print(output)
# 方法二 直接调用SMA函数,传入计算时间间隔计算5日均线
output = ta.SMA(se, timeperiod=5)
print(output)
输出结果:
移动平均线是技术分析理论中应用最普遍的指标之一,主要用于确认、跟踪和判断趋势,提示买入和卖出信号,在单边市场行情中可以较好的把握市场机会和规避风险。但是,移动平均线一般要与其他的技术指标或基本面相结合来使用,特别是当市场处于盘整行情时,其买入卖出信号会频繁出现,容易失真。
代码例子二:
计算跨境通2021-01-01至2021-01-20日之间股价的5日算术均线(简单易懂平均线)
使用聚宽平台获取股票数据。
import numpy as np
import talib as ta
from talib import MA_Type
import pandas as pd
import jqdatasdk as jq
# 聚宽平台权限验证
jq.auth('*******', '********')
# 聚宽平台获取股价
close = jq.get_price('002640.XSHE',
start_date='2021-01-01',
end_date='2021-01-20',
frequency='1d',
fq='pre')
# 方法一使用通用函数MA计算5日算术均线,传入matype参数0等同于MA_Type.SMA
close['5MA'] = ta.MA(close['close'], timeperiod=5, matype=0)
close['10MA'] = ta.MA(close['close'], timeperiod=10, matype=MA_Type.SMA)
# 由于日期间隔短,无法计算20日、30日、60日的均线
'''close['20MA'] = ta.MA(close['close'], timeperiod=20, matype=MA_Type.SMA)
close['30MA'] = ta.MA(close['close'], timeperiod=30, matype=MA_Type.SMA)
close['60MA'] = ta.MA(close['close'], timeperiod=60, matype=MA_Type.SMA)'''
print(close)
import numpy as np
import talib as ta
from talib import MA_Type
import pandas as pd
import jqdatasdk as jq
from matplotlib import pyplot as plt
from pylab import mpl
# 聚宽平台权限验证
jq.auth('******', '*******')
# 聚宽平台获取股价
close = jq.get_price('002640.XSHE',
start_date='2020-11-01',
end_date='2021-01-20',
frequency='1d',
fq='pre')
mpl.rcParams['font.sans-serif'] = [
'SimHei'
] # 使图形中的中文正常编码显示,其中,sans-serif 表示字体中的无衬线体,SimHe是黑体
mpl.rcParams['axes.unicode_minus'] = False # 使坐标轴刻度表签不显示正负号
types = ['SMA', 'EMA', 'WMA', 'DEMA', 'TEMA', 'TRIMA', 'KAMA', 'MAMA', 'T3']
for i in range(len(types)):
close[types[i]] = ta.MA(close['close'], timeperiod=5, matype=i)
#close.tail()
# 使用loc[]获取局部行和列的切片
'''
iloc:即index locate 用index索引进行定位,所以参数是整型,如:df.iloc[10:20,3:5]
loc:则可以使用column名和index名进行定位,如:df.loc['image1':'image10','age':'score']
df['col1']取得第一列或df[['col1','col2','col3']]获取三列
'''
# 使用DataFrame的plot方法绘制图像会按照数据的每一列绘制一条曲线
# figsize=(16, 6)图片尺寸大小16*6
close.loc['2020-12-16':,'SMA':].plot(figsize=(16, 6))
# 获取当前坐标轴
ax = plt.gca()
# 设置右侧框线无颜色(隐藏)
ax.spines['right'].set_color('none')
# 设置顶部框线无颜色(隐藏)
ax.spines['top'].set_color('none')
# 设置图形标题
plt.title('上证指数各种类型移动平均线',fontsize=15)
# 设置X轴标签文字为空
plt.xlabel('')
# plt.ylabel('y轴') # y轴标签文字设置
plt.show()
输出结果:
ax = plt.gca()
# spines是指坐标图四周的框
# 获取你想要挪动的坐标轴,这里只有顶部、底部、左、右四个方向参数
ax.xaxis.set_ticks_position('bottom') # 要挪动底部的X轴,所以先目光锁定底部!
# 在这里,position位置参数有三种,这里用到了“按Y轴刻度位置挪动”
# 'data'表示按数值挪动,其后数字代表挪动到Y轴的刻度值
ax.spines['bottom'].set_position(('data', 0))
默认情况下坐标系四周有边框,这个边框叫做spines,下图中红框选定的黑色线就叫做边框
这四个边框时可以使用颜色隐藏的,将颜色设置成无色就隐藏了
ax.spines['right'].set_color('none')
代码中没有使用matplotlib的 pyplot进行画图,而是用了pandas.DataFrame.plot( )方法进行了画图
plt画图方式
plt.figure(figsize = (5,5))
plt.plot() # 画个只有坐标系的图(因为没有传参数,所以显示空白)
pandas.DataFrame.plot( )简介
使用DataFrame的plot方法绘制图像会按照数据的每一列绘制一条曲线,默认按照列columns的名称在适当的位置展示图例,比matplotlib绘制节省时间,且DataFrame格式的数据更规范,方便向量化及计算。
DataFrame.plot( )函数:
DataFrame.plot(x=None, y=None, kind='line', ax=None, subplots=False,
sharex=None, sharey=False, layout=None, figsize=None,
use_index=True, title=None, grid=None, legend=True,
style=None, logx=False, logy=False, loglog=False,
xticks=None, yticks=None, xlim=None, ylim=None, rot=None,
fontsize=None, colormap=None, position=0.5, table=False, yerr=None,
xerr=None, stacked=True/False, sort_columns=False,
secondary_y=False, mark_right=True, **kwds)
注意:每种绘图类型都有相对应的方法
df.plot(kind=‘line’)与df.plot.line()等价
参数介绍
x : label or position, default None#指数据列的标签或位置参数
y : label, position or list of label, positions, default None
kind : str#绘图类型
‘line’ : line plot (default)#折线图
‘bar’ : vertical bar plot#条形图。stacked为True时为堆叠的柱状图
‘barh’ : horizontal bar plot#横向条形图
‘hist’ : histogram#直方图(数值频率分布)
‘box’ : boxplot#箱型图
‘kde’ : Kernel Density Estimation plot#密度图,主要对柱状图添加Kernel 概率密度线
‘density’ : same as ‘kde’
‘area’ : area plot#与x轴所围区域图(面积图)。Stacked=True时,每列必须全部为正或负值,stacked=False时,对数据没有要求
‘pie’ : pie plot#饼图。数值必须为正值,需指定Y轴或者subplots=True
‘scatter’ : scatter plot#散点图。需指定X轴Y轴
‘hexbin’ : hexbin plot#蜂巢图。需指定X轴Y轴
ax : matplotlib axes object, default None#子图(axes, 也可以理解成坐标轴) 要在其上进行绘制的matplotlib subplot对象。如果没有设置,则使用当前matplotlib subplot其中,变量和函数通过改变figure和axes中的元素(例如:title,label,点和线等等)一起描述figure和axes,也就是在画布上绘图。
subplots : boolean, default False#是否对列分别作子图
sharex : boolean, default True if ax is None else False#如果ax为None,则默认为True,否则为False
sharey : boolean, default False#如果有子图,子图共y轴刻度,标签
figsize : a tuple (width, height) in inches#图片尺寸大小
use_index : boolean, default True#默认用索引做x轴
title : string#图片的标题用字符串
以上是摘录的一些参数介绍,具体关于函数的内容可以点击链接参考一下别人的总结。
函数名: MACD
名称: 平滑异同移动平均线
简介: 利用收盘价的短期(常用为12日)指数移动平均线与长期(常用为26日)指数移动平均线之间的聚合与分离状况,对买进、卖出时机作出研判的技术指标
函数调用方式:
macd, macdsignal, macdhist = MACD(close, fastperiod=12, slowperiod=26, signalperiod=9)
MACD是DIFF线,它的反应会比较快。
MACDsinal是DEA线,它的反应会比较慢。
而MACDhist是x坐标轴上的柱子。
例子一
import numpy as np
import talib as ta
from talib import MA_Type
import pandas as pd
import jqdatasdk as jq
from matplotlib import pyplot as plt
from pylab import mpl
# 聚宽平台权限验证
jq.auth('19935162681', 'ByKy19935162681')
# 聚宽平台获取股价
close = jq.get_price('601899.XSHG',
start_date='2020-10-14',
end_date='2021-01-20',
frequency='1d',
fq='pre')
# macd为DIFF线,macdsignal为DEA线,macdhist为MACD柱状线
macd, macdsignal, macdhist = ta.MACD(close["close"],
fastperiod=12,
slowperiod=26,
signalperiod=9)
close['DIFF'] = macd
close['DEA'] = macdsignal
close['hists'] = macdhist
# 画线,由于三条线是两种类型,需要单画
df=close.loc['2020-11-30':'2021-01-21', 'DIFF':]
with pd.plotting.plot_params.use('x_compat', True): #方法一
df.DIFF.plot(figsize=(16, 6))
df.DEA.plot()
#df.hists.plot.bar(width=0.1)
df.hists.plot()
print(df)
mpl.rcParams['font.sans-serif'] = [
'SimHei'
] # 使图形中的中文正常编码显示,其中,sans-serif 表示字体中的无衬线体,SimHe 是 黑体
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.title('MACD平滑异同移动平均线', fontsize=15)
plt.xlabel('')
plt.show()
使用talib中MACD函数,计算会存在一定误差,所以通过自己写一个函数来实现与股票软件中公式计算结果一致,代码如下:
import pandas as pd
# 在k线基础上计算MACD,并将结果存储在df上面(dif,dea,bar)
def calc_macd(close, fastperiod=12, slowperiod=26, signalperiod=9):
'''
通过传入的收盘价close的series类型计算MACD,返回的macd是dif,macdsignal是dea,macdhist是macd
fastperiod=12, slowperiod=26, signalperiod=9这三个参数分别对应股票软件上的三个日期参数
close是收盘价列
'''
if not isinstance(close, pd.Series):
raise Exception("传入的close参数不是Series类型!")
ewma12 = close.ewm(span=fastperiod, adjust=False).mean()
ewma26 = close.ewm(span=slowperiod, adjust=False).mean()
macd = ewma12 - ewma26
macdsignal = macd.ewm(span=signalperiod, adjust=False).mean()
macdhist = (macd - macdsignal) * 2
return (macd, macdsignal, macdhist)
单独放在一个模块中,引入即可。
函数名: CCI
名称: 顺势指标
简介: CCI指标专门测量股价是否已超出常态分布范围
指标应用:
1.当CCI指标曲线在+100线~-100线的常态区间里运行时,CCI指标参考意义不大,可以用KDJ等其它技术指标进行研判。
2.当CCI指标曲线从上向下突破+100线而重新进入常态区间时,表明市场价格的上涨阶段可能结束,将进入一个比较长时间的震荡整理阶段,应及时平多做空。
3.当CCI指标曲线从上向下突破-100线而进入另一个非常态区间(超卖区)时,表明市场价格的弱势状态已经形成,将进入一个比较长的寻底过程,可以持有空单等待更高利润。如果CCI指标曲线在超卖区运行了相当长的一段时间后开始掉头向上,表明价格的短期底部初步探明,可以少量建仓。CCI指标曲线在超卖区运行的时间越长,确认短期的底部的准确度越高。
4.CCI指标曲线从下向上突破-100线而重新进入常态区间时,表明市场价格的探底阶段可能结束,有可能进入一个盘整阶段,可以逢低少量做多。
5.CCI指标曲线从下向上突破+100线而进入非常态区间(超买区)时,表明市场价格已经脱离常态而进入强势状态,如果伴随较大的市场交投,应及时介入成功率将很大。
6.CCI指标曲线从下向上突破+100线而进入非常态区间(超买区)后,只要CCI指标曲线一直朝上运行,表明价格依然保持强势可以继续持有待涨。但是,如果在远离+100线的地方开始掉头向下时,则表明市场价格的强势状态将可能难以维持,涨势可能转弱,应考虑卖出。如果前期的短期涨幅过高同时价格回落时交投活跃,则应该果断逢高卖出或做空。
CCI主要是在超买和超卖区域发生作用,对急涨急跌的行情检测性相对准确。非常适用于股票、外汇、贵金属等市场的短期操作。
函数调用方式:
real = CCI(high, low, close, timeperiod=14)
例子一
计算紫金矿业从2020-10-14至2021-01-21内的每天CCI指标,并将11-30以后的cci画图显示。
import numpy as np
import talib as ta
from talib import MA_Type
import pandas as pd
import jqdatasdk as jq
from matplotlib import pyplot as plt
from pylab import mpl
# 聚宽平台权限验证
jq.auth('19935162681', 'ByKy19935162681')
# 聚宽平台获取股价
close = jq.get_price('601899.XSHG',
start_date='2020-10-14',
end_date='2021-01-22',
frequency='1d',
fq='pre')
# 参数分别是最高价集合、最低价集合、收盘价集合,时间间隔14天
close['cci'] = ta.CCI(close['high'], close['low'], close['close'], timeperiod=14)
# 截取行从11-30至01-22
df=close.loc['2020-11-30':'2021-01-22']
# 针对cci列进行划线
df.cci.plot(figsize=(16, 6))
print(df)
mpl.rcParams['font.sans-serif'] = [
'SimHei'
] # 使图形中的中文正常编码显示,其中,sans-serif 表示字体中的无衬线体,SimHe 是 黑体
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.title('CCI顺势指标', fontsize=15)
plt.xlabel('')
plt.show()
KDJ指标又叫随机指标,是一种相当新颖、实用的技术分析指标,它起先用于期货市场的分析,后被广泛用于股市的中短期趋势分析,是期货和股票市场上最常用的技术分析工具。
随机指标KDJ一般是用于股票分析的统计体系,根据统计学原理,通过一个特定的周期(常为9日、9周等)内出现过的最高价、最低价及最后一个计算周期的收盘价及这三者之间的比例关系,来计算最后一个计算周期的未成熟随机值RSV,然后根据平滑移动平均线的方法来计算K值、D值与J值,并绘成曲线图来研判股票走势。
在talib库中没有直接计算KDJ的函数,在炒股软件中针对kdj的公式如下:
#RSV赋值:(收盘价-N日内最低价的最低值)/(N日内最高价的最高值-N日内最低价的最低值)*100
RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100;
#输出K:RSV的M1日[1日权重]移动平均
K:SMA(RSV,M1,1);
#输出D:K的M2日[1日权重]移动平均
D:SMA(K,M2,1);
#输出J:3*K-2*D
J:3*K-2*D;
通过上面的公式可以看出来K和D指标使用的SMA进行计算的,而这个SMA公式的股票软件中的定义是这样的:
上图红框中可以看出来,股票软件中的SMA函数是加权移动平均函数,不是talib中的SMA简单移动平均函数,talib库中的SMA函数对应股票软件中的函数是MA。
但是我从talib库中没有找到能与股票软件中SMA能对应的函数,所以这里将股票软件中的KD两个指标的公式调整成MA,这样救恩那个保证计算结果一致。
上图是股票软件中修改后的公式。
函数名: STOCH
名称: 随机指标,俗称KD
函数调用方式:
slowk, slowd = STOCH(high, low, close, fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0)
例子一
紫金矿业时间段内的KDJ指标
import numpy as np
import talib as ta
from talib import MA_Type
import pandas as pd
import jqdatasdk as jq
from matplotlib import pyplot as plt
from pylab import mpl
# 聚宽平台权限验证
jq.auth('19935162681', 'ByKy19935162681')
# 聚宽平台获取股价
close = jq.get_price('601899.XSHG',
start_date='2020-10-14',
end_date='2021-01-22',
frequency='1d',
fq='pre')
# slowk是指标K,slowd是指标D
close['slowk'], close['slowd'] = ta.STOCH(
close['high'], # 股票最高价集合
close['low'], # 股票最低价集合
close['close'],# 股票收盘价集合
fastk_period=9,# 指定RSV参数中N日的N,一般输入9日
slowk_period=3,# 指标K中M1的参数,一般为3日
slowk_matype=0,# 指定使用的均线函数 0=SMA, 1=EMA, 2=WMA, 3=DEMA, 4=TEMA, 5=TRIMA, 6=KAMA, 7=MAMA, 8=T3 (Default=SMA)
slowd_period=3,# 指标K中M2的参数,一般为3日
slowd_matype=0)# 指定使用的均线函数 0=SMA, 1=EMA, 2=WMA, 3=DEMA, 4=TEMA, 5=TRIMA, 6=KAMA, 7=MAMA, 8=T3 (Default=SMA)
# J线指标需要自己计算,根据股票软件中J的公式进行计算
close['slowj'] = 3*close['slowk']- 2*close['slowd']
# 截取行从11-30至01-22
df=close.loc['2020-11-30':'2021-01-22','slowk':]
# 进行划线
df.plot(figsize=(16, 6))
print(df)
mpl.rcParams['font.sans-serif'] = [
'SimHei'
] # 使图形中的中文正常编码显示,其中,sans-serif 表示字体中的无衬线体,SimHe 是 黑体
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.title('KDJ随机指标', fontsize=15)
plt.xlabel('')
plt.show()
由于talib库中STOCH函数计算缺陷,这里我们自己实现一个KDJ计算的函数,下面代码是自己写的一个tools模块,引入模块后调用cal_kdj函数即可计算出与股票软件公式的计算相符合的结果
import pandas as pd
'''
针对股票数据计算工具模块
'''
def calc_kdj(df, fastk_period=9, slowk_period=3,slowd_period=3,fillna=False):
'''
根据传入的最高价、最低价、收盘价计算KDJ指标
参数:
df:pandas的DataFrame类型,需要包含最低价、最高价及收盘价
fastk_period:RSV中日期间隔 int 类型。默认为9日
slowk_period:K线指标日期间隔 int类型。默认为3天
slowd_period:D线指标日期间隔 int类型。默认为3天
fillna:bool类型,默认为False。为True时,在计算RSV的最高价(或最低价)的最大值(或最小值)过程中如果存在Nan数据将被传入的df中的最大值或最小值填充
'''
# 检查传入的参数是否是pandas的DataFrame类型
if not isinstance(df, pd.DataFrame):
raise Exception("传入的参数不是pandas的DataFrame类型!")
# 检查传入的df是否存在high、low、close三列,不存在报错
if ('high' not in df.columns) or ('low' not in df.columns) or (
'close' not in df.columns):
# 抛出异常
raise Exception("传入的参数不存在最高价、最低价、收盘价中的一个或几个!")
# 计算指定日期间隔内的最低价的最小值
low_list = df['low'].rolling(fastk_period, min_periods=fastk_period).min()
# 将NAN填充成现有数据中的最小值
if fillna == True:
low_list.fillna(value=df['low'].expanding().min(), inplace=True)
# 计算指定日期间隔的最高阶的最大值
high_list = df['high'].rolling(9, min_periods=9).max()
# 将NAN填充成现有数据中的最大值
if fillna == True:
high_list.fillna(value=df['high'].expanding().max(), inplace=True)
# 计算RSV (国泰君安中的RSV公式RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100;)
# RSV赋值:(收盘价-N日内最低价的最低值)/(N日内最高价的最高值-N日内最低价的最低值)*100
rsv = (df['close'] - low_list) / (high_list - low_list) * 100
k = pd.DataFrame(rsv).ewm(com=slowk_period-1).mean()
d = k.ewm(com=slowd_period-1).mean()
j = 3 * k - 2 * d
return (k, d, j)
1、 人工智能学习网站