![](/img/trans.png)
[英]Scraping stock price from Yahoo Finance using Python & BeautifulSoup
[英]download stock price history from yahoo finance with python 3.5
我目前正在尋找一種從Yahoo Finance加載多年股價歷史的方法。 我將有100多個股票代碼,我將下載1985年至今的數據。 我希望將“打開”,“高”,“低”,“關閉”,“調整關閉”,“體積”加載到各個數據框(熊貓)中,並將數據框的名稱命名為當前行情自動收錄器。
我的問題是我的變量行情自動收錄器不起作用,即使它起作用了,如何存儲這些數據呢?
import csv
import pandas as pd
import pandas_datareader.data as web
import datetime
#This represents the start and end date for the data
start = datetime.datetime(1985, 1, 1)
end = datetime.datetime(2016, 1, 27)
ticker = ['aapl','tvix','ugaz']
i= 0
while i < len(ticker):
f = web.DataReader(ticker, 'yahoo', start, end)
print(f)
i+=1
我希望能夠永久存儲所有這些數據,例如,如果今天加載100個股票代碼的30年價格歷史記錄,那么明天我將只需要追加一天的數據,而不是全部30年的數據。 另外,數據框似乎是組織數據的最有效方法,但是我不確定,但是我想進行機器學習和數據分析。
您可以使用pandas_datareader
模塊下載所需的數據(如果它們在yahoo上可用)。 您可以pip install
它,也可以通過其他任何方式安裝它。
以下是一個示例腳本,該腳本獲取少量符號的數據:
from pandas_datareader import data as dreader
symbols = ['GOOG', 'AAPL', 'MMM', 'ACN', 'A', 'ADP']
pnls = {i:dreader.DataReader(i,'yahoo','1985-01-01','2016-09-01') for i in symbols}
這會將數據保存在python字典中,該字典允許您使用.get
方法訪問數據。
例如,如果您想獲取GOOG
的數據,則可以執行以下操作:
print(pnls.get('GOOG').head())
得到以下內容:
Open High Low Close Volume \
Date
2004-08-19 100.000168 104.060182 95.960165 100.340176 44871300
2004-08-20 101.010175 109.080187 100.500174 108.310183 22942800
2004-08-23 110.750191 113.480193 109.050183 109.400185 18342800
2004-08-24 111.240189 111.600192 103.570177 104.870176 15319700
2004-08-25 104.960181 108.000187 103.880180 106.000184 9232100
Adj Close
Date
2004-08-19 50.119968
2004-08-20 54.100990
2004-08-23 54.645447
2004-08-24 52.382705
2004-08-25 52.947145
請記住,如果給定的股票行情一段時間內沒有數據,則返回的數據將忽略那些年或天(顯然)。
腳本的主要問題(除其他事項外)是您多次進行相同的調用( len(ticker)
次),並且一次又一次返回相同的輸出。 這是因為DataReader()
函數在提供list
時會消失,並為該list
每個元素獲取一個data.frame。 因此,當您編寫:
i = 0
while i < len(ticker):
f = web.DataReader(ticker, 'yahoo', start, end)
print(f)
i+=1
您實際上是在說: i = 0
,我希望您繼續進行web.DataReader(ticker, 'yahoo', start, end)
調用,並獲取相同的數據,然后打印直到(通過遞增) i
的值達到我的代碼清單的長度。 使用f = web.DataReader(ticker, 'yahoo', start, end)
可以得到相同的f = web.DataReader(ticker, 'yahoo', start, end)
。 但是即使那樣,您也不知道哪個數據框適用於哪個股票行情。
另外,令我震驚的另一件事是,當您處理100多個代碼時,您想命名返回的每個data.frame。 為什么要在上帝的綠色地球上命名空間中有100多個名稱? 您可以很容易地將所有這些名稱集中到一個dictionary
(如我上面推薦的那樣),並可以隨時使用.get()
並提供代碼來訪問其中的任何data.frame。
回顧:1)不需要while-loop
。 2)如果僅向DataReader()
函數提供代碼的完整列表,則您將無法知道哪個data.frame是哪個代碼的。 3)您不需要命名100個以上data.frames。
建議:只需使用字典(代碼是keys
,返回的數據將是values
)和列表推導遍歷代碼並獲取其數據,即可簡化整個過程。 我懷疑,這可以使您的腳本更容易閱讀並且更短。
這是為了提供一種解決方案,以期只需要運行一次作業,然后每天以最新的可用價格遞增數據,從而可以解決此問題。 這不是唯一的方法,但是我認為這是一個好方法。 首先,您需要創建一個腳本來獲取所有股票行情從1985年到昨天的數據。 該腳本將需要在市場交易時間(或深夜)之后運行以捕獲最新價格。 這可能與我上面的腳本非常相似。 您唯一需要添加的就是幾行代碼,以將數據保存在計算機上的當前工作目錄中。 應該執行以下操作:
from pandas_datareader import data as dreader
symbols = ['GOOG', 'AAPL', 'MMM', 'ACN', 'A', 'ADP']
pnls = {i:dreader.DataReader(i,'yahoo','1985-01-01','2016-09-01') for i in symbols}
for df_name in pnls:
pnls.get(df_name).to_csv("{}_data.csv".format(df_name), index=True, header=True)
然后,您可以編寫另一個腳本,該腳本只獲取當天相同股票的數據。 它也需要在晚上(午夜之前)運行,以便它可以捕獲今天的數據。
from datetime import datetime
from pandas_datareader import data as dreader
from pandas_datareader._utils import RemoteDataError
symbols = ['GOOG', 'AAPL', 'MMM', 'ACN', 'A', 'ADP']
try:
pnls = {i:dreader.DataReader(i,'yahoo',datetime.today(),datetime.today()) for i in symbols}
except RemoteDataError:
pnls = None
if pnls is not None:
for df_name in pnls:
with open("{}_data.csv".format(df_name),"a") as outfile:
pnls.get(df_name).to_csv(outfile,header=False)
else:
print("No data available yet. Please run later.")
第二個腳本應將最新價格附加到以前使用第一個腳本保存的每個數據文件中。
請注意,我假設Yahoo(或任何其他數據源)將在您關閉后,只要市場關閉即可提供當日價格。
我希望這有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.