其实捉历史股价的工具很多,这篇文章只介绍我正在使用的函式库
yfinance
如果要捉国外股价,首选是 yfinanace
顾名思义,yfinance 的资料来源是 Yahoo Finance API,以国外股市来说,大概是目前我找的到最完整的资料来源
使用起来也很简单
安装
pip install yfinance
举例要捉 SPY 2021年以后的资料,只需要一行 code 就可以取得资料
import yfinance as yf
# yfinance 取得股价
df = yf.download("spy", "2021-01-01")
df 是 dataframe 格式,可自行再去运用
ffn
ffn 其实用的也是 yfinance 的资料,不过它提供了不少很好用的 function,现在我捉股价几乎直接都使用 ffn 取代 yfinance (反正是一样的资料)
安装
pip install ffn
举例要捉 SPY 2021年以后的资料,同样只需要一行 code 就可以取得资料
import ffn
# ffn 取得 股价
prices = ffn.get('spy', start='2021-01-01')
ffn function 介绍
rebase ⇒ 将初始价格改为 100,可以比较两个以上的股价涨跌变化
prices = ffn.get('spy, tlt', start='2021-01-01')
# rebase 股价绘图
%matplotlib inline
prices.rebase().plot()
就可以看到在 2021 这两支 ETF 的走势变化
to_drawdown_series ⇒ 看最大的亏损
# Max Drawdown 最大亏损
prices.to_drawdown_series().plot()
从这张图就可以看出今年的 SPY 真的强,一路向上不回头的
calc_stats ⇒ 统计报表
# 统计报表
stats = prices.calc_stats()
stats.display()
我没贴全部的资料,统计数据其实蛮完整的,我想看的差不多都有..
display_monthly_returns ⇒ 月报酬
print(stats['spy'].display_monthly_returns())
不仅有年报酬率,连每个月的报酬率都算出来了...
FinMind
yfinance 是有台股资料的,但并不是很齐全,举例 0050 这档 ETF 是在 2003 年就成立了,但是 yfinance 从 2008 年才有资料,此外,yfinance 只有上市股票,是没有上柜股票价格的,所以要捉台股资料 yfinance 并不是好选择。原本我的作法是直接去爬证交所的网站,一直到后来发现 FinMind
一样要先安装
pip install FinMind
举例捉 0050 资料,开始时间写 2000-01-01 (0050 上市时间是 2003-06)
from FinMind.data import DataLoader
stock_no = '0050'
dl = DataLoader()
stock_data = dl.taiwan_stock_daily(stock_id=stock_no, start_date='2000-01-01')
stock_data.head()
很好,第一笔资料是 2003-06-30,看起来资料是完整的
再测试一下捉上柜股票 6539(台康生技)
from FinMind.data import DataLoader
stock_no = '6539'
dl = DataLoader()
stock_data = dl.taiwan_stock_daily(stock_id=stock_no, start_date='2000-01-01')
stock_data.head()
也成功的捉到资料
FinMind 可以说完美的补足 yfinance 台股资料不足的缺点
FinMind 整合 ffn
既然 ffn 这么好用,我们可以用 FinMind 取得资料后,然后直接用 ffn 的 function 吗 ?
答案是可以的,不过资料需要做些处理
ffn 的 index 是日期,但是 FinMind 的 index 是流水号,date 是其中一个栏位而且是 string 格式,所以我们要将 FinMind 的 index 改成日期格式的 date
stock_data.set_index("date" , inplace=True)
stock_data = stock_data.set_index(pd.DatetimeIndex(pd.to_datetime(stock_data.index)))
然后就可以用 ffn 的 function 了
stats = stock_data[["close"]].calc_stats()
stats.display()
成功取得 0050 的统计资料