使用Python获取股票数据并分析(1)
之前有看到他人作业分享了使用pandas_datareader
包通过雅虎财经获取股票数据的方法,尝试了该方法但返回错误,经查询雅虎财经对API做了调整,pandas_datareader
官网显示所支持的API列表已经没有雅虎财经了。
透过科学上网工具,找到了另外一个获取雅虎财经数据的功能包 -- fix_yahoo_finance。利用该功能包,可以使用相似于pandas_datareader
的方法获取股票数据。
安装导入
控制台安装fix_yahoo_finance
:
pip install fix_yahoo_finance
安装好后打开Jupyter Notebook开始爬取。首先导入各种所需要的功能包。
import matplotlib.pyplot as plt
import fix_yahoo_finance as yf
# 输出矢量图,画图更清晰
%config InlineBackend.figure_format = 'svg'
设置股票代码(tickers)
考虑到公司的对比性,选取了中国互联网三巨头阿里(雅虎财经代码:BABA),腾讯(0700.HK),百度(BIDU),以及美国互联网的三家巨无霸:脸书(FB),亚马逊(AMZN),谷歌(GOOGL)。
tickers = ['0700.HK', 'BABA', 'BIDU', 'GOOGL', 'FB', 'AMZN']
这里没有纳入史上第一家万亿美金市值公司 -- 苹果,个人认为苹果与上述几家互联网公司的不同之处在于苹果的主营业务是硬件,这六家则是软件。股票代码可以在雅虎财经官网查询,腾讯是香港上市公司,代码形式与其他几家的纯字母代码不同。
获取股票数据
获取数据前先设定起始日期和结束日期,我们要比较今年以来这六家公司的股票走势,所以起始日期设置为2018-01-01,结束日期为2018-09-07。
start_date = '2018-01-01'
end_date = '2018-09-10'
现在开始获取股票数据,并存入变量data
。
data = yf.download(tickers = tickers, start = start_date, end = end_date)
或者省略参数名,直接按顺序输入参数值。
data = yf.download(tickers, start_date, end_date)
查看data的前几行数据:
data.head()

可以看到,数据的行索引是交易日日期,列索引像是有两层,第一层应该是当天股票的开盘价,最高价等数据名,第二层列标题是股票代码,因为列数太多,屏幕上不能显示全部列。可以通过查看数据的列信息来证明我们的判断。
df.columns

结果显示列索引有两级,第一级列索引是由股票的当日股价信息列表['Adj Close', 'Close', 'High', 'Low', 'Open', 'Volume']组成,分别代表前复权收盘价,收盘价,最高价,最低价,开盘价钱,成交量。第二级列索引是由公司的股票代码列表 ['0700.HK', 'AMZN', 'BABA', 'BIDU', 'FB', 'GOOGL']。
由于我们需要比较的是今年的股价走势,所以只需考虑收盘价。数据中有两种收盘,Close和Adj Close,分别代表不复权收盘价和前复权收盘价。计算股票收益时,需要考虑分红,配股等因素,前复权收盘价更能体现真实收益。
关于复权的概念,可以参考这篇:
知乎链接
绘制股价走势图
接下来提取前复权收盘价到变量df
,查看数据并绘制股价走势图。
df = data['Adj Close']
df.head()

此时只含有一级列索引,即股票代码。下面绘制股价图:
df.plot()

根据提取的数据绘制出了几家公司股价的走势,每家公司的每股价格差距较大,亚马逊和谷歌每股股价高于1000美金,其他几家低于500,并且腾讯的股价单位是港币。从上图直观上只能看到亚马逊的股价是一路上涨的,其他几家公司的股价走势大致趋于水平。
因此需要对数据进行处理,将每家公司的起始日期收盘价折算为100,这样才能比较今年以来这六家公司的股票收益。我们称100为起始日期基准收盘价,之后股价的波动都是相对100这个基准值而言的,这样也能忽略掉不同货币单位的影响。
另外,由于腾讯所在的港股和其他股所在的美股休市日期不同,股价曲线会有几处中断,代表该日该股无交易。由于休市日无交易,可以认为休市日收盘价等于上一个交易日的收盘价,这样就可以使用df.fillna()
函数填充休市日的股价,使股价曲线无间断。
# 复制df的数据到df2
df2 = df.copy()
# 填充休市日股价为上一个交易日收盘价
df2 = df2.fillna(method='ffill', inplace=True)
# 使用for循环将每个公司的股价基于起始日基准收盘价折算,tickers为之前定义的公司股票代码组成的列表
# tickers = ['0700.HK', 'BABA', 'BIDU', 'GOOGL', 'FB', 'AMZN']
for ticker in tickers:
# 定义基准比值ratio,基准比值 * 100 = 起始日期原始收盘价
ratio = df2[ticker].iloc[0] / 100
# 所以对于起始日,起始日原始收盘价除以基准比值,得到值100,即为起始日基准收盘价
# 股价除以基准比值
df2[ticker] = df2[ticker] / ratio
# 查看处理后的数据
df2.head()

