Skip to content

Commit

Permalink
Add in Fixed Income metrics to Economics section
Browse files Browse the repository at this point in the history
  • Loading branch information
JerBouma committed Apr 2, 2024
1 parent ceb8fa7 commit 253d691
Show file tree
Hide file tree
Showing 2 changed files with 565 additions and 1 deletion.
278 changes: 277 additions & 1 deletion financetoolkit/economics/economics_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import pandas as pd

from financetoolkit.economics import ecb_model, fed_model, oecd_model
from financetoolkit.economics import ecb_model, fed_model, fred_model, oecd_model
from financetoolkit.helpers import calculate_growth, handle_errors

# pylint: disable=too-many-instance-attributes,too-few-public-methods,too-many-lines,
Expand Down Expand Up @@ -1439,6 +1439,282 @@ def get_federal_reserve_rates(self, rate: str = "EFFR"):

return fed_data

@handle_errors
def get_option_adjusted_spread(
self,
maturity: bool = True,
rounding: int | None = None,
):
"""
The ICE BofA Option-Adjusted Spreads (OASs) are the calculated spreads between a computed OAS index
of all bonds in a given maturity and rating category and a spot Treasury curve. An OAS index is constructed
using each constituent bond's OAS, weighted by market capitalization.
The Option-Adjusted Spread (OAS) is the spread relative to a risk-free interest rate, usually measured in
basis points (bp), that equates the theoretical present value of a series of uncertain cash flows to the
market price of a fixed-income investment. The spread is added to the risk-free rate to compensate for the
uncertainty of the cash flows.
See definitions:
- Ratings: https://fred.stlouisfed.org/series/BAMLC0A4CBBB
- Maturity: https://fred.stlouisfed.org/series/BAMLC1A0C13Y
Args:
maturity (bool, optional): Whether to return the maturity option adjusted spread or the rating option adjusted spread.
rounding (int | None, optional): The number of decimals to round the results to. Defaults to None.
Returns:
pd.DataFrame: A DataFrame containing the Option Adjusted Spread
As an example:
```python
from financetoolkit import Economics
economics = Economics(
start_date='2024-01-01',
end_date='2024-01-15',
)
economics.get_option_adjusted_spread()
```
Which returns:
| Date | 1-3 Years | 3-5 Years | 5-7 Years | 7-10 Years | 10-15 Years | 15+ Years |
|:-----------|------------:|------------:|------------:|-------------:|--------------:|------------:|
| 2024-01-01 | 77 | 94 | 108.5 | 127 | 131.5 | 118 |
| 2024-01-02 | 78 | 95 | 109 | 128 | 133 | 119 |
| 2024-01-03 | 80 | 98 | 113 | 133 | 136 | 122 |
| 2024-01-04 | 80 | 98 | 112 | 133 | 135 | 122 |
| 2024-01-05 | 80 | 98 | 112 | 132 | 134 | 121 |
| 2024-01-08 | 79 | 98 | 112 | 132 | 134 | 120 |
| 2024-01-09 | 78 | 96 | 110 | 130 | 131 | 117 |
| 2024-01-10 | 77 | 94 | 108 | 128 | 128 | 113 |
| 2024-01-11 | 75 | 94 | 107 | 128 | 127 | 113 |
| 2024-01-12 | 74 | 94 | 107 | 128 | 126 | 112 |
| 2024-01-15 | 74 | 94 | 107 | 128 | 125 | 111 |
"""
option_adjusted_spread = (
fred_model.get_maturity_option_adjusted_spread()
if maturity
else fred_model.get_rating_option_adjusted_spread()
)

option_adjusted_spread = option_adjusted_spread.loc[
self._start_date : self._end_date
]

option_adjusted_spread = option_adjusted_spread.round(
rounding if rounding else self._rounding
)

return option_adjusted_spread

