diff --git a/README.md b/README.md index 09bafb8..8cfd81c 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ The above call was made 21 minutes after the NYSE open. Notice that the call ret Any interval can be evaluated (limited only by the availability of underlying data). ```python >>> # prices over a specific session at 68 minute intervals ->>> prices.get("68T", start="2022-06-27", end="2022-06-27", force=True) +>>> prices.get("68min", start="2022-06-27", end="2022-06-27", force=True) ``` ``` symbol MSFT @@ -108,7 +108,7 @@ Although some indices are longer than three calendar days, they all comprise of ) >>> # lead_symbol determines the exchange against which the period will be evaluated and >>> # the default output time zone (which for Bitcoin is UTC). ->>> prices_mult.get("90T", hours=9, lead_symbol="BTC-USD") +>>> prices_mult.get("90min", hours=9, lead_symbol="BTC-USD") ``` ``` symbol MSFT 9988.HK BTC-USD @@ -127,7 +127,7 @@ By default prices are shown as missing when the exchange is closed (the time zon The `get` method has plenty of options to customize the output, including `fill` to fill in indices when an exchange is closed... ```python >>> # as before, only now filling in prices when exchanges are closed ->>> prices_mult.get("90T", hours=9, lead_symbol="BTC-USD", fill="both") +>>> prices_mult.get("90min", hours=9, lead_symbol="BTC-USD", fill="both") ``` ``` symbol MSFT 9988.HK BTC-USD diff --git a/src/market_prices/data.py b/src/market_prices/data.py index c950c4c..0033eab 100644 --- a/src/market_prices/data.py +++ b/src/market_prices/data.py @@ -659,7 +659,7 @@ def _requested_dates_adjust(self, dr: DateRangeReq) -> DateRangeReq | None: elif self.bi.is_intraday: assert self._delay is not None # ten minutes to cover provider delays in publishing data. - rerequest_from = helpers.now() - self._delay - pd.Timedelta(10, "T") + rerequest_from = helpers.now() - self._delay - pd.Timedelta(10, "min") if end < rerequest_from: return dr excess = end - rerequest_from diff --git a/src/market_prices/daterange.py b/src/market_prices/daterange.py index cac0094..feb31b6 100644 --- a/src/market_prices/daterange.py +++ b/src/market_prices/daterange.py @@ -866,7 +866,7 @@ def end_now(self) -> tuple[pd.Timestamp, pd.Timestamp]: # which the end is accurate as at the moment the end is requested. # (without the + one minute would be ignoring those price that have # come in since the current minute started.) - end_accuracy = min(end_accuracy, now + pd.Timedelta("1T")) + end_accuracy = min(end_accuracy, now + pd.Timedelta("1min")) return end, end_accuracy def _trading_index( @@ -1055,7 +1055,7 @@ def _offset_days(self, ts: pd.Timestamp, days: int) -> pd.Timestamp: # "previous" to cover ts as close (not a trading minute). session = self.cal.minute_to_session(ts, "previous") - schedule_vals = self.cal.schedule.loc[session].dropna().view(np.int64).values + schedule_vals = self.cal.schedule.loc[session].dropna().astype(np.int64).values if ts.value in schedule_vals: target_i = self.cal.sessions.get_loc(session) + days @@ -1199,7 +1199,7 @@ def daterange(self) -> tuple[mptypes.DateRange, pd.Timestamp]: if intraday_duration: if intraday_duration < self.final_interval.as_minutes: raise errors.PricesUnavailableIntervalDurationError( - pd.Timedelta(intraday_duration, "T"), self + pd.Timedelta(intraday_duration, "min"), self ) if start is None: end_ = end @@ -1269,7 +1269,7 @@ def daterange(self) -> tuple[mptypes.DateRange, pd.Timestamp]: else: minutes = calutils.minutes_in_period(self.cal, start, end_) if self.final_interval.as_minutes > minutes: - period_duration = pd.Timedelta(minutes, "T") + period_duration = pd.Timedelta(minutes, "min") raise errors.PricesUnavailableIntervalPeriodError( self, start, end_, period_duration ) diff --git a/src/market_prices/errors.py b/src/market_prices/errors.py index cb2fb05..d5946ce 100644 --- a/src/market_prices/errors.py +++ b/src/market_prices/errors.py @@ -872,10 +872,10 @@ class PricesMissingWarning(PricesWarning): def __init__(self, symbol: str, bi: BI, sessions: pd.DatetimeIndex, source: str): date_format = "%Y-%m-%d" - sessions = sessions.format(date_format=date_format) + sessions_ = sessions.strftime(date_format).tolist() self._msg = ( f"Prices from {source} are missing for '{symbol}' at the" - f" base interval '{bi}' for the following sessions: {sessions}." + f" base interval '{bi}' for the following sessions: {sessions_}." ) diff --git a/src/market_prices/helpers.py b/src/market_prices/helpers.py index 49b5fc2..d1ccb53 100644 --- a/src/market_prices/helpers.py +++ b/src/market_prices/helpers.py @@ -23,8 +23,8 @@ UTC = zoneinfo.ZoneInfo("UTC") ONE_DAY: pd.Timedelta = pd.Timedelta(1, "D") -ONE_MIN: pd.Timedelta = pd.Timedelta(1, "T") -ONE_SEC: pd.Timedelta = pd.Timedelta(1, "S") +ONE_MIN: pd.Timedelta = pd.Timedelta(1, "min") +ONE_SEC: pd.Timedelta = pd.Timedelta(1, "s") def symbols_to_list(symbols: mptypes.Symbols) -> list[str]: @@ -155,7 +155,7 @@ def now( now_ = now_.tz_convert(None) res = "D" else: - res = "T" + res = "min" return now_.ceil(res) if side == "right" else now_.floor(res) @@ -172,7 +172,7 @@ def extract_freq_parts(freq: str) -> tuple[int, str]: Parameters ---------- freq - Pandas frequency, for example "5D", "30T", "4H", "33MS". + Pandas frequency, for example "5D", "30min", "4h", "33MS". Raises ------ @@ -192,8 +192,8 @@ def extract_freq_parts(freq: str) -> tuple[int, str]: Examples -------- - >>> extract_freq_parts("22T") - (22, 'T') + >>> extract_freq_parts("22min") + (22, 'min') >>> extract_freq_parts("1m") (1, 'm') >>> extract_freq_parts("D") diff --git a/src/market_prices/intervals.py b/src/market_prices/intervals.py index 4a80026..31fbccf 100644 --- a/src/market_prices/intervals.py +++ b/src/market_prices/intervals.py @@ -51,10 +51,10 @@ def as_pdtd(self) -> pd.Timedelta: return pd.Timedelta(self) @property - def freq_unit(self) -> typing.Literal["T", "H", "D"]: + def freq_unit(self) -> typing.Literal["min", "h", "D"]: """Return unit of pandas frequency represented by the member. - Returns either "T", "H" or "D". + Returns either "min", "h" or "D". """ return self.as_pdtd.resolution_string @@ -64,7 +64,7 @@ def freq_value(self) -> int: components = self.as_pdtd.components if self.freq_unit == "D": return components.days - elif self.freq_unit == "H": + elif self.freq_unit == "h": return components.hours else: return components.minutes + (components.hours * 60) @@ -74,7 +74,7 @@ def is_intraday(self) -> bool: """Query if a member represents an intraday interval. An interval is considered to be intraday if it is shorter than one - day. The unit of intraday intervals will be either "T" or "H". + day. The unit of intraday intervals will be either "min" or "h". """ return self < helpers.ONE_DAY @@ -126,7 +126,7 @@ def as_offset( calendar Calendar against which to evaluate custom business day for intervals with `self.freq_unit` as "D". Not required for - intervals with `self.freq_unit` as "T" or "H". + intervals with `self.freq_unit` as "min" or "h". one_less If `self.freq_unit` is "D" then: @@ -260,7 +260,7 @@ def is_intraday(self) -> bool: """Query if a member represents an intraday interval. An interval is considered to be intraday if it is shorter than one - day. The unit of intraday intervals will be either "T" or "H". + day. The unit of intraday intervals will be either "min" or "h". """ return False @@ -376,9 +376,9 @@ def create_base_intervals_enum(intervals: list[TDInterval]) -> _BaseInterval: for intrvl in intervals: unit, value = intrvl.freq_unit, intrvl.freq_value td_args: tuple - if unit == "T": + if unit == "min": td_args = (0, 0, 0, 0, value) - elif unit == "H": + elif unit == "h": td_args = (0, 0, 0, 0, 0, value) else: if intrvl is not TDInterval.D1: @@ -432,6 +432,8 @@ def to_ptinterval(interval: str | timedelta | pd.Timedelta) -> PTInterval: f"`interval` unit must by one of {valid_units} (or lower-" f"case) although evaluated to '{unit}'." ) + if unit == "MIN": + unit = "T" else: if interval <= timedelta(0): @@ -448,7 +450,7 @@ def to_ptinterval(interval: str | timedelta | pd.Timedelta) -> PTInterval: ' example "1m" for one month.' ) - valid_resolutions = ["T", "H", "D"] + valid_resolutions = ["min", "h", "D"] if interval.resolution_string not in valid_resolutions: raise ValueError(error_msg) @@ -476,8 +478,7 @@ def raise_value_oob_error(component: str, limit: int): } if isinstance(interval, str): - if unit == "MIN": - unit = "T" + if value > limits[unit]: raise_value_oob_error(components[unit], limits[unit]) if unit == "T" and not value % 60: @@ -487,10 +488,12 @@ def raise_value_oob_error(component: str, limit: int): else: unit = interval.resolution_string - if unit == "T": + if unit in ["min", "T"]: # "T" for compatibility pandas < 2.2 value = int(interval.total_seconds() // 60) - elif unit == "H": + unit = "T" + elif unit in ["h", "H"]: # "H" for compatibility pandas < 2.2 value = int(interval.total_seconds() // 3600) + unit = "H" else: value = interval.days diff --git a/src/market_prices/parsing.py b/src/market_prices/parsing.py index eb2da11..58d2db9 100644 --- a/src/market_prices/parsing.py +++ b/src/market_prices/parsing.py @@ -200,12 +200,12 @@ def _parse_start_end( start_is_date = helpers.is_date(start) if not start_is_date: # do not include any incomplete minute - start = start.ceil("T") + start = start.ceil("min") if end is not None: end_is_date = helpers.is_date(end) if not end_is_date: # do not include incomplete minute - end = end.floor("T") + end = end.floor("min") # if end > now, set to None. now_interval = intervals.ONE_DAY if end_is_date else intervals.ONE_MIN now = helpers.now(now_interval, "left") diff --git a/src/market_prices/prices/base.py b/src/market_prices/prices/base.py index 5a51af8..7b94846 100644 --- a/src/market_prices/prices/base.py +++ b/src/market_prices/prices/base.py @@ -1123,7 +1123,7 @@ def lead_symbol_default(self) -> str: def _set_delays(self, delays: int | list[int] | dict[str, int]): d = self._dict_for_all_symbols("delays", delays) - self._delays = {k: pd.Timedelta(v, "T") for k, v in d.items()} + self._delays = {k: pd.Timedelta(v, "min") for k, v in d.items()} @property def delays(self) -> dict[str, pd.Timedelta]: @@ -1640,8 +1640,8 @@ def _set_indices_aligned(self): index = self._trading_indexes[bi] nano_index = index.left.asi8 - opens = self.cc.opens[slc].view("int64") - closes = self.cc.closes[slc].view("int64") + opens = self.cc.opens[slc].astype("int64") + closes = self.cc.closes[slc].astype("int64") sessions = opens.index srs = pd.Series(True, index=sessions) @@ -3444,7 +3444,7 @@ def get( value: one or more digits. unit: - "min", "t", "MIN" or "T" for minutes + "min", "MIN", "T" or "t" for minutes "h" or "H" for hours "d" or "D' for days 'm' or "M" for months @@ -3452,12 +3452,12 @@ def get( Examples: thirty minutes: "30min", "30T" - pd.Timedelta(30, "T"), pd.Timedelta(minutes=30) + pd.Timedelta(30, "min"), pd.Timedelta(minutes=30) timedelta(minutes=30) three hours: "3h", "3H" - pd.Timedelta(3, "H"), pd.Timedelta(hours=3) + pd.Timedelta(3, "h"), pd.Timedelta(hours=3) timedelta(hours=3) one day: @@ -3854,8 +3854,8 @@ def get( greater than the interval although the indice bounds they evaluate to do not. For example, if a session opens at 09.00, `start` is 09.01 and `end` is 09.09 - then a call for data at a "5T" `interval` will evalute - the period bounds as from 09.05 through 09.05. + then a call for data at a "5min" `interval` will + evalute the period bounds as from 09.05 through 09.05. errors.PricesUnavailableDOIntervalPeriodError: Monthly `interval` is longer than the evaluated period. diff --git a/src/market_prices/prices/yahoo.py b/src/market_prices/prices/yahoo.py index 840c602..dce02bd 100644 --- a/src/market_prices/prices/yahoo.py +++ b/src/market_prices/prices/yahoo.py @@ -560,7 +560,7 @@ def _set_daily_bi_limit(self): @staticmethod def _bi_to_source_key(interval: intervals.BI) -> str: """Map interval to value for source's interval parameter.""" - if interval.freq_unit == "T": + if interval.freq_unit == "min": return str(interval.freq_value) + "m" else: return interval.as_pdfreq.lower() # as yahooquery value @@ -868,6 +868,6 @@ def _request_data( # 22 hours ensures markets opening in Americas included # whilst avoiding including the following session of # Australasian markets - end_ += pd.Timedelta(22, "H") + end_ += pd.Timedelta(22, "h") prices = self._request_yahoo(interval=interval, start=start, end=end_) return self._tidy_yahoo(prices, interval, start, end) diff --git a/src/market_prices/pt.py b/src/market_prices/pt.py index 601cd04..0884292 100644 --- a/src/market_prices/pt.py +++ b/src/market_prices/pt.py @@ -677,11 +677,11 @@ def _partial_non_trading( # minute long non trading period. if start != trading_mins[0]: for nanos in [calendar.first_minutes_nanos, calendar.break_ends_nanos]: - arr = np.intersect1d(nanos, trading_mins.values.view("int64")) + arr = np.intersect1d(nanos, trading_mins.values.astype("int64")) if arr.size > 0: trading_mins = trading_mins.drop(pd.DatetimeIndex(arr, tz=UTC)) - all_mins = pd.date_range(start, end, freq="1T") + all_mins = pd.date_range(start, end, freq="1min") non_t = all_mins.difference(trading_mins) bv_discontinuous = non_t[1:] != (non_t[:-1] + helpers.ONE_MIN) side = "left" @@ -1057,8 +1057,9 @@ def stacked(self) -> pd.DataFrame: "Only price tables with a single row can be stacked (price table" f" has {num_rows} rows)." ) - df = self.prices.stack(level=0, dropna=False) + df = self.prices.stack(level=0, future_stack=True) assert isinstance(df, pd.DataFrame) + df.sort_index(axis=0, level=0, ascending=True, inplace=True) return helpers.order_cols(df) @abc.abstractmethod @@ -1479,7 +1480,7 @@ def downsample( # pylint: disable=arguments-differ else: return self._downsample_days(pdfreq) - if unit in ["H", "T", "min", "S", "L", "ms", "U", "us", "N"]: + if unit in ["h", "min", "s", "L", "ms", "U", "us", "N", "ns"]: raise ValueError( "Cannot downsample to a `pdfreq` with a unit more precise than 'd'." ) @@ -1849,7 +1850,7 @@ def trading_minutes_interval( return None else: mins = int(trading_mins[0]) - return intervals.TDInterval(pd.Timedelta(mins, "T")) + return intervals.TDInterval(pd.Timedelta(mins, "min")) def indices_have_regular_trading_minutes( self, calendar: xcals.ExchangeCalendar @@ -2122,8 +2123,12 @@ def _groupby_composite_session(indice) -> pd.Timestamp: r_dfs = [] for group in grouped: g_df = group[1] + # (at least) pandas 2.2.0 fix if not supporting these versions + # then can directly pass group[0] to cal.session_open + # See https://github.com/pandas-dev/pandas/issues/57192 + session = group[0] if group[0].tz is None else group[0].tz_convert(None) try: - origin = cal.session_open(group[0]) + origin = cal.session_open(session) except xcals.errors.NotSessionError: origin = "start" r_dfs.append(helpers.resample(g_df, rule=offset, origin=origin)) @@ -2208,8 +2213,8 @@ def downsample( pdfreq : str Resample frequency as valid str input to `pd.tseries.frequencies.to_offset` with unit in - ["min", "T", "H", "h"]. Examples: - "15min", "15T", "30min", "1h", "1H", '4h', '12H' + ["min", "h"]. Examples: + "15min", "30min", "1h", '4h', '12h' `pdfreq` must represent an interval higher than the table interval. @@ -2323,7 +2328,7 @@ def downsample( ) unit = genutils.remove_digits(pdfreq) - valid_units = ["min", "T", "h", "H"] + valid_units = ["min", "h"] if unit not in valid_units: raise ValueError( f"The unit of `pdfreq` must be in {valid_units} although received" @@ -2331,8 +2336,8 @@ def downsample( ) value = int(genutils.remove_nondigits(pdfreq)) - minutes = value if unit in ["min", "T"] else 60 * value - interval = pd.Timedelta(minutes, "T") + minutes = value if unit == "min" else 60 * value + interval = pd.Timedelta(minutes, "min") table_interval = self.interval if table_interval > interval: diff --git a/src/market_prices/utils/calendar_utils.py b/src/market_prices/utils/calendar_utils.py index 2d38c4e..3ff5e14 100644 --- a/src/market_prices/utils/calendar_utils.py +++ b/src/market_prices/utils/calendar_utils.py @@ -240,7 +240,7 @@ class CompositeCalendar: LEFT_SIDES = ["left", "both"] RIGHT_SIDES = ["right", "both"] - ONE_MIN = pd.Timedelta(1, "T") + ONE_MIN = pd.Timedelta(1, "min") def __init__(self, calendars: set | abc.Sequence[xcals.ExchangeCalendar]): self._cals = calendars diff --git a/src/market_prices/utils/pandas_utils.py b/src/market_prices/utils/pandas_utils.py index 7d63bf3..9b582a1 100644 --- a/src/market_prices/utils/pandas_utils.py +++ b/src/market_prices/utils/pandas_utils.py @@ -19,14 +19,13 @@ def pdfreq_to_offset(pdfreq: str) -> pd.offsets.BaseOffset: Parameters ---------- pdfreq - pandas frequency string to convert. For example, '15min', - '15T', '3H'. + pandas frequency string to convert. For example, '15min', '3h'. Examples -------- - >>> pdfreq_to_offset('22T') + >>> pdfreq_to_offset('22min') <22 * Minutes> - >>> pdfreq_to_offset('3H') + >>> pdfreq_to_offset('3h') <3 * Hours> >>> pdfreq_to_offset('3MS') <3 * MonthBegins> @@ -93,7 +92,7 @@ def timestamps_in_interval_of_intervals( >>> intervals = pd.interval_range(start, end, freq="10D", closed=closed) >>> intervals - IntervalIndex([[2021-03-02, 2021-03-12], [2021-03-12, 2021-03-22]], dtype='interval[datetime64[ns], both]') + IntervalIndex([[2021-03-02 00:00:00, 2021-03-12 00:00:00], [2021-03-12 00:00:00, 2021-03-22 00:00:00]], dtype='interval[datetime64[ns], both]') >>> timestamps_in_interval_of_intervals(timestamps, intervals) True """ @@ -140,7 +139,7 @@ def make_non_overlapping( Examples -------- - >>> left = pd.date_range('2021-05-01 12:00', periods=5, freq='1H') + >>> left = pd.date_range('2021-05-01 12:00', periods=5, freq='h') >>> intervals = [ ... pd.Interval(left[0], left[0] + pd.Timedelta(45, 'min')), @@ -213,7 +212,7 @@ def make_non_overlapping( # evaluate full_overlap_mask # as 'int64' to use expanding, as series to use expanding and shift - right = pd.Index(index.right.view("int64")).to_series() + right = pd.Index(index.right.astype("int64")).to_series() next_right = right.shift(-1) max_right_to_date = right.expanding().max() # shift 1 to move from overlapping indice to overlapped indice @@ -257,7 +256,7 @@ def get_interval_index( interval. offset - Duration of each interval, for example "15min", "15T", "3H" etc. + Duration of each interval, for example "15min", "3h" etc. closed : default: "left" Side on which to close intervals. @@ -272,8 +271,8 @@ def get_interval_index( Examples -------- - >>> left = pd.date_range('2021-05-01 12:00', periods=5, freq='1H') - >>> index = get_interval_index(left, '33T') + >>> left = pd.date_range('2021-05-01 12:00', periods=5, freq='1h') + >>> index = get_interval_index(left, '33min') >>> index.to_series(index=range(5)) 0 [2021-05-01 12:00:00, 2021-05-01 12:33:00) 1 [2021-05-01 13:00:00, 2021-05-01 13:33:00) @@ -314,8 +313,8 @@ def interval_contains(interval: pd.Interval, intervals: pd.IntervalIndex) -> np. Examples -------- - >>> left = pd.date_range('2021-05-01 12:00', periods=5, freq='1H') - >>> right = left + pd.Timedelta(30, 'T') + >>> left = pd.date_range('2021-05-01 12:00', periods=5, freq='1h') + >>> right = left + pd.Timedelta(30, 'min') >>> intervals = pd.IntervalIndex.from_arrays(left, right) >>> intervals.to_series(index=range(5)) 0 (2021-05-01 12:00:00, 2021-05-01 12:30:00] @@ -389,8 +388,8 @@ def remove_intervals_from_interval( Examples -------- >>> from pprint import pprint - >>> left = pd.date_range('2021-05-01 12:00', periods=5, freq='1H') - >>> right = left + pd.Timedelta(30, 'T') + >>> left = pd.date_range('2021-05-01 12:00', periods=5, freq='h') + >>> right = left + pd.Timedelta(30, 'min') >>> intervals = pd.IntervalIndex.from_arrays(left, right) >>> intervals.to_series(index=range(5)) 0 (2021-05-01 12:00:00, 2021-05-01 12:30:00] @@ -406,11 +405,11 @@ def remove_intervals_from_interval( ... ) >>> rtrn = remove_intervals_from_interval(interval, intervals) >>> pprint(rtrn) - [Interval('2021-05-01 12:30:00', '2021-05-01 13:00:00', closed='left'), - Interval('2021-05-01 13:30:00', '2021-05-01 14:00:00', closed='left'), - Interval('2021-05-01 14:30:00', '2021-05-01 15:00:00', closed='left'), - Interval('2021-05-01 15:30:00', '2021-05-01 16:00:00', closed='left'), - Interval('2021-05-01 16:30:00', '2021-05-01 17:30:00', closed='left')] + [Interval(2021-05-01 12:30:00, 2021-05-01 13:00:00, closed='left'), + Interval(2021-05-01 13:30:00, 2021-05-01 14:00:00, closed='left'), + Interval(2021-05-01 14:30:00, 2021-05-01 15:00:00, closed='left'), + Interval(2021-05-01 15:30:00, 2021-05-01 16:00:00, closed='left'), + Interval(2021-05-01 16:30:00, 2021-05-01 17:30:00, closed='left')] """ if not intervals.is_monotonic_increasing: raise ValueError( @@ -502,9 +501,9 @@ def interval_index_new_tz( -------- >>> tz = ZoneInfo("US/Central") >>> left = pd.date_range( - ... '2021-05-01 12:00', periods=5, freq='1H', tz=tz + ... '2021-05-01 12:00', periods=5, freq='h', tz=tz ... ) - >>> right = left + pd.Timedelta(30, 'T') + >>> right = left + pd.Timedelta(30, 'min') >>> index = pd.IntervalIndex.from_arrays(left, right) >>> index.right.tz zoneinfo.ZoneInfo(key='US/Central') @@ -537,7 +536,7 @@ def index_is_normalized( Examples -------- - >>> index = pd.date_range('2021-05-01 12:00', periods=5, freq='1H') + >>> index = pd.date_range('2021-05-01 12:00', periods=5, freq='h') >>> index_is_normalized(index) False >>> index = pd.date_range('2021-05-01', periods=5, freq='1D') @@ -545,7 +544,7 @@ def index_is_normalized( True >>> index = pd.interval_range( - ... pd.Timestamp('2021-05-01 12:00'), periods=5, freq='1H' + ... pd.Timestamp('2021-05-01 12:00'), periods=5, freq='h' ... ) >>> index_is_normalized(index) False @@ -577,8 +576,8 @@ def indexes_union(indexes: list[pd.Index]) -> pd.Index: Examples -------- - >>> index1 = pd.date_range('2021-05-01 12:20', periods=2, freq='1H') - >>> index2 = pd.date_range('2021-05-02 17:10', periods=2, freq='22T') + >>> index1 = pd.date_range('2021-05-01 12:20', periods=2, freq='1h') + >>> index2 = pd.date_range('2021-05-02 17:10', periods=2, freq='22min') >>> index3 = pd.date_range('2021-05-03', periods=2, freq='1D') >>> indexes_union([index1, index2, index3]) DatetimeIndex(['2021-05-01 12:20:00', '2021-05-01 13:20:00', @@ -604,8 +603,8 @@ def index_union(indexes: list[Union[pd.Index, pd.Series, pd.DataFrame]]) -> pd.I Examples -------- - >>> index1 = pd.date_range('2021-05-01 12:20', periods=2, freq='1H') - >>> index2 = pd.date_range('2021-05-02 17:10', periods=2, freq='22T') + >>> index1 = pd.date_range('2021-05-01 12:20', periods=2, freq='1h') + >>> index2 = pd.date_range('2021-05-02 17:10', periods=2, freq='22min') >>> index3 = pd.date_range('2021-05-03', periods=2, freq='1D') >>> ser = pd.Series(range(2), index=index2) >>> df = pd.DataFrame({'col_int': range(2)}, index=index3) diff --git a/tests/conftest.py b/tests/conftest.py index 2e9d5de..c6a0cbf 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -144,13 +144,13 @@ def one_day() -> abc.Iterator[pd.Timedelta]: @pytest.fixture(scope="session") def one_min() -> abc.Iterator[pd.Timedelta]: """pd.Timedelta with value as one minute.""" - yield pd.Timedelta(1, "T") + yield pd.Timedelta(1, "min") @pytest.fixture(scope="session") def one_sec() -> abc.Iterator[pd.Timedelta]: """pd.Timedelta with value as one second.""" - yield pd.Timedelta(1, "S") + yield pd.Timedelta(1, "s") _now_utc = pd.Timestamp("2021-11-17 21:59", tz=UTC) diff --git a/tests/hypstrtgy.py b/tests/hypstrtgy.py index 4f4ca72..f68e3d6 100644 --- a/tests/hypstrtgy.py +++ b/tests/hypstrtgy.py @@ -387,7 +387,7 @@ def pp_days_start_session( sessions = calendar.sessions limit_r = sessions[-pp["days"]] if start_will_roll_to_ms: - offset = pd.tseries.frequencies.to_offset("M") + offset = pd.tseries.frequencies.to_offset("ME") if TYPE_CHECKING: assert offset is not None limit_r = offset.rollback(limit_r) diff --git a/tests/test_base.py b/tests/test_base.py index f7a5d59..1f0cb7c 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -58,7 +58,7 @@ def t1_us_lon() -> abc.Iterator[pd.DataFrame]: Recreate table with: > symbols = ["MSFT", "AZN.L"] > df = prices.get( - "1T", + "1min", start=pd.Timestamp("2022-02"), end=pd.Timestamp("2022-02-09"), anchor="open", @@ -74,7 +74,7 @@ def t5_us_lon() -> abc.Iterator[pd.DataFrame]: Recreate table with: > symbols = ["MSFT", "AZN.L"] > df = prices.get( - "5T", + "5min", start=pd.Timestamp("2022-01"), end=pd.Timestamp("2022-02-07"), anchor="open", @@ -388,7 +388,7 @@ def test_fill_reindexed_daily(one_min, monkeypatch): columns = pd.Index(["open", "high", "low", "close", "volume"]) symbol = "AZN.L" xlon = xcals.get_calendar("XLON", start="1990-01-01", side="left") - delay = pd.Timedelta(15, "T") + delay = pd.Timedelta(15, "min") def f( df: pd.DataFrame, @@ -398,7 +398,7 @@ def f( mindate = cal.first_session if mindate is None else mindate return m.fill_reindexed_daily(df, cal, mindate, delay, symbol, "Yahoo") - def match(sessions: pd.DatetimeIndex) -> str: + def match(sessions: pd.DatetimeIndex | list[str]) -> str: return re.escape( f"Prices from Yahoo are missing for '{symbol}' at the base" f" interval '{intervals.TDInterval.D1}' for the following sessions:" @@ -436,15 +436,13 @@ def match(sessions: pd.DatetimeIndex) -> str: # and a missing prices warning is raised. now = xlon.session_open(index[-1]) + delay + one_min mock_now(monkeypatch, now) - missing_sessions = pd.DatetimeIndex( - [ - "2021-01-04", - "2021-01-07", - "2021-01-08", - "2021-01-12", - "2021-01-14", - ] - ).format(date_format="%Y-%m-%d") + missing_sessions = [ + "2021-01-04", + "2021-01-07", + "2021-01-08", + "2021-01-12", + "2021-01-14", + ] rtrn, warnings_ = f(df.copy(), xlon) with pytest.warns(errors.PricesMissingWarning, match=match(missing_sessions)): @@ -1411,22 +1409,22 @@ def test_multiple_calendars(self, PricesMock, xlon, xasx, xnys, zero_td): assert prices.calendars_symbols == calendars_symbols_expected expected_delays = { - "NY": pd.Timedelta(5, "T"), - "LON": pd.Timedelta(10, "T"), - "LON2": pd.Timedelta(15, "T"), + "NY": pd.Timedelta(5, "min"), + "LON": pd.Timedelta(10, "min"), + "LON2": pd.Timedelta(15, "min"), "OZ": zero_td, } assert prices.delays == expected_delays assert prices.min_delay == zero_td - assert prices.max_delay == pd.Timedelta(15, "T") + assert prices.max_delay == pd.Timedelta(15, "min") assert prices.calendars_min_delay == { - xlon: pd.Timedelta(10, "T"), - xnys: pd.Timedelta(5, "T"), + xlon: pd.Timedelta(10, "min"), + xnys: pd.Timedelta(5, "min"), xasx: zero_td, } assert prices.calendars_max_delay == { - xlon: pd.Timedelta(15, "T"), - xnys: pd.Timedelta(5, "T"), + xlon: pd.Timedelta(15, "min"), + xnys: pd.Timedelta(5, "min"), xasx: zero_td, } @@ -1522,7 +1520,7 @@ def match(bis, limit_keys) -> str: # pylint: disable=function-redefined # verify cannot include an interval that is not a base interval. base_limits_copy = PricesMock.BASE_LIMITS.copy() not_bi = intervals.TDInterval.T30 - base_limits_copy[not_bi] = pd.Timedelta(1, "S") + base_limits_copy[not_bi] = pd.Timedelta(1, "s") limit_keys = base_limits_copy.keys() with pytest.raises(ValueError, match=match(prices.bis, limit_keys)): prices._update_base_limits({not_bi: pd.Timedelta(100, "D")}) @@ -1594,22 +1592,21 @@ def test_calendar_too_short_warning( cal2 = xcals.get_calendar("XASX", start=start, side=side) def match(cal: xcals.ExchangeCalendar) -> str: - return re.escape( + return ( f"Calendar '{cal.name}' is too short to support all available price" f" history. Calendar starts '{cal.first_session}' whilst earliest date" f" for which price history is available is '{daily_limit}'. Prices" f" will not be available for any date prior to {cal.first_session}." ) - with pytest.warns(errors.CalendarTooShortWarning, match=match(cal)): + with pytest.warns(errors.CalendarTooShortWarning, match=re.escape(match(cal))): PricesMock(symbols, cal) - with pytest.warns(errors.CalendarTooShortWarning, match=match(cal)) as ws: + with pytest.warns(errors.CalendarTooShortWarning) as ws: PricesMock(symbols, [good_cal, cal, cal2]) assert len(ws.list) == 2 - - with pytest.warns(errors.CalendarTooShortWarning, match=match(cal2)): - PricesMock(symbols, [good_cal, cal, cal2]) + for match in (match(cal), match(cal2)): + assert match in str(ws[0].message) or match in str(ws[1].message) def test_calendar_too_short_error( self, PricesMock, symbols, side, xnys, one_day, monkeypatch @@ -1777,8 +1774,8 @@ def mock_now(tz=None) -> pd.Timestamp: if bi.is_daily: assert prices.limits[bi] == (daily_limit, today) else: - ll = (now - PricesMock.BASE_LIMITS[bi]).ceil("T") + one_min - rl = now.floor("T") + bi + ll = (now - PricesMock.BASE_LIMITS[bi]).ceil("min") + one_min + rl = now.floor("min") + bi assert prices.limits[bi] == (ll, rl) # verify `limit_daily` @@ -1788,7 +1785,7 @@ def mock_now(tz=None) -> pd.Timestamp: # verify `limit_intraday` delta = PricesMock.BASE_LIMITS[PricesMock.BaseInterval.T5] # unaligned at H1 - limit_raw = (now - delta).ceil("T") + one_min + limit_raw = (now - delta).ceil("min") + one_min limits_intraday = [] for cal in calendars: expected_limit_intraday = cal.minute_to_trading_minute(limit_raw, "next") @@ -1798,7 +1795,7 @@ def mock_now(tz=None) -> pd.Timestamp: assert prices.limit_intraday() == expected_latest_intraday_limit assert prices.limit_intraday(None) == expected_latest_intraday_limit # verify `limit_right_intraday` - assert prices.limit_right_intraday == now.floor("T") + assert prices.limit_right_intraday == now.floor("min") # verify 'limit_sessions' assert len(prices.limits_sessions) == len(PricesMock.BaseInterval) @@ -1838,7 +1835,7 @@ def mock_now(tz=None) -> pd.Timestamp: assert set(prices.limits.keys()) == set(PricesMockIntradayOnly.BaseInterval) assert len(prices.limits) == len(PricesMockIntradayOnly.BaseInterval) - assert pd.Timedelta(1, "T") in prices.bis + assert pd.Timedelta(1, "min") in prices.bis assert not pd.Timedelta(1, "D") in prices.bis assert prices.limit_daily is None @@ -1949,7 +1946,7 @@ def test_limits_fixed( PricesMockIntradayOnlyFixedLimits.BaseInterval ) assert len(prices.limits) == len(PricesMockIntradayOnlyFixedLimits.BaseInterval) - assert pd.Timedelta(1, "T") in prices.bis + assert pd.Timedelta(1, "min") in prices.bis assert not pd.Timedelta(1, "D") in prices.bis assert prices.limit_daily is None @@ -2599,14 +2596,14 @@ def patch_now(monkey, ts): # now at limit of minute + min xlon delay (10) with monkeypatch.context() as m: - now = minute + pd.Timedelta(10, "T") + now = minute + pd.Timedelta(10, "min") patch_now(m, now) assert f(minute, *args) == session # verify makes no difference if pass minute ahead of now assert f(minute + pd.Timedelta(5, "D"), *args) == session # now less than minute + min xlon delay (10) - now = minute + pd.Timedelta(9, "T") + now = minute + pd.Timedelta(9, "min") patch_now(m, now) assert not f(minute, *args) == session assert f(minute, *args) == xlon_prev_session @@ -2617,7 +2614,7 @@ def patch_now(monkey, ts): with monkeypatch.context() as m: # now at limit of minute + min xnys delay (5) - now = minute + pd.Timedelta(5, "T") + now = minute + pd.Timedelta(5, "min") patch_now(m, now) assert f(minute, *args) == next_session @@ -2625,7 +2622,7 @@ def patch_now(monkey, ts): assert f(minute + pd.Timedelta(5, "D"), *args) == next_session # now less than minute + min xlon delay (5) - now = minute + pd.Timedelta(4, "T") + now = minute + pd.Timedelta(4, "min") patch_now(m, now) assert not f(minute, *args) == next_session assert f(minute, *args) == session @@ -2990,8 +2987,8 @@ def get_mock_drg_limit_available( """ start = prices.BASE_LIMITS[bi] assert isinstance(start, pd.Timestamp) - end = (start if limit_end else self._now) + pd.Timedelta(delta_end, "T") - start += pd.Timedelta(delta, "T") + end = (start if limit_end else self._now) + pd.Timedelta(delta_end, "min") + start += pd.Timedelta(delta, "min") return self.get_mock_drg(GetterMock, prices.cc, start, end) def get_mock_drg_limit_right_available( @@ -3024,8 +3021,8 @@ def get_mock_drg_limit_right_available( end = prices.BASE_LIMITS_RIGHT[bi] start = end if limit_start else prices.BASE_LIMITS[bi] assert isinstance(start, pd.Timestamp) - start += pd.Timedelta(delta_start, "T") - end += pd.Timedelta(delta, "T") + start += pd.Timedelta(delta_start, "min") + end += pd.Timedelta(delta, "min") return self.get_mock_drg(GetterMock, prices.cc, start, end) def get_drg( @@ -3085,7 +3082,7 @@ def test__bis_valid(self, PricesMockBis, GetterMock, symbols, xlon, xnys, one_mi def f(interval: int, drg: daterange.GetterIntraday) -> list[intervals.BI]: self.set_prices_gpp_drg_properties(prices, drg) - prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "T") + prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "min") return prices._bis_valid drg_aligned = GetterMock(daterange_sessions=sessions_aligned) @@ -3179,17 +3176,17 @@ def test__bis_available( get_drg_args = (prices, GetterMock) def bis_available_all(interval: int, drg) -> list[intervals.BI]: - prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "T") + prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "min") self.set_prices_gpp_drg_properties(prices, drg) return prices._bis_available_all def bis_available_end(interval: int, drg) -> list[intervals.BI]: - prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "T") + prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "min") self.set_prices_gpp_drg_properties(prices, drg) return prices._bis_available_end def bis_available_any(interval: int, drg) -> list[intervals.BI]: - prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "T") + prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "min") self.set_prices_gpp_drg_properties(prices, drg) return prices._bis_available_any @@ -3265,17 +3262,17 @@ def test__bis_available_fixed_right( get_drg_args = (prices, GetterMock) def bis_available_all(interval: int, drg) -> list[intervals.BI]: - prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "T") + prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "min") self.set_prices_gpp_drg_properties(prices, drg) return prices._bis_available_all def bis_available_end(interval: int, drg) -> list[intervals.BI]: - prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "T") + prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "min") self.set_prices_gpp_drg_properties(prices, drg) return prices._bis_available_end def bis_available_any(interval: int, drg) -> list[intervals.BI]: - prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "T") + prices.gpp.ds_interval = intervals.to_ptinterval(str(interval) + "min") self.set_prices_gpp_drg_properties(prices, drg) return prices._bis_available_any @@ -3344,7 +3341,7 @@ def test_bis_stored_methods(self, PricesMockBis, GetterMock, symbols, xlon, xnys prices = PricesMockBis(symbols, [xlon, xnys]) get_drg_args = (prices, GetterMock) - prices.gpp.ds_interval = intervals.to_ptinterval("30T") + prices.gpp.ds_interval = intervals.to_ptinterval("30min") for bi in prices.bis_intraday: drg = self.get_mock_drg_limit_available(*get_drg_args, bi) self.set_prices_gpp_drg_properties(prices, drg) diff --git a/tests/test_base_prices.py b/tests/test_base_prices.py index e325982..2631f9b 100644 --- a/tests/test_base_prices.py +++ b/tests/test_base_prices.py @@ -630,22 +630,22 @@ def prices_us_lon_hk( @pytest.fixture def session_length_xnys() -> abc.Iterator[pd.Timedelta]: - yield pd.Timedelta(6.5, "H") + yield pd.Timedelta(6.5, "h") @pytest.fixture def session_length_xhkg() -> abc.Iterator[pd.Timedelta]: - yield pd.Timedelta(6.5, "H") + yield pd.Timedelta(6.5, "h") @pytest.fixture def session_length_xlon() -> abc.Iterator[pd.Timedelta]: - yield pd.Timedelta(8.5, "H") + yield pd.Timedelta(8.5, "h") @pytest.fixture def session_length_bvmf() -> abc.Iterator[pd.Timedelta]: - yield pd.Timedelta(8, "H") + yield pd.Timedelta(8, "h") @pytest.fixture @@ -1418,7 +1418,7 @@ def test__get_bi_table_intraday_interval_bi(self, prices_us, stricts, priorities table_H1, bi = f() assert bi is prices.bis.H1 assert_interval(table_H1, prices.bis.H1) - assert_bounds(table_H1, (start, end_session_open + pd.Timedelta(1, "H"))) + assert_bounds(table_H1, (start, end_session_open + pd.Timedelta(1, "h"))) def test__get_bi_table_intraday_interval_non_bi( self, prices_us, stricts, priorities, one_min @@ -1554,7 +1554,7 @@ def test__get_table_intraday_interval_T4(self, prices_us, one_min): assert_most_common_interval(table_T4_T1, ds_interval) assert table_T4_T1.pt.last_ts == end assert table_T4_T1.pt.first_ts in pd.date_range( - start=start, periods=4, freq="T" + start=start, periods=4, freq="min" ) # verify prices unavailable if period extends beyond limit of availability @@ -1582,7 +1582,7 @@ def test__get_table_intraday_interval_T4(self, prices_us, one_min): table = f() assert_most_common_interval(table, ds_interval) assert table.pt.last_ts == end - one_min - assert table.pt.first_ts in pd.date_range(start=start, periods=4, freq="T") + assert table.pt.first_ts in pd.date_range(start=start, periods=4, freq="min") def test__get_table_intraday_interval_H2(self, prices_us): """Test `_get_table_intraday` for H2 ds_interval. @@ -1613,7 +1613,7 @@ def test__get_table_intraday_interval_H2(self, prices_us): ) table = f() assert_bounds(table, (start, end_close)) - assert table.index[-1].length == pd.Timedelta(30, "T") + assert table.index[-1].length == pd.Timedelta(30, "min") assert_most_common_interval(table, ds_interval) # verify when openend is MAINTAIN @@ -1621,7 +1621,7 @@ def test__get_table_intraday_interval_H2(self, prices_us): prices, pp, ds_interval, openend=OpenEnd.MAINTAIN ) delta = 30 if ds_interval is prices.bis.H1 else 90 - end_maintain = end_close + pd.Timedelta(delta, "T") + end_maintain = end_close + pd.Timedelta(delta, "min") table = f() assert_bounds(table, (start, end_maintain)) assert_interval(table, ds_interval) @@ -1639,7 +1639,7 @@ def test__get_table_intraday_interval_H1(self, prices_lon_us): interval = prices.bis.T5 range_start, _ = th.get_sessions_range_for_bi(prices, interval) _, range_end = th.get_sessions_range_for_bi(prices, prices.bis.T1) - length = pd.Timedelta(13, "H") + length = pd.Timedelta(13, "h") start, end = th.get_conforming_cc_sessions( prices.cc, length, range_start, range_end, 2 ) @@ -1668,7 +1668,7 @@ def test__get_table_intraday_interval_H1(self, prices_lon_us): # before close as nyse continues to trade after the close, hence to maintain # interval end on the last full interval prior to the close. Same effect for # H1 and H2. - end_maintain = end_close - pd.Timedelta(30, "T") + end_maintain = end_close - pd.Timedelta(30, "min") assert_bounds(table, (start_open, end_maintain)) assert_interval(table, ds_interval) @@ -1678,7 +1678,7 @@ def test__get_table_intraday_interval_H1(self, prices_lon_us): ) table = prices._get_table_intraday() assert_bounds(table, (start_open, end_close)) - assert table.index[-1].length == pd.Timedelta(30, "T") + assert table.index[-1].length == pd.Timedelta(30, "min") assert_most_common_interval(table, ds_interval) # Verify for xnys lead @@ -1705,7 +1705,7 @@ def test__get_table_intraday_interval_H1(self, prices_lon_us): # 30/90 minutes although nothing trades after the close, hence maintains the # interval by extending the right of the last indice to beyond the close. delta = 30 if ds_interval is prices.bis.H1 else 90 - end_maintain = end_close + pd.Timedelta(delta, "T") + end_maintain = end_close + pd.Timedelta(delta, "min") assert_bounds(table, (start_open, end_maintain)) assert_interval(table, ds_interval) @@ -1715,7 +1715,7 @@ def test__get_table_intraday_interval_H1(self, prices_lon_us): ) table = prices._get_table_intraday() assert_bounds(table, (start_open, end_close)) - assert table.index[-1].length == pd.Timedelta(30, "T") + assert table.index[-1].length == pd.Timedelta(30, "min") assert_most_common_interval(table, ds_interval) def assertions_downsample_bi_table( @@ -2224,7 +2224,7 @@ def test__get_table_composite_intraday( prices, prices.bis.T1, calendars, session_length, 2 ) end_session_open = prices.cc.session_open(end_session) - end = end_session_open + pd.Timedelta(7, "T") + end = end_session_open + pd.Timedelta(7, "min") _, start_session = get_conforming_sessions( prices, prices.bis.T5, calendars, session_length, 2 ) @@ -2239,9 +2239,9 @@ def test__get_table_composite_intraday( assert table.pt.last_ts == end # Test edge case 1. - limit_T1_mock = end_session_open - pd.Timedelta(1, "H") + limit_T1_mock = end_session_open - pd.Timedelta(1, "h") prices = get_prices_limit_mock(prices, prices.bis.T1, limit_T1_mock) - end = end_session_open + pd.Timedelta(3, "T") + end = end_session_open + pd.Timedelta(3, "min") pp = get_pp(start=start_session, end=end) prices = set_get_prices_params(prices, pp, ds_interval=None, lead_symbol=lead) table_edgecase1 = prices._get_table_composite() @@ -2250,9 +2250,9 @@ def test__get_table_composite_intraday( assert_frame_equal(table_edgecase1[:-3], table[:-7]) # Test edge case 2. - limit_T1_mock = end_session_open + pd.Timedelta(6, "T") + limit_T1_mock = end_session_open + pd.Timedelta(6, "min") prices = get_prices_limit_mock(prices, prices.bis.T1, limit_T1_mock) - end = end_session_open + pd.Timedelta(9, "T") + end = end_session_open + pd.Timedelta(9, "min") pp = get_pp(start=start_session, end=end) prices = set_get_prices_params(prices, pp, ds_interval=None, lead_symbol=lead) table_edgecase2 = prices._get_table_composite() @@ -2268,9 +2268,9 @@ def test__get_table_composite_intraday( # Verify raises error under edge case 2 when 'next table' has same interval # as table1. - limit_T1_mock = end_session_open + pd.Timedelta(20, "T") # unable to serve + limit_T1_mock = end_session_open + pd.Timedelta(20, "min") # unable to serve # T2 unable to serve from start of day - limit_T2_mock = end_session_open + pd.Timedelta(6, "T") + limit_T2_mock = end_session_open + pd.Timedelta(6, "min") limits = prices.BASE_LIMITS.copy() limits[prices.bis.T1] = limit_T1_mock limits[prices.bis.T2] = limit_T2_mock @@ -2282,7 +2282,7 @@ class PricesMock(PricesBaseTst): prices = PricesMock(symbols, prices._prices_tables, prices.lead_symbol_default) - end = end_session_open + pd.Timedelta(8, "T") + end = end_session_open + pd.Timedelta(8, "min") pp = get_pp(start=start_session, end=end) prices = set_get_prices_params(prices, pp, ds_interval=None, lead_symbol=lead) @@ -2305,7 +2305,7 @@ def test__get_table_composite_daily_intraday( # set up as: # end avaialble from T2 data and can be reflected accurately by T2 data. # start available only for daily data. - length = pd.Timedelta(13, "H") + length = pd.Timedelta(13, "h") _start_session, end_session = get_sessions_daterange_for_bi( prices, prices.bis.T2, length_end_session=length ) @@ -2317,7 +2317,7 @@ def test__get_table_composite_daily_intraday( raise ValueError(f"Unable to get a 'T2' session of length {length}.") end_session_open = prices.cc.session_open(end_session) - end = end_session_open + pd.Timedelta(6, "T") + end = end_session_open + pd.Timedelta(6, "min") start_H1, _ = get_sessions_daterange_for_bi(prices, prices.bis.H1) calendar = prices.calendars[lead] @@ -2355,7 +2355,7 @@ def test__get_table_composite_daily_intraday( # Verify returns daily/intraday composite table under intraday/daily edge case # set up so that T2 availability starts between session open and period end. - limit_T2_mock = end_session_open + pd.Timedelta(1, "T") + limit_T2_mock = end_session_open + pd.Timedelta(1, "min") prices = get_prices_limit_mock(prices, prices.bis.T2, limit_T2_mock) pp = get_pp(start=start_session, end=end) prices = set_get_prices_params(prices, pp, ds_interval=None, lead_symbol=lead) @@ -2386,7 +2386,7 @@ def test__get_table_composite_error(self, prices_us_lon, lead): calendar = prices.calendars[lead] end_session = calendar.session_offset(start_H1, -50) end_session_open = prices.cc.session_open(end_session) - end = end_session_open + pd.Timedelta(1, "H") + end = end_session_open + pd.Timedelta(1, "h") start_session = calendar.session_offset(end_session, -20) pp = get_pp(start=start_session, end=end) @@ -2426,7 +2426,7 @@ def test_gpp(self, prices_us_lon): assert not prices.has_data # verify options default values - prices.get("5T", minutes=30) + prices.get("5min", minutes=30) assert prices.has_data assert isinstance(prices.gpp, m.PricesBase.GetPricesParams) assert prices.gpp.anchor is Anchor.OPEN @@ -2440,7 +2440,7 @@ def test_gpp(self, prices_us_lon): lead = prices.lead_symbol_default strict = True prices.get( - "10T", + "10min", minutes=30, anchor="open", openend="maintain", @@ -2459,7 +2459,7 @@ def test_gpp(self, prices_us_lon): lead = get_symbols_for_calendar(prices, "XLON") strict = False prices.get( - "3T", + "3min", minutes=30, anchor="workback", openend="shorten", @@ -2511,7 +2511,7 @@ def test_params_errors(self, prices_us, one_min, session_length_xnys): " received 'wrkback'." ) with pytest.raises(valimp.InputsError, match=msg): - prices.get("30T", anchor="wrkback") + prices.get("30min", anchor="wrkback") # verify period parameters being verified by `verify_period_parameters` msg = "If pass start and end then cannot pass a duration component." @@ -2573,13 +2573,13 @@ def test_intervals_inferred(self, prices_us): # Verify return at intraday intervals. # verify end as time. Given end T5 is highest intraday interval that can fulfil. - end = cal.session_open(rng_end) + pd.Timedelta(5, "T") + end = cal.session_open(rng_end) + pd.Timedelta(5, "min") df = prices.get(start=rng_start, end=end) assertions_intraday_common(df, prices, prices.bis.T5) assert_bounds(df, (rng_start_open, end)) # verify start as time. - start = cal.session_open(rng_start) + pd.Timedelta(5, "T") + start = cal.session_open(rng_start) + pd.Timedelta(5, "min") df = prices.get(start=start, end=rng_end) assertions_intraday_common(df, prices, prices.bis.H1) assert df.pt.first_ts == (rng_start_open + prices.bis.H1) @@ -2593,14 +2593,14 @@ def test_intervals_inferred(self, prices_us): # verify minutes df = prices.get(start=rng_start, minutes=4) assertions_intraday_common(df, prices, prices.bis.T2) - assert_bounds(df, (rng_start_open, rng_start_open + pd.Timedelta(4, "T"))) + assert_bounds(df, (rng_start_open, rng_start_open + pd.Timedelta(4, "min"))) df = prices.get(minutes=4) assert df.pt.interval in (prices.bis.T1, prices.bis.T2) # verify hours df = prices.get(start=rng_start, hours=4) assertions_intraday_common(df, prices, prices.bis.H1) - assert_bounds(df, (rng_start_open, rng_start_open + pd.Timedelta(4, "H"))) + assert_bounds(df, (rng_start_open, rng_start_open + pd.Timedelta(4, "h"))) df = prices.get(start=rng_start, hours=50) assert df.pt.interval in prices.bis_intraday @@ -2671,9 +2671,9 @@ def test_interval_invalid(self, prices_us, session_length_xnys, one_min): f = prices.get # Verify raises PricesUnavailableIntervalDurationError - f("2H", hours=2, anchor="workback") + f("2h", hours=2, anchor="workback") with pytest.raises(errors.PricesUnavailableIntervalDurationError): - f("2H", hours=1, minutes=59) + f("2h", hours=1, minutes=59) # Verify raises PricesUnvailableDurationConflict (raised directly by `get``) match = ( @@ -2712,15 +2712,15 @@ def test_interval_invalid(self, prices_us, session_length_xnys, one_min): f(session_length_xnys + one_min, **kwargs) # Verify raises PricesUnavailableIntervalPeriodError - start = cal.session_close(session) - pd.Timedelta(2, "T") - end = cal.session_open(cal.next_session(session)) + pd.Timedelta(2, "T") + start = cal.session_close(session) - pd.Timedelta(2, "min") + end = cal.session_open(cal.next_session(session)) + pd.Timedelta(2, "min") with pytest.raises(errors.PricesUnavailableIntervalPeriodError): - f("5T", start=start, end=end) + f("5min", start=start, end=end) start = cal.session_open(session) + prices.bis.T5 - end = start + pd.Timedelta(4, "T") + end = start + pd.Timedelta(4, "min") with pytest.raises(errors.PricesUnavailableIntervalPeriodError): - f("5T", start=start, end=end) + f("5min", start=start, end=end) def test_interval_only_param(self, prices_us, one_day, one_min): """Test passing interval as only parameter. @@ -2738,7 +2738,7 @@ def test_interval_only_param(self, prices_us, one_day, one_min): last_to = cal.minute_to_trading_minute(limit_right, "previous") last_from = cal.minute_offset_by_sessions(last_to, -1) if bi is prices.bis.H1: - last_to += pd.Timedelta(30, "T") # provide for possibly unaligned end + last_to += pd.Timedelta(30, "min") # provide for possibly unaligned end df = f(bi) assert first_from <= df.pt.first_ts <= first_to # + one_min to cover processing between evaluating last_to and evaluating df @@ -2786,7 +2786,7 @@ def test_intervals_overlapping_247(self, prices_247): """ prices = prices_247 with pytest.warns(errors.IntervalIrregularWarning): - df = prices.get("7T", days=2) + df = prices.get("7min", days=2) assert_most_common_interval(df, intervals.TDInterval.T7) def test_intervals_overlapping_with_break(self, prices_with_break, one_min): @@ -2833,7 +2833,7 @@ def test_start_end_inputs(self, prices_us_lon): start_dt = datetime.datetime(sl.year, sl.month, sl.day, sl.hour, sl.minute) end = cal.session_close(session) - end -= pd.Timedelta(30, "T") + end -= pd.Timedelta(30, "min") end_utc = end end_local = el = end.astimezone(prices.tz_default) end_str = el.strftime("%Y-%m-%d %H:%M") @@ -2844,15 +2844,15 @@ def test_start_end_inputs(self, prices_us_lon): starts = (start_utc, start_local, start_str, start_str2, start_int, start_dt) ends = (end_utc, end_local, end_str, end_str2, end_int, end_dt) - df_base = prices.get("2H", starts[0], ends[0]) + df_base = prices.get("2h", starts[0], ends[0]) for start, end in zip(starts[1:], ends[1:]): - df = prices.get("2H", start, end) + df = prices.get("2h", start, end) assert_frame_equal(df, df_base) # Verify `tzin` symb_xnys = get_symbols_for_calendar(prices, "XNYS") for tzin in ("America/New_York", ZoneInfo("America/New_York"), symb_xnys): - df = prices.get("2H", start_utc, end_str, tzin=tzin) + df = prices.get("2h", start_utc, end_str, tzin=tzin) assert_frame_equal(df, df_base) # verify can pass as non-default symbol @@ -2862,7 +2862,7 @@ def test_start_end_inputs(self, prices_us_lon): end_lon_tz = end_utc.astimezone(prices.timezones[symb_xlon]) end_lon_str = end_lon_tz.strftime("%Y-%m-%d %H:%M") df = prices.get( - "2H", start_lon_str, end_lon_str, tzin=symb_xlon, tzout=symb_xnys + "2h", start_lon_str, end_lon_str, tzin=symb_xlon, tzout=symb_xnys ) assert_frame_equal(df, df_base) @@ -2896,7 +2896,7 @@ def test_start_end_parsing(self, prices_us, session_length_xnys, one_min, one_se # verify returning intaday data, also verifies can pass `start` and `end` # as positional arguments - df = prices.get("5T", start_session, end_session) + df = prices.get("5min", start_session, end_session) start = cal.session_open(start_session) end = cal.session_close(end_session) num_rows = int((session_length_xnys / prices.bis.T5)) * num_sessions @@ -2922,33 +2922,33 @@ def test_start_end_parsing(self, prices_us, session_length_xnys, one_min, one_se ) # verify return of intraday data. - df = prices.get("10T", start, end) + df = prices.get("10min", start, end) assertions_intraday(df, TDInterval.T10, prices, start, end, num_rows // 2) - df = prices.get("5T", start, end) + df = prices.get("5min", start, end) assertions_intraday(df, TDInterval.T5, prices, start, end, num_rows) # verify passing `start` and `end` as non-trading times - assert_frame_equal(df, prices.get("5T", start - one_min, end + one_min)) - delta = pd.Timedelta(45, "T") - assert_frame_equal(df, prices.get("5T", start - delta, end + delta)) + assert_frame_equal(df, prices.get("5min", start - one_min, end + one_min)) + delta = pd.Timedelta(45, "min") + assert_frame_equal(df, prices.get("5min", start - delta, end + delta)) # verify passing `start` and `end` 6 min inside session bounds knocks 2 indices # off each end - delta = pd.Timedelta(6, "T") - assert_frame_equal(df[2:-2], prices.get("5T", start + delta, end - delta)) + delta = pd.Timedelta(6, "min") + assert_frame_equal(df[2:-2], prices.get("5min", start + delta, end - delta)) # verify just one second inside the session bounds will knock off the # first/last indices - assert_frame_equal(df[1:-1], prices.get("5T", start + one_sec, end - one_sec)) + assert_frame_equal(df[1:-1], prices.get("5min", start + one_sec, end - one_sec)) # Verify passing `start` and `end` as mix of data and time assert_frame_equal(df_daily, prices.get("1D", start_session, end)) assert_frame_equal(df_daily, prices.get("1D", start, end_session)) assert_frame_equal(df_daily[1:], prices.get("1D", start + one_sec, end_session)) - assert_frame_equal(df, prices.get("5T", start_session, end)) - assert_frame_equal(df[:-1], prices.get("5T", start_session, end - one_sec)) - assert_frame_equal(df, prices.get("5T", start, end_session)) + assert_frame_equal(df, prices.get("5min", start_session, end)) + assert_frame_equal(df[:-1], prices.get("5min", start_session, end - one_sec)) + assert_frame_equal(df, prices.get("5min", start, end_session)) def test_start_end_none_bi(self, prices_us): """Test `start` and `end` as None and intervals as base intervals.""" @@ -3002,31 +3002,33 @@ def test_trading_sessions_duration( # getting intraday data open_ = cal.session_open(start_session) close = cal.session_close(end_session) - num_rows = int((session_length_xnys * num_sessions) / pd.Timedelta(30, "T")) - df = prices.get("30T", start=start_session, days=num_sessions) + num_rows = int((session_length_xnys * num_sessions) / pd.Timedelta(30, "min")) + df = prices.get("30min", start=start_session, days=num_sessions) assertions_intraday(df, TDInterval.T30, prices, open_, close, num_rows) - assert_frame_equal(df, prices.get("30T", end=end_session, days=num_sessions)) + assert_frame_equal(df, prices.get("30min", end=end_session, days=num_sessions)) # verify to bound as time # getting intraday data - start = open_ + pd.Timedelta(88, "T") - df_intra = prices.get("30T", start, days=num_sessions - 1) - exp_start = open_ + pd.Timedelta(90, "T") - exp_end = cal.session_open(end_session) + pd.Timedelta(90, "T") + start = open_ + pd.Timedelta(88, "min") + df_intra = prices.get("30min", start, days=num_sessions - 1) + exp_start = open_ + pd.Timedelta(90, "min") + exp_end = cal.session_open(end_session) + pd.Timedelta(90, "min") num_rows -= 13 if exp_start.time() != exp_end.time(): # adjust for different DST observance if exp_end.time() > exp_start.time(): - exp_end -= pd.Timedelta(1, "H") + exp_end -= pd.Timedelta(1, "h") num_rows -= 2 else: - exp_end += pd.Timedelta(1, "H") + exp_end += pd.Timedelta(1, "h") num_rows += 2 assertions_intraday( df_intra, TDInterval.T30, prices, exp_start, exp_end, num_rows ) end = exp_end + one_min # verify aligning as expected - assert_frame_equal(df_intra, prices.get("30T", end=end, days=num_sessions - 1)) + assert_frame_equal( + df_intra, prices.get("30min", end=end, days=num_sessions - 1) + ) # getting daily data df = prices.get("1D", start, days=num_sessions - 1) assertions_daily(df, prices, sessions[1], end_session) @@ -3036,11 +3038,11 @@ def test_trading_sessions_duration( # verify to now as trading time # one sec short of 30 min post last session open mock_now(monkeypatch, exp_end - one_sec) - df = prices.get("30T", days=num_sessions - 1) + df = prices.get("30min", days=num_sessions - 1) assert_frame_equal(df_intra, df) # verify to now as non-trading time - mock_now(monkeypatch, close + pd.Timedelta(2, "H")) + mock_now(monkeypatch, close + pd.Timedelta(2, "h")) assert_frame_equal( df_daily, prices.get("D", end=end_session, days=num_sessions) ) @@ -3071,26 +3073,26 @@ def test_calendar_time_duration( # verify getting intraday data with bound as date end_session = cal.session_offset(start_session, num_sessions_in_week - 1) - df = prices.get("30T", start_session, weeks=1) + df = prices.get("30min", start_session, weeks=1) # Verifications piggy backs on separate testing of durations in terms of # trading sessions - expected = prices.get("30T", start_session, days=num_sessions_in_week) + expected = prices.get("30min", start_session, days=num_sessions_in_week) assert_frame_equal(df, expected) - expected = prices.get("30T", end=end_session, days=num_sessions_in_week) + expected = prices.get("30min", end=end_session, days=num_sessions_in_week) assert_frame_equal(df, expected) # verify getting intraday data with bound as time # end_session will now be one session later end_session2 = cal.session_offset(start_session, num_sessions_in_week) open_ = cal.session_open(start_session) - start = open_ + pd.Timedelta(28, "T") - df = prices.get("30T", start, weeks=1) + start = open_ + pd.Timedelta(28, "min") + df = prices.get("30min", start, weeks=1) # Verification piggy backs on separate testing of durations in terms of # trading sessions - expected = prices.get("30T", start, days=num_sessions_in_week) + expected = prices.get("30min", start, days=num_sessions_in_week) assert_frame_equal(df, expected) - end = cal.session_open(end_session2) + pd.Timedelta(32, "T") - df_intra = prices.get("30T", end=end, weeks=1) + end = cal.session_open(end_session2) + pd.Timedelta(32, "min") + df_intra = prices.get("30min", end=end, weeks=1) assert_frame_equal(df_intra, expected) # verify getting daily data @@ -3113,14 +3115,14 @@ def test_calendar_time_duration( assertions_monthly(df, prices, None, first_exp, last_exp) # verify to now as trading time - now = cal.session_open(end_session2) + pd.Timedelta(30, "T") - one_sec + now = cal.session_open(end_session2) + pd.Timedelta(30, "min") - one_sec # one sec short of 30 min post last session open mock_now(monkeypatch, now - one_sec) - df = prices.get("30T", weeks=1) + df = prices.get("30min", weeks=1) assert_frame_equal(df_intra, df) # verify to now as non-trading time - mock_now(monkeypatch, cal.session_open(end_session) + pd.Timedelta(2, "H")) + mock_now(monkeypatch, cal.session_open(end_session) + pd.Timedelta(2, "h")) assert_frame_equal(df_daily, prices.get("D", weeks=1), check_freq=False) def test_trading_time_duration(self, prices_us, monkeypatch): @@ -3132,55 +3134,55 @@ def test_trading_time_duration(self, prices_us, monkeypatch): prev_session, session = get_consecutive_sessions(prices, prices.bis.T1, cal) # verify bounds with a session - df = prices.get("5T", session, minutes=20) + df = prices.get("5min", session, minutes=20) open_, close = cal.session_open_close(session) assertions_intraday( - df, TDInterval.T5, prices, open_, open_ + pd.Timedelta(20, "T"), 4 + df, TDInterval.T5, prices, open_, open_ + pd.Timedelta(20, "min"), 4 ) - df = prices.get("15T", end=session, hours=1) + df = prices.get("15min", end=session, hours=1) assertions_intraday( - df, TDInterval.T15, prices, close - pd.Timedelta(1, "H"), close, 4 + df, TDInterval.T15, prices, close - pd.Timedelta(1, "h"), close, 4 ) # verify bounds with a time - bound = open_ + pd.Timedelta(30, "T") - df = prices.get("15T", bound, hours=1, minutes=15) + bound = open_ + pd.Timedelta(30, "min") + df = prices.get("15min", bound, hours=1, minutes=15) delta = pd.Timedelta(hours=1, minutes=15) assertions_intraday(df, TDInterval.T15, prices, bound, bound + delta, 5) # verify crossing sessions - df = prices.get("15T", end=bound, hours=1, minutes=15) + df = prices.get("15min", end=bound, hours=1, minutes=15) prev_close = cal.session_close(prev_session) - exp_start = prev_close - pd.Timedelta(45, "T") + exp_start = prev_close - pd.Timedelta(45, "min") assertions_intraday(df, TDInterval.T15, prices, exp_start, bound, 5) # verify Silver Rule (if bound unaligned then start from next aligned indice) - df = prices.get("25T", start=bound, hours=1, minutes=40) - exp_start = bound + pd.Timedelta(20, "T") + df = prices.get("25min", start=bound, hours=1, minutes=40) + exp_start = bound + pd.Timedelta(20, "min") exp_end = exp_start + pd.Timedelta(hours=1, minutes=40) assertions_intraday(df, TDInterval.T25, prices, exp_start, exp_end, 4) # verify limit before next indice would be included - assert_frame_equal(df, prices.get("25T", start=bound, hours=2, minutes=4)) - df = prices.get("25T", start=bound, hours=2, minutes=5) - exp_end += pd.Timedelta(25, "T") + assert_frame_equal(df, prices.get("25min", start=bound, hours=2, minutes=4)) + df = prices.get("25min", start=bound, hours=2, minutes=5) + exp_end += pd.Timedelta(25, "min") assertions_intraday(df, TDInterval.T25, prices, exp_start, exp_end, 5) # verify default end with now as trading time - now = open_ + pd.Timedelta(32, "T") + now = open_ + pd.Timedelta(32, "min") mock_now(monkeypatch, now) - df = prices.get("5T", minutes=20) - exp_end = open_ + pd.Timedelta(35, "T") - exp_start = exp_end - pd.Timedelta(20, "T") + df = prices.get("5min", minutes=20) + exp_end = open_ + pd.Timedelta(35, "min") + exp_start = exp_end - pd.Timedelta(20, "min") assertions_intraday(df, TDInterval.T5, prices, exp_start, exp_end, 4) # verify default end with now as non-trading time - now = close + pd.Timedelta(2, "H") + now = close + pd.Timedelta(2, "h") mock_now(monkeypatch, now) - df = prices.get("2T", minutes=41) + df = prices.get("2min", minutes=41) assertions_intraday( - df, TDInterval.T2, prices, close - pd.Timedelta(40, "T"), close, 20 + df, TDInterval.T2, prices, close - pd.Timedelta(40, "min"), close, 20 ) def test_lead_symbol(self, prices_us_lon, session_length_xnys, session_length_xlon): @@ -3210,11 +3212,11 @@ def test_lead_symbol(self, prices_us_lon, session_length_xnys, session_length_xl # start as one hour prior to XNYS open xnys_open = xnys.session_open(session) - start = xnys_open - pd.Timedelta(1, "H") - args, kwargs = ("6T", start), {"minutes": 30} + start = xnys_open - pd.Timedelta(1, "h") + args, kwargs = ("6min", start), {"minutes": 30} # verify start rolls forward to XNYS open df = prices.get(*args, **kwargs, lead_symbol=symb_xnys) - half_hour = pd.Timedelta(30, "T") + half_hour = pd.Timedelta(30, "min") assertions_intraday( df, TDInterval.T6, prices, xnys_open, xnys_open + half_hour, 5 ) @@ -3241,15 +3243,15 @@ def test_add_a_row(self, prices_us): # verify for intraday interval, with add_a_row causing cross in sessions _, session = get_consecutive_sessions(prices, prices.bis.T1, cal) start = cal.session_open(session) - args = ("10T", start) + args = ("10min", start) kwargs = {"minutes": 30} base_df = prices.get(*args, **kwargs) - exp_end = start + pd.Timedelta(30, "T") + exp_end = start + pd.Timedelta(30, "min") assertions_intraday(base_df, TDInterval.T10, prices, start, exp_end, 3) df = prices.get(*args, **kwargs, add_a_row=True) assert_frame_equal(df[1:], base_df, check_freq=False) - exp_start = cal.previous_close(start) - pd.Timedelta(10, "T") + exp_start = cal.previous_close(start) - pd.Timedelta(10, "min") assertions_intraday(df, TDInterval.T10, prices, exp_start, exp_end, 4) # ---------------------- Tests related to anchor ---------------------- @@ -3293,7 +3295,7 @@ def test_open_indices_us(self, prices_us, session_length_xnys): start_session, end_session = get_conforming_sessions( prices, prices.bis.T1, [xnys], [session_length_xnys], 2 ) - df = prices.get("30T", start_session, end_session, anchor="open", tzout=UTC) + df = prices.get("30min", start_session, end_session, anchor="open", tzout=UTC) assert df.pt.has_regular_interval assert df.pt.indices_have_regular_trading_minutes(xnys) @@ -3308,11 +3310,11 @@ def test_open_indices_us(self, prices_us, session_length_xnys): assert_index_equal(df.index, exp_index) # verify when unaligned with session close - df = prices.get("90T", start_session, end_session, anchor="open", tzout=UTC) + df = prices.get("90min", start_session, end_session, anchor="open", tzout=UTC) assert df.pt.has_regular_interval assert not df.pt.indices_have_regular_trading_minutes(xnys) - misalignment = pd.Timedelta(1, "H") + misalignment = pd.Timedelta(1, "h") start = xnys.session_open(start_session) end_start_session = xnys.session_close(start_session) + misalignment start_end_session = xnys.session_open(end_session) @@ -3340,7 +3342,7 @@ def test_open_indices_with_break( prices, prices.bis.T1, [xhkg], [session_length_xhkg], 2 ) - df = prices.get("30T", start_session, end_session, anchor="open", tzout=UTC) + df = prices.get("30min", start_session, end_session, anchor="open", tzout=UTC) assert df.pt.has_regular_interval assert df.pt.indices_have_regular_trading_minutes(xhkg) @@ -3355,25 +3357,25 @@ def test_open_indices_with_break( assert_index_equal(df.index, exp_index) # verify when unaligned with both am and pm subsession closes - df = prices.get("40T", start_session, end_session, anchor="open", tzout=UTC) + df = prices.get("40min", start_session, end_session, anchor="open", tzout=UTC) assert df.pt.has_regular_interval assert not df.pt.indices_have_regular_trading_minutes(xhkg) starts, ends = [], [] for session in (start_session, end_session): starts.append(xhkg.session_open(session)) - ends.append(xhkg.session_break_start(session) + pd.Timedelta(10, "T")) + ends.append(xhkg.session_break_start(session) + pd.Timedelta(10, "min")) starts.append(xhkg.session_break_end(session)) - ends.append(xhkg.session_close(session) + pd.Timedelta(20, "T")) + ends.append(xhkg.session_close(session) + pd.Timedelta(20, "min")) interval = TDInterval.T40 exp_index = self.create_index(starts, ends, interval) assert_index_equal(df.index, exp_index) # # verify to now includes live indice and nothing beyond - now = ends[-1] - pd.Timedelta(50, "T") + now = ends[-1] - pd.Timedelta(50, "min") mock_now(monkeypatch, now) # should lose last indice - df_ = prices.get("40T", start_session, end_session, anchor="open", tzout=UTC) + df_ = prices.get("40min", start_session, end_session, anchor="open", tzout=UTC) # last indice be the same although not values as now is 10 minutes short # of the full indice assert_frame_equal(df_[:-1], df[:-2]) @@ -3392,7 +3394,9 @@ def test_workback_indices_us( prices, prices.bis.T1, [xnys], [session_length_xnys], 2 ) - df = prices.get("90T", start_session, end_session, anchor="workback", tzout=UTC) + df = prices.get( + "90min", start_session, end_session, anchor="workback", tzout=UTC + ) assert len(df.pt.indices_length) == 2 assert len(df.pt.indices_partial_trading(xnys)) == 1 assert df.pt.indices_have_regular_trading_minutes(xnys) @@ -3402,7 +3406,7 @@ def test_workback_indices_us( start = end - (interval * 4) index_end = self.create_single_index(start, end, interval) - end = xnys.session_close(start_session) - pd.Timedelta(1, "H") + end = xnys.session_close(start_session) - pd.Timedelta(1, "h") start = end - (interval * 3) index_start = self.create_single_index(start, end, interval) @@ -3415,8 +3419,8 @@ def test_workback_indices_us( assert_index_equal(df.index, index) # Verify to specific minute - end = xnys.session_close(start_session) - pd.Timedelta(43, "T") - df = prices.get("30T", end=end, hours=4, anchor="workback", tzout=UTC) + end = xnys.session_close(start_session) - pd.Timedelta(43, "min") + df = prices.get("30min", end=end, hours=4, anchor="workback", tzout=UTC) interval = TDInterval.T30 start = end - (8 * interval) index = self.create_single_index(start, end, interval) @@ -3425,7 +3429,7 @@ def test_workback_indices_us( # Verify to now mock_now(monkeypatch, end - one_min) prices = reset_prices(prices) - df_ = prices.get("30T", hours=4, anchor="workback", tzout=UTC) + df_ = prices.get("30min", hours=4, anchor="workback", tzout=UTC) assert_frame_equal(df_, df) def test_workback_indices_with_break(self, prices_with_break, session_length_xhkg): @@ -3440,7 +3444,7 @@ def test_workback_indices_with_break(self, prices_with_break, session_length_xhk prices, prices.bis.T1, [xhkg], [session_length_xhkg], 1 )[0] - df = prices.get("40T", session, session, anchor="workback", tzout=UTC) + df = prices.get("40min", session, session, anchor="workback", tzout=UTC) assert len(df.pt.indices_length) == 2 assert len(df.pt.indices_partial_trading(xhkg)) == 1 assert df.pt.indices_have_regular_trading_minutes(xhkg) @@ -3450,7 +3454,7 @@ def test_workback_indices_with_break(self, prices_with_break, session_length_xhk start = end - (interval * 4) index_end = self.create_single_index(start, end, interval) - end = xhkg.session_break_start(session) - pd.Timedelta(20, "T") + end = xhkg.session_break_start(session) - pd.Timedelta(20, "min") start = end - (interval * 3) index_start = self.create_single_index(start, end, interval) @@ -3477,13 +3481,13 @@ def test_mult_cal_indices(self, prices_us_lon): start_session, end_session = get_sessions_xnys_xhkg_xlon(prices.bis.T1, 2) kwargs = { - "interval": "1H", + "interval": "1h", "start": start_session, "end": end_session, "tzout": UTC, } interval = TDInterval.H1 - half_hour = pd.Timedelta(30, "T") + half_hour = pd.Timedelta(30, "min") # Verify for indices anchored "open" with xlon as lead cal df = prices.get(**kwargs, anchor="open", lead_symbol=xlon_symb) @@ -3568,7 +3572,7 @@ def test_force(self, prices_with_break, session_length_xhkg): )[0] # verify not forced - df = prices.get("40T", session, session, anchor="open", force=False) + df = prices.get("40min", session, session, anchor="open", force=False) assert df.pt.has_regular_interval assert xhkg.session_break_start(session) not in df.index.right assert df.pt.last_ts != xhkg.session_close(session) @@ -3576,11 +3580,11 @@ def test_force(self, prices_with_break, session_length_xhkg): assert len(df.pt.indices_partial_trading(xhkg)) == 2 # verify not forced by default - df_ = prices.get("40T", session, session, anchor="open") + df_ = prices.get("40min", session, session, anchor="open") assert_frame_equal(df_, df) # verify forced - df_f = prices.get("40T", session, session, anchor="open", force=True) + df_f = prices.get("40min", session, session, anchor="open", force=True) assert not df_f.pt.has_regular_interval assert xhkg.session_break_start(session) in df_f.index.right assert df_f.pt.last_ts == xhkg.session_close(session) @@ -3603,7 +3607,7 @@ def test_overlapping_sessions(self, prices_247): start_session_close = x247.session_close(start_session) end_session_open = x247.session_open(end_session) assert start_session_close == end_session_open - df = prices.get("8H", start_session, end_session, anchor="open") + df = prices.get("8h", start_session, end_session, anchor="open") assert df.pt.has_regular_interval assert len(df.pt.indices_length) == 1 assert start_session_close in df.index.left @@ -3611,7 +3615,7 @@ def test_overlapping_sessions(self, prices_247): # verify warns with pytest.warns(errors.IntervalIrregularWarning): - df = prices.get("7H", start_session, end_session, anchor="open") + df = prices.get("7h", start_session, end_session, anchor="open") assert not df.pt.has_regular_interval assert len(df.pt.indices_length) == 2 assert start_session_close in df.index.left @@ -3630,7 +3634,7 @@ def test_overlapping_subsessions(self, prices_with_break, session_length_xhkg): )[0] # verify am/pm indices do not overlap on limit - df = prices.get("105T", session, session, anchor="open") + df = prices.get("105min", session, session, anchor="open") assert df.pt.has_regular_interval assert len(df.pt.indices_length) == 1 assert xhkg.session_break_end(session) in df.index.left @@ -3638,7 +3642,7 @@ def test_overlapping_subsessions(self, prices_with_break, session_length_xhkg): # verify warns with pytest.warns(errors.IntervalIrregularWarning): - df = prices.get("106T", session, session, anchor="open") + df = prices.get("106min", session, session, anchor="open") assert not df.pt.has_regular_interval assert len(df.pt.indices_length) == 2 assert xhkg.session_break_end(session) in df.index.left @@ -3661,12 +3665,12 @@ def test_cal_break_ignored_with_origin_open( prices, interval, [xhkg], [session_length_xhkg], 1 )[0] - df = prices.get("1H", session, session, anchor="open", tzout=UTC) + df = prices.get("1h", session, session, anchor="open", tzout=UTC) assert df.pt.has_regular_interval assert (df.index.left.minute == 30).all() assert (df.index.right.minute == 30).all() start = xhkg.session_open(session) - end = xhkg.session_close(session) + pd.Timedelta(30, "T") + end = xhkg.session_close(session) + pd.Timedelta(30, "min") index = self.create_single_index(start, end, interval) assert_index_equal(df.index, index) @@ -3682,7 +3686,7 @@ def test_cal_break_ignored_with_partial_overlap(self, prices_hk_lon): start_session, end_session = get_sessions_xnys_xhkg_xlon(prices.bis.T1, 2) interval = TDInterval.T50 - df = prices.get("50T", start_session, end_session, anchor="open", tzout=UTC) + df = prices.get("50min", start_session, end_session, anchor="open", tzout=UTC) df = df[:9] # only take what's necessary to prove the point assert df.pt.last_ts > xhkg.session_break_end(start_session) starts, ends = [], [] @@ -3711,18 +3715,18 @@ def test_openend_no_trading_after(self, prices_us, session_length_xnys): start, end = xnys.session_open_close(session) # verify maintain when no symbol trades after unaligned close - df = prices.get("1H", start, end, openend="maintain") + df = prices.get("1h", start, end, openend="maintain") assert df.pt.has_regular_interval - half_hour = pd.Timedelta(30, "T") + half_hour = pd.Timedelta(30, "min") exp_end = end + half_hour assertions_intraday(df, prices.bis.H1, prices, start, exp_end, 7) # verify maintain is default - df_ = prices.get("1H", start, end) + df_ = prices.get("1h", start, end) assert_frame_equal(df, df_) # verify shorten - df = prices.get("1H", start, end, openend="shorten") + df = prices.get("1h", start, end, openend="shorten") assert not df.pt.has_regular_interval last_indice = df.index[-1] assert last_indice.right == end @@ -3749,14 +3753,14 @@ def test_openend_trading_after(self, prices_lon_247, session_length_xlon): start, end = xlon.session_open_close(session) # verify maintain when symbol trades after unaligned close - df = prices.get("1H", start, end, openend="maintain") + df = prices.get("1h", start, end, openend="maintain") assert df.pt.has_regular_interval - half_hour = pd.Timedelta(30, "T") + half_hour = pd.Timedelta(30, "min") exp_end = end - half_hour assertions_intraday(df, prices.bis.H1, prices, start, exp_end, 8) # verify shorten - df = prices.get("1H", start, end, openend="shorten") + df = prices.get("1h", start, end, openend="shorten") assert not df.pt.has_regular_interval last_indice = df.index[-1] assert last_indice.right == end @@ -3771,7 +3775,7 @@ def test_openend_trading_after(self, prices_lon_247, session_length_xlon): prices, prices.bis.H1, [xlon], [session_length_xlon], 1 )[0] start, end = xlon.session_open_close(session) - df = prices.get("1H", start, end, openend="shorten") + df = prices.get("1h", start, end, openend="shorten") assert df.pt.has_regular_interval exp_end = end - half_hour assertions_intraday(df, prices.bis.H1, prices, start, exp_end, 8) @@ -3999,7 +4003,7 @@ def assertions( # verify when single interval would have comprise minutes from both end of # previous session and start of session - delta = pd.Timedelta(2, "T") + delta = pd.Timedelta(2, "min") start = prev_session_close - bi + delta end = session_open + delta @@ -4020,7 +4024,7 @@ def assertions( session_open = cal.session_open(session) prev_session_close = cal.session_close(prev_session) - delta = pd.Timedelta(2, "T") + delta = pd.Timedelta(2, "min") start = prev_session_close - bi + delta end = session_open + delta @@ -4083,7 +4087,7 @@ def test_raises_PricesUnavailableIntervalPeriodError2( prices.get(bi, start, minutes=4, anchor=anchor) prices.get(dsi, start, minutes=14, anchor=anchor) - delta = pd.Timedelta(2, "T") + delta = pd.Timedelta(2, "min") end = session_open_T1 + delta anchor = "workback" @@ -4127,9 +4131,9 @@ def test_raises_PricesUnavailableIntervalPeriodError2( # Test effect of strict on error raised l_limit = prices.limits[prices.bis.T5][0] l_limit = cal.minute_to_trading_minute(l_limit, "next") - end = l_limit + pd.Timedelta(2, "H") + end = l_limit + pd.Timedelta(2, "h") # error depends on strict - get_kwargs = dict(interval="3H", end=end, hours=6, anchor="workback") + get_kwargs = dict(interval="3h", end=end, hours=6, anchor="workback") with pytest.raises(errors.PricesIntradayUnavailableError): prices.get(**get_kwargs, strict=True) with pytest.raises(errors.PricesUnavailableIntervalPeriodError): @@ -4159,7 +4163,7 @@ def test_raises_PricesIntradayUnavailableError(self, prices_us, one_min): errors.PricesIntradayUnavailableError, match=msg_pass_strict ): prices.get( - "3T", + "3min", session_T5, session_T5, strict=strict, @@ -4173,10 +4177,10 @@ def test_raises_PricesIntradayUnavailableError(self, prices_us, one_min): ): # `priority` should make no difference for priority in priorities: - prices.get("3T", session_T5, priority=priority) + prices.get("3min", session_T5, priority=priority) # although returns data from limit if strict False - df = prices.get("3T", session_T5, strict=False) + df = prices.get("3min", session_T5, strict=False) assert df.pt.first_ts >= prices.limits[prices.bis.T1][0] - one_min assert df.pt.interval == TDInterval.T3 @@ -4196,7 +4200,7 @@ def test_raises_LastIndiceInaccurateError(self, prices_us): limit_H1 = prices.limits[prices.bis.H1][0] # period end that can only be represented with T1 or T5 data - end = xnys.session_close(end_T1) - pd.Timedelta(15, "T") + end = xnys.session_close(end_T1) - pd.Timedelta(15, "min") # verify data available if requested period falls within bounds of # available T5 data @@ -4242,29 +4246,31 @@ def test_raises_LastIndiceInaccurateError(self, prices_us): # given the data that's available. # set end to time that can only be represented by T1, although for which # smallest interval for which data is available is T5 - end = xnys.session_close(start_T5) - pd.Timedelta(3, "T") + end = xnys.session_close(start_T5) - pd.Timedelta(3, "min") df = prices.get(start=start_T5, end=end) assert df.pt.interval == prices.bis.T5 - assert df.pt.last_ts == end - pd.Timedelta(2, "T") + assert df.pt.last_ts == end - pd.Timedelta(2, "min") # verify error not raised when interval passed and anchor "open", # regardless of final indice not representing period end - df_ = prices.get("5T", start=start_T5, end=end) + df_ = prices.get("5min", start=start_T5, end=end) assert_frame_equal(df, df_) # verify that raises errors when anchor="workback" # set period such that T1 data only available over period end and # period end can only be served with T1 data. - end = xnys.session_close(start_T1) - pd.Timedelta(3, "T") + end = xnys.session_close(start_T1) - pd.Timedelta(3, "min") # whilst prices available when anchor "open" - df = prices.get("10T", start=start_T5, end=end, anchor="open") + df = prices.get("10min", start=start_T5, end=end, anchor="open") assert df.pt.interval == TDInterval.T10 # verify not when anchor is "workback" with pytest.raises(errors.LastIndiceInaccurateError): - prices.get("10T", start=start_T5, end=end, anchor="workback") + prices.get("10min", start=start_T5, end=end, anchor="workback") # verify will return later part of period if strict False - df = prices.get("10T", start=start_T5, end=end, anchor="workback", strict=False) + df = prices.get( + "10min", start=start_T5, end=end, anchor="workback", strict=False + ) assert df.pt.last_ts == end assert df.pt.first_ts >= limit_T1 assert df.index[0].length == TDInterval.T10 @@ -4273,7 +4279,7 @@ def test_raises_LastIndiceInaccurateError(self, prices_us): # verify will return full period if priority "period", althrough with # lesser end accuracy df = prices.get( - "10T", start=start_T5, end=end, anchor="workback", priority="period" + "10min", start=start_T5, end=end, anchor="workback", priority="period" ) assert df.pt.last_ts < end assert df.pt.first_ts < limit_T1 @@ -4302,7 +4308,7 @@ def test_raises_direct_errors(self, prices_us): start_H1_oob = xnys.session_offset(start_H1, -2) start_T5 = th.get_sessions_range_for_bi(prices, prices.bis.T5)[0] - end = xnys.session_close(start_T5) - pd.Timedelta(3, "T") + end = xnys.session_close(start_T5) - pd.Timedelta(3, "min") end = end.astimezone(prices.tz_default) with pytest.raises(errors.LastIndiceInaccurateError): @@ -4376,7 +4382,7 @@ def test_raises_daily_only_direct_errors(self, prices_us_daily): " intraday base intervals defined." ) with pytest.raises(errors.PricesIntradayIntervalError, match=match): - prices_us_daily.get("5T", limit, days=2) + prices_us_daily.get("5min", limit, days=2) def test_raises_intraday_only_direct_errors(self, prices_us, prices_us_intraday): """Test get() directly raises expected errors when no daily interval. @@ -4780,7 +4786,7 @@ def test__price_at_from_daily(self, prices_us_lon_hk, one_min, monkeypatch): self.assertions(table, df, indice, values) # now as after xnys open, verify indice reflects 'now' as live session - now = xnys.session_open(session) + pd.Timedelta(22, "T") + now = xnys.session_open(session) + pd.Timedelta(22, "min") mock_now(monkeypatch, now) df = f(None, UTC) indice = now @@ -4871,7 +4877,7 @@ def test_daily(self, prices_us_lon_hk, monkeypatch): # verify minute after intraday limit returns via intraday data limit_id = prices.limit_intraday() - minute = limit_id + pd.Timedelta(1, "H") + minute = limit_id + pd.Timedelta(1, "h") df = prices.price_at(minute) assert df.notna().all(axis=None) assert prices._pdata[prices.bis.D1]._table is None @@ -4880,7 +4886,7 @@ def test_daily(self, prices_us_lon_hk, monkeypatch): self.assert_price_at_rtrn_format(table_, df) # verify minute prior to intraday limit returns via _price_at_from_daily - minute = xnys.previous_close(limit_id) - pd.Timedelta(1, "H") + minute = xnys.previous_close(limit_id) - pd.Timedelta(1, "h") session_xnys = helpers.to_tz_naive(xnys.minute_to_session(minute)) session_xhkg = helpers.to_tz_naive(xhkg.minute_to_session(minute, "previous")) session_xlon = helpers.to_tz_naive(xlon.minute_to_session(minute, "previous")) @@ -4931,7 +4937,7 @@ def test_single_symbol_T1_and_now( xnys = prices.calendar_default symb = prices.lead_symbol_default - delta = pd.Timedelta(33, "T") + delta = pd.Timedelta(33, "min") bi = prices.bis.T1 session_prev, session = get_conforming_sessions( @@ -4944,12 +4950,12 @@ def test_single_symbol_T1_and_now( close = xnys.session_close(session) open_next = xnys.session_open(xnys.next_session(session)) - table = prices.get("1T", session_before, session, tzout=UTC) + table = prices.get("1min", session_before, session, tzout=UTC) tableD1 = prices.get("1D", session_before, session) delay = 20 prices = reset_prices(prices) - prices._delays[symb] = pd.Timedelta(delay, "T") # mock delay + prices._delays[symb] = pd.Timedelta(delay, "min") # mock delay f = prices.price_at # prior to xlon open @@ -4995,14 +5001,14 @@ def test_single_symbol_T1_and_now( self.assertions(tableD1, df, indice, values) for i in range(delay): - minute = now - pd.Timedelta(i, "T") + minute = now - pd.Timedelta(i, "min") df = f(minute, UTC) indice = minute # indices as requested minute values = {symb: (session, "close")} self.assertions(tableD1, df, indice, values) # verify that on delay limit prices return for intraday data - minute = now - pd.Timedelta(delay, "T") + minute = now - pd.Timedelta(delay, "min") df = f(minute, UTC) indice = minute values = {symb: (minute, "open")} @@ -5019,7 +5025,7 @@ def test_when_all_data_available(self, prices_us_lon_hk, one_min): symb_xhkg = get_symbols_for_calendar(prices, "XHKG") bi = prices.bis.T1 - delta = pd.Timedelta(43, "T") + delta = pd.Timedelta(43, "min") # consecutive sessions sessions = get_sessions_xnys_xhkg_xlon(bi, 4) @@ -5043,7 +5049,7 @@ def test_when_all_data_available(self, prices_us_lon_hk, one_min): # otherwise xlon open is same as xhkg close xhkg_xlon_touch = xlon_open == xhkg_close # touch as opposed to overlap - table = prices.get("1T", session_before, session_after, tzout=UTC) + table = prices.get("1min", session_before, session_after, tzout=UTC) prices = reset_prices(prices) f = prices.price_at @@ -5233,8 +5239,8 @@ def test_data_available_from_T5(self, prices_us_lon_hk, one_min): symb_xlon = get_symbols_for_calendar(prices, "XLON") symb_xhkg = get_symbols_for_calendar(prices, "XHKG") - delta = pd.Timedelta(43, "T") - offset = pd.Timedelta(3, "T") + delta = pd.Timedelta(43, "min") + offset = pd.Timedelta(3, "min") delta_reg = delta - offset # following assertions from knowledge of standard sessions @@ -5262,7 +5268,7 @@ def test_data_available_from_T5(self, prices_us_lon_hk, one_min): xhkg_xlon_touch = xlon_open == xhkg_close # touch as opposed to overlap - table = prices.get("5T", session_before, session_after, tzout=UTC) + table = prices.get("5min", session_before, session_after, tzout=UTC) # reset prices prices = reset_prices(prices) @@ -5533,13 +5539,13 @@ def test_data_available_from_H1(self, prices_us_hk, one_min): symb_xnys = prices.lead_symbol_default symb_xhkg = get_symbols_for_calendar(prices, "XHKG") - delta = pd.Timedelta(63, "T") - offset = pd.Timedelta(3, "T") + delta = pd.Timedelta(63, "min") + offset = pd.Timedelta(3, "min") delta_reg = delta - offset bi = prices.bis.H1 bi_less_one_min = bi - one_min - half_hour = pd.Timedelta(30, "T") + half_hour = pd.Timedelta(30, "min") # consecutive sessions sessions = get_sessions_xnys_xhkg_xlon(bi, 4) @@ -5555,7 +5561,7 @@ def test_data_available_from_H1(self, prices_us_hk, one_min): xhkg_break_start = xhkg.session_break_start(session) xhkg_break_end = xhkg.session_break_end(session) - table = prices.get("1H", session_before, session_after, tzout=UTC) + table = prices.get("1h", session_before, session_after, tzout=UTC) prices = reset_prices(prices) f = prices.price_at @@ -5602,7 +5608,7 @@ def test_data_available_from_H1(self, prices_us_hk, one_min): symb_xhkg: (indice, "open"), } for i in (0, 1, 2, bi.as_minutes - 2, bi.as_minutes - 1): - minute_ = minute + pd.Timedelta(i, "T") + minute_ = minute + pd.Timedelta(i, "min") df = f(minute_, UTC) self.assertions(table, df, indice, values) @@ -5782,13 +5788,13 @@ def test_unaligned_single_symbol( xhkg = prices.calendar_default symb_xhkg = prices.lead_symbol_default - delta = pd.Timedelta(63, "T") - offset = pd.Timedelta(3, "T") + delta = pd.Timedelta(63, "min") + offset = pd.Timedelta(3, "min") delta_reg = delta - offset bi = prices.bis.H1 bi_less_one_min = bi - one_min - half_hour = pd.Timedelta(30, "T") + half_hour = pd.Timedelta(30, "min") # four consecutive sessions sessions = get_conforming_sessions(prices, bi, [xhkg], [session_length_xhkg], 4) session_before, session_prev, session, session_after = sessions @@ -5799,7 +5805,7 @@ def test_unaligned_single_symbol( break_start = xhkg.session_break_start(session) break_end = xhkg.session_break_end(session) - table = prices.get("1H", session_before, session_after, tzout=UTC) + table = prices.get("1h", session_before, session_after, tzout=UTC) prices = reset_prices(prices) f = prices.price_at @@ -5833,7 +5839,7 @@ def test_unaligned_single_symbol( indice = minute values = {symb_xhkg: (indice, "open")} for i in (0, 1, 2, bi.as_minutes - 2, bi.as_minutes - 1): - minute_ = minute + pd.Timedelta(i, "T") + minute_ = minute + pd.Timedelta(i, "min") df = f(minute_, UTC) self.assertions(table, df, indice, values) @@ -5971,7 +5977,7 @@ def test_close_at(prices_us_lon_hk, one_day, monkeypatch): # reset prices with monkeypatch.context() as monkey: mock_today = pd.Timestamp("2021-12-23") - now = xhkg.session_close(mock_today) - pd.Timedelta(1, "H") + now = xhkg.session_close(mock_today) - pd.Timedelta(1, "h") mock_now(monkey, now) prices = reset_prices(prices) @@ -6016,9 +6022,9 @@ def test_price_range(prices_us_lon_hk, one_day, monkeypatch): symb_xhkg = get_symbols_for_calendar(prices, "XHKG") _, session = get_sessions_xnys_xhkg_xlon(prices.bis.T1, 2) - minute = xlon.session_close(session) - pd.Timedelta(43, "T") + minute = xlon.session_close(session) - pd.Timedelta(43, "min") session_T5 = get_sessions_xnys_xhkg_xlon(prices.bis.T5, 2)[-1] - minute_T5 = xhkg.session_close(session_T5) - pd.Timedelta(78, "T") + minute_T5 = xhkg.session_close(session_T5) - pd.Timedelta(78, "min") def get(kwargs, **others) -> pd.DataFrame: return prices.get(**kwargs, **others, composite=True, openend="shorten") @@ -6195,16 +6201,16 @@ def test_prices_for_symbols(prices_us_lon): session = pd.Timestamp("2022-06-08") us_open = cal_us.opens[session] lon_close = cal_lon.closes[session] - assert us_open + pd.Timedelta(1, "H") < lon_close # verify overlap > one hour - start = us_open - pd.Timedelta(2, "H") - end = lon_close + pd.Timedelta(2, "H") - - _ = prices.get("5T", start, us_open, lead_symbol="AZN.L") - _ = prices.get("2T", start, us_open, lead_symbol="AZN.L") - _ = prices.get("1T", start, us_open, lead_symbol="AZN.L") - _ = prices.get("5T", us_open, end) - _ = prices.get("2T", us_open, end) - _ = prices.get("1T", us_open, end) + assert us_open + pd.Timedelta(1, "h") < lon_close # verify overlap > one hour + start = us_open - pd.Timedelta(2, "h") + end = lon_close + pd.Timedelta(2, "h") + + _ = prices.get("5min", start, us_open, lead_symbol="AZN.L") + _ = prices.get("2min", start, us_open, lead_symbol="AZN.L") + _ = prices.get("1min", start, us_open, lead_symbol="AZN.L") + _ = prices.get("5min", us_open, end) + _ = prices.get("2min", us_open, end) + _ = prices.get("1min", us_open, end) def assertions( pdata: data.Data, diff --git a/tests/test_calendar_utils.py b/tests/test_calendar_utils.py index 612334e..e8390a2 100644 --- a/tests/test_calendar_utils.py +++ b/tests/test_calendar_utils.py @@ -366,7 +366,7 @@ def _get_session_first_minute(self, session: pd.Timestamp) -> pd.Timestamp: def sessions_with_gap_after(self) -> pd.DatetimeIndex: mask = self.closes >= self.opens.shift(-1) if self.side == "both": - closes_plus_min = self.closes + pd.Timedelta(1, "T") + closes_plus_min = self.closes + pd.Timedelta(1, "min") mask = mask | (closes_plus_min == self.opens.shift(-1)) return self.sessions[~mask][:-1] @@ -962,7 +962,9 @@ def test_sessions_length(self, composite_calendars_with_answers): rtrn = cc.sessions_length() pd.testing.assert_series_equal(expected, rtrn, check_freq=False) - @pytest.mark.parametrize("factor", [pd.Timedelta(v, "T") for v in [5, 7, 11, 300]]) + @pytest.mark.parametrize( + "factor", [pd.Timedelta(v, "min") for v in [5, 7, 11, 300]] + ) def test_is_factor_of_sessions(self, composite_calendars_with_answers, factor): cc, answers = composite_calendars_with_answers rtrn = cc.is_factor_of_sessions(factor) diff --git a/tests/test_csv.py b/tests/test_csv.py index 319f535..3ebbbe4 100644 --- a/tests/test_csv.py +++ b/tests/test_csv.py @@ -582,8 +582,8 @@ def test_parse_csvs(csv_dir, csv_dir_paths, csv_read_kwargs, symbols): def test__get_limits_from_parsed(): start = start_5t = pd.Timestamp("2023-11-21 09:00", tz="UTC") end = end_5t = pd.Timestamp("2023-11-27 16:30", tz="UTC") - freq = "5T" - delta = pd.Timedelta("10T") + freq = "5min" + delta = pd.Timedelta("10min") index_5t_0 = pd.date_range(start, end - delta, freq=freq) index_5t_1 = pd.date_range(start + delta, end - delta, freq=freq) index_5t_2 = pd.date_range(start + delta, end, freq=freq) @@ -616,7 +616,7 @@ def get_df(index: pd.DatetimeIndex) -> pd.DataFrame: expected = ( {TDInterval.T5: start_5t, TDInterval.D1: start_1d}, - {TDInterval.T5: end_5t + pd.Timedelta("5T"), TDInterval.D1: end_1d}, + {TDInterval.T5: end_5t + pd.Timedelta("5min"), TDInterval.D1: end_1d}, ) assert rtrn == expected @@ -779,7 +779,7 @@ def test_tables(csv_dir, symbols, calendars, res_us_lon_hk): for interval, pdata in prices._pdata.items(): table = pdata._table - res = res_us_lon_hk[0][interval.as_pdfreq[-1::-1]] # just reversed freq str + res = res_us_lon_hk[0][interval.name] if interval.is_daily: expected = res.loc[table.index[0] : table.index[-1]].dropna( how="all", axis=0 diff --git a/tests/test_data.py b/tests/test_data.py index 9145aeb..7d3dae2 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -353,7 +353,7 @@ def assert_single_daterange( assert table is not None assert_table_matches(table, daterange, df) assert mr_admin.last_request is None - delta = delta if delta == helpers.ONE_DAY else pd.Timedelta(30, "T") + delta = delta if delta == helpers.ONE_DAY else pd.Timedelta(30, "min") from_ += delta to -= delta table = data.get_table((from_, to)) @@ -412,9 +412,9 @@ def rngs( rngs.append(((from_minute, to_minute), (from_session, to_session))) from_session = cal.session_offset(end_session, -5) - from_minute = cal.session_open(from_session) - pd.Timedelta(70, "T") + from_minute = cal.session_open(from_session) - pd.Timedelta(70, "min") to_session = cal.session_offset(from_session, 2) - to_minute = cal.session_close(to_session) + pd.Timedelta(70, "T") + to_minute = cal.session_close(to_session) + pd.Timedelta(70, "min") rngs.append(((from_minute, to_minute), (from_session, to_session))) yield rngs @@ -487,7 +487,7 @@ def test_each_range( @pytest.fixture(scope="class") def thirty_mins(self) -> abc.Iterator[pd.Timedelta]: - yield pd.Timedelta(30, "T") + yield pd.Timedelta(30, "min") def test_extending_requested_range( self, @@ -903,7 +903,7 @@ def set_now(now: pd.Timestamp): # now, and hence left_bound, set to a time that provides for 1H bi # to fall on frequency, save for left_bound + (2*delta) - now = cal.previous_open(pd.Timestamp.now()) + pd.Timedelta(59, "T") + now = cal.previous_open(pd.Timestamp.now()) + pd.Timedelta(59, "min") set_now(now) if bi_daily: left_bound = today - left_limit @@ -1012,7 +1012,7 @@ def get_data() -> m.Data: table = data.get_table(dr) assert_table_matches(table, dr, df) assert admin.last_request is None - delta = delta if delta == helpers.ONE_DAY else pd.Timedelta(30, "T") + delta = delta if delta == helpers.ONE_DAY else pd.Timedelta(30, "min") from_ = dr[0] + delta to = dr[1] - delta table = data.get_table((from_, to)) @@ -1066,12 +1066,12 @@ def set_now(now: pd.Timestamp): ) if not bi_daily: - now = cal.session_close(last_session) - pd.Timedelta(90, "T") + now = cal.session_close(last_session) - pd.Timedelta(90, "min") data, _ = get_data(now) set_now(now) assert data.rl == now + bi for _ in range(18): - now += pd.Timedelta(10, "T") + now += pd.Timedelta(10, "min") set_now(now) assert data.rl == now + bi assert not data.to_rl @@ -1093,7 +1093,7 @@ def assertions(data, table, now, dr, admin, delay): bi = data.bi from_, to = dr # discount calculation reasonable only given the bis tested (1T, 1H, 1D) - discount = max(bi, delay + pd.Timedelta(10, "T")) + discount = max(bi, delay + pd.Timedelta(10, "min")) rightmost = now - discount table_dr = dr[0], min(dr[1], now + bi) @@ -1177,7 +1177,7 @@ def assertions(data, table, now, dr, admin, delay): now = now.normalize().tz_convert(None) dr = start, now - for delay in [no_delay, pd.Timedelta(15, "T")]: + for delay in [no_delay, pd.Timedelta(15, "min")]: # on right limit data, admin = get_data(now, delay) table = data.get_table(dr) @@ -1248,4 +1248,4 @@ def test_raises_PricesUnavailableFromSourceError( session, _ = session_ends session_open = xlon.session_open(session) with pytest.raises(errors.PricesUnavailableFromSourceError): - data.get_table((session_open, session_open + pd.Timedelta(30, "T"))) + data.get_table((session_open, session_open + pd.Timedelta(30, "min"))) diff --git a/tests/test_daterange.py b/tests/test_daterange.py index 6df72c4..5e1a427 100644 --- a/tests/test_daterange.py +++ b/tests/test_daterange.py @@ -2070,14 +2070,14 @@ def test_end_now_and_get_end_none( # test trading_minute session = ans.sessions_sample[-4] open_ = ans.opens[session] - now = open_ + pd.Timedelta(20, "T") + now = open_ + pd.Timedelta(20, "min") monkeypatch.setattr("pandas.Timestamp.now", lambda *a, **k: now) drg = self.get_drg(cal, pp, interval=interval) end = open_ + (TDInterval.T15 * 2) # end is end of current live interval assert drg.end_now == drg.get_end(None) == (end, now + one_min) # test trading minute with delay - delay = pd.Timedelta(10, "T") + delay = pd.Timedelta(10, "min") drg = self.get_drg(cal, pp, interval=interval, delay=delay) end = open_ + TDInterval.T15 assert drg.end_now == drg.get_end(None) == (end, now + one_min - delay) @@ -2088,14 +2088,14 @@ def test_end_now_and_get_end_none( return session = sessions[-4] close = ans.closes[session] - now = close + pd.Timedelta(10, "T") + now = close + pd.Timedelta(10, "min") monkeypatch.setattr("pandas.Timestamp.now", lambda *a, **k: now) drg = self.get_drg(cal, pp, interval=TDInterval.T1) assert drg.end_now == drg.get_end(None) == (close, close) - delay = pd.Timedelta(15, "T") + delay = pd.Timedelta(15, "min") drg = self.get_drg(cal, pp, interval=TDInterval.T1, delay=delay) - end = close - pd.Timedelta(5, "T") + one_min # returns right of live indice + end = close - pd.Timedelta(5, "min") + one_min # returns right of live indice assert drg.end_now == drg.get_end(None) == (end, now + one_min - delay) # verify None input to `get_end` returns any fixed right limit @@ -2129,9 +2129,9 @@ def test_get_start_get_end_anchor_effect( ) # verify that drg_wb behaves as drg_bi, i.e. aligning based on bi, not dsi - delta = pd.Timedelta(4, "T") + delta = pd.Timedelta(4, "min") minutes = pd.date_range(open_ - delta, close + delta, freq=delta) - delta = pd.Timedelta(7, "T") + delta = pd.Timedelta(7, "min") minutes = minutes.union(pd.date_range(open_ - delta, close + delta, freq=delta)) for minute in minutes: @@ -2231,7 +2231,7 @@ def match( duration_insert = "" if anchor is Anchor.WORKBACK: assert duration is not None - duration_ = pd.Timedelta(duration, "T") + duration_ = pd.Timedelta(duration, "min") duration_insert = f"\nPeriod duration evaluated as {duration_}." return re.escape( f"Period does not span a full indice of length {final_interval}." @@ -2365,7 +2365,7 @@ def assertions( # verify when single interval would comprise minutes from both end of # previous session and start of session - delta = pd.Timedelta(3, "T") + delta = pd.Timedelta(3, "min") pp = get_pp_default() pp["start"] = start = prev_session_close - dsi + delta pp["end"] = end = session_open + delta @@ -2988,7 +2988,7 @@ def test_daterange_duration_intraday_start_minute_ool( end, end_accuracy = drg.end_now minutes = 5 - pp["start"] = start = end - pd.Timedelta(minutes, "T") + pp["start"] = start = end - pd.Timedelta(minutes, "min") # on now pp["minutes"] = minutes @@ -3015,7 +3015,7 @@ def test_daterange_duration_intraday_end_minute_oolb( # on limit minutes = 5 - pp["end"] = end = limit + pd.Timedelta(minutes, "T") + pp["end"] = end = limit + pd.Timedelta(minutes, "min") pp["minutes"] = minutes drg = self.get_drg(cal, pp, interval=bi, limit=limit, strict=False) assert drg.daterange == ((limit, end), end) @@ -3112,8 +3112,8 @@ def test_daterange_tight(self, xlon_calendar_extended, pp_default): kwargs = {"interval": TDInterval.H1, "ds_interval": TDInterval.H2} exp_start = open_ - exp_end = close + pd.Timedelta(90, "T") - exp_end_tight = close + pd.Timedelta(30, "T") + exp_end = close + pd.Timedelta(90, "min") + exp_end_tight = close + pd.Timedelta(30, "min") exp_end_accuracy = close # verify daterange same as daterange_tight when Alignment BI @@ -3148,7 +3148,7 @@ def test_daterange_duration_intraday_intervalduration_error( # duration < final interval pp["minutes"] = minutes = pp["minutes"] - 1 drg = self.get_drg(cal, pp, **drg_kwargs) - duration = pd.Timedelta(minutes, "T") + duration = pd.Timedelta(minutes, "min") match = re.escape( f"Period duration shorter than interval. Interval is {base_interval}" f" although period duration is only {duration}." @@ -3212,7 +3212,7 @@ def get_drgs(pp: dict) -> tuple[m.GetterIntraday, m.GetterIntraday]: assert drg_wb_dr[0][1] == drg_wb_dr[1] == start + dsi + one_min # verify for prior_start that represent an interval that crosses sessions - delta = pd.Timedelta(7, "T") + delta = pd.Timedelta(7, "min") pp["start"] = start = open_ + delta drg_open, drg_wb = get_drgs(pp) end_ = start + dsi + one_min diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 5ec6d6f..a9dde8d 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -38,8 +38,8 @@ def test_constants(): # Just to make sure they aren't inadvertently changed assert m.UTC is ZoneInfo("UTC") assert m.ONE_DAY == pd.Timedelta(1, "D") - assert m.ONE_MIN == pd.Timedelta(1, "T") - assert m.ONE_SEC == pd.Timedelta(1, "S") + assert m.ONE_MIN == pd.Timedelta(1, "min") + assert m.ONE_SEC == pd.Timedelta(1, "s") def test_is_date(one_min): @@ -323,7 +323,7 @@ def test_resample(intraday_pt): df = intraday_pt.pt.utc df = df.loc["2021-12-17":"2021-12-20"].copy() - rtrn = f(df.pt.indexed_left, "1H") + rtrn = f(df.pt.indexed_left, "1h") # create expected return groups = [] @@ -359,8 +359,8 @@ def test_resample(intraday_pt): # add rows with missing values to expected index = pd.date_range( start=df.pt.first_ts, - end=df.pt.last_ts - pd.Timedelta(1, "H"), - freq="1H", + end=df.pt.last_ts - pd.Timedelta(1, "h"), + freq="1h", name="left", ) expected = expected.reindex(index) diff --git a/tests/test_intervals.py b/tests/test_intervals.py index d85bc57..349d326 100644 --- a/tests/test_intervals.py +++ b/tests/test_intervals.py @@ -56,18 +56,18 @@ def test_tdintervals(xlon_calendar): if i <= intraday_daily_separator: if i % 60: assert en == getattr(m.TDInterval, "T" + str(i)) - assert en.freq_unit == "T" + assert en.freq_unit == "min" assert en.freq_value == i - assert en.as_pdfreq == str(i) + "T" + assert en.as_pdfreq == str(i) + "min" for c, one_less in itertools.product([cal, None], [True, False]): assert en.as_offset(c, one_less) == pd.tseries.offsets.Minute(i) assert en.as_offset() == pd.tseries.offsets.Minute(i) else: i_ = i // 60 assert en == getattr(m.TDInterval, "H" + str(i_)) - assert en.freq_unit == "H" + assert en.freq_unit == "h" assert en.freq_value == i_ - assert en.as_pdfreq == str(i_) + "H" + assert en.as_pdfreq == str(i_) + "h" for c, one_less in itertools.product([cal, None], [True, False]): assert en.as_offset(c, one_less) == pd.tseries.offsets.Hour(i_) assert en.as_offset() == pd.tseries.offsets.Hour(i_) @@ -118,13 +118,13 @@ def test_tdintervals(xlon_calendar): def test_tdintervals_comparion_with_timedelta(): """Verify comparisons of TDInterval with pd.Timedelta as expected.""" - assert m.TDInterval.T5 == pd.Timedelta(5, "T") - assert m.TDInterval.T5 > pd.Timedelta(4, "T") - assert m.TDInterval.T5 >= pd.Timedelta(4, "T") - assert m.TDInterval.T5 >= pd.Timedelta(5, "T") - assert m.TDInterval.T5 < pd.Timedelta(6, "T") - assert m.TDInterval.T5 <= pd.Timedelta(6, "T") - assert m.TDInterval.T5 <= pd.Timedelta(5, "T") + assert m.TDInterval.T5 == pd.Timedelta(5, "min") + assert m.TDInterval.T5 > pd.Timedelta(4, "min") + assert m.TDInterval.T5 >= pd.Timedelta(4, "min") + assert m.TDInterval.T5 >= pd.Timedelta(5, "min") + assert m.TDInterval.T5 < pd.Timedelta(6, "min") + assert m.TDInterval.T5 <= pd.Timedelta(6, "min") + assert m.TDInterval.T5 <= pd.Timedelta(5, "min") def test_dointervals(xlon_calendar): @@ -214,8 +214,8 @@ def test_base_interval(self, BaseInterval, BaseIntervalIntradayOnly): assert bi.next is None # pylint: disable=undefined-loop-variable assert m.TDInterval.T5 in BaseInterval assert m.TDInterval.T6 not in BaseInterval - assert pd.Timedelta(5, "T") in BaseInterval - assert pd.Timedelta(6, "T") not in BaseInterval + assert pd.Timedelta(5, "min") in BaseInterval + assert pd.Timedelta(6, "min") not in BaseInterval assert BaseInterval.daily_bi() == pd.Timedelta(1, "D") assert BaseInterval.intraday_bis() == BaseInterval[:-1] @@ -271,13 +271,15 @@ def components(self) -> abc.Iterator[dict]: yield { "T": "minutes", "MIN": "minutes", + "min": "minutes", "H": "hours", + "h": "hours", "D": "days", "M": "months", } def test_type(self, f): - for invalid_input in [("2T",), ["1D"], 33]: + for invalid_input in [("2min",), ["1D"], 33]: with pytest.raises(TypeError): f(invalid_input) @@ -292,7 +294,7 @@ def test_str_input(self, f, components): f("0" + unit) assert f("1" + unit) - for invalid_input in ["2s2", "T1", "H2H", "3T4H", "HH2"]: + for invalid_input in ["2s2", "T1", "h2h", "3min4h", "HH2"]: with pytest.raises(ValueError, match=match): f(invalid_input) @@ -330,13 +332,13 @@ def test_unit(unit: str, limit: int, Cls: m.PTInterval): test_unit("d", 250, m.TDInterval) test_unit("m", 36, m.DOInterval) - assert f("60min") == f("60MIN") == f("1H") == f("1h") == m.TDInterval.H1 + assert f("60min") == f("60T") == f("1H") == f("1h") == m.TDInterval.H1 def test_timedelta_input(self, f, components): # pylint: disable=too-complex match = "`interval` cannot be negative or zero." for i in range(0, -3, -1): - for unit in ["T", "H", "D"]: + for unit in ["min", "h", "D"]: with pytest.raises(ValueError, match=match): f(pd.Timedelta(i, unit)) for kwarg in ["minutes", "hours", "days"]: @@ -363,14 +365,18 @@ def match_comps_error(td: pd.Timedelta) -> str: def test_unit(unit: str, limit: int, Cls: m.PTInterval): for i in range(1, limit + 1): for td in (pdtd := pd.Timedelta(i, unit), pdtd.to_pytimedelta()): - if unit == "T" and not i % 60: + if unit == "min" and not i % 60: assert f(td) == getattr(Cls, "H" + str(i // 60)) + elif unit == "min": + assert f(td) == getattr(Cls, "T" + str(i)) + elif unit == "h": + assert f(td) == getattr(Cls, "H" + str(i)) else: assert f(td) == getattr(Cls, unit + str(i)) for i in range(limit + 1, limit + 6): for td in (pdtd := pd.Timedelta(i, unit), pdtd.to_pytimedelta()): - if unit == "H" and i >= 24: + if unit == "h" and i >= 24: if i == 24: assert f(td) == m.TDInterval.D1 if i > 24: @@ -380,8 +386,8 @@ def test_unit(unit: str, limit: int, Cls: m.PTInterval): with pytest.raises(ValueError, match=match_too_high(td, limit)): _ = f(td) - test_unit("T", 1320, m.TDInterval) - test_unit("H", 22, m.TDInterval) + test_unit("min", 1320, m.TDInterval) + test_unit("h", 22, m.TDInterval) test_unit("D", 250, m.TDInterval) # test multiple components diff --git a/tests/test_limits.py b/tests/test_limits.py index bfa868b..fbc8265 100644 --- a/tests/test_limits.py +++ b/tests/test_limits.py @@ -243,7 +243,7 @@ def stricts() -> abc.Iterator[list[bool]]: @pytest.fixture def intrvls() -> abc.Iterator[tuple[None, str]]: - yield (None, "5T") + yield (None, "5min") @pytest.fixture @@ -362,7 +362,7 @@ def test_start_loll_end_ok( # verify as required at the edge end = ends_T5[0] - one_min = pd.Timedelta(1, "T") + one_min = pd.Timedelta(1, "min") limit_start_5T, _ = prices.limits[prices.bis.T5] start_ool = limit_start_5T - prices.bis.T5 start_valid = start_ool + one_min @@ -375,7 +375,7 @@ def test_start_loll_end_ok( check(prices, df, prices.bis.T5, end=expected_end_T5) # check when explicitly defining interval df = prices.get( - "5T", start=start_valid, end=end, priority=priority, strict=strict + "5min", start=start_valid, end=end, priority=priority, strict=strict ) check(prices, df, prices.bis.T5, end=expected_end_T5) @@ -400,7 +400,7 @@ def test_start_loll_end_ok( for priority in priorities: with pytest.raises(errors.PricesIntradayUnavailableError, match=match): prices.get( - "5T", start=start_ool, end=end, priority=priority, strict=True + "5min", start=start_ool, end=end, priority=priority, strict=True ) # verify doesn't raise when strict False @@ -409,7 +409,7 @@ def test_start_loll_end_ok( check(prices, df, prices.bis.T5, end=expected_end_T5) # check when explicitly defining interval df = prices.get( - "5T", start=start_ool, end=end, priority=priority, strict=False + "5min", start=start_ool, end=end, priority=priority, strict=False ) check(prices, df, prices.bis.T5, end=expected_end_T5) @@ -481,21 +481,21 @@ def test_start_ok_end_rorl( for start, priority in itertools.product(all_starts, priorities): # as neither period nor end can be met return will be based on highest interval df = prices.get(start=start, end=rorl, priority=priority, strict=False) - mod = pd.Timedelta((start.time().minute % 5), "T") + mod = pd.Timedelta((start.time().minute % 5), "min") expected_start = start if not mod else start + (prices.bis.T5 - mod) check(prices, df, prices.bis.T5, start=expected_start) # verify when explicitly defining interval df = prices.get( - "5T", start=start, end=rorl, priority=priority, strict=False + "5min", start=start, end=rorl, priority=priority, strict=False ) check(prices, df, prices.bis.T5, start=expected_start) # check when define lower interval that returns at that interval for start, priority in itertools.product(starts_T2, priorities): df = prices.get( - "2T", start=start, end=rorl, priority=priority, strict=False + "2min", start=start, end=rorl, priority=priority, strict=False ) - mod = pd.Timedelta((start.time().minute % 2), "T") + mod = pd.Timedelta((start.time().minute % 2), "min") expected_start = start if not mod else start + (prices.bis.T2 - mod) check(prices, df, prices.bis.T2, start=expected_start) @@ -513,7 +513,7 @@ def test_start_ok_end_rorl( check(prices, df, prices.bis.T5, start=expected_start_T5) # check when explicitly defining interval df = prices.get( - "5T", start=start, end=end_valid, priority=priority, strict=strict + "5min", start=start, end=end_valid, priority=priority, strict=strict ) check(prices, df, prices.bis.T5, start=expected_start_T5) @@ -559,7 +559,7 @@ def test_start_ok_end_rorl( for priority in priorities: with pytest.raises(errors.PricesIntradayUnavailableError, match=match): prices.get( - "5T", start=start, end=end_ool_5, priority=priority, strict=True + "5min", start=start, end=end_ool_5, priority=priority, strict=True ) # verify doesn't raise when False @@ -571,7 +571,9 @@ def test_start_ok_end_rorl( assert df.index[-1].right == end_ool_1 # will be fulfilled by 1T data within confined of what's available - df = prices.get("5T", start=start, end=end_ool_5, priority="end", strict=False) + df = prices.get( + "5min", start=start, end=end_ool_5, priority="end", strict=False + ) assert isinstance(df, pd.DataFrame) assert df.pt.interval == prices.bis.T5 assert df.index[0].left == prices.limits[prices.bis.T1][0] @@ -689,13 +691,17 @@ def test_start_loll_end_rorl( ) with pytest.raises(errors.PricesIntradayUnavailableError, match=match): prices.get( - "5T", start=start_ool_T5, end=end_ool_T5, priority="period", strict=True + "5min", + start=start_ool_T5, + end=end_ool_T5, + priority="period", + strict=True, ) with pytest.raises(errors.LastIndiceInaccurateError): # as prior reasoning prices.get(start=start_ool_T5, end=end_ool_T5, priority="end", strict=True) with pytest.raises(errors.PricesIntradayUnavailableError): prices.get( - "5T", start=start_ool_T5, end=end_ool_T5, priority="end", strict=True + "5min", start=start_ool_T5, end=end_ool_T5, priority="end", strict=True ) # strict False @@ -711,7 +717,7 @@ def test_start_loll_end_rorl( check(prices, df, prices.bis.T1, end=end_ool_T5) # will meet with downsampled 1T data that can meet end - df = prices.get("5T", start_ool_T5, end_ool_T5, priority="end", strict=False) + df = prices.get("5min", start_ool_T5, end_ool_T5, priority="end", strict=False) check(prices, df, prices.bis.T5, prices.limits[prices.bis.T1][0], end_ool_T5) # going way out @@ -892,7 +898,7 @@ def test_defined_ool_evaluated_ok( df = prices.get(start=loll, days=days, priority="end", strict=False) check(prices, df, prices.bis.T2, end=end) - mod = pd.Timedelta((end.time().minute % 5), "T") + mod = pd.Timedelta((end.time().minute % 5), "min") expected_end = end + (prices.bis.T5 - mod) for intrvl, priority in itertools.product(intrvls, priorities): if intrvl is None and priority == "end": @@ -910,7 +916,11 @@ def test_defined_ool_evaluated_ok( for priority in priorities: with pytest.raises(errors.PricesIntradayUnavailableError, match=match): prices.get( - "5T", start=loll, days=days_to_T5[0], priority=priority, strict=True + "5min", + start=loll, + days=days_to_T5[0], + priority=priority, + strict=True, ) # end defined ool @@ -921,7 +931,7 @@ def test_defined_ool_evaluated_ok( # value such that aligns with 5T. start will then be evaluated off this aligned # value, such that falls earlier than what would be the 2T target days, start = days_back_to_T2 - mod = pd.Timedelta((end.time().minute % 5), "T") + mod = pd.Timedelta((end.time().minute % 5), "min") expected_start = start - (prices.bis.T5 - mod) for intrvl, priority in itertools.product(intrvls, priorities): df = prices.get( @@ -1025,7 +1035,7 @@ def test_defined_ok_evaluated_ool( df = prices.get(end=end, days=days, priority="end", strict=False) check(prices, df, prices.bis.T2, end=end) - mod = pd.Timedelta((end.time().minute % 5), "T") + mod = pd.Timedelta((end.time().minute % 5), "min") expected_end = end - mod for intrvl, priority in itertools.product(intrvls, priorities): if intrvl is None and priority == "end": @@ -1040,7 +1050,7 @@ def test_defined_ok_evaluated_ool( ) for priority in priorities: with pytest.raises(errors.PricesIntradayUnavailableError, match=match): - prices.get("5T", end=end, days=days, priority=priority, strict=True) + prices.get("5min", end=end, days=days, priority=priority, strict=True) # start defined within limits # strict True @@ -1048,7 +1058,7 @@ def test_defined_ok_evaluated_ool( # priority not important as cannot meet end, will be returned at highest # avaialble intraday interval, i.e. 5T days, start = days_back_to_T2 - mod = pd.Timedelta((end.time().minute % 5), "T") + mod = pd.Timedelta((end.time().minute % 5), "min") expected_start = start + mod for intrvl, priority in itertools.product(intrvls, priorities): @@ -1272,16 +1282,16 @@ def test_period_defined_to_left_of_available( for priority, strict in itertools.product(priorities, stricts): with pytest.raises(errors.PricesIntradayUnavailableError, match=match): prices.get( - "5T", + "5min", start=loll, end=loll + one_day, priority=priority, strict=strict, ) with pytest.raises(errors.PricesIntradayUnavailableError): - prices.get("5T", start=loll, days=2, priority=priority, strict=strict) + prices.get("5min", start=loll, days=2, priority=priority, strict=strict) with pytest.raises(errors.PricesIntradayUnavailableError): - prices.get("5T", end=loll, days=2, priority=priority, strict=strict) + prices.get("5min", end=loll, days=2, priority=priority, strict=strict) # interval inferred match_start = "Given the parameters receieved, the interval was inferred as intraday although the request can only be met with daily data. To return daily prices pass `interval` as a daily interval, for example '1D'.\nNB. The interval will only be inferred as daily if `end` and `start` are defined (if passed) as sessions (timezone naive and with time component as 00:00) and any duration is defined in terms of either `days` or `weeks`, `months` and `years`. Also, if both `start` and `end` are passed then the distance between them should be no less than 6 sessions." @@ -1429,16 +1439,16 @@ def test_period_defined_to_right_of_available( for priority, strict in itertools.product(priorities, stricts): with pytest.raises(errors.StartTooLateError, match=match_stl): prices.get( - "5T", + "5min", start=rorl, end=rorl + one_day * 2, priority=priority, strict=strict, ) with pytest.raises(errors.StartTooLateError): - prices.get("5T", start=rorl, days=2, priority=priority, strict=strict) + prices.get("5min", start=rorl, days=2, priority=priority, strict=strict) with pytest.raises(errors.PricesIntradayUnavailableError, match=match): - prices.get("5T", end=rorl, days=2, priority=priority, strict=strict) + prices.get("5min", end=rorl, days=2, priority=priority, strict=strict) # interval inferred as intraday match = re.escape( diff --git a/tests/test_mptypes.py b/tests/test_mptypes.py index 01dcab8..c2be4d7 100644 --- a/tests/test_mptypes.py +++ b/tests/test_mptypes.py @@ -38,7 +38,7 @@ def mock_func( return arg # verify valid input - freq = "3H" + freq = "3h" rtrn = mock_func(freq) assert rtrn == freq # verify mptype property diff --git a/tests/test_pandas_utils.py b/tests/test_pandas_utils.py index 4083825..d2007f0 100644 --- a/tests/test_pandas_utils.py +++ b/tests/test_pandas_utils.py @@ -28,7 +28,7 @@ @pytest.fixture def datetime_index_hourly_freq(): - yield pd.date_range("2021-05-01 12:00", periods=10, freq="1H") + yield pd.date_range("2021-05-01 12:00", periods=10, freq="1h") @pytest.fixture @@ -43,7 +43,7 @@ def interval_index_non_overlapping( datetime_index_hourly_freq, ) -> abc.Iterator[pd.IntervalIndex]: """1H between indices. Interval 30min. 30min gap from right to next left.""" - right = datetime_index_hourly_freq + pd.Timedelta(30, "T") + right = datetime_index_hourly_freq + pd.Timedelta(30, "min") yield pd.IntervalIndex.from_arrays(datetime_index_hourly_freq, right) @@ -54,7 +54,7 @@ def interval_index_overlapping( """One indice of interval index fully overlaps following indice.""" index = interval_index_non_overlapping i = 3 - new_indice = pd.Interval(index[i].left, index[i + 1].left + pd.Timedelta(5, "T")) + new_indice = pd.Interval(index[i].left, index[i + 1].left + pd.Timedelta(5, "min")) index = index.insert(i, new_indice) index = index.drop(index[i + 1]) assert index.is_monotonic_increasing @@ -70,7 +70,7 @@ def interval_index_fully_overlapping( index = interval_index_non_overlapping i = 3 indice = pd.Interval( - index[i].left - pd.Timedelta(5, "T"), index[i].right + pd.Timedelta(5, "T") + index[i].left - pd.Timedelta(5, "min"), index[i].right + pd.Timedelta(5, "min") ) index = index.insert(i, indice) assert index.is_overlapping @@ -84,8 +84,8 @@ def interval_index_not_monotonoic_increasing( index = interval_index_non_overlapping i = 3 new_indice = pd.Interval( - index[i].right + pd.Timedelta(5, "T"), - index[i + 1].left - pd.Timedelta(5, "T"), + index[i].right + pd.Timedelta(5, "min"), + index[i + 1].left - pd.Timedelta(5, "min"), closed=index.closed, ) index = index.insert(i, new_indice) diff --git a/tests/test_parsing.py b/tests/test_parsing.py index 49eab91..db75a65 100644 --- a/tests/test_parsing.py +++ b/tests/test_parsing.py @@ -183,7 +183,7 @@ def f( @pytest.fixture(scope="class") def delays(self) -> abc.Iterator[tuple[pd.Timedelta, pd.Timedelta]]: - yield pd.Timedelta(0), pd.Timedelta(15, "T") + yield pd.Timedelta(0), pd.Timedelta(15, "min") @pytest.fixture(scope="class") def as_times(self) -> abc.Iterator[typing.Literal[True]]: diff --git a/tests/test_pt.py b/tests/test_pt.py index 0679f27..69288b1 100644 --- a/tests/test_pt.py +++ b/tests/test_pt.py @@ -91,7 +91,7 @@ def intraday_cc_overlapping_pt() -> abc.Iterator[pd.DataFrame]: Recreate table with: > symbols = ["BTC-USD", "ES=F"] - > prices.get("15T", start="2021-12-21", end="2021-12-23", anchor="open") + > prices.get("15min", start="2021-12-21", end="2021-12-23", anchor="open") """ yield get_resource("intraday_cc_overlapping_pt") @@ -154,7 +154,7 @@ def intraday_detached_pt() -> abc.Iterator[pd.DataFrame]: Recreate table with: > symbols = ["MSFT", "9988.HK"] - > df = prices.get("30T", start="2022-04-01", end="2022-04-07") + > df = prices.get("30min", start="2022-04-01", end="2022-04-07") """ yield get_resource("intraday_detached_pt") @@ -333,7 +333,7 @@ def test_new_constructor_errors( _ = intraday_df.pt daily_df = daily_pt.copy() - daily_df.index = daily_df.index + pd.Timedelta(1, "T") + daily_df.index = daily_df.index + pd.Timedelta(1, "min") match = re.escape( "PT accessor not available where index is a pd.DatatimeIndex with" " one or more indices that have a time component (Index must be" @@ -799,7 +799,7 @@ def test_intraday_1h_pt(self, intraday_1h_pt, symbols, calendars, side): assert_index_equal(df.pt.indices_partial_trading(cal), partial_indices) # create indices_partial_trading_info - delta = pd.Timedelta(30, "T") + delta = pd.Timedelta(30, "min") d = {} for indice in partial_indices: non_trading_part = pd.Interval(indice.right - delta, indice.right, side) @@ -821,14 +821,14 @@ def test_intraday_1h_pt(self, intraday_1h_pt, symbols, calendars, side): date = "2021-12-24" # First indice is a trading indice left = cal.session_open(date) - right = left + pd.Timedelta(1, "H") + right = left + pd.Timedelta(1, "h") indice1 = pd.Interval(left, right, side) bv_trading_status.loc[indice1] = True bv_partial_trading.loc[indice1] = False # last indice is a parital trading indice. - left = cal.session_close(date) - pd.Timedelta(30, "T") - right = left + pd.Timedelta(1, "H") + left = cal.session_close(date) - pd.Timedelta(30, "min") + right = left + pd.Timedelta(1, "h") indice2 = pd.Interval(left, right, side) bv_trading_status.loc[indice2] = np.nan bv_partial_trading.loc[indice2] = True @@ -841,7 +841,7 @@ def test_intraday_1h_pt(self, intraday_1h_pt, symbols, calendars, side): partial_indices = df.index[bv_partial_trading] assert_index_equal(df.pt.indices_partial_trading(cal), partial_indices) - delta = pd.Timedelta(30, "T") + delta = pd.Timedelta(30, "min") d = {} for indice in partial_indices: if indice == indice2: @@ -908,7 +908,7 @@ def test_indices_partial_trading_info( session = "2021-12-16" side = "left" xasx_open = xasx.session_open(session) - right = xasx_open + pd.Timedelta(6, "H") + right = xasx_open + pd.Timedelta(6, "h") indice = pd.Interval(xasx_open, right, side) xhkg_non_trading_periods = [ @@ -1968,7 +1968,7 @@ def test_errors(self, daily_pt, daily_pt_ss, calendars, xnys, xlon): # test raises expected errors match = "Cannot downsample to a `pdfreq` with a unit more precise than 'd'." - invalid_freqs = ("5T", "5min", "1ms", "3h", "2H", "120s", "1000ns", "26H") + invalid_freqs = ("5min", "1ms", "3h", "120s", "1000ns", "26h") for freq in invalid_freqs: with pytest.raises(ValueError, match=match): f(freq, calendars[0]) @@ -1981,7 +1981,7 @@ def match_f(freq) -> str: ' than one day. For example "2d", "5d" "QS" etc.' ) - invalid_freqs = ("D2", "a_string", "3E", "3") + invalid_freqs = ("D2", "astring", "3E", "3") for freq in invalid_freqs: with pytest.raises(ValueError, match=match_f(freq)): f(freq, calendars[0]) @@ -2295,24 +2295,24 @@ def test_errors(self, intraday_pt, composite_intraday_pt, one_min): f = df.pt.downsample minutes = (df.pt.interval - one_min).seconds // 60 - expected_interval = pd.Timedelta(minutes, "T") + expected_interval = pd.Timedelta(minutes, "min") match = ( "Downsampled interval must be higher than table interval, although" f" downsample interval evaluated as {expected_interval} whilst table" f" interval is {df.pt.interval}." ) with pytest.raises(ValueError, match=match): - f(str(minutes) + "T") + f(str(minutes) + "min") minutes = (df.pt.interval + one_min).seconds // 60 - expected_interval = pd.Timedelta(minutes, "T") + expected_interval = pd.Timedelta(minutes, "min") match = ( "Table interval must be a factor of downsample interval, although" f" downsampled interval evaluated as {expected_interval} whilst table" f" interval is {df.pt.interval}." ) with pytest.raises(ValueError, match=match): - f(str(minutes) + "T") + f(str(minutes) + "min") table_freq = df.pt.interval.as_pdfreq match = ( @@ -2324,17 +2324,17 @@ def test_errors(self, intraday_pt, composite_intraday_pt, one_min): def match_f(pdfreq) -> str: return re.escape( - f"The unit of `pdfreq` must be in ['min', 'T', 'h', 'H'] although" + f"The unit of `pdfreq` must be in ['min', 'h'] although" f" received `pdfreq` as {pdfreq}." ) - invalid_pdfreqs = ["1d", "1s", "1ns", "1ms", "1m", "1y"] + invalid_pdfreqs = ["1d", "1s", "1ns", "1ms", "1ME", "1YE"] for pdfreq in invalid_pdfreqs: with pytest.raises(ValueError, match=match_f(pdfreq)): f(pdfreq) # verify no error raised for valid units - valid_pdfreqs = [table_freq, table_freq[:-1] + "min", "1h", "1H"] + valid_pdfreqs = [table_freq, table_freq[:-3] + "min", "1h"] for pdfreq in valid_pdfreqs: f(pdfreq) @@ -2451,23 +2451,23 @@ def f(freq) -> pd.DataFrame: return df.pt.downsample(freq, anchor="workback") base_minutes = (df.pt.interval).seconds // 60 - base_freq = str(base_minutes) + "T" + base_freq = str(base_minutes) + "min" # assert unchanged if downsample to table frequency assert_frame_equal(f(base_freq), df) test_freqs = [ (pd.tseries.frequencies.to_offset(base_freq) * 2).freqstr, - "30T", - "1H", - "4H", - "8H", + "30min", + "1h", + "4h", + "8h", ] excess_rowss = [] for freq in test_freqs: offset = pd.tseries.frequencies.to_offset(freq) - freq_minutes = offset.delta.seconds // 60 + freq_minutes = pd.Timedelta(offset).seconds // 60 factor = freq_minutes // base_minutes excess_rows = len(df) % factor excess_rowss.append(excess_rows) @@ -2664,8 +2664,8 @@ def test_composite_calendar( factor = 3 ds_minutes = df.pt.interval.as_minutes * factor - ds_freq = str(ds_minutes) + "T" - ds_interval = pd.Timedelta(ds_minutes, "T") + ds_freq = str(ds_minutes) + "min" + ds_interval = pd.Timedelta(ds_minutes, "min") def f(cal, comp_cal=None) -> pd.DataFrame: return df_test.pt.downsample(ds_freq, "open", cal, False, comp_cal) @@ -2970,7 +2970,7 @@ def test_composite_daily_intraday(self, composite_daily_intraday_pt): df = composite_daily_intraday_pt match = f"downsample is not implemented for {type(df.pt)}." with pytest.raises(NotImplementedError, match=match): - df.pt.downsample("10T") + df.pt.downsample("10min") class TestPTIntraday: diff --git a/tests/test_tutorial_helpers.py b/tests/test_tutorial_helpers.py index d4d3e7c..37eb3a5 100644 --- a/tests/test_tutorial_helpers.py +++ b/tests/test_tutorial_helpers.py @@ -339,7 +339,7 @@ def match( with pytest.raises(errors.TutorialDataUnavailableError, match=match(*args)): f_cc_var(*args) - length = pd.Timedelta(4, "H") + length = pd.Timedelta(4, "h") lengths = [[length]] num = 1 msg = match(cals, [[length] * num], start, end) @@ -372,7 +372,7 @@ def match( cals = [xlon, xnys] cc = calutils.CompositeCalendar(cals) full_session_xnys = pd.Timedelta(hours=6, minutes=30) - full_session_cc = pd.Timedelta(13, "H") + full_session_cc = pd.Timedelta(13, "h") length_by_cal = [full_session_xlon, full_session_xnys] length_cc = full_session_cc @@ -531,7 +531,7 @@ def match( ] lengths_cc = [ full_session_cc, - pd.Timedelta(11, "H"), + pd.Timedelta(11, "h"), full_session_xnys, full_session_cc, full_session_cc, diff --git a/tests/test_yahoo.py b/tests/test_yahoo.py index 4c4ef47..71865c3 100644 --- a/tests/test_yahoo.py +++ b/tests/test_yahoo.py @@ -533,7 +533,7 @@ def test_delays(self, prices, delays): expected_delays = delays for k, delay in prices.delays.items(): assert isinstance(delay, pd.Timedelta) - assert delay == pd.Timedelta(expected_delays[k], "T") + assert delay == pd.Timedelta(expected_delays[k], "min") def test_adj_close(self): """Verify `adj_close` parameter returns alternative close col. @@ -634,17 +634,17 @@ def test_api_down(self, monkeypatch): @pytest.fixture def session_length_xnys() -> abc.Iterator[pd.Timedelta]: - yield pd.Timedelta(6.5, "H") + yield pd.Timedelta(6.5, "h") @pytest.fixture def session_length_xhkg() -> abc.Iterator[pd.Timedelta]: - yield pd.Timedelta(6.5, "H") + yield pd.Timedelta(6.5, "h") @pytest.fixture def session_length_xlon() -> abc.Iterator[pd.Timedelta]: - yield pd.Timedelta(8.5, "H") + yield pd.Timedelta(8.5, "h") @pytest.fixture(scope="module") @@ -1161,7 +1161,7 @@ def test_data_unavailable_for_symbol(self, pricess): xlon = prices.calendars["AZN.L"] common_index = xnys.opens[slc].index.intersection(xlon.opens[slc].index) - delta = pd.Timedelta(2, "H") + delta = pd.Timedelta(2, "h") # don't use first index for i in reversed(range(len(common_index) - 1)): @@ -1186,7 +1186,7 @@ def test_start_end_session_minutes(self, pricess, one_min): interval = prices.BaseInterval.T5 _, slc = get_data_bounds(prices, interval) - delta = pd.Timedelta(20, "T") + delta = pd.Timedelta(20, "min") start = cc.opens[slc].iloc[0] + delta end = cc.closes[slc].iloc[-1] - delta @@ -1244,7 +1244,7 @@ def test_start_end_non_session_minutes( start = xlon.session_open(session_start) end = xnys.session_close(session_end) df = prices._request_data(interval, start, end) - delta = pd.Timedelta(20, "T") + delta = pd.Timedelta(20, "min") start_ = start - delta end_ = end + delta df_not_mins = prices._request_data(interval, start_, end_) @@ -1266,7 +1266,7 @@ def test_start_end_non_session_minutes( def test_start_none(self, pricess): """Verify as expected when start is None.""" prices = pricess["inc_247"] - end = pd.Timestamp.now().floor("T") + end = pd.Timestamp.now().floor("min") start = None for interval in prices.BaseInterval[:-1]: match = ( @@ -1282,7 +1282,7 @@ def test_live_indice(self, pricess): prices = pricess["inc_247"] start = pd.Timestamp.now(tz=UTC).floor("D") - pd.Timedelta(2, "D") for interval in prices.BaseInterval[:-1]: - now = pd.Timestamp.now(tz=UTC).floor("T") + now = pd.Timestamp.now(tz=UTC).floor("min") end = now + interval df = prices._request_data(interval, start, end) num_rows = (now - start) / interval @@ -1295,7 +1295,7 @@ def test_live_indice(self, pricess): prices = m.PricesYahoo(symbol, calendars="24/7", delays=delay_mins) cal = prices.calendars[symbol] cc = calutils.CompositeCalendar([cal]) - delay = pd.Timedelta(delay_mins, "T") + delay = pd.Timedelta(delay_mins, "min") start = pd.Timestamp.now(tz=UTC).floor("D") - pd.Timedelta(2, "D") pp = { "minutes": 0, @@ -1314,7 +1314,7 @@ def test_live_indice(self, pricess): ) (_, end), _ = drg.daterange df = prices._request_data(interval, start, end) - now = pd.Timestamp.now(tz=UTC).floor("T") + now = pd.Timestamp.now(tz=UTC).floor("min") num_rows = (now - delay - start) / interval num_rows = np.ceil(num_rows) if num_rows % 1 else num_rows + 1 expected_end = start + (num_rows * interval) @@ -1329,7 +1329,7 @@ def test_one_min_interval(self, pricess): prices = pricess["only_247"] interval = prices.BaseInterval.T1 for days in [5, 6, 7, 11, 12, 13]: - end = pd.Timestamp.now(tz=UTC).ceil("T") + end = pd.Timestamp.now(tz=UTC).ceil("min") start = end - pd.Timedelta(days, "D") df = prices._request_data(interval, start, end) num_expected_rows = days * 24 * 60 @@ -1417,22 +1417,22 @@ def assertions( prices = pricess["us"] symbol = prices.symbols[0] cal = prices.calendars[symbol] - now = pd.Timestamp.now(UTC).floor("T") + now = pd.Timestamp.now(UTC).floor("min") session = cal.minute_to_past_session(now, 2) session = get_valid_session(session, cal, "previous") # extra 30T to cover unaligned end of 1H interval - end = cal.session_close(session) + pd.Timedelta(30, "T") - start = cal.session_open(session) + pd.Timedelta(1, "H") + end = cal.session_close(session) + pd.Timedelta(30, "min") + start = cal.session_open(session) + pd.Timedelta(1, "h") assertions(prices, start, end) # Verify for lon prices prices = m.PricesYahoo("AZN.L", calendars="XLON", delays=15) cal = prices.calendars["AZN.L"] - now = pd.Timestamp.now(UTC).floor("T") + now = pd.Timestamp.now(UTC).floor("min") session = cal.minute_to_past_session(now, 2) session = get_valid_session(session, cal, "previous") # extra 30T to cover unaligned end of 1H interval - end = cal.session_close(session) + pd.Timedelta(30, "T") + end = cal.session_close(session) + pd.Timedelta(30, "min") start = cal.session_open(session) prev_close = cal.previous_close(session) assertions(prices, start, end, prev_close) diff --git a/tests/utils.py b/tests/utils.py index 075d678..f6014b9 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -179,7 +179,7 @@ def save_resource_pbt( now = pd.Timestamp.now(tz=UTC) prices.request_all_prices() - if pd.Timestamp.now(tz=UTC).floor("T") != now.floor("T"): + if pd.Timestamp.now(tz=UTC).floor("min") != now.floor("min"): remove_resource_pbt(key, store_only=True) raise RuntimeError( "Operation aborted as unable to get all data within the same minute." @@ -308,8 +308,8 @@ class Answers: # pylint: disable=too-many-public-methods - ONE_MIN = pd.Timedelta(1, "T") - TWO_MIN = pd.Timedelta(2, "T") + ONE_MIN = pd.Timedelta(1, "min") + TWO_MIN = pd.Timedelta(2, "min") ONE_DAY = pd.Timedelta(1, "D") LEFT_SIDES = ["left", "both"] @@ -482,10 +482,10 @@ def get_sessions_minutes( self.first_pm_minutes[indexer], ): if pd.isna(last_am): - dtis.append(pd.date_range(first, last, freq="T")) + dtis.append(pd.date_range(first, last, freq="min")) else: - dtis.append(pd.date_range(first, last_am, freq="T")) - dtis.append(pd.date_range(first_pm, last, freq="T")) + dtis.append(pd.date_range(first, last_am, freq="min")) + dtis.append(pd.date_range(first_pm, last, freq="min")) index = pdutils.indexes_union(dtis) assert isinstance(index, pd.DatetimeIndex) @@ -519,11 +519,11 @@ def get_session_minutes( first_pm = self.first_pm_minutes[session] if pd.isna(last_am) or ignore_breaks: - return (pd.date_range(first, last, freq="T"),) + return (pd.date_range(first, last, freq="min"),) else: return ( - pd.date_range(first, last_am, freq="T"), - pd.date_range(first_pm, last, freq="T"), + pd.date_range(first, last_am, freq="min"), + pd.date_range(first_pm, last, freq="min"), ) def get_session_break_minutes(self, session: pd.Timestamp) -> pd.DatetimeIndex: @@ -536,7 +536,7 @@ def get_session_break_minutes(self, session: pd.Timestamp) -> pd.DatetimeIndex: am_mins, pm_mins = minutes # pylint: disable=unbalanced-tuple-unpacking first = am_mins[-1] + self.ONE_MIN last = pm_mins[0] - self.ONE_MIN - return pd.date_range(first, last, freq="T") + return pd.date_range(first, last, freq="min") def get_session_edge_minutes( self, session: pd.Timestamp, delta: int | pd.Timedelta = 0 @@ -551,7 +551,7 @@ def get_session_edge_minutes( VERIFIED by this method. """ if isinstance(delta, int): - delta = pd.Timedelta(delta, "T") + delta = pd.Timedelta(delta, "min") first_minute = self.first_minutes[session] last_minute = self.last_minutes[session] has_break = self.session_has_break(session) @@ -809,7 +809,7 @@ def _mask_sessions_without_gap_after(self) -> pd.Series: # a trading minute cannot be a minute of more than one session. assert not (self.closes == self.opens.shift(-1)).any() # there will be no gap if next open is one minute after previous close - closes_plus_min = self.closes + pd.Timedelta(1, "T") + closes_plus_min = self.closes + pd.Timedelta(1, "min") return self.opens.shift(-1) == closes_plus_min else: @@ -826,7 +826,7 @@ def _mask_sessions_without_gap_before(self) -> pd.Series: # a trading minute cannot be a minute of more than one session. assert not (self.closes == self.opens.shift(-1)).any() # there will be no gap if previous close is one minute before next open - opens_minus_one = self.opens - pd.Timedelta(1, "T") + opens_minus_one = self.opens - pd.Timedelta(1, "min") return self.closes.shift(1) == opens_minus_one else: @@ -923,10 +923,10 @@ def _get_sessions_with_times_different_to_next_session( column_ = column_.ffill().bfill() diff = (column_.shift(-1) - column_)[:-1] - remainder = diff % pd.Timedelta(24, "H") + remainder = diff % pd.Timedelta(24, "h") mask = remainder != pd.Timedelta(0) sessions = self.sessions[:-1][mask] - next_session_earlier_mask = remainder[mask] > pd.Timedelta(12, "H") + next_session_earlier_mask = remainder[mask] > pd.Timedelta(12, "h") next_session_earlier = sessions[next_session_earlier_mask] next_session_later = sessions[~next_session_earlier_mask] @@ -1567,7 +1567,7 @@ def non_trading_minutes_only(self) -> abc.Iterator[pd.Timestamp]: def _trading_minute_to_break_minute( self, sessions, break_sessions ) -> list[list[pd.Timestamp]]: - times = (self.last_am_minutes[break_sessions] + pd.Timedelta(1, "T")).dt.time + times = (self.last_am_minutes[break_sessions] + pd.Timedelta(1, "min")).dt.time mask = (self.first_minutes[sessions].dt.time.values < times.values) & ( times.values < self.last_minutes[sessions].dt.time.values