PYield 0.31.0__tar.gz → 0.31.2__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.31.0 → pyield-0.31.2}/PKG-INFO +47 -44
- {pyield-0.31.0 → pyield-0.31.2}/README.md +46 -43
- pyield-0.31.2/pyield/__about__.py +1 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/__init__.py +2 -1
- {pyield-0.31.0 → pyield-0.31.2}/pyield/anbima/__init__.py +2 -1
- {pyield-0.31.0 → pyield-0.31.2}/pyield/anbima/ettj.py +58 -25
- {pyield-0.31.0 → pyield-0.31.2}/pyield/anbima/tpf.py +2 -1
- {pyield-0.31.0 → pyield-0.31.2}/pyield/tpf/lft.py +7 -6
- {pyield-0.31.0 → pyield-0.31.2}/pyield/tpf/ltn.py +16 -10
- {pyield-0.31.0 → pyield-0.31.2}/pyield/tpf/ntnb.py +36 -15
- pyield-0.31.2/pyield/tpf/ntnc.py +276 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/tpf/ntnf.py +27 -25
- {pyield-0.31.0 → pyield-0.31.2}/pyproject.toml +1 -0
- pyield-0.31.0/pyield/__about__.py +0 -1
- {pyield-0.31.0 → pyield-0.31.2}/.gitignore +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/LICENSE +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/anbima/ima.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/anbima/imaq.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/anbima/ipca.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/b3/__init__.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/b3/di.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/b3/di_over.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/b3/futures/__init__.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/b3/futures/common.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/b3/futures/historical.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/b3/futures/intraday.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/b3/futures/xml.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/bc/__init__.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/bc/auction.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/bc/bcdata.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/bc/ptax.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/bc/repo.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/bc/trade.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/bc/vna.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/bday.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/conftest.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/data_cache.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/date_converter.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/forwards.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/holidays/__init__.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/holidays/br_holidays_new.txt +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/holidays/br_holidays_old.txt +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/holidays/brholidays.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/ibge/__init__.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/ibge/ipca.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/interpolator.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/py.typed +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/retry.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/tpf/__init__.py +0 -0
- {pyield-0.31.0 → pyield-0.31.2}/pyield/tpf/tools.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PYield
|
|
3
|
-
Version: 0.31.
|
|
3
|
+
Version: 0.31.2
|
|
4
4
|
Summary: A Python library for analysis of fixed income instruments in Brazil
|
|
5
5
|
Project-URL: Source, https://github.com/crdcj/PYield
|
|
6
6
|
Author-email: Carlos Carvalho <cr.cj@outlook.com>
|
|
@@ -49,8 +49,6 @@ PYield is a Python library designed for the analysis of Brazilian fixed income i
|
|
|
49
49
|
|
|
50
50
|
Documentation: [https://crdcj.github.io/PYield/](https://crdcj.github.io/PYield/)
|
|
51
51
|
|
|
52
|
-
Source Code: [https://github.com/crdcj/PYield](https://github.com/crdcj/PYield)
|
|
53
|
-
|
|
54
52
|
## Key Features
|
|
55
53
|
|
|
56
54
|
- **Data Collection**: Automated fetching of data from ANBIMA and B3.
|
|
@@ -103,38 +101,39 @@ date = pd.to_datetime("05-31-2024", format="%m-%d-%Y")
|
|
|
103
101
|
```python
|
|
104
102
|
>>> from pyield import ntnb, ntnf, ltn
|
|
105
103
|
|
|
104
|
+
# Get ANBIMA data for a given date
|
|
105
|
+
>>> ltn.data("23-08-2024")
|
|
106
|
+
ReferenceDate BondType MaturityDate IndicativeRate Price
|
|
107
|
+
0 2024-08-23 LTN 2024-10-01 0.104416 989.415342
|
|
108
|
+
1 2024-08-23 LTN 2025-01-01 0.107171 964.293046
|
|
109
|
+
2 2024-08-23 LTN 2025-04-01 0.110866 938.943013
|
|
110
|
+
3 2024-08-23 LTN 2025-07-01 0.113032 913.849158
|
|
111
|
+
4 2024-08-23 LTN 2025-10-01 0.114374 887.394285
|
|
112
|
+
5 2024-08-23 LTN 2026-01-01 0.114654 863.026594
|
|
113
|
+
6 2024-08-23 LTN 2026-04-01 0.114997 840.232741
|
|
114
|
+
7 2024-08-23 LTN 2026-07-01 0.115265 818.020491
|
|
115
|
+
8 2024-08-23 LTN 2026-10-01 0.115357 795.185488
|
|
116
|
+
9 2024-08-23 LTN 2027-07-01 0.115335 733.981131
|
|
117
|
+
10 2024-08-23 LTN 2028-01-01 0.115694 693.647778
|
|
118
|
+
11 2024-08-23 LTN 2028-07-01 0.116417 655.6398
|
|
119
|
+
12 2024-08-23 LTN 2030-01-01 0.117436 554.331151
|
|
120
|
+
|
|
106
121
|
# Calculate the quotation of a NTN-B bond as per ANBIMA's rules
|
|
107
122
|
>>> ntnb.quotation("31-05-2024", "15-05-2035", 0.061490)
|
|
108
123
|
99.3651
|
|
109
124
|
>>> ntnb.quotation("31-05-2024", "15-08-2060", 0.061878)
|
|
110
125
|
99.5341
|
|
111
126
|
|
|
112
|
-
# Calculate the DI Spread of NTN-F bonds in a given date
|
|
113
|
-
>>> ntnf.di_spreads("
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
# Get ANBIMA's indicative rates for LTN bonds
|
|
123
|
-
>>> ltn.anbima_rates("17-07-2024")
|
|
124
|
-
2024-10-01 0.104236
|
|
125
|
-
2025-01-01 0.105400
|
|
126
|
-
2025-04-01 0.107454
|
|
127
|
-
2025-07-01 0.108924
|
|
128
|
-
2025-10-01 0.110751
|
|
129
|
-
2026-01-01 0.111753
|
|
130
|
-
2026-04-01 0.112980
|
|
131
|
-
2026-07-01 0.113870
|
|
132
|
-
2026-10-01 0.114592
|
|
133
|
-
2027-07-01 0.116090
|
|
134
|
-
2028-01-01 0.117160
|
|
135
|
-
2028-07-01 0.118335
|
|
136
|
-
2030-01-01 0.120090
|
|
137
|
-
Name: IndicativeRate, dtype: Float64
|
|
127
|
+
# Calculate the DI Spread of NTN-F and LTN bonds in a given date
|
|
128
|
+
>>> ntnf.di_spreads("23-08-2024")
|
|
129
|
+
MaturityDate DISpread
|
|
130
|
+
0 2025-01-01 -5.38
|
|
131
|
+
1 2027-01-01 4.39
|
|
132
|
+
2 2029-01-01 7.37
|
|
133
|
+
3 2031-01-01 12.58
|
|
134
|
+
4 2033-01-01 7.67
|
|
135
|
+
5 2035-01-01 12.76
|
|
136
|
+
|
|
138
137
|
```
|
|
139
138
|
|
|
140
139
|
### Business Days Tools (Brazilian holidays are automatically considered)
|
|
@@ -162,22 +161,11 @@ Timestamp('2023-12-29 00:00:00')
|
|
|
162
161
|
0 2023-12-29
|
|
163
162
|
1 2024-01-02
|
|
164
163
|
2 2024-01-03
|
|
165
|
-
dtype: datetime64[ns]
|
|
166
164
|
```
|
|
167
165
|
|
|
168
166
|
### Futures Data
|
|
169
167
|
```python
|
|
170
168
|
>>> import pyield as yd
|
|
171
|
-
# Fetch current DI Futures data from B3 (15 minutes delay)
|
|
172
|
-
>>> yd.futures(contract_code="DI1")
|
|
173
|
-
LastUpdatee TickerSymbol ExpirationDate BDaysToExp ... MaxRate LastAskRate LastBidRate LastRate
|
|
174
|
-
2024-04-21 13:37:39 DI1K24 2024-05-02 7 ... 0.10660 0.10652 0.10660 0.10660
|
|
175
|
-
2024-04-21 13:37:39 DI1M24 2024-06-03 28 ... 0.10518 0.10510 0.10516 0.10518
|
|
176
|
-
2024-04-21 13:37:39 DI1N24 2024-07-01 48 ... 0.10480 0.10456 0.10462 0.10460
|
|
177
|
-
... ... ... ... ... ... ... ... ...
|
|
178
|
-
2024-04-21 13:37:39 DI1F37 2037-01-02 3183 ... <NA> <NA> 0.11600 <NA>
|
|
179
|
-
2024-04-21 13:37:39 DI1F38 2038-01-04 3432 ... <NA> <NA> 0.11600 <NA>
|
|
180
|
-
2024-04-21 13:37:39 DI1F39 2039-01-03 3683 ... <NA> <NA> <NA> <NA>
|
|
181
169
|
|
|
182
170
|
# Fetch historical DI Futures data from B3
|
|
183
171
|
>>> yd.futures(contract_code="DI1", date='08-03-2024')
|
|
@@ -189,20 +177,35 @@ TradeDate TickerSymbol ExpirationDate BDaysToExp ... LastRate LastAskRate LastB
|
|
|
189
177
|
2024-03-08 DI1F37 2037-01-02 3213 ... <NA> <NA> <NA> 10.859
|
|
190
178
|
2024-03-08 DI1F38 2038-01-04 3462 ... <NA> <NA> <NA> 10.859
|
|
191
179
|
2024-03-08 DI1F39 2039-01-03 3713 ... <NA> <NA> <NA> 10.85
|
|
180
|
+
|
|
181
|
+
# Fetch current DI Futures data from B3 (15 minutes delay)
|
|
182
|
+
>>> yd.futures(contract_code="DI1", date="21-03-2024") # when the date used is the current date and market is open
|
|
183
|
+
LastUpdatee TickerSymbol ExpirationDate BDaysToExp ... MaxRate LastAskRate LastBidRate LastRate
|
|
184
|
+
2024-04-21 13:37:39 DI1K24 2024-05-02 7 ... 0.10660 0.10652 0.10660 0.10660
|
|
185
|
+
2024-04-21 13:37:39 DI1M24 2024-06-03 28 ... 0.10518 0.10510 0.10516 0.10518
|
|
186
|
+
2024-04-21 13:37:39 DI1N24 2024-07-01 48 ... 0.10480 0.10456 0.10462 0.10460
|
|
187
|
+
... ... ... ... ... ... ... ... ...
|
|
188
|
+
2024-04-21 13:37:39 DI1F37 2037-01-02 3183 ... <NA> <NA> 0.11600 <NA>
|
|
189
|
+
2024-04-21 13:37:39 DI1F38 2038-01-04 3432 ... <NA> <NA> 0.11600 <NA>
|
|
190
|
+
2024-04-21 13:37:39 DI1F39 2039-01-03 3683 ... <NA> <NA> <NA> <NA>
|
|
192
191
|
```
|
|
193
192
|
|
|
194
193
|
### Indicators Data
|
|
195
194
|
```python
|
|
196
195
|
>>> from pyield import bc
|
|
197
|
-
|
|
198
|
-
|
|
196
|
+
|
|
197
|
+
# Fetch the SELIC target rates from the Central Bank of Brazil
|
|
198
|
+
>>> bc.selic_over_series("26-01-2025", "30-01-2025") # No data on 26-01-2025 (sunday)
|
|
199
199
|
Date Value
|
|
200
200
|
0 2025-01-27 0.1215
|
|
201
201
|
1 2025-01-28 0.1215
|
|
202
202
|
2 2025-01-29 0.1215
|
|
203
203
|
3 2025-01-30 0.1315
|
|
204
|
-
|
|
205
|
-
|
|
204
|
+
|
|
205
|
+
# Fetch the SELIC target rate for a specific date
|
|
206
|
+
>>> bc.selic_over("27-01-2025")
|
|
207
|
+
Date Value
|
|
208
|
+
0.1215 # 12.15%
|
|
206
209
|
```
|
|
207
210
|
|
|
208
211
|
### Projections Data
|
|
@@ -8,8 +8,6 @@ PYield is a Python library designed for the analysis of Brazilian fixed income i
|
|
|
8
8
|
|
|
9
9
|
Documentation: [https://crdcj.github.io/PYield/](https://crdcj.github.io/PYield/)
|
|
10
10
|
|
|
11
|
-
Source Code: [https://github.com/crdcj/PYield](https://github.com/crdcj/PYield)
|
|
12
|
-
|
|
13
11
|
## Key Features
|
|
14
12
|
|
|
15
13
|
- **Data Collection**: Automated fetching of data from ANBIMA and B3.
|
|
@@ -62,38 +60,39 @@ date = pd.to_datetime("05-31-2024", format="%m-%d-%Y")
|
|
|
62
60
|
```python
|
|
63
61
|
>>> from pyield import ntnb, ntnf, ltn
|
|
64
62
|
|
|
63
|
+
# Get ANBIMA data for a given date
|
|
64
|
+
>>> ltn.data("23-08-2024")
|
|
65
|
+
ReferenceDate BondType MaturityDate IndicativeRate Price
|
|
66
|
+
0 2024-08-23 LTN 2024-10-01 0.104416 989.415342
|
|
67
|
+
1 2024-08-23 LTN 2025-01-01 0.107171 964.293046
|
|
68
|
+
2 2024-08-23 LTN 2025-04-01 0.110866 938.943013
|
|
69
|
+
3 2024-08-23 LTN 2025-07-01 0.113032 913.849158
|
|
70
|
+
4 2024-08-23 LTN 2025-10-01 0.114374 887.394285
|
|
71
|
+
5 2024-08-23 LTN 2026-01-01 0.114654 863.026594
|
|
72
|
+
6 2024-08-23 LTN 2026-04-01 0.114997 840.232741
|
|
73
|
+
7 2024-08-23 LTN 2026-07-01 0.115265 818.020491
|
|
74
|
+
8 2024-08-23 LTN 2026-10-01 0.115357 795.185488
|
|
75
|
+
9 2024-08-23 LTN 2027-07-01 0.115335 733.981131
|
|
76
|
+
10 2024-08-23 LTN 2028-01-01 0.115694 693.647778
|
|
77
|
+
11 2024-08-23 LTN 2028-07-01 0.116417 655.6398
|
|
78
|
+
12 2024-08-23 LTN 2030-01-01 0.117436 554.331151
|
|
79
|
+
|
|
65
80
|
# Calculate the quotation of a NTN-B bond as per ANBIMA's rules
|
|
66
81
|
>>> ntnb.quotation("31-05-2024", "15-05-2035", 0.061490)
|
|
67
82
|
99.3651
|
|
68
83
|
>>> ntnb.quotation("31-05-2024", "15-08-2060", 0.061878)
|
|
69
84
|
99.5341
|
|
70
85
|
|
|
71
|
-
# Calculate the DI Spread of NTN-F bonds in a given date
|
|
72
|
-
>>> ntnf.di_spreads("
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
# Get ANBIMA's indicative rates for LTN bonds
|
|
82
|
-
>>> ltn.anbima_rates("17-07-2024")
|
|
83
|
-
2024-10-01 0.104236
|
|
84
|
-
2025-01-01 0.105400
|
|
85
|
-
2025-04-01 0.107454
|
|
86
|
-
2025-07-01 0.108924
|
|
87
|
-
2025-10-01 0.110751
|
|
88
|
-
2026-01-01 0.111753
|
|
89
|
-
2026-04-01 0.112980
|
|
90
|
-
2026-07-01 0.113870
|
|
91
|
-
2026-10-01 0.114592
|
|
92
|
-
2027-07-01 0.116090
|
|
93
|
-
2028-01-01 0.117160
|
|
94
|
-
2028-07-01 0.118335
|
|
95
|
-
2030-01-01 0.120090
|
|
96
|
-
Name: IndicativeRate, dtype: Float64
|
|
86
|
+
# Calculate the DI Spread of NTN-F and LTN bonds in a given date
|
|
87
|
+
>>> ntnf.di_spreads("23-08-2024")
|
|
88
|
+
MaturityDate DISpread
|
|
89
|
+
0 2025-01-01 -5.38
|
|
90
|
+
1 2027-01-01 4.39
|
|
91
|
+
2 2029-01-01 7.37
|
|
92
|
+
3 2031-01-01 12.58
|
|
93
|
+
4 2033-01-01 7.67
|
|
94
|
+
5 2035-01-01 12.76
|
|
95
|
+
|
|
97
96
|
```
|
|
98
97
|
|
|
99
98
|
### Business Days Tools (Brazilian holidays are automatically considered)
|
|
@@ -121,22 +120,11 @@ Timestamp('2023-12-29 00:00:00')
|
|
|
121
120
|
0 2023-12-29
|
|
122
121
|
1 2024-01-02
|
|
123
122
|
2 2024-01-03
|
|
124
|
-
dtype: datetime64[ns]
|
|
125
123
|
```
|
|
126
124
|
|
|
127
125
|
### Futures Data
|
|
128
126
|
```python
|
|
129
127
|
>>> import pyield as yd
|
|
130
|
-
# Fetch current DI Futures data from B3 (15 minutes delay)
|
|
131
|
-
>>> yd.futures(contract_code="DI1")
|
|
132
|
-
LastUpdatee TickerSymbol ExpirationDate BDaysToExp ... MaxRate LastAskRate LastBidRate LastRate
|
|
133
|
-
2024-04-21 13:37:39 DI1K24 2024-05-02 7 ... 0.10660 0.10652 0.10660 0.10660
|
|
134
|
-
2024-04-21 13:37:39 DI1M24 2024-06-03 28 ... 0.10518 0.10510 0.10516 0.10518
|
|
135
|
-
2024-04-21 13:37:39 DI1N24 2024-07-01 48 ... 0.10480 0.10456 0.10462 0.10460
|
|
136
|
-
... ... ... ... ... ... ... ... ...
|
|
137
|
-
2024-04-21 13:37:39 DI1F37 2037-01-02 3183 ... <NA> <NA> 0.11600 <NA>
|
|
138
|
-
2024-04-21 13:37:39 DI1F38 2038-01-04 3432 ... <NA> <NA> 0.11600 <NA>
|
|
139
|
-
2024-04-21 13:37:39 DI1F39 2039-01-03 3683 ... <NA> <NA> <NA> <NA>
|
|
140
128
|
|
|
141
129
|
# Fetch historical DI Futures data from B3
|
|
142
130
|
>>> yd.futures(contract_code="DI1", date='08-03-2024')
|
|
@@ -148,20 +136,35 @@ TradeDate TickerSymbol ExpirationDate BDaysToExp ... LastRate LastAskRate LastB
|
|
|
148
136
|
2024-03-08 DI1F37 2037-01-02 3213 ... <NA> <NA> <NA> 10.859
|
|
149
137
|
2024-03-08 DI1F38 2038-01-04 3462 ... <NA> <NA> <NA> 10.859
|
|
150
138
|
2024-03-08 DI1F39 2039-01-03 3713 ... <NA> <NA> <NA> 10.85
|
|
139
|
+
|
|
140
|
+
# Fetch current DI Futures data from B3 (15 minutes delay)
|
|
141
|
+
>>> yd.futures(contract_code="DI1", date="21-03-2024") # when the date used is the current date and market is open
|
|
142
|
+
LastUpdatee TickerSymbol ExpirationDate BDaysToExp ... MaxRate LastAskRate LastBidRate LastRate
|
|
143
|
+
2024-04-21 13:37:39 DI1K24 2024-05-02 7 ... 0.10660 0.10652 0.10660 0.10660
|
|
144
|
+
2024-04-21 13:37:39 DI1M24 2024-06-03 28 ... 0.10518 0.10510 0.10516 0.10518
|
|
145
|
+
2024-04-21 13:37:39 DI1N24 2024-07-01 48 ... 0.10480 0.10456 0.10462 0.10460
|
|
146
|
+
... ... ... ... ... ... ... ... ...
|
|
147
|
+
2024-04-21 13:37:39 DI1F37 2037-01-02 3183 ... <NA> <NA> 0.11600 <NA>
|
|
148
|
+
2024-04-21 13:37:39 DI1F38 2038-01-04 3432 ... <NA> <NA> 0.11600 <NA>
|
|
149
|
+
2024-04-21 13:37:39 DI1F39 2039-01-03 3683 ... <NA> <NA> <NA> <NA>
|
|
151
150
|
```
|
|
152
151
|
|
|
153
152
|
### Indicators Data
|
|
154
153
|
```python
|
|
155
154
|
>>> from pyield import bc
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
|
|
156
|
+
# Fetch the SELIC target rates from the Central Bank of Brazil
|
|
157
|
+
>>> bc.selic_over_series("26-01-2025", "30-01-2025") # No data on 26-01-2025 (sunday)
|
|
158
158
|
Date Value
|
|
159
159
|
0 2025-01-27 0.1215
|
|
160
160
|
1 2025-01-28 0.1215
|
|
161
161
|
2 2025-01-29 0.1215
|
|
162
162
|
3 2025-01-30 0.1315
|
|
163
|
-
|
|
164
|
-
|
|
163
|
+
|
|
164
|
+
# Fetch the SELIC target rate for a specific date
|
|
165
|
+
>>> bc.selic_over("27-01-2025")
|
|
166
|
+
Date Value
|
|
167
|
+
0.1215 # 12.15%
|
|
165
168
|
```
|
|
166
169
|
|
|
167
170
|
### Projections Data
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.31.2"
|
|
@@ -6,7 +6,7 @@ from pyield.b3 import futures
|
|
|
6
6
|
from pyield.b3.di import DIFutures
|
|
7
7
|
from pyield.forwards import forward_rates
|
|
8
8
|
from pyield.interpolator import Interpolator
|
|
9
|
-
from pyield.tpf import lft, ltn, ntnb, ntnf
|
|
9
|
+
from pyield.tpf import lft, ltn, ntnb, ntnc, ntnf
|
|
10
10
|
|
|
11
11
|
__all__ = [
|
|
12
12
|
"__version__",
|
|
@@ -20,6 +20,7 @@ __all__ = [
|
|
|
20
20
|
"lft",
|
|
21
21
|
"ltn",
|
|
22
22
|
"ntnb",
|
|
23
|
+
"ntnc",
|
|
23
24
|
"ntnf",
|
|
24
25
|
"bc",
|
|
25
26
|
"b3",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from pyield.anbima.ettj import last_ettj
|
|
1
|
+
from pyield.anbima.ettj import intraday_ettj, last_ettj
|
|
2
2
|
from pyield.anbima.ima import last_ima
|
|
3
3
|
from pyield.anbima.imaq import imaq
|
|
4
4
|
from pyield.anbima.ipca import ipca_projection
|
|
@@ -12,4 +12,5 @@ __all__ = [
|
|
|
12
12
|
"tpf_data",
|
|
13
13
|
"tpf_fixed_rate_maturities",
|
|
14
14
|
"last_ettj",
|
|
15
|
+
"intraday_ettj",
|
|
15
16
|
]
|
|
@@ -4,11 +4,13 @@ from io import StringIO
|
|
|
4
4
|
import pandas as pd
|
|
5
5
|
import requests
|
|
6
6
|
|
|
7
|
-
from pyield.forwards import forward_rates
|
|
8
7
|
from pyield.retry import default_retry
|
|
9
8
|
|
|
10
9
|
logger = logging.getLogger(__name__)
|
|
11
10
|
LAST_ETTJ_URL = "https://www.anbima.com.br/informacoes/est-termo/CZ-down.asp"
|
|
11
|
+
INTRADAY_ETTJ_URL = (
|
|
12
|
+
"https://www.anbima.com.br/informacoes/curvas-intradiarias/cIntra-down.asp"
|
|
13
|
+
)
|
|
12
14
|
|
|
13
15
|
# Anbima ETTJ data has 4 decimal places in percentage values
|
|
14
16
|
# We will round to 6 decimal places to avoid floating point errors
|
|
@@ -76,31 +78,12 @@ def _process_df(df: pd.DataFrame) -> pd.DataFrame:
|
|
|
76
78
|
df["nominal_rate"] = (df["nominal_rate"] / 100).round(ROUND_DIGITS)
|
|
77
79
|
df["implied_inflation"] = (df["implied_inflation"] / 100).round(ROUND_DIGITS)
|
|
78
80
|
|
|
79
|
-
df["real_rate_fwd"] = forward_rates(
|
|
80
|
-
business_days=df["vertex"],
|
|
81
|
-
zero_rates=df["real_rate"],
|
|
82
|
-
groupby_dates=df["date"],
|
|
83
|
-
)
|
|
84
|
-
df["nominal_rate_fwd"] = forward_rates(
|
|
85
|
-
business_days=df["vertex"],
|
|
86
|
-
zero_rates=df["nominal_rate"],
|
|
87
|
-
groupby_dates=df["date"],
|
|
88
|
-
)
|
|
89
|
-
df["implied_inflation_fwd"] = forward_rates(
|
|
90
|
-
business_days=df["vertex"],
|
|
91
|
-
zero_rates=df["implied_inflation"],
|
|
92
|
-
groupby_dates=df["date"],
|
|
93
|
-
)
|
|
94
|
-
|
|
95
81
|
column_order = [
|
|
96
82
|
"date",
|
|
97
83
|
"vertex",
|
|
98
84
|
"nominal_rate",
|
|
99
85
|
"real_rate",
|
|
100
86
|
"implied_inflation",
|
|
101
|
-
"nominal_rate_fwd",
|
|
102
|
-
"real_rate_fwd",
|
|
103
|
-
"implied_inflation_fwd",
|
|
104
87
|
]
|
|
105
88
|
df = df[column_order].copy()
|
|
106
89
|
|
|
@@ -113,8 +96,7 @@ def last_ettj() -> pd.DataFrame:
|
|
|
113
96
|
|
|
114
97
|
This function fetches the most recent yield curve data published by ANBIMA,
|
|
115
98
|
containing real rates (IPCA-indexed), nominal rates, and implied inflation
|
|
116
|
-
at various vertices (time points).
|
|
117
|
-
calculated and included in the returned DataFrame.
|
|
99
|
+
at various vertices (time points).
|
|
118
100
|
|
|
119
101
|
Returns:
|
|
120
102
|
pd.DataFrame: A DataFrame containing the latest ETTJ data.
|
|
@@ -125,9 +107,6 @@ def last_ettj() -> pd.DataFrame:
|
|
|
125
107
|
- nominal_rate: Zero-coupon nominal interest rate
|
|
126
108
|
- real_rate: Zero-coupon real interest rate (IPCA-indexed)
|
|
127
109
|
- implied_inflation: Implied inflation rate (break-even inflation)
|
|
128
|
-
- nominal_rate_fwd: Forward nominal interest rate
|
|
129
|
-
- real_rate_fwd: Forward real interest rate
|
|
130
|
-
- implied_inflation_fwd: Forward implied inflation rate
|
|
131
110
|
|
|
132
111
|
Note:
|
|
133
112
|
All rates are expressed in decimal format (e.g., 0.12 for 12%).
|
|
@@ -135,3 +114,57 @@ def last_ettj() -> pd.DataFrame:
|
|
|
135
114
|
text = _get_last_content()
|
|
136
115
|
df = _convert_text_to_df(text)
|
|
137
116
|
return _process_df(df)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def intraday_ettj() -> pd.DataFrame:
|
|
120
|
+
"""
|
|
121
|
+
Retrieves and processes the intraday Brazilian yield curve data from ANBIMA.
|
|
122
|
+
|
|
123
|
+
This function fetches the most recent intraday yield curve data published by ANBIMA,
|
|
124
|
+
containing real rates (IPCA-indexed), nominal rates, and implied inflation
|
|
125
|
+
at various vertices (time points). The curve is published at around 12:30 PM BRT.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
pd.DataFrame: A DataFrame containing the intraday ETTJ data.
|
|
129
|
+
|
|
130
|
+
DataFrame columns:
|
|
131
|
+
- date: Reference date of the yield curve
|
|
132
|
+
- vertex: Time point in business days
|
|
133
|
+
- nominal_rate: Zero-coupon nominal interest rate
|
|
134
|
+
- real_rate: Zero-coupon real interest rate (IPCA-indexed)
|
|
135
|
+
- implied_inflation: Implied inflation rate (break-even inflation)
|
|
136
|
+
|
|
137
|
+
Note:
|
|
138
|
+
All rates are expressed in decimal format (e.g., 0.12 for 12%).
|
|
139
|
+
"""
|
|
140
|
+
text = requests.get(INTRADAY_ETTJ_URL).text
|
|
141
|
+
text_parts = text.split("ETTJ IPCA (%a.a./252)")
|
|
142
|
+
|
|
143
|
+
nominal_text = text_parts[0]
|
|
144
|
+
lines = nominal_text.splitlines()
|
|
145
|
+
date_str = lines[1]
|
|
146
|
+
date = pd.to_datetime(date_str, format="%d/%m/%Y")
|
|
147
|
+
df_text = "\n".join(lines[2:])
|
|
148
|
+
df_nominal = pd.read_csv(StringIO(df_text), sep=";", decimal=",", thousands=".")
|
|
149
|
+
df_nominal = df_nominal.drop(columns=["Fechamento D -1"])
|
|
150
|
+
df_nominal = df_nominal.rename(columns={"D0": "nominal_rate"})
|
|
151
|
+
|
|
152
|
+
real_text = text_parts[1]
|
|
153
|
+
lines = real_text.splitlines()
|
|
154
|
+
df_text = "\n".join(lines[2:])
|
|
155
|
+
df_real = pd.read_csv(StringIO(df_text), sep=";", decimal=",", thousands=".")
|
|
156
|
+
df_real = df_real.drop(columns=["Fechamento D -1"])
|
|
157
|
+
df_real = df_real.rename(columns={"D0": "real_rate"})
|
|
158
|
+
|
|
159
|
+
df = pd.merge(df_nominal, df_real, on="Vertices", how="right")
|
|
160
|
+
df = df.rename(columns={"Vertices": "vertex"})
|
|
161
|
+
|
|
162
|
+
# Divide float columns by 100 and round to 6 decimal places
|
|
163
|
+
df["real_rate"] = (df["real_rate"] / 100).round(ROUND_DIGITS)
|
|
164
|
+
df["nominal_rate"] = (df["nominal_rate"] / 100).round(ROUND_DIGITS)
|
|
165
|
+
df["implied_inflation"] = (df["nominal_rate"] + 1) / (df["real_rate"] + 1) - 1
|
|
166
|
+
df["implied_inflation"] = df["implied_inflation"].round(ROUND_DIGITS)
|
|
167
|
+
|
|
168
|
+
df["date"] = date
|
|
169
|
+
column_order = ["date", "vertex", "nominal_rate", "real_rate", "implied_inflation"]
|
|
170
|
+
return df[column_order].copy()
|
|
@@ -81,7 +81,8 @@ def _process_raw_df(df_raw: pd.DataFrame) -> pd.DataFrame:
|
|
|
81
81
|
def tpf_web_data(
|
|
82
82
|
date: DateScalar, bond_type: str | BOND_TYPES | None = None
|
|
83
83
|
) -> pd.DataFrame:
|
|
84
|
-
"""Fetch and process TPF secondary market data from ANBIMA website.
|
|
84
|
+
"""Fetch and process TPF secondary market data directly from the ANBIMA website.
|
|
85
|
+
Only the last 5 days of data are available in the ANBIMA website.
|
|
85
86
|
|
|
86
87
|
This function retrieves bond market data from the ANBIMA website for a
|
|
87
88
|
specified reference date. It handles different file formats based on the date
|
|
@@ -3,7 +3,7 @@ import pandas as pd
|
|
|
3
3
|
from pyield import anbima, bday
|
|
4
4
|
from pyield import date_converter as dc
|
|
5
5
|
from pyield.date_converter import DateScalar
|
|
6
|
-
from pyield.tpf import tools
|
|
6
|
+
from pyield.tpf import tools
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def data(date: DateScalar) -> pd.DataFrame:
|
|
@@ -22,8 +22,8 @@ def data(date: DateScalar) -> pd.DataFrame:
|
|
|
22
22
|
- Price: The price of the LFT bond.
|
|
23
23
|
|
|
24
24
|
Examples:
|
|
25
|
-
|
|
26
|
-
>>>
|
|
25
|
+
>>> from pyield import lft
|
|
26
|
+
>>> lft.data("23-08-2024")
|
|
27
27
|
ReferenceDate BondType MaturityDate IndicativeRate Price
|
|
28
28
|
0 2024-08-23 LFT 2024-09-01 0.000272 15252.158852
|
|
29
29
|
1 2024-08-23 LFT 2025-03-01 -0.000418 15255.605864
|
|
@@ -61,7 +61,8 @@ def quotation(
|
|
|
61
61
|
|
|
62
62
|
Examples:
|
|
63
63
|
Calculate the quotation of a LFT bond with a 0.02 yield rate:
|
|
64
|
-
>>>
|
|
64
|
+
>>> from pyield import lft
|
|
65
|
+
>>> lft.quotation(
|
|
65
66
|
... settlement="24-07-2024",
|
|
66
67
|
... maturity="01-09-2030",
|
|
67
68
|
... rate=0.001717, # 0.1717%
|
|
@@ -76,11 +77,11 @@ def quotation(
|
|
|
76
77
|
bdays = bday.count(settlement, maturity)
|
|
77
78
|
|
|
78
79
|
# Calculate the number of periods truncated as per Anbima rules
|
|
79
|
-
num_of_years =
|
|
80
|
+
num_of_years = tools.truncate(bdays / 252, 14)
|
|
80
81
|
|
|
81
82
|
discount_factor = 1 / (1 + rate) ** num_of_years
|
|
82
83
|
|
|
83
|
-
return
|
|
84
|
+
return tools.truncate(100 * discount_factor, 4)
|
|
84
85
|
|
|
85
86
|
|
|
86
87
|
def premium(lft_rate: float, selic_over: float) -> float:
|
|
@@ -4,7 +4,7 @@ from pyield import anbima, bday
|
|
|
4
4
|
from pyield import date_converter as dc
|
|
5
5
|
from pyield.b3 import di
|
|
6
6
|
from pyield.date_converter import DateScalar
|
|
7
|
-
from pyield.tpf import tools
|
|
7
|
+
from pyield.tpf import tools
|
|
8
8
|
|
|
9
9
|
FACE_VALUE = 1000
|
|
10
10
|
|
|
@@ -20,7 +20,8 @@ def data(date: DateScalar) -> pd.DataFrame:
|
|
|
20
20
|
pd.DataFrame: DataFrame with columns "MaturityDate" and "IndicativeRate".
|
|
21
21
|
|
|
22
22
|
Examples:
|
|
23
|
-
>>>
|
|
23
|
+
>>> from pyield import ltn
|
|
24
|
+
>>> ltn.data("23-08-2024")
|
|
24
25
|
ReferenceDate BondType MaturityDate IndicativeRate Price
|
|
25
26
|
0 2024-08-23 LTN 2024-10-01 0.104416 989.415342
|
|
26
27
|
1 2024-08-23 LTN 2025-01-01 0.107171 964.293046
|
|
@@ -51,7 +52,8 @@ def maturities(date: DateScalar) -> pd.Series:
|
|
|
51
52
|
pd.Series: A Series of bond maturities available for the reference date.
|
|
52
53
|
|
|
53
54
|
Examples:
|
|
54
|
-
>>>
|
|
55
|
+
>>> from pyield import ltn
|
|
56
|
+
>>> ltn.maturities("22-08-2024")
|
|
55
57
|
0 2024-10-01
|
|
56
58
|
1 2025-01-01
|
|
57
59
|
2 2025-04-01
|
|
@@ -97,7 +99,8 @@ def price(
|
|
|
97
99
|
- https://www.anbima.com.br/data/files/A0/02/CC/70/8FEFC8104606BDC8B82BA2A8/Metodologias%20ANBIMA%20de%20Precificacao%20Titulos%20Publicos.pdf
|
|
98
100
|
|
|
99
101
|
Examples:
|
|
100
|
-
>>>
|
|
102
|
+
>>> from pyield import ltn
|
|
103
|
+
>>> ltn.price("05-07-2024", "01-01-2030", 0.12145)
|
|
101
104
|
535.279902
|
|
102
105
|
"""
|
|
103
106
|
|
|
@@ -109,12 +112,12 @@ def price(
|
|
|
109
112
|
bdays = bday.count(settlement, maturity)
|
|
110
113
|
|
|
111
114
|
# Calculate the number of periods truncated as per Anbima rule
|
|
112
|
-
num_of_years =
|
|
115
|
+
num_of_years = tools.truncate(bdays / 252, 14)
|
|
113
116
|
|
|
114
117
|
discount_factor = (1 + rate) ** num_of_years
|
|
115
118
|
|
|
116
119
|
# Truncate the price to 6 decimal places as per Anbima rules
|
|
117
|
-
return
|
|
120
|
+
return tools.truncate(FACE_VALUE / discount_factor, 6)
|
|
118
121
|
|
|
119
122
|
|
|
120
123
|
def di_spreads(date: DateScalar) -> pd.DataFrame:
|
|
@@ -132,7 +135,8 @@ def di_spreads(date: DateScalar) -> pd.DataFrame:
|
|
|
132
135
|
pd.DataFrame: DataFrame with the columns "MaturityDate" and "DISpread" (in bps).
|
|
133
136
|
|
|
134
137
|
Examples:
|
|
135
|
-
>>>
|
|
138
|
+
>>> from pyield import ltn
|
|
139
|
+
>>> ltn.di_spreads("22-08-2024")
|
|
136
140
|
MaturityDate DISpread
|
|
137
141
|
0 2024-10-01 -3.06
|
|
138
142
|
1 2025-01-01 -9.95
|
|
@@ -149,7 +153,7 @@ def di_spreads(date: DateScalar) -> pd.DataFrame:
|
|
|
149
153
|
12 2030-01-01 14.96
|
|
150
154
|
"""
|
|
151
155
|
# Fetch DI Spreads for the reference date
|
|
152
|
-
df =
|
|
156
|
+
df = tools.pre_spreads(date)
|
|
153
157
|
df.query("BondType == 'LTN'", inplace=True)
|
|
154
158
|
df.sort_values(["MaturityDate"], ignore_index=True, inplace=True)
|
|
155
159
|
return df[["MaturityDate", "DISpread"]]
|
|
@@ -170,7 +174,8 @@ def premium(ltn_rate: float, di_rate: float) -> float:
|
|
|
170
174
|
Reference date: 22-08-2024
|
|
171
175
|
LTN rate for 01-01-2030: 0.118746
|
|
172
176
|
DI (JAN30) Settlement rate: 0.11725
|
|
173
|
-
>>>
|
|
177
|
+
>>> from pyield import ltn
|
|
178
|
+
>>> ltn.premium(0.118746, 0.11725)
|
|
174
179
|
1.0120718007994287
|
|
175
180
|
"""
|
|
176
181
|
# Cálculo das taxas diárias
|
|
@@ -197,7 +202,8 @@ def historical_premium(
|
|
|
197
202
|
If the data is not available, returns NaN.
|
|
198
203
|
|
|
199
204
|
Examples:
|
|
200
|
-
>>>
|
|
205
|
+
>>> from pyield import ltn
|
|
206
|
+
>>> ltn.historical_premium("22-08-2024", "01-01-2030")
|
|
201
207
|
1.0120718007994287
|
|
202
208
|
|
|
203
209
|
"""
|
|
@@ -34,7 +34,8 @@ def data(date: DateScalar) -> pd.DataFrame:
|
|
|
34
34
|
- IndicativeRate: The indicative rate for the bond.
|
|
35
35
|
|
|
36
36
|
Examples:
|
|
37
|
-
>>>
|
|
37
|
+
>>> from pyield import ntnb
|
|
38
|
+
>>> ntnb.data("23-08-2024")
|
|
38
39
|
ReferenceDate BondType MaturityDate IndicativeRate Price
|
|
39
40
|
0 2024-08-23 NTN-B 2025-05-15 0.063804 4377.008543
|
|
40
41
|
1 2024-08-23 NTN-B 2026-08-15 0.065795 4278.316344
|
|
@@ -66,8 +67,8 @@ def maturities(date: DateScalar) -> pd.Series:
|
|
|
66
67
|
pd.Series: Series containing the maturity dates for the NTN-B bonds.
|
|
67
68
|
|
|
68
69
|
Examples:
|
|
69
|
-
|
|
70
|
-
>>>
|
|
70
|
+
>>> from pyield import ntnb
|
|
71
|
+
>>> ntnb.maturities("16-08-2024")
|
|
71
72
|
0 2025-05-15
|
|
72
73
|
1 2026-08-15
|
|
73
74
|
2 2027-05-15
|
|
@@ -147,7 +148,8 @@ def payment_dates(
|
|
|
147
148
|
pd.Series: Series of coupon dates within the specified range.
|
|
148
149
|
|
|
149
150
|
Examples:
|
|
150
|
-
>>>
|
|
151
|
+
>>> from pyield import ntnb
|
|
152
|
+
>>> ntnb.payment_dates("10-05-2024", "15-05-2025")
|
|
151
153
|
0 2024-05-15
|
|
152
154
|
1 2024-11-15
|
|
153
155
|
2 2025-05-15
|
|
@@ -194,7 +196,8 @@ def cash_flows(
|
|
|
194
196
|
- CashFlow: Cash flow value for the bond
|
|
195
197
|
|
|
196
198
|
Examples:
|
|
197
|
-
>>>
|
|
199
|
+
>>> from pyield import ntnb
|
|
200
|
+
>>> ntnb.cash_flows("10-05-2024", "15-05-2025")
|
|
198
201
|
PaymentDate CashFlow
|
|
199
202
|
0 2024-05-15 2.956301
|
|
200
203
|
1 2024-11-15 2.956301
|
|
@@ -238,11 +241,12 @@ def quotation(
|
|
|
238
241
|
Anbima rules.
|
|
239
242
|
|
|
240
243
|
Examples:
|
|
241
|
-
>>>
|
|
244
|
+
>>> from pyield import ntnb
|
|
245
|
+
>>> ntnb.quotation("31-05-2024", "15-05-2035", 0.061490)
|
|
242
246
|
99.3651
|
|
243
|
-
>>>
|
|
247
|
+
>>> ntnb.quotation("31-05-2024", "15-08-2060", 0.061878)
|
|
244
248
|
99.5341
|
|
245
|
-
>>>
|
|
249
|
+
>>> ntnb.quotation("15-08-2024", "15-08-2032", 0.05929)
|
|
246
250
|
100.6409
|
|
247
251
|
"""
|
|
248
252
|
# Validate and normalize dates
|
|
@@ -286,9 +290,10 @@ def price(
|
|
|
286
290
|
- https://www.anbima.com.br/data/files/A0/02/CC/70/8FEFC8104606BDC8B82BA2A8/Metodologias%20ANBIMA%20de%20Precificacao%20Titulos%20Publicos.pdf
|
|
287
291
|
|
|
288
292
|
Examples:
|
|
289
|
-
>>>
|
|
293
|
+
>>> from pyield import ntnb
|
|
294
|
+
>>> ntnb.price(4299.160173, 99.3651)
|
|
290
295
|
4271.864805
|
|
291
|
-
>>>
|
|
296
|
+
>>> ntnb.price(4315.498383, 100.6409)
|
|
292
297
|
4343.156412
|
|
293
298
|
"""
|
|
294
299
|
return bt.truncate(vna * quotation / 100, 6)
|
|
@@ -319,11 +324,11 @@ def spot_rates(
|
|
|
319
324
|
pd.DataFrame: DataFrame with columns "MaturityDate", "SpotRate".
|
|
320
325
|
|
|
321
326
|
Examples:
|
|
322
|
-
|
|
323
|
-
>>>
|
|
324
|
-
|
|
325
|
-
# Calculate the spot rates considering the settlement at the reference date
|
|
326
|
-
>>>
|
|
327
|
+
>>> from pyield import ntnb
|
|
328
|
+
>>> # Get the NTN-B rates for a specific reference date
|
|
329
|
+
>>> df = ntnb.data("16-08-2024")
|
|
330
|
+
>>> # Calculate the spot rates considering the settlement at the reference date
|
|
331
|
+
>>> ntnb.spot_rates(
|
|
327
332
|
... settlement="16-08-2024",
|
|
328
333
|
... maturities=df["MaturityDate"],
|
|
329
334
|
... rates=df["IndicativeRate"],
|
|
@@ -521,6 +526,22 @@ def duration(
|
|
|
521
526
|
maturity: DateScalar,
|
|
522
527
|
rate: float,
|
|
523
528
|
) -> float:
|
|
529
|
+
"""
|
|
530
|
+
Calculate the Macaulay duration of the NTN-B bond in business years.
|
|
531
|
+
|
|
532
|
+
Args:
|
|
533
|
+
settlement (DateScalar): The settlement date of the operation.
|
|
534
|
+
maturity (DateScalar): The maturity date of the NTN-B bond.
|
|
535
|
+
rate (float): The discount rate used to calculate the duration.
|
|
536
|
+
|
|
537
|
+
Returns:
|
|
538
|
+
float: The Macaulay duration of the NTN-B bond in business years.
|
|
539
|
+
|
|
540
|
+
Examples:
|
|
541
|
+
>>> from pyield import ntnb
|
|
542
|
+
>>> ntnb.duration("23-08-2024", "15-08-2060", 0.061005)
|
|
543
|
+
15.083054313130464
|
|
544
|
+
"""
|
|
524
545
|
settlement = dc.convert_input_dates(settlement)
|
|
525
546
|
maturity = dc.convert_input_dates(maturity)
|
|
526
547
|
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pandas as pd
|
|
3
|
+
|
|
4
|
+
import pyield.date_converter as dc
|
|
5
|
+
import pyield.tpf.tools as bt
|
|
6
|
+
from pyield import anbima, bday
|
|
7
|
+
from pyield.date_converter import DateScalar
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
Constants calculated as per Anbima Rules and in base 100
|
|
11
|
+
Valid for NTN-C bonds with maturity date 01-01-2031:
|
|
12
|
+
PRINCIPAL = 100
|
|
13
|
+
COUPON_RATE = (0.12 + 1) ** 0.5 - 1 # 12% annual rate compounded semi-annually
|
|
14
|
+
COUPON_PMT = round(100 * COUPON_RATE, 6) -> 5.830052
|
|
15
|
+
FINAL_PMT = principal + last coupon payment = 100 + COUPON_PMT = 105.830052
|
|
16
|
+
|
|
17
|
+
All other NTN-C bonds will have different values for COUPON_PMT and FINAL_PMT:
|
|
18
|
+
COUPON_RATE = (0.06 + 1) ** 0.5 - 1 # 6% annual rate compounded semi-annually
|
|
19
|
+
COUPON_PMT = round(100 * COUPON_RATE, 6) -> 2.956301
|
|
20
|
+
FINAL_PMT = principal + last coupon payment = 100 + 2.956301
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
COUPON_DAY = 1
|
|
24
|
+
COUPON_PMT_2031 = 5.830052
|
|
25
|
+
FINAL_PMT_2031 = 105.830052
|
|
26
|
+
|
|
27
|
+
COUPON_PMT = 2.956301
|
|
28
|
+
FINAL_PMT = 102.956301
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _get_coupon_pmt(maturity: pd.Timestamp) -> float:
|
|
32
|
+
if maturity.year == 2031: # noqa
|
|
33
|
+
return COUPON_PMT_2031
|
|
34
|
+
return COUPON_PMT
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _get_final_pmt(maturity: pd.Timestamp) -> float:
|
|
38
|
+
if maturity.year == 2031: # noqa
|
|
39
|
+
return FINAL_PMT_2031
|
|
40
|
+
return FINAL_PMT
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def data(date: DateScalar) -> pd.DataFrame:
|
|
44
|
+
"""
|
|
45
|
+
Fetch the LTN Anbima indicative rates for the given reference date.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
date (DateScalar): The reference date for fetching the data.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
pd.DataFrame: DataFrame with columns "MaturityDate" and "IndicativeRate".
|
|
52
|
+
|
|
53
|
+
Examples:
|
|
54
|
+
>>> from pyield import ntnc
|
|
55
|
+
>>> ntnc.data("21-03-2025")
|
|
56
|
+
ReferenceDate BondType MaturityDate IndicativeRate Price
|
|
57
|
+
0 2025-03-21 NTN-C 2031-01-01 0.067626 8347.348705
|
|
58
|
+
"""
|
|
59
|
+
return anbima.tpf_data(date, "NTN-C")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def payment_dates(
|
|
63
|
+
settlement: DateScalar,
|
|
64
|
+
maturity: DateScalar,
|
|
65
|
+
) -> pd.Series:
|
|
66
|
+
"""
|
|
67
|
+
Generate all remaining coupon dates between a given date and the maturity date.
|
|
68
|
+
The dates are inclusive. The NTN-C bond is determined by its maturity date.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
settlement (DateScalar): The settlement date (exlusive) to start generating
|
|
72
|
+
the coupon dates.
|
|
73
|
+
maturity (DateScalar): The maturity date.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
pd.Series: Series of coupon dates within the specified range.
|
|
77
|
+
|
|
78
|
+
Examples:
|
|
79
|
+
>>> from pyield import ntnc
|
|
80
|
+
>>> ntnc.payment_dates("21-03-2025", "01-01-2031")
|
|
81
|
+
0 2025-07-01
|
|
82
|
+
1 2026-01-01
|
|
83
|
+
2 2026-07-01
|
|
84
|
+
3 2027-01-01
|
|
85
|
+
4 2027-07-01
|
|
86
|
+
5 2028-01-01
|
|
87
|
+
6 2028-07-01
|
|
88
|
+
7 2029-01-01
|
|
89
|
+
8 2029-07-01
|
|
90
|
+
9 2030-01-01
|
|
91
|
+
10 2030-07-01
|
|
92
|
+
11 2031-01-01
|
|
93
|
+
dtype: datetime64[ns]
|
|
94
|
+
"""
|
|
95
|
+
# Validate and normalize dates
|
|
96
|
+
settlement = dc.convert_input_dates(settlement)
|
|
97
|
+
maturity = dc.convert_input_dates(maturity)
|
|
98
|
+
|
|
99
|
+
# Check if maturity date is after the start date
|
|
100
|
+
if maturity < settlement:
|
|
101
|
+
raise ValueError("Maturity date must be after the start date.")
|
|
102
|
+
|
|
103
|
+
# Initialize loop variables
|
|
104
|
+
coupon_dates = maturity
|
|
105
|
+
cp_dates = []
|
|
106
|
+
|
|
107
|
+
# Iterate backwards from the maturity date to the settlement date
|
|
108
|
+
while coupon_dates > settlement:
|
|
109
|
+
cp_dates.append(coupon_dates)
|
|
110
|
+
# Move the coupon date back 6 months
|
|
111
|
+
coupon_dates -= pd.DateOffset(months=6)
|
|
112
|
+
|
|
113
|
+
return pd.Series(cp_dates).sort_values(ignore_index=True)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def cash_flows(
|
|
117
|
+
settlement: DateScalar,
|
|
118
|
+
maturity: DateScalar,
|
|
119
|
+
) -> pd.DataFrame:
|
|
120
|
+
"""
|
|
121
|
+
Generate the cash flows for NTN-C bonds between the settlement and maturity dates.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
settlement (DateScalar): The settlement date (exclusive) to start generating
|
|
125
|
+
the cash flows.
|
|
126
|
+
maturity (DateScalar): The maturity date of the bond.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
pd.DataFrame: DataFrame with columns "PaymentDate" and "CashFlow".
|
|
130
|
+
|
|
131
|
+
Returned columns:
|
|
132
|
+
- PaymentDate: The payment date of the cash flow
|
|
133
|
+
- CashFlow: Cash flow value for the bond
|
|
134
|
+
|
|
135
|
+
Examples:
|
|
136
|
+
>>> from pyield import ntnc
|
|
137
|
+
>>> ntnc.cash_flows("21-03-2025", "01-01-2031")
|
|
138
|
+
PaymentDate CashFlow
|
|
139
|
+
0 2025-07-01 5.830052
|
|
140
|
+
1 2026-01-01 5.830052
|
|
141
|
+
2 2026-07-01 5.830052
|
|
142
|
+
3 2027-01-01 5.830052
|
|
143
|
+
4 2027-07-01 5.830052
|
|
144
|
+
5 2028-01-01 5.830052
|
|
145
|
+
6 2028-07-01 5.830052
|
|
146
|
+
7 2029-01-01 5.830052
|
|
147
|
+
8 2029-07-01 5.830052
|
|
148
|
+
9 2030-01-01 5.830052
|
|
149
|
+
10 2030-07-01 5.830052
|
|
150
|
+
11 2031-01-01 105.830052
|
|
151
|
+
"""
|
|
152
|
+
# Validate and normalize dates
|
|
153
|
+
settlement = dc.convert_input_dates(settlement)
|
|
154
|
+
maturity = dc.convert_input_dates(maturity)
|
|
155
|
+
|
|
156
|
+
# Get the coupon dates between the settlement and maturity dates
|
|
157
|
+
p_dates = payment_dates(settlement, maturity)
|
|
158
|
+
|
|
159
|
+
# Get the right coupon payment and final payment values
|
|
160
|
+
coupon_pmt = _get_coupon_pmt(maturity)
|
|
161
|
+
final_pmt = _get_final_pmt(maturity)
|
|
162
|
+
|
|
163
|
+
# Set the cash flow at maturity to FINAL_PMT and the others to COUPON_PMT
|
|
164
|
+
cfs = np.where(p_dates == maturity, final_pmt, coupon_pmt).tolist()
|
|
165
|
+
|
|
166
|
+
# Return a dataframe with the payment dates and cash flows
|
|
167
|
+
return pd.DataFrame(data={"PaymentDate": p_dates, "CashFlow": cfs})
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def quotation(
|
|
171
|
+
settlement: DateScalar,
|
|
172
|
+
maturity: DateScalar,
|
|
173
|
+
rate: float,
|
|
174
|
+
) -> float:
|
|
175
|
+
"""
|
|
176
|
+
Calculate the NTN-C quotation in base 100 using Anbima rules.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
settlement (DateScalar): The settlement date of the operation.
|
|
180
|
+
maturity (DateScalar): The maturity date of the NTN-C bond.
|
|
181
|
+
rate (float): The discount rate used to calculate the present value of
|
|
182
|
+
the cash flows, which is the yield to maturity (YTM) of the NTN-C.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
float: The NTN-C quotation truncated to 4 decimal places.
|
|
186
|
+
|
|
187
|
+
References:
|
|
188
|
+
- https://www.anbima.com.br/data/files/A0/02/CC/70/8FEFC8104606BDC8B82BA2A8/Metodologias%20ANBIMA%20de%20Precificacao%20Titulos%20Publicos.pdf
|
|
189
|
+
- The semi-annual coupon is set to 2.956301, which represents a 6% annual
|
|
190
|
+
coupon rate compounded semi-annually and rounded to 6 decimal places as per
|
|
191
|
+
Anbima rules.
|
|
192
|
+
|
|
193
|
+
Examples:
|
|
194
|
+
>>> from pyield import ntnc
|
|
195
|
+
>>> ntnc.quotation("21-03-2025", "01-01-2031", 0.067626)
|
|
196
|
+
126.4958
|
|
197
|
+
"""
|
|
198
|
+
# Validate and normalize dates
|
|
199
|
+
settlement = dc.convert_input_dates(settlement)
|
|
200
|
+
maturity = dc.convert_input_dates(maturity)
|
|
201
|
+
|
|
202
|
+
cf_df = cash_flows(settlement, maturity)
|
|
203
|
+
cf_dates = cf_df["PaymentDate"]
|
|
204
|
+
cf_values = cf_df["CashFlow"]
|
|
205
|
+
|
|
206
|
+
# Calculate the number of business days between settlement and cash flow dates
|
|
207
|
+
bdays = bday.count(settlement, cf_dates)
|
|
208
|
+
|
|
209
|
+
# Calculate the number of periods truncated as per Anbima rules
|
|
210
|
+
num_of_years = bt.truncate(bdays / 252, 14)
|
|
211
|
+
|
|
212
|
+
discount_factor = (1 + rate) ** num_of_years
|
|
213
|
+
|
|
214
|
+
# Calculate the present value of each cash flow (DCF) rounded as per Anbima rules
|
|
215
|
+
cf_present_value = (cf_values / discount_factor).round(10)
|
|
216
|
+
|
|
217
|
+
# Return the quotation (the dcf sum) truncated as per Anbima rules
|
|
218
|
+
return bt.truncate(cf_present_value.sum(), 4)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def price(
|
|
222
|
+
vna: float,
|
|
223
|
+
quotation: float,
|
|
224
|
+
) -> float:
|
|
225
|
+
"""
|
|
226
|
+
Calculate the NTN-C price using Anbima rules.
|
|
227
|
+
|
|
228
|
+
price = VNA * quotation / 100
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
vna (float): The nominal value of the NTN-C bond.
|
|
232
|
+
quotation (float): The NTN-C quotation in base 100.
|
|
233
|
+
|
|
234
|
+
Returns:
|
|
235
|
+
float: The NTN-C price truncated to 6 decimal places.
|
|
236
|
+
|
|
237
|
+
References:
|
|
238
|
+
- https://www.anbima.com.br/data/files/A0/02/CC/70/8FEFC8104606BDC8B82BA2A8/Metodologias%20ANBIMA%20de%20Precificacao%20Titulos%20Publicos.pdf
|
|
239
|
+
|
|
240
|
+
Examples:
|
|
241
|
+
>>> from pyield import ntnc
|
|
242
|
+
>>> ntnc.price(6598.913723, 126.4958)
|
|
243
|
+
8347.348705
|
|
244
|
+
"""
|
|
245
|
+
return bt.truncate(vna * quotation / 100, 6)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def duration(
|
|
249
|
+
settlement: DateScalar,
|
|
250
|
+
maturity: DateScalar,
|
|
251
|
+
rate: float,
|
|
252
|
+
) -> float:
|
|
253
|
+
"""
|
|
254
|
+
Calculate the Macaulay duration of the NTN-C bond in business years.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
settlement (DateScalar): The settlement date of the operation.
|
|
258
|
+
maturity (DateScalar): The maturity date of the NTN-C bond.
|
|
259
|
+
rate (float): The discount rate used to calculate the duration.
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
float: The Macaulay duration of the NTN-C bond in business years.
|
|
263
|
+
|
|
264
|
+
Examples:
|
|
265
|
+
>>> from pyield import ntnc
|
|
266
|
+
>>> ntnc.duration("21-03-2025", "01-01-2031", 0.067626)
|
|
267
|
+
4.405363320448003
|
|
268
|
+
"""
|
|
269
|
+
settlement = dc.convert_input_dates(settlement)
|
|
270
|
+
maturity = dc.convert_input_dates(maturity)
|
|
271
|
+
|
|
272
|
+
df = cash_flows(settlement, maturity)
|
|
273
|
+
df["BY"] = bday.count(settlement, df["PaymentDate"]) / 252
|
|
274
|
+
df["DCF"] = df["CashFlow"] / (1 + rate) ** df["BY"]
|
|
275
|
+
np_duration = (df["DCF"] * df["BY"]).sum() / df["DCF"].sum()
|
|
276
|
+
return float(np_duration)
|
|
@@ -8,7 +8,7 @@ from pyield import date_converter as dc
|
|
|
8
8
|
from pyield import interpolator as ip
|
|
9
9
|
from pyield.b3 import di
|
|
10
10
|
from pyield.date_converter import DateScalar
|
|
11
|
-
from pyield.tpf import tools
|
|
11
|
+
from pyield.tpf import tools
|
|
12
12
|
|
|
13
13
|
"""
|
|
14
14
|
Constants calculated as per Anbima Rules
|
|
@@ -34,7 +34,8 @@ def data(date: DateScalar) -> pd.DataFrame:
|
|
|
34
34
|
pd.DataFrame: DataFrame with columns "MaturityDate" and "IndicativeRate".
|
|
35
35
|
|
|
36
36
|
Examples:
|
|
37
|
-
>>>
|
|
37
|
+
>>> from pyield import ntnf
|
|
38
|
+
>>> ntnf.data("23-08-2024")
|
|
38
39
|
ReferenceDate BondType MaturityDate IndicativeRate Price
|
|
39
40
|
0 2024-08-23 NTN-F 2025-01-01 0.107692 1011.189166
|
|
40
41
|
1 2024-08-23 NTN-F 2027-01-01 0.115109 985.834842
|
|
@@ -57,7 +58,8 @@ def maturities(date: DateScalar) -> pd.Series:
|
|
|
57
58
|
pd.Series: A Series of NTN-F bond maturities available for the reference date.
|
|
58
59
|
|
|
59
60
|
Examples:
|
|
60
|
-
>>>
|
|
61
|
+
>>> from pyield import ntnf
|
|
62
|
+
>>> ntnf.maturities("23-08-2024")
|
|
61
63
|
0 2025-01-01
|
|
62
64
|
1 2027-01-01
|
|
63
65
|
2 2029-01-01
|
|
@@ -65,7 +67,6 @@ def maturities(date: DateScalar) -> pd.Series:
|
|
|
65
67
|
4 2033-01-01
|
|
66
68
|
5 2035-01-01
|
|
67
69
|
dtype: datetime64[ns]
|
|
68
|
-
|
|
69
70
|
"""
|
|
70
71
|
df_rates = data(date)
|
|
71
72
|
s_maturities = df_rates["MaturityDate"]
|
|
@@ -106,8 +107,8 @@ def payment_dates(
|
|
|
106
107
|
(exclusive) and maturity (inclusive) dates.
|
|
107
108
|
|
|
108
109
|
Examples:
|
|
109
|
-
|
|
110
|
-
>>>
|
|
110
|
+
>>> from pyield import ntnf
|
|
111
|
+
>>> ntnf.payment_dates("15-05-2024", "01-01-2025")
|
|
111
112
|
0 2024-07-01
|
|
112
113
|
1 2025-01-01
|
|
113
114
|
dtype: datetime64[ns]
|
|
@@ -157,7 +158,8 @@ def cash_flows(
|
|
|
157
158
|
pd.DataFrame: DataFrame with columns "PaymentDate" and "CashFlow".
|
|
158
159
|
|
|
159
160
|
Examples:
|
|
160
|
-
>>>
|
|
161
|
+
>>> from pyield import ntnf
|
|
162
|
+
>>> ntnf.cash_flows("15-05-2024", "01-01-2025")
|
|
161
163
|
PaymentDate CashFlow
|
|
162
164
|
0 2024-07-01 48.80885
|
|
163
165
|
1 2025-01-01 1048.80885
|
|
@@ -206,18 +208,19 @@ def price(
|
|
|
206
208
|
Anbima rules.
|
|
207
209
|
|
|
208
210
|
Examples:
|
|
209
|
-
>>>
|
|
211
|
+
>>> from pyield import ntnf
|
|
212
|
+
>>> ntnf.price("05-07-2024", "01-01-2035", 0.11921)
|
|
210
213
|
895.359254
|
|
211
214
|
"""
|
|
212
215
|
cf_df = cash_flows(settlement, maturity)
|
|
213
216
|
cf_values = cf_df["CashFlow"]
|
|
214
217
|
bdays = bday.count(settlement, cf_df["PaymentDate"])
|
|
215
|
-
byears =
|
|
218
|
+
byears = tools.truncate(bdays / 252, 14)
|
|
216
219
|
discount_factors = (1 + rate) ** byears
|
|
217
220
|
# Calculate the present value of each cash flow (DCF) rounded as per Anbima rules
|
|
218
221
|
dcf = (cf_values / discount_factors).round(9)
|
|
219
222
|
# Return the sum of the discounted cash flows truncated as per Anbima rules
|
|
220
|
-
return
|
|
223
|
+
return tools.truncate(dcf.sum(), 6)
|
|
221
224
|
|
|
222
225
|
|
|
223
226
|
def spot_rates( # noqa
|
|
@@ -254,9 +257,10 @@ def spot_rates( # noqa
|
|
|
254
257
|
"BDToMat" is the business days from the settlement date to the maturities.
|
|
255
258
|
|
|
256
259
|
Examples:
|
|
257
|
-
>>>
|
|
258
|
-
>>>
|
|
259
|
-
>>>
|
|
260
|
+
>>> from pyield import ntnf, ltn
|
|
261
|
+
>>> df_ltn = ltn.data("03-09-2024")
|
|
262
|
+
>>> df_ntnf = ntnf.data("03-09-2024")
|
|
263
|
+
>>> ntnf.spot_rates(
|
|
260
264
|
... settlement="03-09-2024",
|
|
261
265
|
... ltn_maturities=df_ltn["MaturityDate"],
|
|
262
266
|
... ltn_rates=df_ltn["IndicativeRate"],
|
|
@@ -306,7 +310,7 @@ def spot_rates( # noqa
|
|
|
306
310
|
# Calculate the present value of the coupon payments
|
|
307
311
|
cf_dates = payment_dates(settlement, row["MaturityDate"])[:-1] # noqa
|
|
308
312
|
cf_df = df.query("MaturityDate in @cf_dates").reset_index(drop=True)
|
|
309
|
-
cf_present_value =
|
|
313
|
+
cf_present_value = tools.calculate_present_value(
|
|
310
314
|
cash_flows=cf_df["Coupon"],
|
|
311
315
|
rates=cf_df["SpotRate"],
|
|
312
316
|
periods=cf_df["BDToMat"] / 252,
|
|
@@ -339,7 +343,8 @@ def di_spreads(date: DateScalar) -> pd.DataFrame:
|
|
|
339
343
|
pd.DataFrame: DataFrame with columns "MaturityDate", "DISpread".
|
|
340
344
|
|
|
341
345
|
Examples:
|
|
342
|
-
>>>
|
|
346
|
+
>>> from pyield import ntnf
|
|
347
|
+
>>> ntnf.di_spreads("23-08-2024")
|
|
343
348
|
MaturityDate DISpread
|
|
344
349
|
0 2025-01-01 -5.38
|
|
345
350
|
1 2027-01-01 4.39
|
|
@@ -350,7 +355,7 @@ def di_spreads(date: DateScalar) -> pd.DataFrame:
|
|
|
350
355
|
|
|
351
356
|
"""
|
|
352
357
|
# Fetch DI Spreads for the reference date
|
|
353
|
-
df =
|
|
358
|
+
df = tools.pre_spreads(date)
|
|
354
359
|
df = (
|
|
355
360
|
df.query("BondType == 'NTN-F'")
|
|
356
361
|
.sort_values(["MaturityDate"])
|
|
@@ -550,7 +555,7 @@ def premium(
|
|
|
550
555
|
df["DIRate"] = df["BDToMat"].apply(ff_interpolator)
|
|
551
556
|
|
|
552
557
|
# Calculate the present value of the cash flows using the DI rate
|
|
553
|
-
bond_price =
|
|
558
|
+
bond_price = tools.calculate_present_value(
|
|
554
559
|
cash_flows=df["CashFlow"],
|
|
555
560
|
rates=df["DIRate"],
|
|
556
561
|
periods=df["BDToMat"] / 252,
|
|
@@ -599,7 +604,7 @@ def historical_premium(
|
|
|
599
604
|
)
|
|
600
605
|
|
|
601
606
|
# Calculate the present value of the cash flows using the DI rate
|
|
602
|
-
bond_price =
|
|
607
|
+
bond_price = tools.calculate_present_value(
|
|
603
608
|
cash_flows=df["CashFlow"],
|
|
604
609
|
rates=df["DIRate"],
|
|
605
610
|
periods=df["BDToMat"] / 252,
|
|
@@ -625,11 +630,7 @@ def duration(
|
|
|
625
630
|
rate: float,
|
|
626
631
|
) -> float:
|
|
627
632
|
"""
|
|
628
|
-
Calculate the Macaulay duration for an NTN-F bond.
|
|
629
|
-
|
|
630
|
-
The Macaulay duration is a weighted average of the times until each payment is
|
|
631
|
-
received, with the weights proportional to the present value of the cash flows.
|
|
632
|
-
It measures the bond's sensitivity to interest rate changes.
|
|
633
|
+
Calculate the Macaulay duration for an NTN-F bond in business years.
|
|
633
634
|
|
|
634
635
|
Args:
|
|
635
636
|
settlement (DateScalar): The settlement date to calculate the duration.
|
|
@@ -637,10 +638,11 @@ def duration(
|
|
|
637
638
|
rate (float): The yield to maturity (YTM) used to discount the cash flows.
|
|
638
639
|
|
|
639
640
|
Returns:
|
|
640
|
-
float: The Macaulay duration in years.
|
|
641
|
+
float: The Macaulay duration in business business years.
|
|
641
642
|
|
|
642
643
|
Examples:
|
|
643
|
-
>>>
|
|
644
|
+
>>> from pyield import ntnf
|
|
645
|
+
>>> ntnf.duration("02-09-2024", "01-01-2035", 0.121785)
|
|
644
646
|
6.32854218039796
|
|
645
647
|
"""
|
|
646
648
|
settlement = dc.convert_input_dates(settlement)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.31.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|