我使用 Python 包yfinance获取股票的历史股价(在本例中为特斯拉的股票)。
当我执行以下操作并以一分钟为间隔获取上周的股票价格时:
import yfinance as yf
print(yf.Ticker('TSLA').history(period='7d', interval='1m'))
Run Code Online (Sandbox Code Playgroud)
我明白了
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]
Run Code Online (Sandbox Code Playgroud)
这样我就可以看到每个间隔的日期和时间。
但是,当我选择一小时间隔时:
import yfinance as yf
print(yf.Ticker('TSLA').history(period='7d', interval='1h'))
Run Code Online (Sandbox Code Playgroud)
我明白了
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
Run Code Online (Sandbox Code Playgroud)
这意味着我不知道不同时间间隔的时间,只知道它们是在哪一天记录的。怎么会?我在选择一分钟间隔时得到了一天中的时间,那么为什么我不得到一小时间隔呢?使用一小时间隔时,我是否可以以某种方式轻松获取一天中的时间,或者我是否必须将它们与一分钟间隔进行比较,并尝试找出哪个间隔对应于哪个小时?
我查看了文件夹yfinance中的编码\venv\Lib\site-packages\yfinance,并对其进行了一段时间的修改,这是我发现的:
base.py第 182 行:(yfinance 查询其数据)
quotes = utils.parse_quotes(data["chart"]["result"][0], tz)
Run Code Online (Sandbox Code Playgroud)
utils.py第131行:(yfinance将时间转换为指定格式)
quotes.index = _pd.to_datetime(timestamps, unit="s")
Run Code Online (Sandbox Code Playgroud)
datetimes.py第 605 - 617 行(发生转换的函数)
def to_datetime()
Run Code Online (Sandbox Code Playgroud)
最后一个函数似乎是日期转换发生的地方,弄乱这些设置除了破坏程序之外没有做任何事情,所以我回到那里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"
Run Code Online (Sandbox Code Playgroud)
看看你的数据,你会发现一个大问题......
最大的问题是数据增加了 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
Run Code Online (Sandbox Code Playgroud)
此时,我们可以继续调整yfinance,但说实话,我们自己获取数据会更容易。我从拆解中编写了以下代码yfinance,并将其修改为我们需要的:
直接从雅虎财经下载 1 小时数据的代码
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)
Run Code Online (Sandbox Code Playgroud)
您可以根据自己的规范修改上面的内容,目前它返回一个包含与收盘价配对的日期时间的列表,并且它确实包含交易日期间 :30 分钟的数据。
编辑
好消息是我仔细检查了,显然直接从雅虎财经获取 1 小时数据将始终返回 :30 分钟间隔交易数据,因此问题不在于 python 库,yfinance而在于雅虎财经网站本身。我想解决这个问题的方法是下载 1 分钟的数据并将其更新为 1 小时,但这样您就只能使用上周的数据。
如果您只需要股票数据,我建议您查看Alpha Vantage API,它包含 2 年的日内数据,并且免费,限制为每分钟 5 个请求(或类似的限制)。
| 归档时间: |
|
| 查看次数: |
10530 次 |
| 最近记录: |