@handle_errors
def get_effective_yield(
self,
maturity: bool = True,
rounding: int | None = None,
):
"""
This data represents the effective yield of the ICE BofA Indices, When the last calendar day of the month
takes place on the weekend, weekend observations will occur as a result of month ending accrued interest adjustments.
The Effective Yield is the yield of a bond, calculated by dividing the bond's coupon payments by its market price.
The effective yield is not the same as the stated yield, which is the yield on the bond's coupon payments divided
by the bond's principal value. The effective yield is a more accurate measure of a bond's return, as it takes into
account the fact that the investor will not hold the bond to maturity and will likely sell it before it matures.
See definitions:
- Ratings: https://fred.stlouisfed.org/series/BAMLC0A4CBBBEY
- Maturity: https://fred.stlouisfed.org/series/BAMLC1A0C13YEY
Args:
maturity (bool, optional): Whether to return the maturity effective yield or the rating effective yield.
rounding (int | None, optional): The number of decimals to round the results to. Defaults to None.
Returns:
pd.DataFrame: A DataFrame containing the Gross Domestic Product
As an example:
```python
from financetoolkit import Economics
economics = Economics(
start_date='2024-01-01',
end_date='2024-01-15',
)
economics.get_effective_yield(maturity=False)
```
Which returns:
| Date | AAA | AA | A | BBB | BB | B | CCC |
|:-----------|-------:|-------:|-------:|-------:|-------:|-------:|-------:|
| 2024-01-01 | 0.0456 | 0.047 | 0.0505 | 0.054 | 0.0613 | 0.0752 | 0.1319 |
| 2024-01-02 | 0.0459 | 0.0473 | 0.0509 | 0.0543 | 0.0622 | 0.0763 | 0.1333 |
| 2024-01-03 | 0.0459 | 0.0474 | 0.051 | 0.0544 | 0.0634 | 0.0779 | 0.1358 |
| 2024-01-04 | 0.0466 | 0.0481 | 0.0518 | 0.0551 | 0.0639 | 0.0784 | 0.1367 |
| 2024-01-05 | 0.047 | 0.0485 | 0.0521 | 0.0554 | 0.0641 | 0.0787 | 0.137 |
| 2024-01-08 | 0.0465 | 0.0481 | 0.0517 | 0.055 | 0.0633 | 0.0776 | 0.1365 |
| 2024-01-09 | 0.0464 | 0.048 | 0.0516 | 0.0548 | 0.0629 | 0.0771 | 0.1359 |
| 2024-01-10 | 0.0464 | 0.048 | 0.0515 | 0.0547 | 0.0622 | 0.0762 | 0.1351 |
| 2024-01-11 | 0.0456 | 0.0472 | 0.0507 | 0.054 | 0.0619 | 0.076 | 0.1344 |
| 2024-01-12 | 0.0451 | 0.0467 | 0.0502 | 0.0534 | 0.0613 | 0.0753 | 0.1338 |
| 2024-01-15 | 0.0451 | 0.0467 | 0.0501 | 0.0533 | 0.0611 | 0.0751 | 0.1328 |
"""
effective_yield = (
fred_model.get_maturity_effective_yield()
if maturity
else fred_model.get_rating_effective_yield()
)

effective_yield = effective_yield.loc[self._start_date : self._end_date]

effective_yield = effective_yield.round(
rounding if rounding else self._rounding
)

return effective_yield

@handle_errors
def get_total_return(
self,
maturity: bool = True,
rounding: int | None = None,
):
"""
This data represents the total return of the ICE BofA Indices, When the last calendar day of the month
takes place on the weekend, weekend observations will occur as a result of month ending accrued interest adjustments.
The total return is the actual rate of return of an investment or a pool of investments over a given evaluation period.
Total return includes interest, capital gains, dividends and distributions realized over a given period of time.
See definitions:
- Ratings: https://fred.stlouisfed.org/series/BAMLC0A4CBBBEY
- Maturity: https://fred.stlouisfed.org/series/BAMLC1A0C13YEY
Args:
maturity (bool, optional): Whether to return the maturity total return or the rating total return.
rounding (int | None, optional): The number of decimals to round the results to. Defaults to None.
Returns:
pd.DataFrame: A DataFrame containing the Gross Domestic Product
As an example:
```python
from financetoolkit import Economics
economics = Economics(
start_date='2024-01-01',
end_date='2024-01-15',
)
economics.get_total_return(maturity=True)
```
Which returns:
| Date | 1-3 Years | 3-5 Years | 5-7 Years | 7-10 Years | 10-15 Years | 15+ Years |
|:-----------|------------:|------------:|------------:|-------------:|--------------:|------------:|
| 2024-01-01 | 1913.78 | 2487.68 | 809.13 | 585.705 | 4206.25 | 4358.69 |
| 2024-01-02 | 1912.73 | 2484.25 | 807.62 | 584.32 | 4193.7 | 4343.71 |
| 2024-01-03 | 1912.18 | 2483.95 | 807.54 | 583.84 | 4194.39 | 4339.07 |
| 2024-01-04 | 1910.86 | 2477.9 | 804.35 | 580.42 | 4163.24 | 4289.24 |
| 2024-01-05 | 1910.86 | 2475.75 | 802.82 | 578.73 | 4148.31 | 4262.52 |
| 2024-01-08 | 1912.48 | 2480.39 | 804.97 | 580.71 | 4167.04 | 4302.16 |
| 2024-01-09 | 1913.5 | 2482.27 | 805.72 | 581.26 | 4173.04 | 4303.34 |
| 2024-01-10 | 1914.12 | 2483.6 | 806.21 | 581.29 | 4175.16 | 4304.82 |
| 2024-01-11 | 1918.28 | 2492.25 | 809.94 | 583.92 | 4200.49 | 4330.72 |
| 2024-01-12 | 1922.1 | 2498.89 | 812.41 | 585.2 | 4213.47 | 4338.43 |
| 2024-01-15 | 1922.67 | 2499.76 | 812.67 | 585.41 | 4215.34 | 4340.24 |
"""
total_return = (
fred_model.get_maturity_total_return()
if maturity
else fred_model.get_rating_total_return()
)

