Many more improvements

This commit is contained in:
jeroen
2023-02-21 15:41:12 +01:00
parent dd925a0ab2
commit 55f0751082
7 changed files with 193 additions and 772 deletions

View File

@@ -8,7 +8,7 @@ from typing import Tuple
import pandas as pd
from openbb_terminal.decorators import log_start_end
from openbb_terminal.rich_config import console
from openbb_terminal.rich_config import console, optional_rich_track
logger = logging.getLogger(__name__)
@@ -49,7 +49,7 @@ def get_ecb_yield_curve(
yield_type: str = "spot_rate",
return_date: bool = False,
detailed: bool = False,
aaa_only: bool = True,
any_rating: bool = True,
) -> Tuple[pd.DataFrame, str]:
"""Gets euro area yield curve data from ECB.
@@ -97,11 +97,11 @@ def get_ecb_yield_curve(
>>> ycrv_df, ycrv_date = openbb.fixedincome.ycrv(return_date=True)
"""
if yield_type == "spot_rate":
yield_type = f"YC.B.U2.EUR.4F.G_N_{'A' if aaa_only else 'C'}.SV_C_YM.SR_"
yield_type = f"YC.B.U2.EUR.4F.G_N_{'A' if any_rating else 'C'}.SV_C_YM.SR_"
elif yield_type == "instantaneous_forward":
yield_type = f"YC.B.U2.EUR.4F.G_N_{'A' if aaa_only else 'C'}.SV_C_YM.IF_"
yield_type = f"YC.B.U2.EUR.4F.G_N_{'A' if any_rating else 'C'}.SV_C_YM.IF_"
elif yield_type == "par_yield":
yield_type = f"YC.B.U2.EUR.4F.G_N_{'A' if aaa_only else 'C'}.SV_C_YM.PY"
yield_type = f"YC.B.U2.EUR.4F.G_N_{'A' if any_rating else 'C'}.SV_C_YM.PY"
else:
console.print("[red]Incorrect input for parameter yield_type[/red]")
if return_date:
@@ -109,6 +109,7 @@ def get_ecb_yield_curve(
return pd.DataFrame()
if detailed:
console.print("Note that due to the large amount of data, this may take a while. Use CTRL + C to cancel.")
series_id = [
f"{yield_type}{y}Y{m}M" if y != 0 else f"{yield_type}{m}M"
for y in range(0, 30)
@@ -149,10 +150,14 @@ def get_ecb_yield_curve(
if not date:
date = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
for i in range(len(series_id)):
temp = get_series_data(series_id[i], date, date)
temp.columns = [labels[i]]
df = pd.concat([df, temp], axis=1)
try:
for i in optional_rich_track( range(len(series_id)), desc="Obtaining yield curve data"):
temp = get_series_data(series_id[i], date, date)
temp.columns = [labels[i]]
df = pd.concat([df, temp], axis=1)
except KeyboardInterrupt:
console.print("Data collection was canceled.")
return pd.DataFrame(), date
if df.empty:
if return_date:
@@ -162,8 +167,13 @@ def get_ecb_yield_curve(
# Drop rows with NaN -- corresponding to weekends typically
df = df.dropna()
if datetime.strptime(date, "%Y-%m-%d") not in df.index:
date_of_yield = df.index[-1].strftime("%Y-%m-%d")
rates = pd.DataFrame(df.iloc[-1, :].values, columns=["Rate"])
nearest_value = df.index.get_indexer([datetime.strptime(date, "%Y-%m-%d")], method='nearest')
date_of_yield = df.iloc[nearest_value].index[0].date()
series = df[df.index == df.iloc[nearest_value].index[0]]
if series.empty:
return pd.DataFrame(), date_of_yield
rates = pd.DataFrame(series.values.T, columns=["Rate"])
console.print(f"{date} not available, therefore selecting the nearest date, {date_of_yield}.")
else:
date_of_yield = date
series = df[df.index == datetime.strptime(date, "%Y-%m-%d")]

View File

@@ -107,7 +107,7 @@ def display_ecb_yield_curve(
date: str = "",
yield_type: str = "spot_rate",
detailed: bool = False,
aaa_only: bool = True,
any_rating: bool = True,
external_axes: Optional[List[plt.Axes]] = None,
raw: bool = False,
export: str = "",
@@ -148,8 +148,9 @@ def display_ecb_yield_curve(
export : str
Export data to csv,json,xlsx or png,jpg,pdf,svg file
"""
print(date)
rates, date_of_yield = ecb_model.get_ecb_yield_curve(
date, yield_type, True, detailed, aaa_only
date, yield_type, True, detailed, any_rating
)
if rates.empty:
console.print(f"[red]Yield data not found for {date_of_yield}.[/red]\n")
@@ -167,8 +168,9 @@ def display_ecb_yield_curve(
theme.style_primary_axis(ax)
if external_axes is None:
ax.set_title(
f"Euro Area{' AAA Bonds' if aaa_only else ' All Bonds'} {yield_type.replace('_', ' ').title()} "
f"Yield Curve for {date_of_yield}"
f"Euro Area{' AAA Bonds' if not any_rating else ' All Bonds'} {yield_type.replace('_', ' ').title()} "
f"Yield Curve for {date_of_yield}",
fontsize=15
)
theme.visualize_output()
@@ -177,7 +179,7 @@ def display_ecb_yield_curve(
rates,
headers=list(rates.columns),
show_index=False,
title=f"Euro Area{' AAA Bonds' if aaa_only else ' All Bonds'} {yield_type.replace('_', ' ').title()} "
title=f"Euro Area{' AAA Bonds' if not any_rating else ' All Bonds'} {yield_type.replace('_', ' ').title()} "
f"Yield Curve for {date_of_yield}",
floatfmt=".3f",
)
@@ -186,6 +188,6 @@ def display_ecb_yield_curve(
export,
os.path.dirname(os.path.abspath(__file__)),
"ecbycrv",
pd.DataFrame(rates, columns=[date_of_yield]) / 100,
rates / 100,
sheet_name
)

View File

@@ -7,6 +7,7 @@ import argparse
import logging
from datetime import datetime, timedelta
from typing import List
import pandas as pd
from openbb_terminal.custom_prompt_toolkit import NestedCompleter
@@ -18,6 +19,7 @@ from openbb_terminal.fixedincome import fred_view, oecd_model
from openbb_terminal.helper_funcs import (
EXPORT_BOTH_RAW_DATA_AND_FIGURES,
list_from_str,
print_rich_table,
valid_date,
EXPORT_ONLY_RAW_DATA_ALLOWED,
)
@@ -45,13 +47,9 @@ class FixedIncomeController(BaseController):
"tmc",
"ffrmc",
"ycrv",
"iiycrv",
"ecbycrv",
"tbill",
"tips",
"cmn",
"usrates",
"tbffr",
"ty"
]
PATH = "/fixedincome/"
@@ -138,32 +136,7 @@ class FixedIncomeController(BaseController):
"6_month": "T6MFF",
"3_month": "T3MFF",
}
tbill_parameter_to_fred_id = {
"4_week": "DTB4WK",
"3_month": "TB3MS",
"6_month": "DTB6",
"1_year": "DTB1YR",
}
tips_parameter_to_fred_id = {
"5_year": "DFII5",
"7_year": "DFII7",
"10_year": "DFII10",
"20_year": "DFII20",
"30_year": "DFII30",
}
cmn_parameter_to_fred_id = {
"1_month": "DGS1MO",
"3_month": "DGS3MO",
"6_month": "DGS6MO",
"1_year": "DGS1",
"2_year": "DGS2",
"3_year": "DGS3",
"5_year": "DGS5",
"7_year": "DGS7",
"10_year": "DGS10",
"20_year": "DGS20",
"30_year": "DGS30",
}
tbffr_parameter_to_fred_id = {
"3_month": "TB3SMFFM",
"6_month": "TB6SMFFM",
@@ -197,15 +170,14 @@ class FixedIncomeController(BaseController):
mt.add_raw("\n")
mt.add_info("_government_bonds_")
mt.add_cmd("treasury")
mt.add_cmd("usrates")
mt.add_cmd("ycrv")
mt.add_cmd("iiycrv")
mt.add_cmd("ecbycrv")
mt.add_cmd("tbill")
mt.add_cmd("cmn")
mt.add_cmd("tips")
mt.add_cmd("ty")
mt.add_raw("\n")
mt.add_info("_corporate_bonds_")
mt.add_raw("\n")
mt.add_info("_spreads_")
mt.add_raw("\n")
mt.add_cmd("tmc")
mt.add_cmd("ffrmc")
mt.add_cmd("tbffr")
@@ -763,76 +735,6 @@ class FixedIncomeController(BaseController):
else None,
)
@log_start_end(log=logger)
def call_ltir(self, other_args: List[str]):
"""Process ltir command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="str",
description="Plot long term interest rates from selected countries. \nLong-term interest rates refer to "
"government bonds maturing in ten years. Rates are mainly determined by the price charged by "
"the lender, the risk from the borrower and the fall in the capital value. Long-term interest "
"rates are generally averages of daily rates, measured as a percentage. These interest rates "
"are implied by the prices at which the government bonds are traded on financial markets, "
"not the interest rates at which the loans were issued. In all cases, they refer to bonds "
"whose capital repayment is guaranteed by governments. Long-term interest rates are one of "
"the determinants of business investment. Low long-term interest rates encourage investment "
"in new equipment and high interest rates discourage it. Investment is, in turn, "
"a major source of economic growth.",
)
parser.add_argument(
"-c",
"--country",
type=str,
action="store",
nargs="+",
dest="countries",
help="Countries to get data for, use three letter country codes.",
default=["USA"],
)
parser.add_argument(
"-s",
"--start",
type=valid_date,
help="Start date of data, in YYYY-MM-DD format",
dest="start_date",
default=None,
)
parser.add_argument(
"-e",
"--end",
type=valid_date,
help="End date of data, in YYYY-MM-DD format",
dest="end_date",
default=None,
)
parser.add_argument(
"--forecast",
action="store_true",
dest="forecast",
default=False,
help="If True, plot forecasts for long term interest rates",
)
ns_parser = self.parse_known_args_and_warn(
parser,
other_args,
export_allowed=EXPORT_ONLY_RAW_DATA_ALLOWED,
raw=True,
)
if ns_parser:
oecd_view.plot_long_term_interest_rate(
countries=ns_parser.countries,
forecast=ns_parser.forecast,
start_date=ns_parser.start_date,
end_date=ns_parser.end_date,
export=ns_parser.export,
sheet_name=" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
)
@log_start_end(log=logger)
def call_tmc(self, other_args: List[str]):
"""Process tmc command"""
@@ -971,6 +873,14 @@ class FixedIncomeController(BaseController):
dest="date",
default=None,
)
parser.add_argument(
"-i",
"--inflation-adjusted",
action="store_true",
help="Whether to plot the inflation adjusted yield curve.",
dest="inflation_adjusted",
default=False,
)
ns_parser = self.parse_known_args_and_warn(
parser,
other_args,
@@ -978,59 +888,9 @@ class FixedIncomeController(BaseController):
raw=True,
)
if ns_parser:
fred_view.display_yield_curve(
date=ns_parser.date.strftime("%Y-%m-%d") if ns_parser.date else "",
raw=ns_parser.raw,
export=ns_parser.export,
sheet_name=" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
)
@log_start_end(log=logger)
def call_iiycrv(self, other_args: List[str]):
"""Process iiycrv command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="iiycrv",
description="Generate US inflation-indexed yield curve. \nThe yield curve shows the bond rates"
"at different maturities.\nThe graphic depiction of the relationship between the yield on bonds of the "
"same credit quality but different maturities is known as the yield curve. In the past, "
"most market participants have constructed yield curves from the observations of prices and "
"yields in the Treasury market. Two reasons account for this tendency. First, "
"Treasury securities are viewed as free of default risk, and differences in creditworthiness "
"do not affect yield estimates. Second, as the most active bond market, the Treasury market "
"offers the fewest problems of illiquidity or infrequent trading. The key function of the "
"Treasury yield curve is to serve as a benchmark for pricing bonds and setting yields in "
"other sectors of the debt market.\nIt is clear that the market’s expectations of future rate "
"changes are one important determinant of the yield-curve shape. For example, "
"a steeply upward-sloping curve may indicate market expectations of near-term Fed tightening "
"or of rising inflation. However, it may be too restrictive to assume that the yield "
"differences across bonds with different maturities only reflect the market’s rate "
"expectations. The well-known pure expectations hypothesis has such an extreme implication. "
"The pure expectations hypothesis asserts that all government bonds have the same near-term "
"expected return (as the nominally riskless short-term bond) because the return-seeking "
"activity of risk-neutral traders removes all expected return differentials across bonds.",
)
parser.add_argument(
"-d",
"--date",
type=valid_date,
help="Date to get data from FRED. If not supplied, the most recent entry will be used.",
dest="date",
default=None,
)
ns_parser = self.parse_known_args_and_warn(
parser,
other_args,
export_allowed=EXPORT_ONLY_RAW_DATA_ALLOWED,
raw=True,
)
if ns_parser:
fred_view.display_inflation_indexed_yield_curve(
date=ns_parser.date.strftime("%Y-%m-%d") if ns_parser.date else "",
inflation_adjusted=ns_parser.inflation_adjusted,
raw=ns_parser.raw,
export=ns_parser.export,
sheet_name=" ".join(ns_parser.sheet_name)
@@ -1089,11 +949,11 @@ class FixedIncomeController(BaseController):
help="If True, returns detailed data. Note that this is very slow.",
)
parser.add_argument(
"--aaa_only",
"--any-rating",
action="store_true",
dest="aaa_only",
default=True,
help="If True, it only returns rates for AAA rated bonds. If False, it returns rates for all bonds.",
dest="any_rating",
default=False,
help="If False, it only returns rates for AAA rated bonds. If True, it returns rates for all bonds.",
)
ns_parser = self.parse_known_args_and_warn(
parser,
@@ -1106,7 +966,7 @@ class FixedIncomeController(BaseController):
date=ns_parser.date.strftime("%Y-%m-%d") if ns_parser.date else "",
yield_type=ns_parser.parameter,
detailed=ns_parser.detailed,
aaa_only=ns_parser.aaa_only,
any_rating=ns_parser.any_rating,
raw=ns_parser.raw,
export=ns_parser.export,
sheet_name=" ".join(ns_parser.sheet_name)
@@ -1115,98 +975,43 @@ class FixedIncomeController(BaseController):
)
@log_start_end(log=logger)
def call_tbill(self, other_args: List[str]):
"""Process tbill command"""
def call_usrates(self, other_args: List[str]):
"""Process usrates command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="tbill",
description="Plot the Treasury Bill Secondary Market Rate.\nA Treasury Bill (T-Bill) is a short-term U.S. "
"government debt obligation backed by the Treasury Department with a maturity of one year or "
"less. Treasury bills are usually sold in denominations of $1,000. However, some can reach a "
"maximum denomination of $5 million in non-competitive bids. These securities are widely "
"regarded as low-risk and secure investments.",
prog="usrates",
description="Plot various rates from the United States. This includes tbill (Treasury Bills), "
"Constant Maturity treasuries (cmn) and Inflation Protected Treasuries (TIPS)"
)
parser.add_argument(
"-p",
"--parameter",
dest="parameter",
"-m",
"--maturity",
dest="maturity",
type=str,
help="Specific Treasury Bill Secondary Market Rate data to plot",
default="3_month",
choices=list(self.tbill_parameter_to_fred_id.keys()),
)
parser.add_argument(
"-s",
"--start",
dest="start_date",
type=valid_date,
help="Starting date (YYYY-MM-DD) of data",
default="1980-01-01",
)
parser.add_argument(
"-e",
"--end",
dest="end_date",
type=valid_date,
help="Ending date (YYYY-MM-DD) of data",
default=None,
)
ns_parser = self.parse_known_args_and_warn(
parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES
)
if ns_parser:
if ns_parser.source == "FRED":
fred_view.plot_tbill(
self.tbill_parameter_to_fred_id[ns_parser.parameter],
ns_parser.start_date,
ns_parser.end_date,
ns_parser.export,
" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
)
elif ns_parser.source == "EconDB":
econdb_view.plot_tbill(
ns_parser.parameter,
ns_parser.start_date,
ns_parser.end_date,
ns_parser.export,
" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
)
@log_start_end(log=logger)
def call_cmn(self, other_args: List[str]):
"""Process cmn command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="cmn",
description="Plot the Treasury Constant Maturity Nominal Market Yield. \nYields on Treasury nominal "
"securities at “constant maturity” are interpolated by the U.S. Treasury from the daily yield "
"curve for non-inflation-indexed Treasury securities. This curve, which relates the yield on "
"a security to its time to maturity, is based on the closing market bid yields on actively "
"traded Treasury securities in the over-the-counter market. These market yields are "
"calculated from composites of quotations obtained by the Federal Reserve Bank of New York. "
"The constant maturity yield values are read from the yield curve at fixed maturities, "
"currently 1, 3, and 6 months and 1, 2, 3, 5, 7, 10, 20, and 30 years. This method provides a "
"yield for a 10-year maturity, for example, even if no outstanding security has exactly 10 "
"years remaining to maturity. Similarly, yields on inflation-indexed securities at “constant "
"maturity” are interpolated from the daily yield curve for Treasury inflation protected "
"securities in the over-the-counter market. The inflation-indexed constant maturity yields "
"are read from this yield curve at fixed maturities, currently 5, 7, 10, 20, and 30 years.",
choices=list(fred_view.USARATES_TO_FRED_ID.keys()),
)
parser.add_argument(
"-p",
"--parameter",
dest="parameter",
type=str,
help="Specific Treasury Constant Maturity Nominal Market Yield data to plot",
default="3_month",
choices=list(self.cmn_parameter_to_fred_id.keys()),
help="Choose either tbill (Treasury Bills), Constant Maturity treasuries (cmn) "
"or Inflation Protected Treasuries (TIPS)",
default="tbill",
choices=['tbill', 'cmn', 'tips']
)
parser.add_argument(
"-o",
"--options",
dest="options",
action="store_true",
help="See the available options",
default=False
)
parser.add_argument(
"-s",
"--start",
@@ -1224,96 +1029,25 @@ class FixedIncomeController(BaseController):
default=None,
)
ns_parser = self.parse_known_args_and_warn(
parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES
parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES, raw=True
)
if ns_parser:
if ns_parser.source == "FRED":
fred_view.plot_cmn(
self.cmn_parameter_to_fred_id[ns_parser.parameter],
ns_parser.start_date,
ns_parser.end_date,
ns_parser.export,
" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
if ns_parser.options:
print_rich_table(
pd.DataFrame.from_dict(fred_view.USARATES_TO_FRED_ID).T.fillna("-"),
show_index=True,
title="Available options including FRED Series name"
)
elif ns_parser.source == "EconDB":
econdb_view.plot_cmn(
ns_parser.parameter,
ns_parser.start_date,
ns_parser.end_date,
ns_parser.export,
" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
)
@log_start_end(log=logger)
def call_tips(self, other_args: List[str]):
"""Process tips command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="tips",
description="Plot Yields on Treasury inflation protected securities (TIPS) adjusted to constant "
"maturities. \nYields on Treasury nominal securities at “constant maturity” are interpolated "
"by the U.S. Treasury from the daily yield curve for non-inflation-indexed Treasury "
"securities. This curve, which relates the yield on a security to its time to maturity, "
"is based on the closing market bid yields on actively traded Treasury securities in the "
"over-the-counter market. These market yields are calculated from composites of quotations "
"obtained by the Federal Reserve Bank of New York. The constant maturity yield values are "
"read from the yield curve at fixed maturities, currently 1, 3, and 6 months and 1, 2, 3, 5, "
"7, 10, 20, and 30 years. This method provides a yield for a 10-year maturity, for example, "
"even if no outstanding security has exactly 10 years remaining to maturity. Similarly, "
"yields on inflation-indexed securities at “constant maturity” are interpolated from the "
"daily yield curve for Treasury inflation protected securities in the over-the-counter "
"market. The inflation-indexed constant maturity yields are read from this yield curve at "
"fixed maturities, currently 5, 7, 10, 20, and 30 years.",
)
parser.add_argument(
"-p",
"--parameter",
dest="parameter",
type=str,
help="Specific Yields on TIPS adjusted to constant maturities data to plot",
default="10_year",
choices=list(self.tips_parameter_to_fred_id.keys()),
)
parser.add_argument(
"-s",
"--start",
dest="start_date",
type=valid_date,
help="Starting date (YYYY-MM-DD) of data",
default="1980-01-01",
)
parser.add_argument(
"-e",
"--end",
dest="end_date",
type=valid_date,
help="Ending date (YYYY-MM-DD) of data",
default=None,
)
ns_parser = self.parse_known_args_and_warn(
parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES
)
if ns_parser:
if ns_parser.source == "FRED":
fred_view.plot_tips(
self.tips_parameter_to_fred_id[ns_parser.parameter],
ns_parser.start_date,
ns_parser.end_date,
ns_parser.export,
" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
)
elif ns_parser.source == "EconDB":
econdb_view.plot_tips(
elif ns_parser.parameter not in fred_view.USARATES_TO_FRED_ID[ns_parser.maturity]:
console.print(f"[red]Maturity {ns_parser.maturity.replace('_', ' ')} is not "
f"available for {ns_parser.parameter}. Please use 'usrates --options'.[/red]")
else:
fred_view.plot_usrates(
ns_parser.parameter,
ns_parser.maturity,
ns_parser.start_date,
ns_parser.end_date,
ns_parser.raw,
ns_parser.export,
" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
@@ -1366,52 +1100,4 @@ class FixedIncomeController(BaseController):
" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
)
@log_start_end(log=logger)
def call_ty(self, other_args: List[str]):
"""Process ty command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="ty",
description="Plot Selected Treasury Yield.",
)
parser.add_argument(
"-p",
"--parameter",
dest="parameter",
type=str,
help="Selected Treasury Yield",
default="10_year",
choices=["5_year", "10_year", "30_year"],
)
parser.add_argument(
"-s",
"--start",
dest="start_date",
type=valid_date,
help="Starting date (YYYY-MM-DD) of data",
default=None,
)
parser.add_argument(
"-e",
"--end",
dest="end_date",
type=valid_date,
help="Ending date (YYYY-MM-DD) of data",
default=None,
)
ns_parser = self.parse_known_args_and_warn(
parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES
)
if ns_parser:
yfinance_view.plot_ty(
ns_parser.parameter,
ns_parser.start_date,
ns_parser.end_date,
ns_parser.export,
" ".join(ns_parser.sheet_name)
if ns_parser.sheet_name
else None,
)
)

View File

@@ -19,6 +19,30 @@ from openbb_terminal.decorators import log_start_end, check_api_key
logger = logging.getLogger(__name__)
YIELD_CURVE_SERIES_NOMINAL = {
"1Month": "DGS1MO",
"3Month": "DGS3MO",
"6Month": "DGS6MO",
"1Year": "DGS1",
"2Year": "DGS2",
"3Year": "DGS3",
"5Year": "DGS5",
"7Year": "DGS7",
"10Year": "DGS10",
"20Year": "DGS20",
"30Year": "DGS30",
}
YIELD_CURVE_SERIES_REAL = {
"5Year": "DFII5",
"7Year": "DFII7",
"10Year": "DFII10",
"20Year": "DFII20",
"30Year": "DFII30",
}
YIELD_CURVE_NOMINAL_RATES = [1 / 12, 0.25, 0.5, 1, 2, 3, 5, 7, 10, 20, 30]
YIELD_CURVE_REAL_RATES = [5, 7, 10, 20, 30]
@log_start_end(log=logger)
@check_api_key(["API_FRED_KEY"])
@@ -59,7 +83,7 @@ def get_series_data(
@log_start_end(log=logger)
@check_api_key(["API_FRED_KEY"])
def get_yield_curve(
date: str = "", return_date: bool = False
date: str = "", return_date: bool = False, inflation_adjusted: bool = False
) -> Tuple[pd.DataFrame, str]:
"""Gets yield curve data from FRED.
@@ -108,19 +132,7 @@ def get_yield_curve(
# os.environ["SSL_CERT_FILE"] = certifi.where()
fredapi_client = Fred(cfg.API_FRED_KEY)
fred_series = {
"1Month": "DGS1MO",
"3Month": "DGS3MO",
"6Month": "DGS6MO",
"1Year": "DGS1",
"2Year": "DGS2",
"3Year": "DGS3",
"5Year": "DGS5",
"7Year": "DGS7",
"10Year": "DGS10",
"20Year": "DGS20",
"30Year": "DGS30",
}
df = pd.DataFrame()
# Check that the date is in the past
today = datetime.now().strftime("%Y-%m-%d")
@@ -136,6 +148,13 @@ def get_yield_curve(
if not date:
date = (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d")
get_last = True
if inflation_adjusted:
fred_series = YIELD_CURVE_SERIES_REAL
years = YIELD_CURVE_REAL_RATES
else:
fred_series = YIELD_CURVE_SERIES_NOMINAL
years = YIELD_CURVE_NOMINAL_RATES
for key, s_id in fred_series.items():
df = pd.concat(
@@ -167,119 +186,7 @@ def get_yield_curve(
rates.insert(
0,
"Maturity",
[1 / 12, 0.25, 0.5, 1, 2, 3, 5, 7, 10, 20, 30],
)
if return_date:
return rates, date_of_yield
return rates
@log_start_end(log=logger)
@check_api_key(["API_FRED_KEY"])
def get_inflation_indexed_yield_curve(
date: str = "", return_date: bool = False
) -> Tuple[pd.DataFrame, str]:
"""Gets inflation-indexed yield curve data from FRED.
The graphic depiction of the relationship between the yield on bonds of the same credit quality but different
maturities is known as the yield curve. In the past, most market participants have constructed yield curves from
the observations of prices and yields in the Treasury market. Two reasons account for this tendency. First,
Treasury securities are viewed as free of default risk, and differences in creditworthiness do not affect yield
estimates. Second, as the most active bond market, the Treasury market offers the fewest problems of illiquidity
or infrequent trading. The key function of the Treasury yield curve is to serve as a benchmark for pricing bonds
and setting yields in other sectors of the debt market.
It is clear that the market’s expectations of future rate changes are one important determinant of the
yield-curve shape. For example, a steeply upward-sloping curve may indicate market expectations of near-term Fed
tightening or of rising inflation. However, it may be too restrictive to assume that the yield differences across
bonds with different maturities only reflect the market’s rate expectations. The well-known pure expectations
hypothesis has such an extreme implication. The pure expectations hypothesis asserts that all government bonds
have the same near-term expected return (as the nominally riskless short-term bond) because the return-seeking
activity of risk-neutral traders removes all expected return differentials across bonds.
Parameters
----------
date: str
Date to get curve for. If empty, gets most recent date (format yyyy-mm-dd)
return_date: bool
If True, returns date of yield curve
Returns
-------
Tuple[pd.DataFrame, str]
Dataframe of yields and maturities,
Date for which the yield curve is obtained
Examples
--------
>>> from openbb_terminal.sdk import openbb
>>> ycrv_df = openbb.fixedincome.iiycrv()
Since there is a delay with the data, the most recent date is returned and can be accessed with return_date=True
>>> ycrv_df, ycrv_date = openbb.fixedincome.iiycrv(return_date=True)
"""
# Necessary for installer so that it can locate the correct certificates for
# API calls and https
# https://stackoverflow.com/questions/27835619/urllib-and-ssl-certificate-verify-failed-error/73270162#73270162
# os.environ["REQUESTS_CA_BUNDLE"] = certifi.where()
# os.environ["SSL_CERT_FILE"] = certifi.where()
fredapi_client = Fred(cfg.API_FRED_KEY)
fred_series = {
"5Year": "DFII5",
"7Year": "DFII7",
"10Year": "DFII10",
"20Year": "DFII20",
"30Year": "DFII30",
}
df = pd.DataFrame()
# Check that the date is in the past
today = datetime.now().strftime("%Y-%m-%d")
if date and date >= today:
console.print("[red]Date cannot be today or in the future[/red]")
if return_date:
return pd.DataFrame(), date
return pd.DataFrame()
# Add in logic that will get the most recent date.
get_last = False
if not date:
date = (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d")
get_last = True
for key, s_id in fred_series.items():
df = pd.concat(
[
df,
pd.DataFrame(fredapi_client.get_series(s_id, date), columns=[key]),
],
axis=1,
)
if df.empty:
if return_date:
return pd.DataFrame(), date
return pd.DataFrame()
# Drop rows with NaN -- corresponding to weekends typically
df = df.dropna()
if date not in df.index or get_last:
# If the get_last flag is true, we want the first date, otherwise we want the last date.
idx = -1 if get_last else 0
date_of_yield = df.index[idx].strftime("%Y-%m-%d")
rates = pd.DataFrame(df.iloc[idx, :].values, columns=["Rate"])
else:
date_of_yield = date
series = df[df.index == date]
if series.empty:
return pd.DataFrame(), date_of_yield
rates = pd.DataFrame(series.values.T, columns=["Rate"])
rates.insert(
0,
"Maturity",
[5, 7, 10, 20, 30],
years
)
if return_date:
return rates, date_of_yield

View File

@@ -139,6 +139,21 @@ NAME_TO_ID_ECB = {
"refinancing": "ECBMRRFR"
}
USARATES_TO_FRED_ID = {
"4_week": {"tbill": "DTB4WK"},
"1_month": { "cmn": "DGS1MO"},
"3_month": {"tbill": "TB3MS", "cmn": "DGS3MO"},
"6_month": {"tbill": "DTB6", "cmn": "DGS6MO"},
"1_year": {"tbill": "DTB1YR", "cmn": "DGS1"},
"2_year": {"cmn": "DGS2"},
"3_year": {"cmn": "DGS3"},
"5_year": {"tips": "DFII5", "cmn": "DGS5"},
"7_year": {"tips": "DFII7", "cmn": "DGS7"},
"10_year": {"tips": "DFII10", "cmn": "DGS10"},
"20_year": {"tips": "DFII20", "cmn": "DGS20"},
"30_year": {"tips": "DFII30", "cmn": "DGS30"},
}
@log_start_end(log=logger)
@check_api_key(["API_FRED_KEY"])
@@ -1201,10 +1216,11 @@ def plot_ffrmc(
@check_api_key(["API_FRED_KEY"])
def display_yield_curve(
date: str = "",
external_axes: Optional[List[plt.Axes]] = None,
inflation_adjusted: bool = False,
raw: bool = False,
export: str = "",
sheet_name: str = "",
external_axes: Optional[List[plt.Axes]] = None,
):
"""Display yield curve based on US Treasury rates for a specified date.
@@ -1235,7 +1251,7 @@ def display_yield_curve(
export : str
Export data to csv,json,xlsx or png,jpg,pdf,svg file
"""
rates, date_of_yield = fred_model.get_yield_curve(date, True)
rates, date_of_yield = fred_model.get_yield_curve(date, True, inflation_adjusted)
if rates.empty:
console.print(f"[red]Yield data not found for {date_of_yield}.[/red]\n")
return
@@ -1251,7 +1267,7 @@ def display_yield_curve(
ax.set_ylabel("Rate (%)")
theme.style_primary_axis(ax)
if external_axes is None:
ax.set_title(f"US Yield Curve for {date_of_yield} ")
ax.set_title(f"US {'Real' if inflation_adjusted else 'Nominal'} Yield Curve for {date_of_yield} ")
theme.visualize_output()
if raw:
@@ -1259,7 +1275,7 @@ def display_yield_curve(
rates,
headers=list(rates.columns),
show_index=False,
title=f"United States Yield Curve for {date_of_yield}",
title=f"United States {'Real' if inflation_adjusted else 'Nominal'} Yield Curve for {date_of_yield}",
floatfmt=".3f",
)
@@ -1267,105 +1283,46 @@ def display_yield_curve(
export,
os.path.dirname(os.path.abspath(__file__)),
"ycrv",
pd.DataFrame(rates, columns=["YCRV"]) / 100,
rates.set_index('Maturity') / 100,
sheet_name
)
@log_start_end(log=logger)
@check_api_key(["API_FRED_KEY"])
def display_inflation_indexed_yield_curve(
date: str = "",
external_axes: Optional[List[plt.Axes]] = None,
def plot_usrates(
parameter: str = "tbills",
maturity: str = "3_months",
start_date: Optional[str] = None,
end_date: Optional[str] = None,
raw: bool = False,
export: str = "",
sheet_name: str = "",
):
"""Display inflation-indexed yield curve based on US Treasury rates for a specified date.
The graphic depiction of the relationship between the yield on bonds of the same credit quality but different
maturities is known as the yield curve. In the past, most market participants have constructed yield curves from
the observations of prices and yields in the Treasury market. Two reasons account for this tendency. First,
Treasury securities are viewed as free of default risk, and differences in creditworthiness do not affect yield
estimates. Second, as the most active bond market, the Treasury market offers the fewest problems of illiquidity
or infrequent trading. The key function of the Treasury yield curve is to serve as a benchmark for pricing bonds
and setting yields in other sectors of the debt market.
It is clear that the market’s expectations of future rate changes are one important determinant of the
yield-curve shape. For example, a steeply upward-sloping curve may indicate market expectations of near-term Fed
tightening or of rising inflation. However, it may be too restrictive to assume that the yield differences across
bonds with different maturities only reflect the market’s rate expectations. The well-known pure expectations
hypothesis has such an extreme implication. The pure expectations hypothesis asserts that all government bonds
have the same near-term expected return (as the nominally riskless short-term bond) because the return-seeking
activity of risk-neutral traders removes all expected return differentials across bonds.
Parameters
----------
date: str
Date to get curve for. If None, gets most recent date (format yyyy-mm-dd)
external_axes : Optional[List[plt.Axes]], optional
External axes (1 axis is expected in the list), by default None
raw : bool
Output only raw data
export : str
Export data to csv,json,xlsx or png,jpg,pdf,svg file
"""
rates, date_of_yield = fred_model.get_inflation_indexed_yield_curve(date, True)
if rates.empty:
console.print(f"[red]Yield data not found for {date_of_yield}.[/red]\n")
return
if external_axes is None:
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
elif is_valid_axes_count(external_axes, 1):
(ax,) = external_axes
else:
return
ax.plot(rates["Maturity"], rates["Rate"], "-o")
ax.set_xlabel("Maturity")
ax.set_ylabel("Rate (%)")
theme.style_primary_axis(ax)
if external_axes is None:
ax.set_title(f"US Yield Curve for {date_of_yield} ")
theme.visualize_output()
if raw:
print_rich_table(
rates,
headers=list(rates.columns),
show_index=False,
title=f"United States Yield Curve for {date_of_yield}",
floatfmt=".3f",
)
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"iiycrv",
pd.DataFrame(rates, columns=["IIYCRV"]) / 100,
sheet_name
)
@log_start_end(log=logger)
@check_api_key(["API_FRED_KEY"])
def plot_tbill(
series_id: str = "TB3MS",
start_date: Optional[str] = None,
end_date: Optional[str] = None,
export: str = "",
sheet_name: str = "",
external_axes: Optional[List[plt.Axes]] = None,
):
"""Plot Treasury Bill Secondary Market Rate.
"""Plot various treasury rates from the United States
A Treasury Bill (T-Bill) is a short-term U.S. government debt obligation backed by the Treasury Department with a
maturity of one year or less. Treasury bills are usually sold in denominations of $1,000. However, some can reach
a maximum denomination of $5 million in non-competitive bids. These securities are widely regarded as low-risk
and secure investments.
Yields on Treasury nominal securities at “constant maturity” are interpolated by the U.S. Treasury from the daily
yield curve for non-inflation-indexed Treasury securities. This curve, which relates the yield on a security to
its time to maturity, is based on the closing market bid yields on actively traded Treasury securities in the
over-the-counter market. These market yields are calculated from composites of quotations obtained by the Federal
Reserve Bank of New York. The constant maturity yield values are read from the yield curve at fixed maturities,
currently 1, 3, and 6 months and 1, 2, 3, 5, 7, 10, 20, and 30 years. This method provides a yield for a 10-year
maturity, for example, even if no outstanding security has exactly 10 years remaining to maturity. Similarly,
yields on inflation-indexed securities at “constant maturity” are interpolated from the daily yield curve for
Treasury inflation protected securities in the over-the-counter market. The inflation-indexed constant maturity
yields are read from this yield curve at fixed maturities, currently 5, 7, 10, 20, and 30 years.
Parameters
----------
parameter: str
Either "tbills", "cmn", or "tips".
maturity: str
Depending on the chosen parameter, a set of maturities is available.
series_id: str
FRED ID of Treasury Bill Secondary Market Rate data to plot, options: ['TB3MS', 'DTB4WK', 'DTB1YR', 'DTB6']
start_date: Optional[str]
@@ -1377,6 +1334,7 @@ def plot_tbill(
external_axes: Optional[List[plt.Axes]]
External axes (1 axis is expected in the list)
"""
series_id = USARATES_TO_FRED_ID[maturity][parameter]
df = fred_model.get_series_data(
series_id=series_id, start_date=start_date, end_date=end_date
)
@@ -1393,170 +1351,37 @@ def plot_tbill(
ax.plot(
df.index,
df.values,
marker="o",
linestyle="dashed",
linewidth=2,
markersize=4,
color=next(colors, "#FCED00"),
)
ax.set_title(f"{ID_TO_NAME_SECONDARY[series_id]} Treasury Bill Secondary Market Rate, Discount Basis [Percent]")
if parameter == "tbill":
title = f"{maturity.replace('_', ' ').title()} Treasury Bill Secondary Market Rate, Discount Basis"
elif parameter == "cmn":
title = f"{maturity.replace('_', ' ').title()} Treasury Constant Maturity Nominal Market Yield"
elif parameter == "tips":
title = f"{maturity.replace('_', ' ').title()} Yields on Treasury inflation protected securities (TIPS) adjusted to constant maturities"
ax.set_title(title, fontsize=15)
ax.set_ylabel("Yield (%})")
theme.style_primary_axis(ax)
if external_axes is None:
theme.visualize_output()
if raw:
print_rich_table(
pd.DataFrame(df, columns=[parameter]).iloc[-10:],
title=title,
show_index=True,
floatfmt=".3f",
)
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
series_id,
pd.DataFrame(df, columns=["TBILL"]) / 100,
sheet_name
)
@log_start_end(log=logger)
@check_api_key(["API_FRED_KEY"])
def plot_cmn(
series_id: str = "DGS10",
start_date: Optional[str] = None,
end_date: Optional[str] = None,
export: str = "",
sheet_name: str = "",
external_axes: Optional[List[plt.Axes]] = None,
):
"""Plot Treasury Constant Maturity Nominal Market Yield.
Yields on Treasury nominal securities at “constant maturity” are interpolated by the U.S. Treasury from the daily
yield curve for non-inflation-indexed Treasury securities. This curve, which relates the yield on a security to
its time to maturity, is based on the closing market bid yields on actively traded Treasury securities in the
over-the-counter market. These market yields are calculated from composites of quotations obtained by the Federal
Reserve Bank of New York. The constant maturity yield values are read from the yield curve at fixed maturities,
currently 1, 3, and 6 months and 1, 2, 3, 5, 7, 10, 20, and 30 years. This method provides a yield for a 10-year
maturity, for example, even if no outstanding security has exactly 10 years remaining to maturity. Similarly,
yields on inflation-indexed securities at “constant maturity” are interpolated from the daily yield curve for
Treasury inflation protected securities in the over-the-counter market. The inflation-indexed constant maturity
yields are read from this yield curve at fixed maturities, currently 5, 7, 10, 20, and 30 years.
Parameters
----------
series_id: str
FRED ID of Treasury Constant Maturity Nominal Market Yield data to plot, options: ['DGS1MO', 'DGS3MO', 'DGS6MO', 'DGS1', 'DGS2', 'DGS3', 'DGS5', 'DGS7', 'DGS10', 'DGS20', DGS30']
start_date: Optional[str]
Start date, formatted YYYY-MM-DD
end_date: Optional[str]
End date, formatted YYYY-MM-DD
export: str
Export data to csv or excel file
external_axes: Optional[List[plt.Axes]]
External axes (1 axis is expected in the list)
"""
df = fred_model.get_series_data(
series_id=series_id, start_date=start_date, end_date=end_date
)
# This plot has 1 axis
if not external_axes:
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
elif is_valid_axes_count(external_axes, 1):
(ax,) = external_axes
else:
return
colors = cycle(theme.get_colors())
ax.plot(
df.index,
df.values,
marker="o",
linestyle="dashed",
linewidth=2,
markersize=4,
color=next(colors, "#FCED00"),
)
ax.set_title(f"{ID_TO_NAME_CMN[series_id]} Treasury Constant Maturity Nominal Market Yield [Percent]")
theme.style_primary_axis(ax)
if external_axes is None:
theme.visualize_output()
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
series_id,
pd.DataFrame(df, columns=["CMN"]) / 100,
sheet_name
)
@log_start_end(log=logger)
@check_api_key(["API_FRED_KEY"])
def plot_tips(
series_id: str = "DFII10",
start_date: Optional[str] = None,
end_date: Optional[str] = None,
export: str = "",
sheet_name: str = "",
external_axes: Optional[List[plt.Axes]] = None,
):
"""Plot Plot Yields on Treasury inflation protected securities (TIPS) adjusted to constant maturities.
Yields on Treasury nominal securities at “constant maturity” are interpolated by the U.S. Treasury from the daily
yield curve for non-inflation-indexed Treasury securities. This curve, which relates the yield on a security to
its time to maturity, is based on the closing market bid yields on actively traded Treasury securities in the
over-the-counter market. These market yields are calculated from composites of quotations obtained by the Federal
Reserve Bank of New York. The constant maturity yield values are read from the yield curve at fixed maturities,
currently 1, 3, and 6 months and 1, 2, 3, 5, 7, 10, 20, and 30 years. This method provides a yield for a 10-year
maturity, for example, even if no outstanding security has exactly 10 years remaining to maturity. Similarly,
yields on inflation-indexed securities at “constant maturity” are interpolated from the daily yield curve for
Treasury inflation protected securities in the over-the-counter market. The inflation-indexed constant maturity
yields are read from this yield curve at fixed maturities, currently 5, 7, 10, 20, and 30 years.
Parameters
----------
series_id: str
FRED ID of TIPS adjusted to constant maturities data to plot, options: ['DFII5', 'DFII7', 'DFII10', 'DFII20', 'DFII30']
start_date: Optional[str]
Start date, formatted YYYY-MM-DD
end_date: Optional[str]
End date, formatted YYYY-MM-DD
export: str
Export data to csv or excel file
external_axes: Optional[List[plt.Axes]]
External axes (1 axis is expected in the list)
"""
df = fred_model.get_series_data(
series_id=series_id, start_date=start_date, end_date=end_date
)
# This plot has 1 axis
if not external_axes:
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
elif is_valid_axes_count(external_axes, 1):
(ax,) = external_axes
else:
return
colors = cycle(theme.get_colors())
ax.plot(
df.index,
df.values,
marker="o",
linestyle="dashed",
linewidth=2,
markersize=4,
color=next(colors, "#FCED00"),
)
ax.set_title(f"{ID_TO_NAME_TIPS[series_id]} Yields on Treasury inflation protected securities (TIPS) adjusted to "
f"constant maturities [Percent]")
theme.style_primary_axis(ax)
if external_axes is None:
theme.visualize_output()
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
series_id,
pd.DataFrame(df, columns=["TIPS"]) / 100,
pd.DataFrame(df, columns=[parameter]) / 100,
sheet_name
)

View File

@@ -499,20 +499,15 @@
"fed": ["FRED"],
"iorb": ["FRED"],
"projection": ["FRED"],
"oldprojetion": ["FRED"],
"dwpcr": ["FRED"],
"ecb": ["FRED"],
"treasury": ["OECD"],
"usrates": ["FRED"],
"ycrv": ["FRED"],
"ecbycrv": ["ECB"],
"tmc": ["FRED"],
"ffrmc": ["FRED"],
"ycrv": ["FRED"],
"iiycrv": ["FRED"],
"ecbycrv": ["ECB"],
"tbill": ["FRED", "EconDB"],
"cmn": ["FRED", "EconDB"],
"tips": ["FRED", "EconDB"],
"tbffr": ["FRED"],
"ty": ["YahooFinance"]
"tbffr": ["FRED"]
},
"portfolio": {
"po": {

View File

@@ -790,16 +790,12 @@ en:
fixedincome/projection: the Federal Reserve's projection of the federal funds rate.
fixedincome/dwpcr: discount window primary credit rate
fixedincome/ecb: key ECB interest rates
fixedincome/treasury: plot countries (incl. forecasted) short term interest rate
fixedincome/_yield_curves_: Yield curves
fixedincome/ycrv: plot US yield curve
fixedincome/iiycrv: plot US inflation-indexed yield curve
fixedincome/ecbycrv: plot euro area yield curve
fixedincome/_government_bonds_: Government Bonds
fixedincome/tbill: plot secondary market rate of treasury bills
fixedincome/cmn: plot nominal constant maturity treasuries
fixedincome/tips: plot treasury inflation protected securities (tips)
fixedincome/ty: plot treasury yields
fixedincome/treasury: plot countries (including forecast) treasury rates
fixedincome/usrates: plot secondary market, constant maturity or inflation protected rates
fixedincome/ycrv: plot US yield curve
fixedincome/ecbycrv: plot euro area yield curve
fixedincome/_corporate_bonds_: Corporate Bonds
fixedincome/_spreads_: Spreads
fixedincome/tmc: 10-year treasury constant maturity minus selected treasury constant maturity
fixedincome/ffrmc: selected treasury constant maturity minus federal funds rate