Skip to content

Commit b1e3c24

Browse files
committed
Fix pandas 2.2. deprecation warnings
Fixes pandas 2.2 deprecation warnings concerning deprecation of frequency units "T", "H" and "S" in favor of "min", "h" and "s".
1 parent 07091ff commit b1e3c24

30 files changed

+517
-489
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ The above call was made 21 minutes after the NYSE open. Notice that the call ret
4747
Any interval can be evaluated (limited only by the availability of underlying data).
4848
```python
4949
>>> # prices over a specific session at 68 minute intervals
50-
>>> prices.get("68T", start="2022-06-27", end="2022-06-27", force=True)
50+
>>> prices.get("68min", start="2022-06-27", end="2022-06-27", force=True)
5151
```
5252
```
5353
symbol MSFT
@@ -108,7 +108,7 @@ Although some indices are longer than three calendar days, they all comprise of
108108
)
109109
>>> # lead_symbol determines the exchange against which the period will be evaluated and
110110
>>> # the default output time zone (which for Bitcoin is UTC).
111-
>>> prices_mult.get("90T", hours=9, lead_symbol="BTC-USD")
111+
>>> prices_mult.get("90min", hours=9, lead_symbol="BTC-USD")
112112
```
113113
```
114114
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
127127
The `get` method has plenty of options to customize the output, including `fill` to fill in indices when an exchange is closed...
128128
```python
129129
>>> # as before, only now filling in prices when exchanges are closed
130-
>>> prices_mult.get("90T", hours=9, lead_symbol="BTC-USD", fill="both")
130+
>>> prices_mult.get("90min", hours=9, lead_symbol="BTC-USD", fill="both")
131131
```
132132
```
133133
symbol MSFT 9988.HK BTC-USD

src/market_prices/data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ def _requested_dates_adjust(self, dr: DateRangeReq) -> DateRangeReq | None:
659659
elif self.bi.is_intraday:
660660
assert self._delay is not None
661661
# ten minutes to cover provider delays in publishing data.
662-
rerequest_from = helpers.now() - self._delay - pd.Timedelta(10, "T")
662+
rerequest_from = helpers.now() - self._delay - pd.Timedelta(10, "min")
663663
if end < rerequest_from:
664664
return dr
665665
excess = end - rerequest_from

src/market_prices/daterange.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,7 @@ def end_now(self) -> tuple[pd.Timestamp, pd.Timestamp]:
866866
# which the end is accurate as at the moment the end is requested.
867867
# (without the + one minute would be ignoring those price that have
868868
# come in since the current minute started.)
869-
end_accuracy = min(end_accuracy, now + pd.Timedelta("1T"))
869+
end_accuracy = min(end_accuracy, now + pd.Timedelta("1min"))
870870
return end, end_accuracy
871871