total_return = total_return.loc[self._start_date : self._end_date]

total_return = total_return.round(rounding if rounding else self._rounding)

return total_return

@handle_errors
def get_yield_to_worst(
self,
maturity: bool = True,
rounding: int | None = None,
):
"""
This data represents the semi-annual yield to worst of the ICE BofA Indices, When the last calendar day of the month
takes place on the weekend, weekend observations will occur as a result of month ending accrued interest adjustments.
Yield to worst is the lowest potential yield that a bond can generate without the issuer defaulting. The standard US
convention for this series is to use semi-annual coupon payments, whereas the standard in the foreign markets is
to use coupon payments with frequencies of annual, semi-annual, quarterly, and monthly.
See definitions:
- Ratings: https://fred.stlouisfed.org/series/BAMLC0A4CBBBEY
- Maturity: https://fred.stlouisfed.org/series/BAMLC1A0C13YEY
Args:
maturity (bool, optional): Whether to return the maturity yield to worst or the rating yield to worst.
rounding (int | None, optional): The number of decimals to round the results to. Defaults to None.
Returns:
pd.DataFrame: A DataFrame containing the Gross Domestic Product
As an example:
```python
from financetoolkit import Economics
economics = Economics(
start_date='2024-01-01',
end_date='2024-01-15',
)
economics.get_yield_to_worst(maturity=False)
```
Which returns:
| Date | AAA | AA | A | BBB | BB | B | CCC |
|:-----------|-------:|-------:|-------:|-------:|-------:|-------:|-------:|
| 2024-01-01 | 0.0456 | 0.0472 | 0.0503 | 0.0542 | 0.0645 | 0.0786 | 0.1316 |
| 2024-01-02 | 0.046 | 0.0475 | 0.0506 | 0.0546 | 0.0652 | 0.0796 | 0.1329 |
| 2024-01-03 | 0.0461 | 0.0475 | 0.0507 | 0.0547 | 0.0662 | 0.081 | 0.1353 |
| 2024-01-04 | 0.0468 | 0.0483 | 0.0515 | 0.0554 | 0.0665 | 0.0814 | 0.136 |
| 2024-01-05 | 0.0471 | 0.0486 | 0.0518 | 0.0557 | 0.0667 | 0.0816 | 0.1362 |
| 2024-01-08 | 0.0466 | 0.0482 | 0.0514 | 0.0553 | 0.066 | 0.0806 | 0.1359 |
| 2024-01-09 | 0.0465 | 0.0481 | 0.0513 | 0.0551 | 0.0656 | 0.0803 | 0.1353 |
| 2024-01-10 | 0.0465 | 0.0481 | 0.0512 | 0.0551 | 0.065 | 0.0795 | 0.1345 |
| 2024-01-11 | 0.0458 | 0.0473 | 0.0504 | 0.0543 | 0.0648 | 0.0793 | 0.134 |
| 2024-01-12 | 0.0453 | 0.0468 | 0.0499 | 0.0537 | 0.0642 | 0.0786 | 0.1335 |
| 2024-01-15 | 0.0452 | 0.0468 | 0.0498 | 0.0537 | 0.064 | 0.0784 | 0.1325 |
"""
yield_to_worst = (
fred_model.get_maturity_yield_to_worst()
if maturity
else fred_model.get_rating_yield_to_worst()
)

yield_to_worst = yield_to_worst.loc[self._start_date : self._end_date]

yield_to_worst = yield_to_worst.round(rounding if rounding else self._rounding)

return yield_to_worst

def get_renewable_energy(
self,
growth: bool = False,
Expand Down
Loading

0 comments on commit 253d691

Please sign in to comment.