我使用Python包yfinance
来获取股票的历史股价(在本例中,是特斯拉的股票(。
当我做以下操作,并以一分钟为间隔获取上周的股价时:
import yfinance as yf
print(yf.Ticker('TSLA').history(period='7d', interval='1m'))
我得到
Open High Low Close Volume Dividends Stock Splits
Datetime
2020-12-03 09:30:00-05:00 586.391479 590.975586 585.549988 586.391479 2999806 0 0
2020-12-03 09:31:00-05:00 586.320007 591.919983 586.320007 591.619995 457446 0 0
2020-12-03 09:32:00-05:00 591.820007 591.907104 586.000000 587.492798 324244 0 0
2020-12-03 09:33:00-05:00 586.909973 590.020020 586.799988 588.919983 306530 0 0
2020-12-03 09:34:00-05:00 588.730774 588.919922 584.330017 584.688416 318614 0 0
... ... ... ... ... ... ... ...
2020-12-11 10:20:00-05:00 613.155029 614.059998 612.770020 613.789978 87083 0 0
2020-12-11 10:21:00-05:00 613.876404 613.960022 612.799988 613.235474 58031 0 0
2020-12-11 10:22:00-05:00 613.262390 614.010010 613.262390 614.000000 106497 0 0
2020-12-11 10:23:00-05:00 614.000000 614.000000 612.659973 613.099426 80285 0 0
2020-12-11 10:24:18-05:00 613.215027 613.215027 613.215027 613.215027 0 0 0
[2390 rows x 7 columns]
这样我就可以看到每个间隔的日期和时间。
然而,当我选择一小时间隔时:
import yfinance as yf
print(yf.Ticker('TSLA').history(period='7d', interval='1h'))
我得到
Open High Low Close Volume Dividends Stock Splits
Date
2020-12-03 590.020020 595.890015 582.429993 588.159973 14637166 0 0
2020-12-03 588.164917 591.000000 583.690002 587.432983 4633556 0 0
2020-12-03 587.370117 593.599976 586.430115 592.580017 4635495 0 0
2020-12-03 592.520020 594.500000 589.450012 594.130005 2941966 0 0
2020-12-03 594.110107 598.969971 593.169983 596.325012 6434228 0 0
2020-12-03 596.499878 598.309998 591.500000 594.809998 4211141 0 0
2020-12-03 594.844971 596.539978 592.000000 593.280029 2916165 0 0
2020-12-04 591.010010 597.440002 585.500000 591.739502 9404838 0 0
2020-12-04 591.859985 595.429993 587.750000 591.310120 4337670 0 0
2020-12-04 591.397888 594.789978 589.919983 593.419983 2994462 0 0
2020-12-04 593.530029 596.000000 592.409973 593.159973 2625920 0 0
2020-12-04 593.140015 594.309998 590.330017 592.700012 2374415 0 0
2020-12-04 592.619995 596.700012 592.239990 594.233398 3066786 0 0
2020-12-04 594.215027 599.000000 594.109985 599.000000 2983803 0 0
2020-12-07 604.919678 624.750000 603.049988 624.164978 14539011 0 0
2020-12-07 624.289978 630.000000 624.109985 626.499878 8340672 0 0
2020-12-07 626.450317 629.301575 625.609985 627.753296 3925194 0 0
2020-12-07 627.734985 633.500000 625.500000 632.647583 4394597 0 0
2020-12-07 632.684998 639.989990 631.500000 638.101013 6408641 0 0
2020-12-07 638.000000 648.785583 635.340027 645.309998 10078446 0 0
2020-12-07 645.304993 648.000000 637.099976 642.000000 6027320 0 0
2020-12-08 625.505005 637.340027 618.500000 629.020020 21461425 0 0
2020-12-08 629.099976 630.830017 624.260010 624.909973 5519322 0 0
2020-12-08 624.950012 630.250000 620.929993 629.372681 5926122 0 0
2020-12-08 629.409973 640.000000 628.520020 639.946594 5931369 0 0
2020-12-08 640.000000 651.280029 636.739990 650.429199 10931715 0 0
2020-12-08 650.500000 650.599915 642.000000 646.159973 7110200 0 0
2020-12-08 646.190002 650.479980 644.229980 650.250000 4363843 0 0
2020-12-09 653.690002 654.320007 630.000000 639.059998 16440841 0 0
2020-12-09 639.083801 643.039978 635.000000 635.594788 6210129 0 0
2020-12-09 635.605591 637.799988 628.500000 632.789978 5634442 0 0
2020-12-09 632.809998 633.400024 613.309998 616.940002 7626216 0 0
2020-12-09 616.759583 618.000000 588.000000 616.830017 18922860 0 0
2020-12-09 616.809998 616.820007 598.000000 601.000000 9894340 0 0
2020-12-09 601.000000 607.879883 600.400024 604.169983 4249969 0 0
2020-12-10 574.369995 607.059998 566.340027 600.495911 22449936 0 0
2020-12-10 600.492798 624.330017 600.309998 621.483887 12631129 0 0
2020-12-10 621.710022 622.679993 609.299988 611.215027 8174524 0 0
2020-12-10 611.290894 616.397217 602.260010 615.700012 6841379 0 0
2020-12-10 615.570129 619.869995 609.929993 618.749390 4659236 0 0
2020-12-10 618.580017 624.489990 615.340027 621.729980 6155838 0 0
2020-12-10 621.599976 627.750000 621.280029 627.150024 4087834 0 0
2020-12-11 615.010010 624.000000 607.307007 612.724426 11765035 0 0
2020-12-11 613.319214 613.319214 613.319214 613.319214 0 0 0
这意味着我不知道不同间隔的时间,只知道它们是在哪一天记录的。怎么回事?当我选择一分钟的间隔时,我会得到一天中的时间,为什么我不选择一小时的间隔呢?当使用一小时的间隔时,我能以某种方式轻松地获得一天中的时间吗?或者我必须将它们与一分钟的间隔进行比较,并试图找出哪个间隔对应于哪个小时?
我在venvLibsite-packagesyfinance
文件夹中查看了yfinance
背后的编码,并对其进行了一段时间的处理,以下是我的发现:
base.py
第182行:(金融查询其数据(
quotes = utils.parse_quotes(data["chart"]["result"][0], tz)
utils.py
第131行:(yfnance将时间转换为指定格式(
quotes.index = _pd.to_datetime(timestamps, unit="s")
datetimes.py
线路605-617(发生转换的功能(
def to_datetime()
最后一个函数似乎是发生日期转换的地方,打乱这些设置除了破坏程序之外什么都没做,所以我回到base.py
,一直在那里乱弄,直到我发现yfinance
在第234行做了第二个时间格式,如果你把elif params["interval"] == '1h': pass
放在第236行之后,你就可以得到没有丢失的小时/分钟/秒标记的数据。
注意修改yfinance
库可能会损坏某些内容,我不建议这样做。
base.py
第234-243行现在应该是这样的:
if params["interval"][-1] == "m":
df.index.name = "Datetime"
elif params["interval"] == '1h':
pass
else:
df.index = _pd.to_datetime(df.index.date)
if tz is not None:
df.index = df.index.tz_localize(tz)
df.index.name = "Date"
看看你的数据,你会发现一个大问题。。。
最大的问题是数据增加了9:30开盘的价值,此后每小时直到下午4点,都是在30分钟而不是00分钟:
Open High ... Dividends Stock Splits
2020-12-03 08:00:00-05:00 592.75 596.28 ... 0 0
2020-12-03 09:00:00-05:00 594.15 594.99 ... 0 0
2020-12-03 09:30:00-05:00 590.02 595.90 ... 0 0
2020-12-03 10:30:00-05:00 588.16 591 ... 0 0
...
2020-12-03 15:30:00-05:00 594.84 596.53 ... 0 0
2020-12-03 16:00:00-05:00 593.33 597.24 ... 0 0
在这一点上,我们可以继续调整yfinance
,但老实说,我们自己获取数据会更容易。我从挑选yfinance
中编写了以下代码,并根据我们的需要对其进行了修改:
直接从雅虎金融下载1h数据的代码
import requests
import datetime as dt
ticker = 'TSLA'
base_url = 'https://query1.finance.yahoo.com'
url = "{}/v8/finance/chart/{}".format(base_url, ticker)
params = {'interval': '1h', 'range': '7d', 'includePrePost': True}
response = requests.get(url=url, params=params)
data = response.json()
epoch = data['chart']['result'][0]['timestamp']
prices = data['chart']['result'][0]['indicators']['quote'][0]['close']
count = 0
list_of_time_and_price = []
for entry in epoch:
date_and_time = dt.datetime.fromtimestamp(entry).strftime('%Y-%m-%d %H:%M:%S')
list_of_time_and_price.append([date_and_time, prices[count]])
count += 1
print(list_of_time_and_price)
您可以根据自己的规范随意处理以上内容,目前它会返回一个带有日期时间和收盘价格的列表,并且确实包括交易日内的30分钟数据。
编辑
好消息是,我仔细检查了一下,显然直接从雅虎金融获得1小时的数据总是会返回:30分钟的交易间隔数据,所以问题不在于python库yfinance
,而在于雅虎金融网站本身。我想解决办法是下载1分钟的数据并将其更新为1小时,但之后您只能使用上周的数据。
如果你只需要股票数据,我建议你看看AlphaVantage API,它有2年的盘中数据,并且是免费的,每分钟最多5次请求(或类似的(。
这对我来说很好:
data = yf.download("TSLA",period='7d' , interval='60m')
data.to_csv("spy.csv")