yfinanceのデータをダウンロードして、日付と日付の間の日数を求めると、誤差が出ることがありました。
これから、その詳細を記載していきます。
事象・原因
yfinanceでダウンロードしたデータの日時は、タイムゾーン情報が付与されていて、通常時とサマータイム適用時でオフセットの差があります。
タイムゾーン情報の違いが原因で、日付間の日数を算出すると誤差が出ていました。
具体例
以下は「2024-03-07」と「2024-05-24」の日数を算出して出力する例です。
import pandas as pd # 年月日のみ date1 = pd.to_datetime("2024-03-07") date2 = pd.to_datetime("2024-05-24") print((date2 - date1).days) # 78 # タイムゾーンオフセットとサマータイム誤差が存在 date1 = pd.to_datetime("2024-03-07 00:00:00-05:00") date2 = pd.to_datetime("2024-05-24 00:00:00-04:00") print((date2 - date1).days) # 77 # タイムゾーン情報を削除 date1 = date1.tz_localize(None) date2 = date2.tz_localize(None) print((date2 - date1).days) # 78
年月日だけの場合は78日、タイムゾーン情報とサマータイムの誤差が存在する場合は77日になります。
対応方法
時間やタイムゾーンを使わない場合は、タイムゾーン情報を削除して良いのかなと思いました。
df.index = df.index.tz_localize(None)
CSVを読み込む場合も、日付が年月日だけだと、同じような扱いになっているのかなと思います。
yfinanceのコード例
yfinanceでデータをダウンロードして、タイムゾーン情報を削除する例は以下の通りです。
import pandas as pd import yfinance as yf # データをダウンロード tk = yf.Ticker("QQQ") df = tk.history( start="2024-03-01", end="2024-05-31", auto_adjust=False, actions=True ) print("## ダウンロード直後") print(df) # タイムゾーン情報を削除 df.index = df.index.tz_localize(None) print("## タイムゾーン削除後") print(df)
スクリプト実行結果
ダウンロード直後のDateは、オフセット情報が付与された状態で、サマータイムの誤差が確認できます。
Date 2024-03-01 00:00:00-05:00 439.899994 ... 2024-03-04 00:00:00-05:00 445.609985 ... 2024-03-05 00:00:00-05:00 440.940002 ... 2024-03-06 00:00:00-05:00 440.320007 ... 2024-03-07 00:00:00-05:00 442.420013 ... ... 2024-05-23 00:00:00-04:00 460.549988 ... 2024-05-24 00:00:00-04:00 455.290009 ... 2024-05-28 00:00:00-04:00 459.179993 ... 2024-05-29 00:00:00-04:00 455.480011 ... 2024-05-30 00:00:00-04:00 455.500000 ...
タイムゾーン削除後のDateは、年月日のみが出力されました。
Date 2024-03-01 439.899994 ... 2024-03-04 445.609985 ... 2024-03-05 440.940002 ... 2024-03-06 440.320007 ... 2024-03-07 442.420013 ... ... 2024-05-23 460.549988 ... 2024-05-24 455.290009 ... 2024-05-28 459.179993 ... 2024-05-29 455.480011 ... 2024-05-30 455.500000 ...