PYield 0.2.5__tar.gz → 0.2.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyield-0.2.5 → pyield-0.2.7}/PKG-INFO +42 -28
- {pyield-0.2.5 → pyield-0.2.7}/README.md +41 -27
- {pyield-0.2.5 → pyield-0.2.7}/pyield/__about__.py +1 -1
- {pyield-0.2.5 → pyield-0.2.7}/pyield/br_calendar.py +23 -20
- {pyield-0.2.5 → pyield-0.2.7}/pyield/di_futures.py +4 -3
- pyield-0.2.5/pyield/br_holidays.txt → pyield-0.2.7/pyield/new_br_holidays.txt +1 -1
- {pyield-0.2.5 → pyield-0.2.7}/pyproject.toml +1 -1
- {pyield-0.2.5 → pyield-0.2.7}/LICENSE +0 -0
- {pyield-0.2.5 → pyield-0.2.7}/pyield/__init__.py +0 -0
- /pyield-0.2.5/pyield/br_holidays_old.txt → /pyield-0.2.7/pyield/old_br_holidays.txt +0 -0
- {pyield-0.2.5 → pyield-0.2.7}/tests/__init__.py +0 -0
- {pyield-0.2.5 → pyield-0.2.7}/tests/test_br_calendar.py +0 -0
- {pyield-0.2.5 → pyield-0.2.7}/tests/test_di.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PYield
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.7
|
|
4
4
|
Summary: A Python library for analysis of fixed income instruments in Brazil
|
|
5
5
|
Keywords: fixed-income, brazil, finance, analysis, bonds
|
|
6
6
|
Author-Email: Carlos Carvalho <cr.cj@outlook.com>
|
|
@@ -62,38 +62,52 @@ You can install PYield using pip:
|
|
|
62
62
|
```sh
|
|
63
63
|
pip install pyield
|
|
64
64
|
```
|
|
65
|
-
##
|
|
65
|
+
## How to use PYield
|
|
66
|
+
### Getting DI Futures Data
|
|
67
|
+
```python
|
|
68
|
+
import pyield as pyd
|
|
69
|
+
|
|
70
|
+
# Get a pandas dataframe with the DI raw data from B3 (first date available is 05-06-1991)
|
|
71
|
+
>>> pyd.di(reference_date='2024-01-15', raw=True)
|
|
72
|
+
VENCTO CONTR. ABERT.(1) ... ÚLT.OF. COMPRA ÚLT.OF. VENDA
|
|
73
|
+
G24 796903 ... 11.650 11.656
|
|
74
|
+
H24 548377 ... 11.346 11.352
|
|
75
|
+
... ... ... ... ...
|
|
76
|
+
|
|
77
|
+
# Get a pandas dataframe with the DI processed data from B3 (default)
|
|
78
|
+
>>> pyd.di(reference_date='2024-01-15')
|
|
79
|
+
contract_code expiration bdays ... last_offer settlement_rate
|
|
80
|
+
G24 2024-02-01 13 ... 11.656 11.650
|
|
81
|
+
H24 2024-03-01 32 ... 11.352 11.349
|
|
82
|
+
... ... ... ... ... ...
|
|
83
|
+
```
|
|
84
|
+
### Business Days Tools (Brazilian holidays are automatically considered)
|
|
85
|
+
```python
|
|
86
|
+
# Generate a pandas series with the business days between two dates
|
|
87
|
+
>>> pyd.generate_bdays(start='2023-12-29', end='2024-01-03')
|
|
88
|
+
0 2023-12-29
|
|
89
|
+
1 2024-01-02
|
|
90
|
+
2 2024-01-03
|
|
91
|
+
dtype: datetime64[ns]
|
|
66
92
|
|
|
67
|
-
|
|
93
|
+
# Get the next business day after a given date (offset=1)
|
|
94
|
+
>>> pyd.offset_bdays(dates="2023-12-29", offset=1)
|
|
95
|
+
Timestamp('2024-01-02 00:00:00')
|
|
68
96
|
|
|
69
|
-
|
|
70
|
-
|
|
97
|
+
# Get the next business day if it is not a business day (offset=0)
|
|
98
|
+
>>> pyd.offset_bdays(dates="2023-12-30", offset=0)
|
|
99
|
+
Timestamp('2024-01-02 00:00:00')
|
|
71
100
|
|
|
72
|
-
#
|
|
73
|
-
|
|
101
|
+
# Since 2023-12-29 is a business day, it returns the same date (offset=0)
|
|
102
|
+
>>> pyd.offset_bdays(dates="2023-12-29", offset=0)
|
|
103
|
+
Timestamp('2023-12-29 00:00:00')
|
|
74
104
|
|
|
75
|
-
# Get DI processed data from B3 (default)
|
|
76
|
-
df_di = yd.di(reference_date='2023-12-28')
|
|
77
|
-
```
|
|
78
105
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
F24 2024-01-02 2 ... 11.636 11.650 11.634
|
|
85
|
-
G24 2024-02-01 24 ... 11.644 11.646 11.648
|
|
86
|
-
H24 2024-03-01 43 ... - 11.426 11.425
|
|
87
|
-
J24 2024-04-01 63 ... 11.285 11.290 11.290
|
|
88
|
-
K24 2024-05-02 85 ... - - 11.121
|
|
89
|
-
M24 2024-06-03 106 ... 10.900 11.000 10.960
|
|
90
|
-
... ... ... ... ... ... ...
|
|
91
|
-
F33 2033-01-03 2260 ... 10.350 10.380 10.363
|
|
92
|
-
F34 2034-01-02 2511 ... - - 10.365
|
|
93
|
-
F35 2035-01-02 2759 ... - - 10.389
|
|
94
|
-
F36 2036-01-02 3008 ... - - 10.395
|
|
95
|
-
F37 2037-01-02 3261 ... - - 10.414
|
|
96
|
-
F38 2038-01-04 3510 ... - - 10.414
|
|
106
|
+
# Count the number of business days between two dates
|
|
107
|
+
# Start date is included, end date is excluded
|
|
108
|
+
>>> pyd.count_bdays(start='2023-12-29', end='2024-01-02')
|
|
109
|
+
1
|
|
110
|
+
|
|
97
111
|
```
|
|
98
112
|
|
|
99
113
|
## Documentation
|
|
@@ -20,38 +20,52 @@ You can install PYield using pip:
|
|
|
20
20
|
```sh
|
|
21
21
|
pip install pyield
|
|
22
22
|
```
|
|
23
|
-
##
|
|
23
|
+
## How to use PYield
|
|
24
|
+
### Getting DI Futures Data
|
|
25
|
+
```python
|
|
26
|
+
import pyield as pyd
|
|
27
|
+
|
|
28
|
+
# Get a pandas dataframe with the DI raw data from B3 (first date available is 05-06-1991)
|
|
29
|
+
>>> pyd.di(reference_date='2024-01-15', raw=True)
|
|
30
|
+
VENCTO CONTR. ABERT.(1) ... ÚLT.OF. COMPRA ÚLT.OF. VENDA
|
|
31
|
+
G24 796903 ... 11.650 11.656
|
|
32
|
+
H24 548377 ... 11.346 11.352
|
|
33
|
+
... ... ... ... ...
|
|
34
|
+
|
|
35
|
+
# Get a pandas dataframe with the DI processed data from B3 (default)
|
|
36
|
+
>>> pyd.di(reference_date='2024-01-15')
|
|
37
|
+
contract_code expiration bdays ... last_offer settlement_rate
|
|
38
|
+
G24 2024-02-01 13 ... 11.656 11.650
|
|
39
|
+
H24 2024-03-01 32 ... 11.352 11.349
|
|
40
|
+
... ... ... ... ... ...
|
|
41
|
+
```
|
|
42
|
+
### Business Days Tools (Brazilian holidays are automatically considered)
|
|
43
|
+
```python
|
|
44
|
+
# Generate a pandas series with the business days between two dates
|
|
45
|
+
>>> pyd.generate_bdays(start='2023-12-29', end='2024-01-03')
|
|
46
|
+
0 2023-12-29
|
|
47
|
+
1 2024-01-02
|
|
48
|
+
2 2024-01-03
|
|
49
|
+
dtype: datetime64[ns]
|
|
24
50
|
|
|
25
|
-
|
|
51
|
+
# Get the next business day after a given date (offset=1)
|
|
52
|
+
>>> pyd.offset_bdays(dates="2023-12-29", offset=1)
|
|
53
|
+
Timestamp('2024-01-02 00:00:00')
|
|
26
54
|
|
|
27
|
-
|
|
28
|
-
|
|
55
|
+
# Get the next business day if it is not a business day (offset=0)
|
|
56
|
+
>>> pyd.offset_bdays(dates="2023-12-30", offset=0)
|
|
57
|
+
Timestamp('2024-01-02 00:00:00')
|
|
29
58
|
|
|
30
|
-
#
|
|
31
|
-
|
|
59
|
+
# Since 2023-12-29 is a business day, it returns the same date (offset=0)
|
|
60
|
+
>>> pyd.offset_bdays(dates="2023-12-29", offset=0)
|
|
61
|
+
Timestamp('2023-12-29 00:00:00')
|
|
32
62
|
|
|
33
|
-
# Get DI processed data from B3 (default)
|
|
34
|
-
df_di = yd.di(reference_date='2023-12-28')
|
|
35
|
-
```
|
|
36
63
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
F24 2024-01-02 2 ... 11.636 11.650 11.634
|
|
43
|
-
G24 2024-02-01 24 ... 11.644 11.646 11.648
|
|
44
|
-
H24 2024-03-01 43 ... - 11.426 11.425
|
|
45
|
-
J24 2024-04-01 63 ... 11.285 11.290 11.290
|
|
46
|
-
K24 2024-05-02 85 ... - - 11.121
|
|
47
|
-
M24 2024-06-03 106 ... 10.900 11.000 10.960
|
|
48
|
-
... ... ... ... ... ... ...
|
|
49
|
-
F33 2033-01-03 2260 ... 10.350 10.380 10.363
|
|
50
|
-
F34 2034-01-02 2511 ... - - 10.365
|
|
51
|
-
F35 2035-01-02 2759 ... - - 10.389
|
|
52
|
-
F36 2036-01-02 3008 ... - - 10.395
|
|
53
|
-
F37 2037-01-02 3261 ... - - 10.414
|
|
54
|
-
F38 2038-01-04 3510 ... - - 10.414
|
|
64
|
+
# Count the number of business days between two dates
|
|
65
|
+
# Start date is included, end date is excluded
|
|
66
|
+
>>> pyd.count_bdays(start='2023-12-29', end='2024-01-02')
|
|
67
|
+
1
|
|
68
|
+
|
|
55
69
|
```
|
|
56
70
|
|
|
57
71
|
## Documentation
|
|
@@ -2,8 +2,8 @@ from pathlib import Path
|
|
|
2
2
|
import pandas as pd
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
5
|
-
new_holidays_path = Path(__file__).parent / "
|
|
6
|
-
old_holidays_path = Path(__file__).parent / "
|
|
5
|
+
new_holidays_path = Path(__file__).parent / "new_br_holidays.txt"
|
|
6
|
+
old_holidays_path = Path(__file__).parent / "old_br_holidays.txt"
|
|
7
7
|
|
|
8
8
|
df_new = pd.read_csv(new_holidays_path, header=None, names=["date"], comment="#")
|
|
9
9
|
df_old = pd.read_csv(old_holidays_path, header=None, names=["date"], comment="#")
|
|
@@ -12,13 +12,12 @@ df_new["date"] = pd.to_datetime(df_new["date"], format="%d/%m/%Y")
|
|
|
12
12
|
df_old["date"] = pd.to_datetime(df_old["date"], format="%d/%m/%Y")
|
|
13
13
|
|
|
14
14
|
# Using numpy datetime64[D] array increases performance by almost 10x
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
BR_HOLIDAYS_OLD = df_old["date"].values.astype("datetime64[D]")
|
|
15
|
+
NEW_BR_HOLIDAYS = df_new["date"].values.astype("datetime64[D]")
|
|
16
|
+
OLD_BR_HOLIDAYS = df_old["date"].values.astype("datetime64[D]")
|
|
18
17
|
|
|
19
18
|
|
|
20
19
|
def offset_bdays(
|
|
21
|
-
dates: str | pd.Timestamp, offset: int, holiday_list: np.ndarray =
|
|
20
|
+
dates: str | pd.Timestamp, offset: int, holiday_list: np.ndarray = NEW_BR_HOLIDAYS
|
|
22
21
|
):
|
|
23
22
|
"""
|
|
24
23
|
Offsets the dates to the next or previous business day. This function is a wrapper
|
|
@@ -40,16 +39,15 @@ def offset_bdays(
|
|
|
40
39
|
https://numpy.org/doc/stable/reference/generated/numpy.busday_offset.html.
|
|
41
40
|
|
|
42
41
|
Examples:
|
|
43
|
-
>>> import pandas as pd
|
|
44
42
|
>>> date = '2023-12-23' # Saturday before Christmas
|
|
45
|
-
>>> offset_bdays(date, 0)
|
|
43
|
+
>>> pyd.offset_bdays(date, 0)
|
|
46
44
|
Timestamp('2023-12-26')
|
|
47
45
|
>>> date = '2023-12-22' # Friday before Christmas
|
|
48
|
-
>>> offset_bdays(date, 0)
|
|
46
|
+
>>> pyd.offset_bdays(date, 0)
|
|
49
47
|
Timestamp('2023-12-22') # No offset because it's a business day
|
|
50
|
-
>>> offset_bdays(date, 1)
|
|
48
|
+
>>> pyd.offset_bdays(date, 1)
|
|
51
49
|
Timestamp('2023-12-26') # Offset to the next business day
|
|
52
|
-
>>> offset_bdays(date, -1)
|
|
50
|
+
>>> pyd.offset_bdays(date, -1)
|
|
53
51
|
Timestamp('2023-12-21') # Offset to the previous business day
|
|
54
52
|
"""
|
|
55
53
|
# Convert to pandas datetime64[ns]
|
|
@@ -58,6 +56,7 @@ def offset_bdays(
|
|
|
58
56
|
dates = pd.Series(dates)
|
|
59
57
|
# Convert to numpy data types
|
|
60
58
|
dates = dates.values.astype("datetime64[D]")
|
|
59
|
+
|
|
61
60
|
# Adjust the dates according to the offset
|
|
62
61
|
adj_dates = np.busday_offset(
|
|
63
62
|
dates, offsets=offset, roll="forward", holidays=holiday_list
|
|
@@ -66,9 +65,11 @@ def offset_bdays(
|
|
|
66
65
|
adj_dates = pd.to_datetime(adj_dates, unit="ns")
|
|
67
66
|
# Convert back to Series
|
|
68
67
|
adj_dates = pd.Series(adj_dates)
|
|
68
|
+
|
|
69
69
|
# Return a single value if a single value was passed
|
|
70
70
|
if len(adj_dates) == 1:
|
|
71
71
|
adj_dates = adj_dates[0]
|
|
72
|
+
|
|
72
73
|
return adj_dates
|
|
73
74
|
|
|
74
75
|
|
|
@@ -97,15 +98,14 @@ def count_bdays(start, end):
|
|
|
97
98
|
selected. Otherwise, the new list is be used.
|
|
98
99
|
|
|
99
100
|
Examples:
|
|
100
|
-
>>> import pandas as pd
|
|
101
101
|
>>> start = '2023-12-15'
|
|
102
102
|
>>> end = '2024-01-01'
|
|
103
|
-
>>> count_bdays(start, end)
|
|
103
|
+
>>> pyd.count_bdays(start, end)
|
|
104
104
|
10
|
|
105
105
|
|
|
106
106
|
>>> start = '2023-01-01'
|
|
107
107
|
>>> end = pd.Series('2023-01-31', '2023-03-01'])
|
|
108
|
-
>>> count_bdays(start, end)
|
|
108
|
+
>>> pyd.count_bdays(start, end)
|
|
109
109
|
array([22, 40])
|
|
110
110
|
"""
|
|
111
111
|
# Convert to pandas Timestamp
|
|
@@ -121,15 +121,19 @@ def count_bdays(start, end):
|
|
|
121
121
|
# Determine which list of holidays to use
|
|
122
122
|
cutoff_date = np.datetime64("2023-12-26", "D")
|
|
123
123
|
if start < cutoff_date:
|
|
124
|
-
holiday_list =
|
|
124
|
+
holiday_list = OLD_BR_HOLIDAYS
|
|
125
125
|
else:
|
|
126
|
-
holiday_list =
|
|
126
|
+
holiday_list = NEW_BR_HOLIDAYS
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
bdays = np.busday_count(start, end, holidays=holiday_list)
|
|
129
|
+
# Return a single value if a single value was passed
|
|
130
|
+
if len(bdays) == 1:
|
|
131
|
+
bdays = bdays[0]
|
|
132
|
+
return bdays
|
|
129
133
|
|
|
130
134
|
|
|
131
135
|
def generate_bdays(
|
|
132
|
-
start=None, end=None, inclusive="both", holiday_list=
|
|
136
|
+
start=None, end=None, inclusive="both", holiday_list=NEW_BR_HOLIDAYS, **kwargs
|
|
133
137
|
):
|
|
134
138
|
"""
|
|
135
139
|
Generates a Series of business days between a `start` (inclusive) and
|
|
@@ -149,10 +153,9 @@ def generate_bdays(
|
|
|
149
153
|
https://pandas.pydata.org/docs/reference/api/pandas.bdate_range.html#
|
|
150
154
|
|
|
151
155
|
Examples:
|
|
152
|
-
>>> import pandas as pd
|
|
153
156
|
>>> start = '2023-12-20'
|
|
154
157
|
>>> end = '2024-01-05'
|
|
155
|
-
>>> generate_bdays(start, end)
|
|
158
|
+
>>> pyd.generate_bdays(start, end)
|
|
156
159
|
2023-12-15 2023-12-15
|
|
157
160
|
2023-12-18 2023-12-18
|
|
158
161
|
2023-12-19 2023-12-19
|
|
@@ -63,7 +63,7 @@ def get_old_expiration_date(
|
|
|
63
63
|
expiration = pd.Timestamp(year, month, 1)
|
|
64
64
|
# Adjust to the next business day when expiration date is a weekend or a holiday
|
|
65
65
|
# Must use the old holiday calendar, since this type of contract code was used until 2006
|
|
66
|
-
return bc.offset_bdays(expiration, offset=0, holiday_list=bc.
|
|
66
|
+
return bc.offset_bdays(expiration, offset=0, holiday_list=bc.OLD_BR_HOLIDAYS)
|
|
67
67
|
|
|
68
68
|
except (KeyError, ValueError):
|
|
69
69
|
return pd.NaT
|
|
@@ -130,7 +130,7 @@ def get_expiration_date(contract_code: str) -> pd.Timestamp:
|
|
|
130
130
|
expiration = pd.Timestamp(year, month, 1)
|
|
131
131
|
# Adjust to the next business day when expiration date is a weekend or a holiday
|
|
132
132
|
# Only the new holiday calendar is used, see docstring for more details
|
|
133
|
-
return bc.offset_bdays(expiration, offset=0, holiday_list=bc.
|
|
133
|
+
return bc.offset_bdays(expiration, offset=0, holiday_list=bc.NEW_BR_HOLIDAYS)
|
|
134
134
|
|
|
135
135
|
except (KeyError, ValueError):
|
|
136
136
|
return pd.NaT
|
|
@@ -300,6 +300,8 @@ def process_di_data(df: pd.DataFrame, reference_date: pd.Timestamp) -> pd.DataFr
|
|
|
300
300
|
"number_of_trades",
|
|
301
301
|
"trading_volume",
|
|
302
302
|
"financial_volume",
|
|
303
|
+
"settlement_price",
|
|
304
|
+
"settlement_rate",
|
|
303
305
|
"opening_rate",
|
|
304
306
|
"min_rate",
|
|
305
307
|
"max_rate",
|
|
@@ -307,7 +309,6 @@ def process_di_data(df: pd.DataFrame, reference_date: pd.Timestamp) -> pd.DataFr
|
|
|
307
309
|
"closing_rate",
|
|
308
310
|
"last_bid",
|
|
309
311
|
"last_offer",
|
|
310
|
-
"settlement_rate",
|
|
311
312
|
]
|
|
312
313
|
]
|
|
313
314
|
return df
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Data Source: https://www.anbima.com.br/feriados/feriados.asp
|
|
3
3
|
# Direct link to the ANBIMA file: https://www.anbima.com.br/feriados/arqs/feriados_nacionais.xls
|
|
4
4
|
# In december 2023, a new holiday was added: "Dia Nacional de Zumbi"
|
|
5
|
-
# Note: dates until 22-12-2023 (inclusive) must use "
|
|
5
|
+
# Note: dates until 22-12-2023 (inclusive) must use "old_br_holidays.txt" list
|
|
6
6
|
01/01/2001
|
|
7
7
|
26/02/2001
|
|
8
8
|
27/02/2001
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|