mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-29 13:32:08 +00:00
Add fixed income menu
This commit is contained in:
39
openbb_terminal/fixedincome/ecb_model.py
Normal file
39
openbb_terminal/fixedincome/ecb_model.py
Normal file
@@ -0,0 +1,39 @@
|
||||
""" ECB model """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import logging
|
||||
import pandas as pd
|
||||
|
||||
from openbb_terminal.decorators import log_start_end
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def get_series_data(
|
||||
series_id: str = "EST.B.EU000A2X2A25.WT", start_date: str = "", end_date: str = ""
|
||||
):
|
||||
"""Get ECB data
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series_id: str
|
||||
ECB ID of data
|
||||
start_date: Optional[str]
|
||||
Start date, formatted YYYY-MM-DD
|
||||
end_date: Optional[str]
|
||||
End date, formatted YYYY-MM-DD
|
||||
"""
|
||||
start_date = start_date[0:4] + start_date[4:7] + start_date[8:9]
|
||||
end_date = end_date[0:4] + end_date[4:7] + end_date[8:9]
|
||||
|
||||
df = pd.read_csv(
|
||||
f"https://sdw.ecb.europa.eu/quickviewexport.do?trans=N&start={start_date}&end={end_date}&SERIES_KEY={series_id}&type=csv",
|
||||
header=5,
|
||||
usecols=[0, 1],
|
||||
index_col=0,
|
||||
parse_dates=True,
|
||||
)
|
||||
df = df.iloc[::-1]
|
||||
|
||||
return df
|
||||
90
openbb_terminal/fixedincome/ecb_view.py
Normal file
90
openbb_terminal/fixedincome/ecb_view.py
Normal file
@@ -0,0 +1,90 @@
|
||||
""" ECB view """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
from typing import Optional, List
|
||||
from itertools import cycle
|
||||
import logging
|
||||
import os
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
from openbb_terminal.config_terminal import theme
|
||||
from openbb_terminal.config_plot import PLOT_DPI
|
||||
from openbb_terminal.decorators import log_start_end
|
||||
from openbb_terminal.helper_funcs import (
|
||||
export_data,
|
||||
plot_autoscale,
|
||||
is_valid_axes_count,
|
||||
)
|
||||
from openbb_terminal.fixedincome.ecb_model import get_series_data
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
ID_TO_NAME = {
|
||||
"EST.B.EU000A2X2A25.WT": "Euro Short-Term Rate: Volume-Weighted Trimmed Mean Rate [Percent]",
|
||||
"EST.B.EU000A2X2A25.TT": "Euro Short-Term Rate: Total Volume [Millions of EUR]",
|
||||
"EST.B.EU000A2X2A25.NT": "Euro Short-Term Rate: Number of Transactions",
|
||||
"EST.B.EU000A2X2A25.R75": "Euro Short-Term Rate: Rate at 75th Percentile of Volume [Percent]",
|
||||
"EST.B.EU000A2X2A25.NB": "Euro Short-Term Rate: Number of Active Banks",
|
||||
"EST.B.EU000A2X2A25.VL": "Euro Short-Term Rate: Share of Volume of the 5 Largest Active Banks [Percent]",
|
||||
"EST.B.EU000A2X2A25.R25": "Euro Short-Term Rate: Rate at 25th Percentile of Volume [Percent]",
|
||||
}
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def plot_estr(
|
||||
series_id: str = "EST.B.EU000A2X2A25.WT",
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Euro Short-Term Rate (ESTR)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series_id: str
|
||||
ECB ID of ESTR data to plot, options: ['EST.B.EU000A2X2A25.WT', 'EST.B.EU000A2X2A25.TT', 'EST.B.EU000A2X2A25.NT', 'EST.B.EU000A2X2A25.R75', 'EST.B.EU000A2X2A25.NB', 'EST.B.EU000A2X2A25.VL', 'EST.B.EU000A2X2A25.R25']
|
||||
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 = get_series_data(
|
||||
series_id, start_date if start_date else "", end_date if end_date else ""
|
||||
)
|
||||
|
||||
# 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(ID_TO_NAME[series_id])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"estr, {series_id}",
|
||||
df,
|
||||
)
|
||||
703
openbb_terminal/fixedincome/fixedincome_controller.py
Normal file
703
openbb_terminal/fixedincome/fixedincome_controller.py
Normal file
@@ -0,0 +1,703 @@
|
||||
""" Futures Controller """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
# pylint:disable=too-many-lines
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List
|
||||
|
||||
from openbb_terminal.custom_prompt_toolkit import NestedCompleter
|
||||
|
||||
from openbb_terminal import feature_flags as obbff
|
||||
from openbb_terminal.decorators import log_start_end
|
||||
from openbb_terminal.fixedincome import ecb_view, nyfed_view
|
||||
from openbb_terminal.fixedincome import fred_view
|
||||
|
||||
from openbb_terminal.helper_funcs import (
|
||||
EXPORT_BOTH_RAW_DATA_AND_FIGURES,
|
||||
valid_date,
|
||||
)
|
||||
from openbb_terminal.parent_classes import BaseController
|
||||
from openbb_terminal.rich_config import console, MenuText
|
||||
from openbb_terminal.menu import session
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FixedIncomeController(BaseController):
|
||||
"""Fixed Income Controller class"""
|
||||
|
||||
CHOICES_COMMANDS = [
|
||||
"estr",
|
||||
"sofr",
|
||||
"sonia",
|
||||
"ameribor",
|
||||
"ffer",
|
||||
"fftr",
|
||||
"effr",
|
||||
"obfr",
|
||||
"iorb",
|
||||
"projection",
|
||||
"oldprojection",
|
||||
"dwpcr",
|
||||
]
|
||||
|
||||
PATH = "/fixedincome/"
|
||||
CHOICES_GENERATION = True
|
||||
|
||||
estr_parameter_to_fred_id = {
|
||||
"volume_weighted_trimmed_mean_rate": "ECBESTRVOLWGTTRMDMNRT",
|
||||
"total_volume": "ECBESTRTOTVOL",
|
||||
"number_of_transactions": "ECBESTRNUMTRANS",
|
||||
"rate_at_75th_percentile_of_volume": "ECBESTRRT75THPCTVOL",
|
||||
"number_of_active_banks": "ECBESTRNUMACTBANKS",
|
||||
"share_of_volume_of_the_5_largest_active_banks": "ECBESTRSHRVOL5LRGACTBNK",
|
||||
"rate_at_25th_percentile_of_volume": "ECBESTRRT25THPCTVOL",
|
||||
}
|
||||
estr_parameter_to_ecb_id = {
|
||||
"volume_weighted_trimmed_mean_rate": "EST.B.EU000A2X2A25.WT",
|
||||
"total_volume": "EST.B.EU000A2X2A25.TT",
|
||||
"number_of_transactions": "EST.B.EU000A2X2A25.NT",
|
||||
"rate_at_75th_percentile_of_volume": "EST.B.EU000A2X2A25.R75",
|
||||
"number_of_active_banks": "EST.B.EU000A2X2A25.NB",
|
||||
"share_of_volume_of_the_5_largest_active_banks": "EST.B.EU000A2X2A25.VL",
|
||||
"rate_at_25th_percentile_of_volume": "EST.B.EU000A2X2A25.R25",
|
||||
}
|
||||
sofr_parameter_to_fred_id = {
|
||||
"overnight": "SOFR",
|
||||
"30_day": "SOFR30DAYAVG",
|
||||
"90_day": "SOFR90DAYAVG",
|
||||
"180_day": "SOFR180DAYAVG",
|
||||
"index": "SOFRINDEX",
|
||||
}
|
||||
sonia_parameter_to_fred_id = {
|
||||
"rate": "IUDSOIA",
|
||||
"index": "IUDZOS2",
|
||||
"10th_percentile": "IUDZLS6",
|
||||
"25th_percentile": "IUDZLS7",
|
||||
"75th_percentile": "IUDZLS8",
|
||||
"90th_percentile": "IUDZLS9",
|
||||
"total_nominal_value": "IUDZLT2",
|
||||
}
|
||||
ameribor_parameter_to_fred_id = {
|
||||
"overnight": "AMERIBOR",
|
||||
"term_30": "AMBOR30T",
|
||||
"term_90": "AMBOR90T",
|
||||
"1_week_term_structure": "AMBOR1W",
|
||||
"1_month_term_structure": "AMBOR1M",
|
||||
"3_month_term_structure": "AMBOR3M",
|
||||
"6_month_term_structure": "AMBOR6M",
|
||||
"1_year_term_structure": "AMBOR1Y",
|
||||
"2_year_term_structure": "AMBOR2Y",
|
||||
"30_day_ma": "AMBOR30",
|
||||
"90_day_ma": "AMBOR90",
|
||||
}
|
||||
ffer_parameter_to_fred_id = {
|
||||
"monthly": "FEDFUNDS",
|
||||
"daily": "DFF",
|
||||
"weekly": "FF",
|
||||
"daily_excl_weekend": "RIFSPFFNB",
|
||||
"annual": "RIFSPFFNA",
|
||||
"biweekly": "RIFSPFFNBWAW",
|
||||
}
|
||||
effr_parameter_to_fred_id = {
|
||||
"rate": "EFFR",
|
||||
"volume": "EFFRVOL",
|
||||
"1th_percentile": "EFFR1",
|
||||
"25th_percentile": "EFFR25",
|
||||
"75th_percentile": "EFFR75",
|
||||
"99th_percentile": "EFFR99",
|
||||
}
|
||||
effr_parameter_to_nyfed_id = {
|
||||
"rate": "percentRate",
|
||||
"volume": "volumeInBillions",
|
||||
"1th_percentile": "percentPercentile1",
|
||||
"25th_percentile": "percentPercentile25",
|
||||
"75th_percentile": "percentPercentile75",
|
||||
"99th_percentile": "percentPercentile99",
|
||||
}
|
||||
obfr_parameter_to_fred_id = {
|
||||
"rate": "OBFR",
|
||||
"volume": "OBFRVOL",
|
||||
"1th_percentile": "EFFR1",
|
||||
"25th_percentile": "EFFR25",
|
||||
"75th_percentile": "EFFR75",
|
||||
"99th_percentile": "EFFR99",
|
||||
}
|
||||
dwpcr_parameter_to_fred_id = {
|
||||
"daily_excl_weekend": "DPCREDIT",
|
||||
"monthly": "MPCREDIT",
|
||||
"weekly": "WPCREDIT",
|
||||
"daily": "RIFSRPF02ND",
|
||||
"annual": "RIFSRPF02NA",
|
||||
}
|
||||
|
||||
def __init__(self, queue: List[str] = None):
|
||||
"""Constructor"""
|
||||
super().__init__(queue)
|
||||
|
||||
if session and obbff.USE_PROMPT_TOOLKIT:
|
||||
self.choices: dict = self.choices_default
|
||||
self.completer = NestedCompleter.from_nested_dict(self.choices) # type: ignore
|
||||
|
||||
def print_help(self):
|
||||
"""Print help"""
|
||||
mt = MenuText("fixedincome/")
|
||||
mt.add_info("_reference_rates_")
|
||||
mt.add_cmd("estr")
|
||||
mt.add_cmd("sofr")
|
||||
mt.add_cmd("sonia")
|
||||
mt.add_cmd("ameribor")
|
||||
mt.add_raw("\n")
|
||||
mt.add_info("_other_interest_rates_")
|
||||
mt.add_cmd("ffer")
|
||||
mt.add_cmd("fftr")
|
||||
mt.add_cmd("effr")
|
||||
mt.add_cmd("obfr")
|
||||
mt.add_cmd("iorb")
|
||||
mt.add_cmd("projection")
|
||||
mt.add_cmd("oldprojection")
|
||||
mt.add_cmd("dwpcr")
|
||||
|
||||
console.print(text=mt.menu_text, menu="Fixed Income")
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_estr(self, other_args: List[str]):
|
||||
"""Process estr command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="estr",
|
||||
description="Get Euro Short-Term Rate data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--parameter",
|
||||
dest="parameter",
|
||||
type=str,
|
||||
help="Specific Euro Short-Term Rate data to retrieve",
|
||||
default="volume_weighted_trimmed_mean_rate",
|
||||
choices=list(self.estr_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=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:
|
||||
if ns_parser.source == "FRED":
|
||||
fred_view.plot_estr(
|
||||
self.estr_parameter_to_fred_id[ns_parser.parameter],
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
elif ns_parser.source == "ECB":
|
||||
ecb_view.plot_estr(
|
||||
self.estr_parameter_to_ecb_id[ns_parser.parameter],
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_sofr(self, other_args: List[str]):
|
||||
"""Process sofr command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="sofr",
|
||||
description="Get Secured Overnight Financing Rate (SOFR) data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--parameter",
|
||||
dest="parameter",
|
||||
type=str,
|
||||
help="Specific SOFR data to retrieve",
|
||||
default="overnight",
|
||||
choices=list(self.sofr_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_sofr(
|
||||
self.sofr_parameter_to_fred_id[ns_parser.parameter],
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
elif ns_parser.source == "NYFED":
|
||||
nyfed_view.plot_sofr(
|
||||
ns_parser.parameter,
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_sonia(self, other_args: List[str]):
|
||||
"""Process sonia command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="sonia",
|
||||
description="Get Sterling Overnight Index Average (SONIA) data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--parameter",
|
||||
dest="parameter",
|
||||
type=str,
|
||||
help="Specific SONIA data to retrieve",
|
||||
default="rate",
|
||||
choices=list(self.sonia_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=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:
|
||||
fred_view.plot_sonia(
|
||||
self.sonia_parameter_to_fred_id[ns_parser.parameter],
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_ameribor(self, other_args: List[str]):
|
||||
"""Process ameribor command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="ameribor",
|
||||
description="Get American Interbank Offered Rate (AMERIBOR) data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--parameter",
|
||||
dest="parameter",
|
||||
type=str,
|
||||
help="Specific AMERIBOR data to retrieve",
|
||||
default="overnight",
|
||||
choices=list(self.ameribor_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=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:
|
||||
fred_view.plot_ameribor(
|
||||
self.ameribor_parameter_to_fred_id[ns_parser.parameter],
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_ffer(self, other_args: List[str]):
|
||||
"""Process ffer command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="ffer",
|
||||
description="Get Federal Funds Effective Rate data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--parameter",
|
||||
dest="parameter",
|
||||
type=str,
|
||||
help="Specific Federal Funds Effective Rate data to retrieve",
|
||||
default="monthly",
|
||||
choices=list(self.ffer_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=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:
|
||||
fred_view.plot_ffer(
|
||||
self.ffer_parameter_to_fred_id[ns_parser.parameter],
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_fftr(self, other_args: List[str]):
|
||||
"""Process fftr command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="fftr",
|
||||
description="Get Federal Funds Target Range data",
|
||||
)
|
||||
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_fftr(
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
elif ns_parser.source == "NYFED":
|
||||
nyfed_view.plot_fftr(
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_effr(self, other_args: List[str]):
|
||||
"""Process effr command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="effr",
|
||||
description="Get Effective Federal Funds Rate data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--parameter",
|
||||
dest="parameter",
|
||||
type=str,
|
||||
help="Specific Effective Federal Funds Rate data to retrieve",
|
||||
default="rate",
|
||||
choices=list(self.effr_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_effr(
|
||||
self.effr_parameter_to_fred_id[ns_parser.parameter],
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
elif ns_parser.source == "NYFED":
|
||||
nyfed_view.plot_effr(
|
||||
self.effr_parameter_to_nyfed_id[ns_parser.parameter],
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_obfr(self, other_args: List[str]):
|
||||
"""Process obfr command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="obfr",
|
||||
description="Get Overnight Bank Funding Rate data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--parameter",
|
||||
dest="parameter",
|
||||
type=str,
|
||||
help="Specific Overnight Bank Funding Rate data to retrieve",
|
||||
default="rate",
|
||||
choices=list(self.obfr_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_obfr(
|
||||
self.obfr_parameter_to_fred_id[ns_parser.parameter],
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
elif ns_parser.source == "NYFED":
|
||||
nyfed_view.plot_obfr(
|
||||
self.effr_parameter_to_nyfed_id[ns_parser.parameter],
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_iorb(self, other_args: List[str]):
|
||||
"""Process iorb command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="iorb",
|
||||
description="Get Interest Rate on Reserve Balances data",
|
||||
)
|
||||
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:
|
||||
fred_view.plot_iorb(
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_projection(self, other_args: List[str]):
|
||||
"""Process projection command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="projection",
|
||||
description="Get FOMC Summary of Economic Projections for the Fed Funds Rate",
|
||||
)
|
||||
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:
|
||||
fred_view.plot_projection(
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_oldprojection(self, other_args: List[str]):
|
||||
"""Process oldprojection command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="oldprojection",
|
||||
description="Get Longer Run FOMC Summary of Economic Projections for the Fed Funds Rate",
|
||||
)
|
||||
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:
|
||||
fred_view.plot_oldprojection(
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def call_dwpcr(self, other_args: List[str]):
|
||||
"""Process dwpcr command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="dwpcr",
|
||||
description="Get Discount Window Primary Credit Rate data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--parameter",
|
||||
dest="parameter",
|
||||
type=str,
|
||||
help="Specific Discount Window Primary Credit Rate data to retrieve",
|
||||
default="daily_excl_weekend",
|
||||
choices=list(self.dwpcr_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=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:
|
||||
fred_view.plot_dwpcr(
|
||||
self.dwpcr_parameter_to_fred_id[ns_parser.parameter],
|
||||
ns_parser.start_date,
|
||||
ns_parser.end_date,
|
||||
ns_parser.export,
|
||||
)
|
||||
57
openbb_terminal/fixedincome/fred_model.py
Normal file
57
openbb_terminal/fixedincome/fred_model.py
Normal file
@@ -0,0 +1,57 @@
|
||||
""" FRED model """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import os
|
||||
import logging
|
||||
from typing import Optional
|
||||
from requests import HTTPError
|
||||
|
||||
import pandas as pd
|
||||
from fredapi import Fred
|
||||
import certifi
|
||||
|
||||
from openbb_terminal import config_terminal as cfg
|
||||
from openbb_terminal.rich_config import console
|
||||
from openbb_terminal.decorators import log_start_end, check_api_key
|
||||
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def get_series_data(
|
||||
series_id: str, start_date: Optional[str] = None, end_date: Optional[str] = None
|
||||
) -> pd.DataFrame:
|
||||
"""Get Series data. [Source: FRED]
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series_id : str
|
||||
Series ID to get data from
|
||||
start_date : Optional[str]
|
||||
Start date to get data from, format yyyy-mm-dd
|
||||
end_date : Optional[str]
|
||||
End data to get from, format yyyy-mm-dd
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame
|
||||
Series data
|
||||
"""
|
||||
df = pd.DataFrame()
|
||||
|
||||
try:
|
||||
# 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)
|
||||
df = fredapi_client.get_series(series_id, start_date, end_date)
|
||||
# Series does not exist & invalid api keys
|
||||
except HTTPError as e:
|
||||
console.print(e)
|
||||
|
||||
return df
|
||||
855
openbb_terminal/fixedincome/fred_view.py
Normal file
855
openbb_terminal/fixedincome/fred_view.py
Normal file
@@ -0,0 +1,855 @@
|
||||
""" FRED view """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
from typing import Optional, List
|
||||
from itertools import cycle
|
||||
import logging
|
||||
import os
|
||||
|
||||
import pandas as pd
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
from openbb_terminal.config_terminal import theme
|
||||
from openbb_terminal.config_plot import PLOT_DPI
|
||||
from openbb_terminal.decorators import log_start_end, check_api_key
|
||||
from openbb_terminal.helper_funcs import (
|
||||
export_data,
|
||||
plot_autoscale,
|
||||
is_valid_axes_count,
|
||||
)
|
||||
from openbb_terminal.fixedincome.fred_model import get_series_data
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
ID_TO_NAME_ESTR = {
|
||||
"ECBESTRVOLWGTTRMDMNRT": "Euro Short-Term Rate: Volume-Weighted Trimmed Mean Rate [Percent]",
|
||||
"ECBESTRTOTVOL": "Euro Short-Term Rate: Total Volume [Millions of EUR]",
|
||||
"ECBESTRNUMTRANS": "Euro Short-Term Rate: Number of Transactions",
|
||||
"ECBESTRRT75THPCTVOL": "Euro Short-Term Rate: Rate at 75th Percentile of Volume [Percent]",
|
||||
"ECBESTRNUMACTBANKS": "Euro Short-Term Rate: Number of Active Banks",
|
||||
"ECBESTRSHRVOL5LRGACTBNK": "Euro Short-Term Rate: Share of Volume of the 5 Largest Active Banks [Percent]",
|
||||
"ECBESTRRT25THPCTVOL": "Euro Short-Term Rate: Rate at 25th Percentile of Volume [Percent]",
|
||||
}
|
||||
ID_TO_NAME_SOFR = {
|
||||
"SOFR": "Secured Overnight Financing Rate (SOFR) [Percent]",
|
||||
"SOFR30DAYAVG": "30-Day Average SOFR [Percent]",
|
||||
"SOFR90DAYAVG": "90-Day Average SOFR [Percent]",
|
||||
"SOFR180DAYAVG": "180-Day Average SOFR [Percent]",
|
||||
"SOFRINDEX": "SOFR Index",
|
||||
}
|
||||
ID_TO_NAME_SONIA = {
|
||||
"IUDSOIA": "Daily Sterling Overnight Index Average (SONIA) Rate [Percent]",
|
||||
"IUDZOS2": "SONIA Compounded Index",
|
||||
"IUDZLS6": "SONIA Rate: 10th percentile [Percent]",
|
||||
"IUDZLS7": "SONIA Rate: 25th percentile [Percent]",
|
||||
"IUDZLS8": "SONIA Rate: 75th percentile [Percent]",
|
||||
"IUDZLS9": "SONIA Rate: 90th percentile [Percent]",
|
||||
"IUDZLT2": "SONIA Rate Total Nominal Value [Millions of GBP]",
|
||||
}
|
||||
ID_TO_NAME_AMERIBOR = {
|
||||
"AMERIBOR": "Overnight Unsecured AMERIBOR Benchmark Interest Rate [Percent]",
|
||||
"AMBOR30T": "AMERIBOR Term-30 Derived Interest Rate Index [Percent]",
|
||||
"AMBOR90T": "AMERIBOR Term-90 Derived Interest Rate Index [Percent]",
|
||||
"AMBOR1W": "1-Week AMERIBOR Term Structure of Interest Rates",
|
||||
"AMBOR1M": "1-Month AMERIBOR Term Structure of Interest Rates",
|
||||
"AMBOR3M": "3-Month AMERIBOR Term Structure of Interest Rates",
|
||||
"AMBOR6M": "6-Month AMERIBOR Term Structure of Interest Rates",
|
||||
"AMBOR1Y": "1-Year AMERIBOR Term Structure of Interest Rates",
|
||||
"AMBOR2Y": "2-Year AMERIBOR Term Structure of Interest Rates",
|
||||
"AMBOR30": "30-Day Moving Average AMERIBOR Benchmark Interest Rate",
|
||||
"AMBOR90": "90-Day Moving Average AMERIBOR Benchmark Interest Rate",
|
||||
}
|
||||
ID_TO_NAME_FFER = {
|
||||
"FEDFUNDS": "Monthly",
|
||||
"DFF": "Daily (incl. Weekends)",
|
||||
"FF": "Weekly",
|
||||
"RIFSPFFNB": "Daily (excl. Weekends)",
|
||||
"RIFSPFFNA": "Annual",
|
||||
"RIFSPFFNBWAW": "Biweekly",
|
||||
}
|
||||
ID_TO_NAME_EFFR = {
|
||||
"EFFR": "Effective Federal Funds Rate [Percent]",
|
||||
"EFFRVOL": "Effective Federal Funds Volume [Billions of USD]",
|
||||
"EFFR1": "Effective Federal Funds Rate: 1th Percentile [Percent]",
|
||||
"EFFR25": "Effective Federal Funds Rate: 25th Percentile [Percent]",
|
||||
"EFFR75": "Effective Federal Funds Rate: 75th Percentile [Percent]",
|
||||
"EFFR99": "Effective Federal Funds Rate: 99th Percentile [Percent]",
|
||||
}
|
||||
ID_TO_NAME_OBFR = {
|
||||
"OBFR": "Overnight Bank Funding Rate [Percent]",
|
||||
"OBFRVOL": "Overnight Bank Funding Volume [Billions of USD]",
|
||||
"OBFR1": "Overnight Bank Funding Rate: 1th Percentile [Percent]",
|
||||
"OBFR25": "Overnight Bank Funding Rate: 25th Percentile [Percent]",
|
||||
"OBFR75": "Overnight Bank Funding Rate: 75th Percentile [Percent]",
|
||||
"OBFR99": "Overnight Bank Funding Rate: 99th Percentile [Percent]",
|
||||
}
|
||||
ID_TO_NAME_DWPCR = {
|
||||
"MPCREDIT": "Monthly",
|
||||
"RIFSRPF02ND": "Daily (incl. Weekends)",
|
||||
"WPCREDIT": "Weekly",
|
||||
"DPCREDIT": "Daily (excl. Weekends)",
|
||||
"RIFSRPF02NA": "Annual",
|
||||
}
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_estr(
|
||||
series_id: str = "ECBESTRVOLWGTTRMDMNRT",
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Euro Short-Term Rate (ESTR)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series_id: str
|
||||
FRED ID of ESTR data to plot, options: ['ECBESTRVOLWGTTRMDMNRT', 'ECBESTRTOTVOL', 'ECBESTRNUMTRANS', 'ECBESTRRT75THPCTVOL', 'ECBESTRNUMACTBANKS', 'ECBESTRSHRVOL5LRGACTBNK', 'ECBESTRRT25THPCTVOL']
|
||||
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 = 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(ID_TO_NAME_ESTR[series_id])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"estr, {series_id}",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_sofr(
|
||||
series_id: str = "SOFR",
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Secured Overnight Financing Rate (SOFR)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series_id: str
|
||||
FRED ID of SOFR data to plot, options: ['SOFR', 'SOFR30DAYAVG', 'SOFR90DAYAVG', 'SOFR180DAYAVG', 'SOFRINDEX']
|
||||
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 = 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(ID_TO_NAME_SOFR[series_id])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"sofr, {series_id}",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_sonia(
|
||||
series_id: str = "IUDSOIA",
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Sterling Overnight Index Average (SONIA)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series_id: str
|
||||
FRED ID of SONIA data to plot, options: ['IUDSOIA', 'IUDZOS2', 'IUDZLS6', 'IUDZLS7', 'IUDZLS8', 'IUDZLS9', 'IUDZLT2']
|
||||
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 = 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(ID_TO_NAME_SONIA[series_id])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"sonia, {series_id}",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_ameribor(
|
||||
series_id: str = "AMERIBOR",
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot American Interbank Offered Rate (AMERIBOR)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series_id: str
|
||||
FRED ID of AMERIBOR data to plot, options: ['AMERIBOR', 'AMBOR30T', 'AMBOR90T', 'AMBOR1W', 'AMBOR1M', 'AMBOR3M', 'AMBOR6M', 'AMBOR1Y', 'AMBOR2Y', 'AMBOR30', 'AMBOR90']
|
||||
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 = 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(ID_TO_NAME_AMERIBOR[series_id])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"ameribor, {series_id}",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_ffer(
|
||||
series_id: str = "FEDFUNDS",
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Federal Funds Effective Rate
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series_id: str
|
||||
FRED ID of FFER data to plot, options: ['FEDFUNDS', 'DFF', 'FF', 'RIFSPFFNB', 'RIFSPFFNA', 'RIFSPFFNBWAW']
|
||||
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 = 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(
|
||||
"Federal Funds Effective Rate " + ID_TO_NAME_FFER[series_id] + " [Percent]"
|
||||
)
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"ffer, {series_id}",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_fftr(
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Federal Funds Target Range
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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_upper = get_series_data(
|
||||
series_id="DFEDTARU", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_lower = get_series_data(
|
||||
series_id="DFEDTARL", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df = pd.DataFrame([df_upper, df_lower]).transpose()
|
||||
|
||||
# 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
|
||||
|
||||
ax.plot(
|
||||
df.index,
|
||||
df.values,
|
||||
)
|
||||
ax.set_title("Federal Funds Target Range [Percent]")
|
||||
ax.legend(["Upper limit", "Lower limit"])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"fftr",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_effr(
|
||||
series_id: str = "EFFR",
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Effective Federal Funds Rate
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series_id: str
|
||||
FRED ID of EFFER data to plot, options: ['EFFR', 'EFFRVOL', 'EFFR1', 'EFFR25', 'EFFR75', 'EFFR99']
|
||||
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 = 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(ID_TO_NAME_EFFR[series_id])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"effr, {series_id}",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_obfr(
|
||||
series_id: str = "OBFR",
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Overnight Bank Funding Rate (OBFR)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series_id: str
|
||||
FRED ID of OBFR data to plot, options: ['OBFR', 'OBFRVOL', 'OBFR1', 'OBFR25', 'OBFR75', 'OBFR99']
|
||||
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 = 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(ID_TO_NAME_OBFR[series_id])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"obfr, {series_id}",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_iorb(
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Interest Rate on Reserve Balances
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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 = get_series_data(series_id="IORB", 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,
|
||||
color=next(colors, "#FCED00"),
|
||||
)
|
||||
ax.set_title("Interest Rate on Reserve Balances [Percent]")
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"iorb",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_projection(
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot FOMC Summary of Economic Projections for the Fed Funds Rate
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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_range_high = get_series_data(
|
||||
series_id="FEDTARRH", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_central_tendency_high = get_series_data(
|
||||
series_id="FEDTARCTH", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_median = get_series_data(
|
||||
series_id="FEDTARMD", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_range_midpoint = get_series_data(
|
||||
series_id="FEDTARRM", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_central_tendency_midpoint = get_series_data(
|
||||
series_id="FEDTARCTM", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_range_low = get_series_data(
|
||||
series_id="FEDTARRL", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_central_tendency_low = get_series_data(
|
||||
series_id="FEDTARCTL", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df = pd.DataFrame(
|
||||
[
|
||||
df_range_high,
|
||||
df_central_tendency_high,
|
||||
df_median,
|
||||
df_range_midpoint,
|
||||
df_central_tendency_midpoint,
|
||||
df_range_low,
|
||||
df_central_tendency_low,
|
||||
]
|
||||
).transpose()
|
||||
|
||||
# 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
|
||||
|
||||
ax.plot(
|
||||
df.index,
|
||||
df.values,
|
||||
)
|
||||
ax.set_title(
|
||||
"FOMC Summary of Economic Projections for the Fed Funds Rate [Percent]"
|
||||
)
|
||||
ax.legend(
|
||||
[
|
||||
"Range High",
|
||||
"Central tendency High",
|
||||
"Median",
|
||||
"Range Midpoint",
|
||||
"Central tendency Midpoint",
|
||||
"Range Low",
|
||||
"Central tendency Low",
|
||||
]
|
||||
)
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"projection",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_oldprojection(
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Longer Run FOMC Summary of Economic Projections for the Fed Funds Rate
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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_range_high = get_series_data(
|
||||
series_id="FEDTARRHLR", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_central_tendency_high = get_series_data(
|
||||
series_id="FEDTARCTHLR", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_median = get_series_data(
|
||||
series_id="FEDTARMDLR", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_range_midpoint = get_series_data(
|
||||
series_id="FEDTARRMLR", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_central_tendency_midpoint = get_series_data(
|
||||
series_id="FEDTARCTMLR", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_range_low = get_series_data(
|
||||
series_id="FEDTARRLLR", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df_central_tendency_low = get_series_data(
|
||||
series_id="FEDTARCTLLR", start_date=start_date, end_date=end_date
|
||||
)
|
||||
df = pd.DataFrame(
|
||||
[
|
||||
df_range_high,
|
||||
df_central_tendency_high,
|
||||
df_median,
|
||||
df_range_midpoint,
|
||||
df_central_tendency_midpoint,
|
||||
df_range_low,
|
||||
df_central_tendency_low,
|
||||
]
|
||||
).transpose()
|
||||
|
||||
# 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
|
||||
|
||||
ax.plot(
|
||||
df.index,
|
||||
df.values,
|
||||
)
|
||||
ax.set_title(
|
||||
"Longer Run FOMC Summary of Economic Projections for the Fed Funds Rate [Percent]"
|
||||
)
|
||||
ax.legend(
|
||||
[
|
||||
"Range High",
|
||||
"Central tendency High",
|
||||
"Median",
|
||||
"Range Midpoint",
|
||||
"Central tendency Midpoint",
|
||||
"Range Low",
|
||||
"Central tendency Low",
|
||||
]
|
||||
)
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"oldprojection",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
@check_api_key(["API_FRED_KEY"])
|
||||
def plot_dwpcr(
|
||||
series_id: str = "DPCREDIT",
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Discount Window Primary Credit Rate
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series_id: str
|
||||
FRED ID of DWPCR data to plot, options: ['MPCREDIT', 'RIFSRPF02ND', 'WPCREDIT', 'DPCREDIT', 'RIFSRPF02NA']
|
||||
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 = 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(
|
||||
"Discount Window Primary Credit Rate "
|
||||
+ ID_TO_NAME_DWPCR[series_id]
|
||||
+ " [Percent]"
|
||||
)
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"dwpcr, {series_id}",
|
||||
df,
|
||||
)
|
||||
133
openbb_terminal/fixedincome/nyfed_model.py
Normal file
133
openbb_terminal/fixedincome/nyfed_model.py
Normal file
@@ -0,0 +1,133 @@
|
||||
""" NYFED model """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
import numpy
|
||||
import pandas as pd
|
||||
from requests import request
|
||||
|
||||
from openbb_terminal.decorators import log_start_end
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def get_sofr_data(
|
||||
series: str = "overnight", start_date: str = "1980-01-01", end_date: str = ""
|
||||
) -> pd.DataFrame:
|
||||
"""Get Secured Overnight Financing Rate (SOFR) data
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series: str
|
||||
Specific data to return, options: ['overnight', '30_day', '90_day', '180_day', 'index', 'all']
|
||||
start_date: str
|
||||
Start date, formatted YYYY-MM-DD
|
||||
end_date:
|
||||
End date, formatted YYYY-MM-DD
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame
|
||||
Dataframe with SOFR data
|
||||
"""
|
||||
if isinstance(start_date, datetime):
|
||||
start_date = datetime.strftime(start_date, "%Y-%m-%d")
|
||||
if series.lower() == "overnight":
|
||||
data = request(
|
||||
"GET",
|
||||
url=f"https://markets.newyorkfed.org/api/rates/secured/sofr/search.json?startDate={start_date}&endDate={end_date}",
|
||||
).json()
|
||||
df = pd.DataFrame.from_records(
|
||||
data["refRates"],
|
||||
index="effectiveDate",
|
||||
exclude=["type", "revisionIndicator", "footnoteId"],
|
||||
)
|
||||
else:
|
||||
data = request(
|
||||
"GET",
|
||||
url=f"https://markets.newyorkfed.org/api/rates/secured/sofrai/search.json?startDate={start_date}&endDate={end_date}",
|
||||
).json()
|
||||
df = pd.DataFrame.from_records(
|
||||
data["refRates"],
|
||||
index="effectiveDate",
|
||||
exclude=["type", "revisionIndicator"],
|
||||
)
|
||||
df.index = pd.to_datetime(df.index)
|
||||
df = df.replace("NA", numpy.NaN)
|
||||
df = df.astype(float)
|
||||
if series == "index":
|
||||
df = df["index"]
|
||||
elif series != "overnight" and series != "all":
|
||||
df = df["average" + series.replace("_", "")]
|
||||
return df
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def get_effr_data(start_date: str = "1980-01-01", end_date: str = "") -> pd.DataFrame:
|
||||
"""Get Effective Federal Funds Rate (EFFR) data
|
||||
|
||||
Parameters
|
||||
----------
|
||||
start_date: str
|
||||
Start date, formatted YYYY-MM-DD
|
||||
end_date:
|
||||
End date, formatted YYYY-MM-DD
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame
|
||||
Dataframe with EFFR data
|
||||
"""
|
||||
if isinstance(start_date, datetime):
|
||||
start_date = datetime.strftime(start_date, "%Y-%m-%d")
|
||||
data = request(
|
||||
"GET",
|
||||
url=f"https://markets.newyorkfed.org/api/rates/unsecured/effr/search.json?startDate={start_date}&endDate={end_date}",
|
||||
).json()
|
||||
df = pd.DataFrame.from_records(
|
||||
data["refRates"],
|
||||
index="effectiveDate",
|
||||
exclude=["type", "revisionIndicator"],
|
||||
)
|
||||
df.index = pd.to_datetime(df.index)
|
||||
df = df.replace("NA", numpy.NaN)
|
||||
df = df.astype(float)
|
||||
|
||||
return df
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def get_obfr_data(start_date: str = "1980-01-01", end_date: str = "") -> pd.DataFrame:
|
||||
"""Get Overnight Bank Funding Rate (OBFR) data
|
||||
|
||||
Parameters
|
||||
----------
|
||||
start_date: str
|
||||
Start date, formatted YYYY-MM-DD
|
||||
end_date:
|
||||
End date, formatted YYYY-MM-DD
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame
|
||||
Dataframe with OBFR data
|
||||
"""
|
||||
if isinstance(start_date, datetime):
|
||||
start_date = datetime.strftime(start_date, "%Y-%m-%d")
|
||||
data = request(
|
||||
"GET",
|
||||
url=f"https://markets.newyorkfed.org/api/rates/unsecured/obfr/search.json?startDate={start_date}&endDate={end_date}",
|
||||
).json()
|
||||
df = pd.DataFrame.from_records(
|
||||
data["refRates"],
|
||||
index="effectiveDate",
|
||||
exclude=["type", "revisionIndicator"],
|
||||
)
|
||||
df.index = pd.to_datetime(df.index)
|
||||
df = df.replace("NA", numpy.NaN)
|
||||
df = df.astype(float)
|
||||
|
||||
return df
|
||||
283
openbb_terminal/fixedincome/nyfed_view.py
Normal file
283
openbb_terminal/fixedincome/nyfed_view.py
Normal file
@@ -0,0 +1,283 @@
|
||||
""" NYFED view """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
from typing import Optional, List
|
||||
from itertools import cycle
|
||||
import logging
|
||||
import os
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
from openbb_terminal.config_terminal import theme
|
||||
from openbb_terminal.config_plot import PLOT_DPI
|
||||
from openbb_terminal.decorators import log_start_end
|
||||
from openbb_terminal.helper_funcs import (
|
||||
export_data,
|
||||
plot_autoscale,
|
||||
is_valid_axes_count,
|
||||
)
|
||||
from openbb_terminal.fixedincome import nyfed_model
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
SERIES_TO_NAME_SOFR = {
|
||||
"overnight": "Secured Overnight Financing Rate (SOFR) [Percent]",
|
||||
"30_day": "30-Day Average SOFR [Percent]",
|
||||
"90_day": "90-Day Average SOFR [Percent]",
|
||||
"180_day": "180-Day Average SOFR [Percent]",
|
||||
"index": "SOFR Index",
|
||||
}
|
||||
SERIES_TO_NAME_EFFR = {
|
||||
"percentRate": "Effective Federal Funds Rate [Percent]",
|
||||
"volumeInBillions": "Effective Federal Funds Volume [Billions of USD]",
|
||||
"percentPercentile1": "Effective Federal Funds Rate: 1th Percentile [Percent]",
|
||||
"percentPercentile25": "Effective Federal Funds Rate: 25th Percentile [Percent]",
|
||||
"percentPercentile75": "Effective Federal Funds Rate: 75th Percentile [Percent]",
|
||||
"percentPercentile99": "Effective Federal Funds Rate: 99th Percentile [Percent]",
|
||||
}
|
||||
SERIES_TO_NAME_OBFR = {
|
||||
"percentRate": "Overnight Bank Funding Rate [Percent]",
|
||||
"volumeInBillions": "Overnight Bank Funding Volume [Billions of USD]",
|
||||
"percentPercentile1": "Overnight Bank Funding Rate: 1th Percentile [Percent]",
|
||||
"percentPercentile25": "Overnight Bank Funding Rate: 25th Percentile [Percent]",
|
||||
"percentPercentile75": "Overnight Bank Funding Rate: 75th Percentile [Percent]",
|
||||
"percentPercentile99": "Overnight Bank Funding Rate: 99th Percentile [Percent]",
|
||||
}
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def plot_sofr(
|
||||
series: str = "overnight",
|
||||
start_date: Optional[str] = "1980-01-01",
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Secured Overnight Financing Rate (SOFR)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series: str
|
||||
Specific data to plot, options: ['overnight', '30_day', '90_day', '180_day', 'index']
|
||||
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 = nyfed_model.get_sofr_data(series, start_date, end_date if end_date else "")
|
||||
if series == "overnight":
|
||||
del df["volumeInBillions"]
|
||||
|
||||
# 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
|
||||
|
||||
ax.plot(
|
||||
df.index,
|
||||
df.values,
|
||||
marker="o",
|
||||
linestyle="dashed",
|
||||
linewidth=2,
|
||||
markersize=4,
|
||||
)
|
||||
ax.set_title(SERIES_TO_NAME_SOFR[series])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if series.lower() == "overnight":
|
||||
ax.legend(
|
||||
[
|
||||
"Rate",
|
||||
"1th percentile",
|
||||
"25th percentile",
|
||||
"75th percentile",
|
||||
"99th percentile",
|
||||
]
|
||||
)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"sofr, {series}",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def plot_fftr(
|
||||
start_date: Optional[str] = "1980-01-01",
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Federal Funding Target Range (upper and lower)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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 = nyfed_model.get_effr_data(start_date, end_date if end_date else "")
|
||||
df = df[["targetRateTo", "targetRateFrom"]]
|
||||
|
||||
# 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
|
||||
|
||||
ax.plot(
|
||||
df.index,
|
||||
df.values,
|
||||
marker="o",
|
||||
linestyle="dashed",
|
||||
linewidth=2,
|
||||
markersize=4,
|
||||
)
|
||||
ax.set_title("Federal Funds Target Range [Percent]")
|
||||
ax.legend(["Upper limit", "Lower limit"])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"fftr",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def plot_effr(
|
||||
series: str = "percentRate",
|
||||
start_date: Optional[str] = "1980-01-01",
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Effective Federal Funds Rate
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series: str
|
||||
Specific data to plot, options: ['percentRate', 'volumeInBillions', 'percentPercentile1', 'percentPercentile25', 'percentPercentile75', 'percentPercentile99']
|
||||
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 = nyfed_model.get_effr_data(start_date, end_date if end_date else "")
|
||||
df = df[series]
|
||||
|
||||
# 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(SERIES_TO_NAME_EFFR[series])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"effr, {series}",
|
||||
df,
|
||||
)
|
||||
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def plot_obfr(
|
||||
series: str = "percentRate",
|
||||
start_date: Optional[str] = "1980-01-01",
|
||||
end_date: Optional[str] = None,
|
||||
export: str = "",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Plot Overnight Bank Funding Rate
|
||||
|
||||
Parameters
|
||||
----------
|
||||
series: str
|
||||
Specific data to plot, options: ['percentRate', 'volumeInBillions', 'percentPercentile1', 'percentPercentile25', 'percentPercentile75', 'percentPercentile99']
|
||||
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 = nyfed_model.get_obfr_data(start_date, end_date if end_date else "")
|
||||
df = df[series]
|
||||
|
||||
# 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(SERIES_TO_NAME_OBFR[series])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
f"obfr, {series}",
|
||||
df,
|
||||
)
|
||||
@@ -504,6 +504,20 @@
|
||||
"historical": ["YahooFinance"],
|
||||
"curve": ["YahooFinance"]
|
||||
},
|
||||
"fixedincome": {
|
||||
"estr": ["FRED", "ECB"],
|
||||
"sofr": ["FRED", "NYFED"],
|
||||
"sonia": ["FRED"],
|
||||
"ameribor": ["FRED"],
|
||||
"ffer": ["FRED"],
|
||||
"fftr": ["FRED", "NYFED"],
|
||||
"effr": ["FRED", "NYFED"],
|
||||
"obfr": ["FRED", "NYFED"],
|
||||
"iorb": ["FRED"],
|
||||
"projection": ["FRED"],
|
||||
"oldprojetion": ["FRED"],
|
||||
"dwpcr": ["FRED"]
|
||||
},
|
||||
"alternative": {
|
||||
"oss": {
|
||||
"rossidx": ["RunaCapital"],
|
||||
|
||||
14
openbb_terminal/miscellaneous/i18n/en.yml
vendored
14
openbb_terminal/miscellaneous/i18n/en.yml
vendored
@@ -771,6 +771,20 @@ en:
|
||||
economy/qa/raw: print raw data
|
||||
economy/qa/decompose: decomposition in cyclic-trend, season, and residuals of prices
|
||||
economy/qa/cusum: detects abrupt changes using cumulative sum algorithm of prices
|
||||
fixedincome/_reference_rates_: Reference rates
|
||||
fixedincome/estr: euro short-term rate (estr)
|
||||
fixedincome/sofr: secured overnight financing rate (sofr)
|
||||
fixedincome/sonia: sterling overnight index average (sonia)
|
||||
fixedincome/ameribor: american interbank offered rate (ameribor)
|
||||
fixedincome/_other_interest_rates_: Other interest rates
|
||||
fixedincome/ffer: federal funds effective rate
|
||||
fixedincome/fftr: federal funds target range
|
||||
fixedincome/effr: effective federal funds rate (effr)
|
||||
fixedincome/obfr: overnight bank funding rate (obfr)
|
||||
fixedincome/iorb: interest rate on reserve balances
|
||||
fixedincome/projection: FOMC summary of economic projections for the fed funds rate
|
||||
fixedincome/oldprojection: longer run FOMC summary of economic projections for the fed funds rate
|
||||
fixedincome/dwpcr: discount window primary credit rate
|
||||
forex/_ticker: Ticker
|
||||
forex/_from: From
|
||||
forex/_to: To
|
||||
|
||||
@@ -103,6 +103,7 @@ class TerminalController(BaseController):
|
||||
"sources",
|
||||
"forecast",
|
||||
"futures",
|
||||
"fixedincome",
|
||||
]
|
||||
|
||||
PATH = "/"
|
||||
@@ -178,6 +179,7 @@ class TerminalController(BaseController):
|
||||
mt.add_menu("economy")
|
||||
mt.add_menu("forex")
|
||||
mt.add_menu("futures")
|
||||
mt.add_menu("fixedincome")
|
||||
mt.add_menu("alternative")
|
||||
mt.add_raw("\n")
|
||||
mt.add_info("_others_")
|
||||
@@ -465,6 +467,14 @@ class TerminalController(BaseController):
|
||||
|
||||
self.queue = self.load_class(FuturesController, self.queue)
|
||||
|
||||
def call_fixedincome(self, _):
|
||||
"""Process fixedincome command."""
|
||||
from openbb_terminal.fixedincome.fixedincome_controller import (
|
||||
FixedIncomeController,
|
||||
)
|
||||
|
||||
self.queue = self.load_class(FixedIncomeController, self.queue)
|
||||
|
||||
def call_intro(self, _):
|
||||
"""Process intro command."""
|
||||
console.print(panel.Panel("[purple]Welcome to the OpenBB Terminal.[/purple]"))
|
||||
|
||||
Reference in New Issue
Block a user