查看原文
其他

抄底美股?用 Python 分析美股实际收益率

Mort Python中文社区 2022-12-04

作者简介:Mort,数据分析爱好者,擅长数据可视化,比较关注机器学习领域,希望能和业内朋友多学习交流。

之前一直在做金融数据方面的工作,有朋友多次问我做股票分析用什么软件好,实际上做股票数据分析也并没有特定的工具,完全就是根据自己的需求来定,笔者见过用MATLAB、R、SPSS、Python以及C++等,种类多种多样,这完全就是取决于业务需求甚至是个人爱好。今天就给大家介绍一下用Python做美股数据的简单分析,覆盖从数据获取、数据处理以及可视化,让大家了解一下。

这次的美股例子就选择了美国显卡制造商英伟达,其股票代码是NVDA,熟悉英伟达的人都知道他们的CEO老黄(Jensen Huang),老黄有两样东西很出名,一是那件能穿4个季度的皮衣,二是精湛的显卡刀法。英伟达在老黄带领下飞速发展,其股价也是一直飙升,所以选择这个股票也是在近几年美股中具有代表性的。

图1. 英伟达CEO Jensen Huang

首先还是导入各种库。

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import yfinance as yf

这里有一个不太常见的库是yfinance,这是从Yahoo网站获取数据的一个库,其使用非常简单,不需要相关api,同时也是免费的,而市场上其他不少库都要api,很多还是收费的,同时还有很多限制,所以我们选用了yfinance作为数据来源。yfinance直接用pip安装即可,笔者用的是anaconda,但用了conda安装会失败,最好还是用pip安装。接下来是获取数据。

df = yf.download('NVDA', start='2015-01-02', end='2020-01-01', progress=False)

yfinance下载的数据直接是pandas的dataframe格式,这里我们只要输入股票代码以及起止时间就可以了,后面的progress是进度条选项,最好关闭,否则下载好之后结果中会有一个进度条(影响也不大)。这里我们下载英伟达过去5年的股票数据,从2015年1月1日到2019年12月31日。这里有一个问题要注意,就是yfinance的数据获取时间是提前1天的,比如设置起始时间start='2015-01-02',但最终得到的股票数据时间是从2015年1月1日开始的, 同样截止时间end='2020-01-01'也就意味着数据的截止时间是2019年12月31日。下载之后的数据如下图所示。

图2. yfinance下载的数据示

然后是数据处理。

df = df[['Adj Close']] #这里要用两个[],否则是一个series而不是df
df.rename(columns={'Adj Close':'adj_close'},inplace=True) #改名
df['s_r'] = df/df.shift(1)-1 #计算会计收益率
df_dates = pd.DataFrame(index=pd.date_range(start='2015-1-1', end='2019-12-31'))
df = df_dates.join(df) #生成新的dataframe
df=df.fillna(method='ffill').asfreq('M') #填充nan数据,并得出每月最后一个交易日的数据
cpi = pd.read_excel('cpi_data.xlsx').values #读取美国cpi数据
cpi = cpi[:, 1:].flatten() #把cpi数据从二维降为一维
df['cpi'] = cpi #生成新的列
df['inf_rate'] = df.cpi.pct_change() #计算通货膨胀率
df['r_r']=(df.s_r+1)/(df.inf_rate+1)-1 #计算实际收益率

上面这些步骤内容较多,在这里详细说明一下。从下载得到的数据中,我们选取Adj Close这一列,其全称是adjusted close,意思是调整收盘价,这就是我们要用到的数据,将其改名为adj_close,然后用adj_close计算会计收益率(也称简单收益率),即simple returns,将其命名为s_r,方法是用后一天数据除以前一天数据,再减一,当然这里用dataframe的pct_change方法也可以,得到的结果是一样的。从前面图2中我们可以看到得到的数据的时间是以天为单位的,但这些日期并不连续,中间有部分间断,这是因为股票市场在周末等节假日不开盘,而这里我们为了利用cpi来计算会计收益率,要设计一个连续时间范围,所以这里生成了一个名为df_dates的变量,其时间范围是连续的,从2015年1月1日到2019年12月31日,让其和df合并,得到的数据如下图所示。这里面NaN(not a number)都是节假日不开盘的日期。