872872
def _trading_index(
@@ -1055,7 +1055,7 @@ def _offset_days(self, ts: pd.Timestamp, days: int) -> pd.Timestamp:
10551055

10561056
# "previous" to cover ts as close (not a trading minute).
10571057
session = self.cal.minute_to_session(ts, "previous")
1058-
schedule_vals = self.cal.schedule.loc[session].dropna().view(np.int64).values
1058+
schedule_vals = self.cal.schedule.loc[session].dropna().astype(np.int64).values
10591059
if ts.value in schedule_vals:
10601060
target_i = self.cal.sessions.get_loc(session) + days
10611061

@@ -1199,7 +1199,7 @@ def daterange(self) -> tuple[mptypes.DateRange, pd.Timestamp]:
11991199
if intraday_duration:
12001200
if intraday_duration < self.final_interval.as_minutes:
12011201
raise errors.PricesUnavailableIntervalDurationError(
1202-
pd.Timedelta(intraday_duration, "T"), self
1202+
pd.Timedelta(intraday_duration, "min"), self
12031203
)
12041204
if start is None:
12051205
end_ = end
@@ -1269,7 +1269,7 @@ def daterange(self) -> tuple[mptypes.DateRange, pd.Timestamp]:
12691269
else:
12701270
minutes = calutils.minutes_in_period(self.cal, start, end_)
12711271
if self.final_interval.as_minutes > minutes:
1272-
period_duration = pd.Timedelta(minutes, "T")
1272+
period_duration = pd.Timedelta(minutes, "min")
12731273
raise errors.PricesUnavailableIntervalPeriodError(
12741274
self, start, end_, period_duration
12751275
)

src/market_prices/errors.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -872,10 +872,10 @@ class PricesMissingWarning(PricesWarning):
872872

873873
def __init__(self, symbol: str, bi: BI, sessions: pd.DatetimeIndex, source: str):
874874
date_format = "%Y-%m-%d"
875-
sessions = sessions.format(date_format=date_format)
875+
sessions_ = sessions.strftime(date_format).tolist()
876876
self._msg = (
877877
f"Prices from {source} are missing for '{symbol}' at the"
878-
f" base interval '{bi}' for the following sessions: {sessions}."
878+
f" base interval '{bi}' for the following sessions: {sessions_}."
879879
)
880880

881881

src/market_prices/helpers.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
UTC = zoneinfo.ZoneInfo("UTC")
2424

2525
ONE_DAY: pd.Timedelta = pd.Timedelta(1, "D")
26-
ONE_MIN: pd.Timedelta = pd.Timedelta(1, "T")
27-
ONE_SEC: pd.Timedelta = pd.Timedelta(1, "S")
26+
ONE_MIN: pd.Timedelta = pd.Timedelta(1, "min")
27+
ONE_SEC: pd.Timedelta = pd.Timedelta(1, "s")
2828

2929

3030
def symbols_to_list(symbols: mptypes.Symbols) -> list[str]:
@@ -155,7 +155,7 @@ def now(
155155
now_ = now_.tz_convert(None)
156156
res = "D"
157157
else:
158-
res = "T"
158+
res = "min"
159159
return now_.ceil(res) if side == "right" else now_.floor(res)
160160

161161

@@ -172,7 +172,7 @@ def extract_freq_parts(freq: str) -> tuple[int, str]:
172172
Parameters
173173
----------
174174
freq
175-
Pandas frequency, for example "5D", "30T", "4H", "33MS".
175+
Pandas frequency, for example "5D", "30min", "4h", "33MS".
176176
177177
Raises
178178
------
@@ -192,8 +192,8 @@ def extract_freq_parts(freq: str) -> tuple[int, str]:
192192
193193
Examples
194194
--------
195-
>>> extract_freq_parts("22T")
196-
(22, 'T')
195+
>>> extract_freq_parts("22min")
196+
(22, 'min')
197197
>>> extract_freq_parts("1m")
198198
(1, 'm')
199199
>>> extract_freq_parts("D")

src/market_prices/intervals.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ def as_pdtd(self) -> pd.Timedelta:
5151
return pd.Timedelta(self)
5252

5353
@property
54-
def freq_unit(self) -> typing.Literal["T", "H", "D"]:
54+
def freq_unit(self) -> typing.Literal["min", "h", "D"]:
5555
"""Return unit of pandas frequency represented by the member.
5656
57-
Returns either "T", "H" or "D".
57+
Returns either "min", "h" or "D".
5858
"""
5959
return self.as_pdtd.resolution_string
6060

@@ -64,7 +64,7 @@ def freq_value(self) -> int:
6464
components = self.as_pdtd.components
6565
if self.freq_unit == "D":
6666
return components.days
67-
elif self.freq_unit == "H":
67+
elif self.freq_unit == "h":
6868
return components.hours
6969
else:
7070
return components.minutes + (components.hours * 60)
@@ -74,7 +74,7 @@ def is_intraday(self) -> bool:
7474
"""Query if a member represents an intraday interval.
7575
7676
An interval is considered to be intraday if it is shorter than one
77-
day. The unit of intraday intervals will be either "T" or "H".
77+
day. The unit of intraday intervals will be either "min" or "h".
7878
"""
7979
return self < helpers.ONE_DAY
8080

@@ -126,7 +126,7 @@ def as_offset(
126126
calendar
127127
Calendar against which to evaluate custom business day for
128128
intervals with `self.freq_unit` as "D". Not required for
129-
intervals with `self.freq_unit` as "T" or "H".
129+
intervals with `self.freq_unit` as "min" or "h".
130130
131131
one_less
132132
If `self.freq_unit` is "D" then:
@@ -260,7 +260,7 @@ def is_intraday(self) -> bool:
260260
"""Query if a member represents an intraday interval.
261261
262262
An interval is considered to be intraday if it is shorter than one
263-
day. The unit of intraday intervals will be either "T" or "H".
263+
day. The unit of intraday intervals will be either "min" or "h".
264264
"""
265265
return False
266266

@@ -376,9 +376,9 @@ def create_base_intervals_enum(intervals: list[TDInterval]) -> _BaseInterval:
376376
for intrvl in intervals:
377377
unit, value = intrvl.freq_unit, intrvl.freq_value
378378
td_args: tuple
379-
if unit == "T":
379+
if unit == "min":
380380
td_args = (0, 0, 0, 0, value)
381-
elif unit == "H":
381+
elif unit == "h":
382382
td_args = (0, 0, 0, 0, 0, value)
383383
else:
384384
if intrvl is not TDInterval.D1:
@@ -432,6 +432,8 @@ def to_ptinterval(interval: str | timedelta | pd.Timedelta) -> PTInterval:
432432
f"`interval` unit must by one of {valid_units} (or lower-"
433433
f"case) although evaluated to '{unit}'."
434434
)
435+
if unit == "MIN":
436+
unit = "T"
435437

436438
else:
437439
if interval <= timedelta(0):
@@ -448,7 +450,7 @@ def to_ptinterval(interval: str | timedelta | pd.Timedelta) -> PTInterval:
448450
' example "1m" for one month.'
449451
)
450452

451-
valid_resolutions = ["T", "H", "D"]
453+
valid_resolutions = ["min", "h", "D"]
452454
if interval.resolution_string not in valid_resolutions:
453455
raise ValueError(error_msg)
454456

@@ -476,8 +478,7 @@ def raise_value_oob_error(component: str, limit: int):
476478
}
477479

