Python在Finance上的應用6 :獲取是S&P 500的成分股股票數據
- 2020 年 2 月 10 日
- 筆記
歡迎來到Python for Finance教程系列的第6講。
在之前的Python教程中,我們介紹了如何獲取感興趣的公司名單(在我們的案例中是S&P 500指數),現在我們將收集所有這些公司的股票數據。
到此為止的程式碼:
import bs4 as bs import pickle import requests # 更改工作路徑 os.getcwd() os.chdir(r'C:UsersHPDesktopstockpython for finance') os.getcwd() def save_sp500_tickers(): resp = requests.get('http://en.wikipedia.org/wiki/List_of_S%26P_500_companies') soup = bs.BeautifulSoup(resp.text, 'lxml') table = soup.find('table', {'class': 'wikitable sortable'}) tickers = [] for row in table.findAll('tr')[1:]: ticker = row.findAll('td')[0].text tickers.append(ticker) with open("sp500tickers.pickle","wb") as f: pickle.dump(tickers,f) return tickers
這次,我們將新導入一些模組
import bs4 as bs import datetime as dt import os import pandas_datareader.data as web import pickle import requests
將使用datetime指定Pandas datareader的日期,os將檢查並創建目錄。你已經知道什麼是pandas了!
在這裡,我將展示一個可以處理是否重新載入S&P500列表的方法的快速示例。如果我們提出要求,該計劃將重新抽取S&P500指數,否則將只使用我們的pickle。現在我們要準備抓取數據。
# save_sp500_tickers() def get_data_from_yahoo(reload_sp500=False): if reload_sp500: tickers = save_sp500_tickers() else: with open("sp500tickers.pickle", "rb") as f: tickers = pickle.load(f)
現在需要決定如何處理數據。我傾向於嘗試解析網站ONCE,並在本地存儲數據。我不會事先知道可能用數據做的所有事情,但是知道如果我將不止一次地拉它,不妨將它保存起來(除非它是一個巨大的數據集,不是)。因此,我們將把所有可以從雅虎返回給我們的每一種股票都拿出來,並保存下來。為此,我們將創建一個新目錄,並在那裡存儲每個公司的庫存數據。首先,需要這個初始目錄:
if not os.path.exists('stock_dfs'): os.makedirs('stock_dfs')
您可以將這些數據集存儲在與腳本相同的目錄中,但在我看來,這將是非常混亂的。現在我們已經準備好了數據。你應該已經知道如何做到這一點,因為在第一個教程中做到了!
start = dt.datetime(2010, 1, 1) end = dt.datetime.now() for ticker in tickers: # just in case your connection breaks, we'd like to save our progress! if not os.path.exists('stock_dfs/{}.csv'.format(ticker)): df = web.DataReader(ticker, 'morningstar', start, end) df.reset_index(inplace=True) df.set_index("Date", inplace=True) df = df.drop("Symbol", axis=1) df.to_csv('stock_dfs/{}.csv'.format(ticker)) else: print('Already have {}'.format(ticker))
你很可能會及時對這個函數做一些 force_data_update
參數,因為現在,它將不再重放已經擁有的數據。因為我們每天都在拉數據,所以你希望能重新拉動至少最新的數據。也就是說,如果是這樣的話,你最好用一個資料庫代替一個公司的表,然後從雅虎資料庫中提取最新的值。不過,我們現在要把事情簡單化!
import bs4 as bs import datetime as dt import os import pandas_datareader.data as web import pickle import requests# change work directory os.getcwd() os.chdir(r'C:UsersHPDesktopstockpython for finance')def save_sp500_tickers(): resp = requests.get('http://en.wikipedia.org/wiki/List_of_S%26P_500_companies') soup = bs.BeautifulSoup(resp.text, 'lxml') table = soup.find('table', {'class': 'wikitable sortable'}) tickers = [] for row in table.findAll('tr')[1:]: ticker = row.findAll('td')[0].text tickers.append(ticker) with open(r'C:UsersHPDesktopstockpython for financesp500tickers.pickle', 'wb') as f: pickle.dump(tickers, f) return tickers# save_sp500_tickers() def get_data_from_yahoo(reload_sp500=False): if reload_sp500: tickers = save_sp500_tickers() else: with open('sp500tickers.pickle', 'rb') as f: tickers = pickle.load(f) if not os.path.exists('stock_dfs'): os.makedirs('stock_dfs') start = dt.datetime(2017, 1, 1) end = dt.datetime.now() # for ticker in tickers: for ticker in tickers[:10]: # just in case your connection breaks, we'd like to save our progress! if not os.path.exists('stock_dfs/{}.csv'.format(ticker)): df = web.DataReader(ticker, 'morningstar', start, end) df.reset_index(inplace=True) df.set_index("Date", inplace=True) df = df.drop("Symbol", axis=1) df.to_csv('stock_dfs/{}.csv'.format(ticker)) else: print('Already have {}'.format(ticker))get_data_from_yahoo()
繼續並運行上述code。如果雅虎扼殺了你,你可能需要import time 並添加一個time.sleep(0.5)。在寫這篇文章的時候,雅虎並沒有完全扼殺我,而且能夠毫無問題地完成整個過程。但是,這可能還需要一段時間,尤其取決於您的機器。但好消息是,我們不需要再做一次!在實踐中,因為這是每日數據,您可能每天都會這樣做。
另外,如果你的網速很慢,你不需要做所有的事情,即使只有10次就足夠了,所以你可以用ticker [:10]或者類似的東西來加快速度。
在下一個教程中,一旦你下載了數據,我們將把感興趣的數據編譯成一個Pandas DataFrame。

ticker[:10] 的股票數據

雅培(ABT)的股票數據
英文版請戳: https://pythonprogramming.net/sp500-company-price-data-python-programming-for-finance/