每列的起始日期收盘价都变成了100,其他日期的股价直接反映了当日股票相对于起始日的收益率,这样就可以方便地作图比较今年以来上述六家公司的股票收益。
df2.plot()

大致完成。可以再对图表做一些美化,添加标题,调整图例等。图例中使用的是股票代码,结合股票代码和公司名组成的字典,通过df.map()
函数将图例变成显示公司名,方便让不熟悉股票代码的读者看图。
fig, ax = plt.subplots(figsize=(12,6))
ax.plot(df2)
# 添加网格线作参照
ax.grid()
# 添加图例,使用map函数将股票代码转换成公司名
code_name = {'0700.HK': '腾讯', 'BABA': '阿里巴巴', 'BIDU': '百度', 'GOOGL': '谷歌', 'FB': '脸书', 'AMZN': '亚马逊'}
ax.legend(df2.columns.map(code_name))
# 添加图表标题
ax.set_title('中美互联网巨头2018年股票收益走势')
# 设定时间区间
ax.set_xlim('2018-01-01','2018-09-30')

股价分析
新的图表更清晰地显示出亚马逊今年的强势表现,股价年初即于另外五家公司拉开差距,之后不断扩大涨幅,创始人贝索斯也因此荣登全球首富。没有惊喜也没有重大负面新闻的谷歌小幅上涨。脸书以及BAT今年股价相对低迷,脸书、百度、阿里这三家公司年初至今收益率趋近,腾讯股价表现不幸垫底,回调超过20%。
特朗普在3月中发动了贸易战,之后的半个月六家公司股票都有明显回调。
脸书因为总统选举数据泄密事件在3月份股价大跌,而后收复失地还创造了新高,但7月份发布的二季报低于市场预期,财报当天股价蒸发20%,之后跌回了今年低位。
近几月BAT则和大部分的中国上市公司一起跌入熊途,此外BAT今年股价都被负面新闻拖累。5月中旬百度股价受陆奇离职冲击,创造高点后迅速回落。电商为主业的阿里受贸易战影响最大,近期市场对马云离任持悲观情绪。腾讯在王者荣耀热度渐渐消散后仍没有找到新的爆款游戏,两份低于预期财报数据让市场选择了Say No。
其他参数设置
yf.download()
函数里面可以进行其他参数的设置获取不同的返回结果。
group_by: 设置分组方式,默认group_by='column'
,即如上文中的按照股票的开盘价,收盘价等参数分组,每个参数下含有不同股票的数据。可以使用group_by='tickers'
设置成按照股票分组。
data2 = yf.download(tickers, start_date, end_date, groupby='tickers')
data2.head()

auto_adjust: 设置收盘价Close是否等于前复权收盘价Adj Close,默认False。当auto_adjust=True
时,返回的收盘价只有一列Close,值等于前复权收盘价。
data3 = yf.download(tickers, start_date, end_date, groupby='tickers', auto_adjust=True)
data3.head()

actions: 设置返回的数据中是否包括分红,配股数据。默认False。
当actions=True
时,返回的数据除了开盘价,收盘价等数据外还包括分红和配股数据列。
data4 = yf.download(tickers='AAPL', start='2016-01-01', end='2018-09-07', group_by='tickers', actions=True)
data4.head()

当actions='only'
时,只返回分红,配股数据列,其他数据不返回。需要注意的是,actions='only'
时必须设置group_by='tickers',否则会提示
"['Open' 'High' 'Low' 'Close' 'Adj Close' 'Volume'] not in index"
因为默认group_by='column'
,此时第一级列索引等于['Open' 'High' 'Low' 'Close' 'Adj Close' 'Volume']
。但actions='only'
时只返回分红和配股数据列,列索引与group_by='column'
冲突。
data5 = yf.download(tickers='AAPL', start='2016-01-01', end='2018-09-07', group_by='tickers', actions='only')
data5.head()
