数据源:使用Pandas中的DataReader调用金融数据的API
场景:选取上证综指(000001.ss)和贵州茅台(600519.ss)股票进行分析,计算两者每日收益率,并且对两者的收益率进行线性回归分析。
注1:严格说上证综指是综合指数,不是单一的股票。
注2:股票代码参考https://cn.investing.com/indices/shanghai-composite-components
完整代码:
# 回归分析(这里用到的statsmodels是统计学里面的包) # statsmodels用于拟合多种统计模型,执行统计测试以及数据探索和可视化 # statsmodels.api共有6个方法/函数/属性 import statsmodels.api as sm # Pandas库提供了专门从财经网站获取金融数据的API接口 from pandas_datareader.data import DataReader import pandas as pd import datetime # OS模块简单的来说它是一个Python的系统编程的操作模块,可以处理文件和目录这些我们日常手动需要做的操作 import os # matplotlib是Python 的绘图库 matplotlib.pyplot是一个有命令风格的函数集合 import matplotlib.pyplot as plt # 设置起止时间(获取此时间范围内的股市信息) start = datetime.datetime(2019, 1, 1) end = datetime.datetime(2019, 12, 31) # 读取上证综指 及 贵州茅台 def load_data(): # 判断目录或文件是否存在 if os.path.exists('000001.csv'): data_ss = pd.read_csv('000001.csv') data_tlz = pd.read_csv('600519.csv') else: # 000001 上证综指(综合指数) data_ss = DataReader("000001.ss", "yahoo", start, end) # 600519 贵州茅台股票 上证 data_mt = DataReader("600519.ss", "yahoo", start, end) data_ss.to_csv('000001.csv') data_mt.to_csv('600519.csv') return data_ss, data_tlz data_ss, data_tlz = load_data() print(data_ss.head()) print(data_tlz.head()) # 两个DataFrame对象连接到一起 stock = pd.merge(data_ss, data_tlz, left_index=True, right_index=True) print(stock.head()) # 把Close_x和Close_y两列的数据取出来,重新赋值给stock stock = stock[['Close_x', 'Close_y']] print(stock.head()) # 给stock列名改一下名字 stock.columns = ['上证综指', '贵州茅台'] print(stock.head()) print(type(stock)) # 计算每日收益率(.dropna()表示删除缺失值,即NaN) # 每日收益率=(今日股价-上日股价)/上日股价 daily_return = (stock.diff() / stock.shift(periods=1)).dropna() # 默认periods=1,axis=0; periods=1表示移动一个距离,axis=0表示按纵轴方向移动 # stock.shift(periods=1,axis=0) print(daily_return.head()) # 收益率生成csv文件 daily_return.to_csv('shouYiLv.csv') print('每日收益>10%') # 国内股市,每日涨跌不会突破10%,所以>0.1的返回值为空 print(daily_return[daily_return['贵州茅台'] > 0.1]) # 图示涨跌幅 # plt.subplots可以将父图像分解为两个子图像 # fig: matplotlib.figure.Figure 对象 # ax:子图对象( matplotlib.axes.Axes)或者是他的数组 # nrows=1, ncols=2表示分解为一行两列的两个图像 # figsize设置图像大小 fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(15, 6)) # 将上证综指这一列在matplotlib上绘图,绘制在ax[0]上 daily_return['上证综指'].plot(ax=ax[0]) # 设置ax[0]的图像标题 ax[0].set_title('shangzheng') # 将贵州茅台这一列在matplotlib上绘图,绘制在ax[1]上 daily_return['贵州茅台'].plot(ax=ax[1]) # 设置ax[1]的图像标题 ax[1].set_title('maotai') # 图像展示出来 plt.show() # print(stock) # 在线百性回归以及广义线性回归中,R-squared误差的大小意味着模型的拟合度的好坏, # R-squared误差取值范围为0到1,这个值越接度近1说明模型的拟合回度越好。 # R-squared越大,线性回归的价值越高,相关性越高 # 加入截距项(系数1.0表示带截距的意思) daily_return["intercept"] = 1.0 # print(daily_return.head()) # OLS:Ordinary Least Squares 普通最小二乘法 # 截距b的系数为1 # y:贵州茅台(每日收益率),kx 上证综指(每日收益率) + b*1 model = sm.OLS(daily_return["贵州茅台"], daily_return[["上证综指", "intercept"]]) # 拟合数据,目的是学习得到参数 results = model.fit() # 结果摘要信息输出 print(results.summary())
上证指数数据:000001.csv
贵州茅台数据:600519.csv
2019.1.1-2019.10.31上证指数、贵州茅台,每日收益率曲线图:
线性回归结果:
总结:
1. load_data()方法用于判断上证综指和贵州茅台的数据是否存在,因为是从yahoo拿数据,每次都从yahoo拿会有点慢,所以建议保存到本地。
2. R-squared越大,线性回归的价值越高,相关性越高,由结果图可知R-squared只有0.329,说明两者相关性不是很大,可能影响因素比较多导致的。
如有不对的地方,欢迎批评指正