图3. join之后的df部分数据

因为要计算实际收益率,其中使用的cpi(onsumer price index,消费者物价指数)是以月为单位的,所以我们也要把df转换成以月为单位,为了避免在每月最后一天是非开盘日,所以首先用了fillna方法,方式是'ffill',即按照前一日数据来填充,然后用asfreq('M')方法来得出每月最后一日的数据。很多人会问,这个每月最后一日的数据有什么用,因为我们用到的cpi数据都是按月份来公布的,每月只有一个cpi数据,所以我们计算会计收益率时也要按照月份来算,而每月会计收益率就是用这个月的最后一个交易日的调整收盘价除以上个月的最后一个交易日的调整收盘价,然后再减一,和前面每日会计收益率的计算方法一样。然后用月份会计收益率和cpi来计算实际收益率。而我们这次所用到的cpi数据,其时间范围从2015年1月至2019年12月,总共5年,这个数据可以从很多网站下载,直接到网上搜索就行了,这里笔者直接从网上复制过来,放在一个Excel文件中,文件名为cpi_data.xlsx,大家可以从笔者的Gitee代码网站上下载,网址是https://gitee.com/leonmovie/nvidia-stock-analysis。这个cpi数据的大致内容如下图所示。

图4. cpi文件内容截图

读取cpi数据之后通过cpi数据计算通货膨胀率,即inflation rate,我们把这一列命名为inf_rate,方法和会计收益率一样,接着再用通货膨胀率计算实际收益率(Real Rate of Return),方法是(1+会计收益率)/(1+通货膨胀率)-1,我们将其命名为r_r。最后得到的df数据如下图所示。

图5. 完成处理的df部分数据

最后就是数据可视化。

plt.style.use('ggplot'#选用ggplot主题
fig, ax = plt.subplots(4, 1, figsize=(12, 10), sharex=True) #共享x轴
df.adj_close.plot(ax=ax[0])
ax[0].set(title = 'Nvidia data analysis', ylabel = 'Stock price')
df.s_r.plot(ax=ax[1])
ax[1].set(ylabel = 'Simple returns')
df.inf_rate.plot(ax=ax[2])
ax[2].set(ylabel = 'Inflation rate')
df.r_r.plot(ax=ax[3])
ax[3].set(xlabel = 'Date', ylabel = 'Real Rate of Returns')

这里我们只要4列数据,即除了cpi之外的其他4列数据。将其置于4个子图中,绘图直接用dataframe的plot方法即可,在这里我们选用了ggplot的绘图主题。得到的结果如下图所示。

图6. 数据可视化

从这里我们也可以看到用pandas分析美股数据非常方便,但是只掌握pandas的使用方法还是不够的,我们还要具备相关的金融基础知识,尤其是计量经济学的相关基础,因此在分析股票数据时最好还要有一定的经济学基础。所以在我们平时的业务工作当中,除了必要的编程技能以外,掌握相关的理论知识也是很重要的。

赞 赏 作 者



Python中文社区作为一个去中心化的全球技术社区,以成为全球20万Python中文开发者的精神部落为愿景,目前覆盖各大主流媒体和协作平台,与阿里、腾讯、百度、微软、亚马逊、开源中国、CSDN等业界知名公司和技术社区建立了广泛的联系,拥有来自十多个国家和地区数万名登记会员,会员来自以工信部、清华大学、北京大学、北京邮电大学、中国人民银行、中科院、中金、华为、BAT、谷歌、微软等为代表的政府机关、科研单位、金融机构以及海内外知名公司,全平台近20万开发者关注。


扫码关注下方公众号后回复“美股”即可获取源码数据



投稿邮箱:pythonpost@163.com



阿里云2020上云开工采购季来临,
服务器价格比双十一还低!
▼ 长按扫描下方二维码 ▼

爆款产品低至1
服务器最低仅74元/年
消费满额可领现金红包
下单抽iPhone 11 Pro
新老用户同享优惠!

↓ ↓ 长 按 扫 码 进 入 活 动 ↓ ↓


【Python中文社区专属优惠码】


指定特惠服务器每人限购1台



▼ 点击阅读原文,即享阿里云产品1折优惠起

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存