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

Don't fix_Yahoo_returning_prepost_unrequested on Indian exhanges and 30m interval #1447

Open
wants to merge 3 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
38 changes: 15 additions & 23 deletions yfinance/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -721,26 +721,6 @@ def history(self, period="1mo", interval="1d",
print('%s: %s' % (self.ticker, err_msg))
return shared._DFS[self.ticker]

# 2) fix weired bug with Yahoo! - returning 60m for 30m bars
if interval.lower() == "30m":
quotes2 = quotes.resample('30T')
quotes = _pd.DataFrame(index=quotes2.last().index, data={
'Open': quotes2['Open'].first(),
'High': quotes2['High'].max(),
'Low': quotes2['Low'].min(),
'Close': quotes2['Close'].last(),
'Adj Close': quotes2['Adj Close'].last(),
'Volume': quotes2['Volume'].sum()
})
try:
quotes['Dividends'] = quotes2['Dividends'].max()
except Exception:
pass
try:
quotes['Stock Splits'] = quotes2['Dividends'].max()
except Exception:
pass

# Select useful info from metadata
quote_type = self._history_metadata["instrumentType"]
expect_capital_gains = quote_type in ('MUTUALFUND', 'ETF')
Expand All @@ -750,9 +730,21 @@ def history(self, period="1mo", interval="1d",
quotes = utils.set_df_tz(quotes, params["interval"], tz_exchange)
quotes = utils.fix_Yahoo_dst_issue(quotes, params["interval"])
quotes = utils.fix_Yahoo_returning_live_separate(quotes, params["interval"], tz_exchange)
intraday = params["interval"][-1] in ("m", 'h')
if not prepost and intraday and "tradingPeriods" in self._history_metadata:
quotes = utils.fix_Yahoo_returning_prepost_unrequested(quotes, params["interval"], self._history_metadata)
quotes = utils.fix_Yahoo_returning_prepost_unrequested(quotes, params, self._history_metadata)

# Fix weired bug with Yahoo! - returning 60m for 30m bars
if interval.lower() == '30m':
# Indian exchanges start at 9:15 AM
offset = '15min' if self._history_metadata['exchangeName'] in ('NSI', 'BSE') else None
quotes = quotes.resample('30min', offset=offset)
quotes = _pd.DataFrame(index=quotes.last().index, data={
'Open': quotes['Open'].first(),
'High': quotes['High'].max(),
'Low': quotes['Low'].min(),
'Close': quotes['Close'].last(),
'Adj Close': quotes['Adj Close'].last(),
'Volume': quotes['Volume'].sum()
})

# actions
dividends, splits, capital_gains = utils.parse_actions(data["chart"]["result"][0])
Expand Down
37 changes: 19 additions & 18 deletions yfinance/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,30 +448,31 @@ def set_df_tz(df, interval, tz):
return df


def fix_Yahoo_returning_prepost_unrequested(quotes, interval, metadata):
# Sometimes Yahoo returns post-market data despite not requesting it.
# Normally happens on half-day early closes.
#
# And sometimes returns pre-market data despite not requesting it.
# E.g. some London tickers.
def fix_Yahoo_returning_prepost_unrequested(quotes, params, metadata):
"""Sometimes Yahoo returns post-market data despite not requesting it.
Normally happens on half-day early closes.
And sometimes returns pre-market data despite not requesting it, e.g. some London tickers.
"""

# Don't need to fix for these conditions
if params["includePrePost"] or params["interval"][-1] not in ('m', 'h') or "tradingPeriods" not in metadata:
return quotes

# Prepare to merge "quotes" with "regular trading hours" on date
tps_df = metadata["tradingPeriods"]
tps_df["_date"] = tps_df.index.date
quotes["_date"] = quotes.index.date
idx = quotes.index.copy()

# Merge
quotes = quotes.merge(tps_df, how="left", validate="many_to_one")
quotes.index = idx
# "end" = end of regular trading hours (including any auction)
f_drop = quotes.index >= quotes["end"]
f_drop = f_drop | (quotes.index < quotes["start"])
if f_drop.any():
# When printing report, ignore rows that were already NaNs:
f_na = quotes[["Open","Close"]].isna().all(axis=1)
n_nna = quotes.shape[0] - _np.sum(f_na)
n_drop_nna = _np.sum(f_drop & ~f_na)
quotes_dropped = quotes[f_drop]
# if debug and n_drop_nna > 0:
# print(f"Dropping {n_drop_nna}/{n_nna} intervals for falling outside regular trading hours")
quotes = quotes[~f_drop]

# Drop quotes outside of the requested period
# "start" and "end" of regular trading hours (including any auction)
quotes = quotes[(quotes["start"] <= quotes.index) & (quotes.index < quotes["end"])]

# Restore
metadata["tradingPeriods"] = tps_df.drop(["_date"], axis=1)
quotes = quotes.drop(["_date", "start", "end"], axis=1)
return quotes
Expand Down