478480
if isinstance(interval, str):
479-
if unit == "MIN":
480-
unit = "T"
481+
481482
if value > limits[unit]:
482483
raise_value_oob_error(components[unit], limits[unit])
483484
if unit == "T" and not value % 60:
@@ -487,10 +488,12 @@ def raise_value_oob_error(component: str, limit: int):
487488

488489
else:
489490
unit = interval.resolution_string
490-
if unit == "T":
491+
if unit in ["min", "T"]: # "T" for compatibility pandas < 2.2
491492
value = int(interval.total_seconds() // 60)
492-
elif unit == "H":
493+
unit = "T"
494+
elif unit in ["h", "H"]: # "H" for compatibility pandas < 2.2
493495
value = int(interval.total_seconds() // 3600)
496+
unit = "H"
494497
else:
495498
value = interval.days
496499

src/market_prices/parsing.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,12 @@ def _parse_start_end(
200200
start_is_date = helpers.is_date(start)
201201
if not start_is_date:
202202
# do not include any incomplete minute
203-
start = start.ceil("T")
203+
start = start.ceil("min")
204204
if end is not None:
205205
end_is_date = helpers.is_date(end)
206206
if not end_is_date:
207207
# do not include incomplete minute
208-
end = end.floor("T")
208+
end = end.floor("min")
209209
# if end > now, set to None.
210210
now_interval = intervals.ONE_DAY if end_is_date else intervals.ONE_MIN
211211
now = helpers.now(now_interval, "left")

src/market_prices/prices/base.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,7 @@ def lead_symbol_default(self) -> str:
11231123

11241124
def _set_delays(self, delays: int | list[int] | dict[str, int]):
11251125
d = self._dict_for_all_symbols("delays", delays)
1126-
self._delays = {k: pd.Timedelta(v, "T") for k, v in d.items()}
1126+
self._delays = {k: pd.Timedelta(v, "min") for k, v in d.items()}
11271127

11281128
@property
11291129
def delays(self) -> dict[str, pd.Timedelta]:
@@ -1640,8 +1640,8 @@ def _set_indices_aligned(self):
16401640

16411641
index = self._trading_indexes[bi]
16421642
nano_index = index.left.asi8
1643-
opens = self.cc.opens[slc].view("int64")
1644-
closes = self.cc.closes[slc].view("int64")
1643+
opens = self.cc.opens[slc].astype("int64")
1644+
closes = self.cc.closes[slc].astype("int64")
16451645

16461646
sessions = opens.index
16471647
srs = pd.Series(True, index=sessions)
@@ -3444,20 +3444,20 @@ def get(
34443444
value:
34453445
one or more digits.
34463446
unit:
3447-
"min", "t", "MIN" or "T" for minutes
3447+
"min", "MIN", "T" or "t" for minutes
34483448
"h" or "H" for hours
34493449
"d" or "D' for days
34503450
'm' or "M" for months
34513451
34523452
Examples:
34533453
thirty minutes:
34543454
"30min", "30T"
3455-
pd.Timedelta(30, "T"), pd.Timedelta(minutes=30)
3455+
pd.Timedelta(30, "min"), pd.Timedelta(minutes=30)
34563456
timedelta(minutes=30)
34573457
34583458
three hours:
34593459
"3h", "3H"
3460-
pd.Timedelta(3, "H"), pd.Timedelta(hours=3)
3460+
pd.Timedelta(3, "h"), pd.Timedelta(hours=3)
34613461
timedelta(hours=3)
34623462
34633463
one day:
@@ -3854,8 +3854,8 @@ def get(
38543854
greater than the interval although the indice bounds
38553855
they evaluate to do not. For example, if a session
38563856
opens at 09.00, `start` is 09.01 and `end` is 09.09
3857-
then a call for data at a "5T" `interval` will evalute
3858-
the period bounds as from 09.05 through 09.05.
3857+
then a call for data at a "5min" `interval` will
3858+
evalute the period bounds as from 09.05 through 09.05.
38593859
38603860
errors.PricesUnavailableDOIntervalPeriodError:
38613861
Monthly `interval` is longer than the evaluated period.

src/market_prices/prices/yahoo.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ def _set_daily_bi_limit(self):
560560
@staticmethod
561561
def _bi_to_source_key(interval: intervals.BI) -> str:
562562
"""Map interval to value for source's interval parameter."""
563-
if interval.freq_unit == "T":
563+
if interval.freq_unit == "min":
564564
return str(interval.freq_value) + "m"
565565
else:
566566
return interval.as_pdfreq.lower() # as yahooquery value
@@ -868,6 +868,6 @@ def _request_data(
868868
# 22 hours ensures markets opening in Americas included
869869
# whilst avoiding including the following session of
870870
# Australasian markets
871-
end_ += pd.Timedelta(22, "H")
871+
end_ += pd.Timedelta(22, "h")
872872
prices = self._request_yahoo(interval=interval, start=start, end=end_)
873873
return self._tidy_yahoo(prices, interval, start, end)

0 commit comments

Comments
 (0)