Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(addLimitsMaxPeriod): limit start_date to its minimal allowed value #1286

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions tests/prices.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,81 @@ def test_monthlyWithEvents(self):
print("{}-without-events missing these dates: {}".format(tkr, missing_from_df2))
raise

def test_min_start_date_if_end_none(self):
tkrs = ["BHP.AX", "BHP.L", "BHP"]
intervals = ["1m", "2m", "60m", "90m", "1h"]

end = None

for tkr in tkrs:
dat = yf.Ticker(tkr, session=self.session)
for interval in intervals:
# First test minimum start is valid (not too old/low)
try:
df1 = dat.history(period="max", interval=interval, raise_errors=True)
except Exception as e:
if "days worth of" in str(e) and "granularity" in str(e):
raise Exception(f"Minimum start is too old ({tkr} @ {interval})")
else:
raise
dt0 = df1.index[0]

# Next test if minimum start is too recent (high)
try:
df2 = dat.history(start=dt0-_dt.timedelta(days=1), interval=interval, raise_errors=True)
except Exception as e:
if "days worth of" in str(e) and "granularity" in str(e):
# Fail = good!
pass
elif "requested range must be within the last" in str(e):
# Fail = good!
pass
else:
raise
else:
if df2.index[0].date() < dt0.date():
# 2nd request fetched more data so minimum could be older
raise Exception(f"Minimum start is too conservative ({tkr} @ {interval})")

def test_min_start_date_if_end_last_week(self):
# tkrs = ["BHP.AX", "BHP.L", "BHP"]
# intervals = ["1m", "2m", "60m", "90m", "1h"]
tkrs = ["BHP.L"]
intervals = ["1m"]

end = _dt.datetime.now() - _dt.timedelta(days=7)

for tkr in tkrs:
dat = yf.Ticker(tkr, session=self.session)
for interval in intervals:
# First test minimum start is valid (not too old/low)
try:
df1 = dat.history(period="max", end=end, interval=interval, raise_errors=True)
except Exception as e:
if "days worth of" in str(e) and "granularity" in str(e):
raise Exception(f"Minimum start is too old ({tkr} @ {interval})")
else:
raise
dt0 = df1.index[0]

# Next test if minimum start is too recent (high)
try:
df2 = dat.history(start=dt0-_dt.timedelta(days=1), end=end, interval=interval, raise_errors=True)
except Exception as e:
if "days worth of" in str(e) and "granularity" in str(e):
# Fail = good!
pass
elif "requested range must be within the last" in str(e):
# Fail = good!
pass
else:
raise
else:
if df2.index[0].date() < dt0.date():
# 2nd request fetched more data so minimum could be older
raise Exception(f"Minimum start is too conservative ({tkr} @ {interval})")


def test_tz_dst_ambiguous(self):
# Reproduce issue #1100

Expand Down
9 changes: 7 additions & 2 deletions yfinance/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,13 @@ def history(self, period="1mo", interval="1d",
else:
end = utils._parse_user_dt(end, tz)
if start is None:
if interval == "1m":
start = end - 604800 # Subtract 7 days
start_limits = {"1m": 30, "2m": 60, "5m": 60, "15m": 60, "30m": 60, "60m": 60, "90m": 60, "1h": 730}
range_limits = {"1m": 7, "2m": 60, "5m": 60, "15m": 60, "30m": 60, "60m": 60, "90m": 60, "1h": 730}
if interval in start_limits:
start = end - int(range_limits[interval] * 86400)
start_min = int(_time.time()) - int(start_limits[interval] * 86400)
start = max(start, start_min)
start += 5 # Allow 5 seconds for Yahoo to process request
else:
_UNIX_TIMESTAMP_1900 = -2208994789
start = _UNIX_TIMESTAMP_1900
Expand Down