Merge branch 'develop' of https://github.com/OpenBB-finance/OpenBB into feature/websockets

This commit is contained in:
Danglewood
2024-11-21 16:09:46 -08:00
6 changed files with 339 additions and 183 deletions

View File

@@ -3,20 +3,19 @@
from datetime import date as dateType
from typing import Optional, Union
from pydantic import Field, field_validator
from openbb_core.provider.abstract.data import Data
from openbb_core.provider.abstract.query_params import QueryParams
from openbb_core.provider.utils.descriptions import (
DATA_DESCRIPTIONS,
QUERY_DESCRIPTIONS,
)
from pydantic import Field, computed_field, field_validator
class YieldCurveQueryParams(QueryParams):
"""Yield Curve Query."""
date: Union[None, dateType, str] = Field(
date: Optional[Union[dateType, str]] = Field(
default=None,
description=QUERY_DESCRIPTIONS.get("date", "")
+ " By default is the current data.",
@@ -34,9 +33,10 @@ class YieldCurveQueryParams(QueryParams):
if isinstance(v, dateType):
return v.strftime("%Y-%m-%d")
new_dates: list = []
dates: list = []
if isinstance(v, str):
dates = v.split(",")
if isinstance(v, list):
elif isinstance(v, list):
dates = v
for date in dates:
new_dates.append(to_datetime(date).date().strftime("%Y-%m-%d"))
@@ -52,7 +52,21 @@ class YieldCurveData(Data):
description=DATA_DESCRIPTIONS.get("date", ""),
)
maturity: str = Field(description="Maturity length of the security.")
rate: float = Field(
description="The yield as a normalized percent (0.05 is 5%)",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
@computed_field( # type: ignore
description="Maturity length, in years, as a decimal.",
return_type=Optional[float],
)
@property
def maturity_years(self) -> Optional[float]:
"""Get the maturity in years as a decimal."""
if "_" not in self.maturity: # pylint: disable=E1135
return None
parts = self.maturity.split("_") # pylint: disable=E1101
months = sum(
int(parts[i + 1]) * (12 if parts[i] == "year" else 1)
for i in range(0, len(parts), 2)
)
return months / 12

View File

@@ -28,7 +28,7 @@ class FixedIncomeViews:
from openbb_core.app.utils import basemodel_to_df
from pandas import DataFrame
data = kwargs.get("data", None)
data = kwargs.get("data")
df: DataFrame = DataFrame()
if data:
if isinstance(data, DataFrame) and not data.empty: # noqa: SIM108
@@ -55,6 +55,9 @@ class FixedIncomeViews:
provider = kwargs.get("provider")
df["date"] = df["date"].astype(str)
maturities = duration_sorter(df["maturity"].unique().tolist())
countries: list = (
df["country"].unique().tolist() if "country" in df.columns else []
)
# Use the supplied colors, if any.
colors = kwargs.get("colors", [])
@@ -66,11 +69,13 @@ class FixedIncomeViews:
figure.update_layout(ChartStyle().plotly_template.get("layout", {}))
text_color = "white" if ChartStyle().plt_style == "dark" else "black"
def create_fig(figure, df, dates, color_count, country: Optional[str] = None):
def create_fig(
figure, dataframe, dates, color_count, country: Optional[str] = None
):
"""Create a scatter for each date in the data."""
for date in dates:
color = colors[color_count % len(colors)]
plot_df = df[df["date"] == date].copy()
plot_df = dataframe[dataframe["date"] == date].copy()
plot_df["rate"] = plot_df["rate"].apply(lambda x: x * 100)
plot_df = plot_df.rename(columns={"rate": "Yield"})
plot_df = (
@@ -81,31 +86,41 @@ class FixedIncomeViews:
)
plot_df = plot_df.rename(columns={"index": "Maturity"})
plot_df["Maturity"] = [
(
d.split("_")[1] + " " + d.split("_")[0].title()
if d != "long_term"
else "Long Term"
)
(d.split("_")[1] + " " + d.split("_")[0].title())
for d in plot_df["Maturity"]
]
figure.add_scatter(
x=plot_df["Maturity"],
y=plot_df["Yield"],
mode="lines+markers",
name=f"{country} - {date}" if country else date,
name=(
f"{country.replace('_', ' ').title().replace('Ecb', 'ECB')} {date}"
if country
else date
),
line=dict(width=3, color=color),
marker=dict(size=10, color=color),
hovertemplate=(
"Maturity: %{x}<br>Yield: %{y}%<extra></extra>"
if len(dates) == 1
if len(dates) == 1 and not countries
else "%{fullData.name}<br>Maturity: %{x}<br>Yield: %{y}%<extra></extra>"
),
)
color_count += 1
return figure, color_count
dates = df.date.unique().tolist()
figure, color_count = create_fig(figure, df, dates, color_count)
if countries:
for _country in countries:
_df = df[df["country"] == _country]
dates = _df.date.unique().tolist()
figure, color_count = create_fig(
figure, _df, dates, color_count, _country
)
else:
dates = df.date.unique().tolist()
figure, color_count = create_fig(figure, df, dates, color_count)
extra_params = kwargs.get("extra_params", {})
extra_params = (
extra_params if isinstance(extra_params, dict) else extra_params.__dict__
@@ -130,14 +145,26 @@ class FixedIncomeViews:
)
country = f"United States {curve_type}"
elif provider == "econdb":
country = extra_params.get("country", "")
country = country.replace("_", " ").title() if country else "United States"
country = (
""
if countries
else (
extra_params.get("country", "")
.replace("_", " ")
.title()
.replace("Ecb", "ECB")
or "United States"
)
)
country = country + " " if country else ""
title = kwargs.get("title", "")
if not title:
title = f"{country}Yield Curve"
if len(dates) == 1:
if len(dates) == 1 and len(countries) == 1:
title = f"{country} Yield Curve - {dates[0]}"
elif countries:
title = f"Yield Curve - {', '.join(countries).replace('_', ' ').title().replace('Ecb', 'ECB')}"
# Update the layout of the figure.
figure.update_layout(
@@ -156,11 +183,7 @@ class FixedIncomeViews:
categoryorder="array",
categoryarray=(
[
(
d.split("_")[1] + " " + d.split("_")[0].title()
if d != "long_term"
else "Long Term"
)
(d.split("_")[1] + " " + d.split("_")[0].title())
for d in maturities
]
),
@@ -186,6 +209,7 @@ class FixedIncomeViews:
margin=dict(
b=25,
t=10,
l=20,
),
)

View File

@@ -3020,7 +3020,7 @@
},
{
"name": "date",
"type": "Union[Union[str, date], List[Union[str, date]]]",
"type": "Union[Union[date, str], List[Union[date, str]]]",
"description": "A specific date to get data for. Multiple items allowed for provider(s): yfinance.",
"default": null,
"optional": true,
@@ -4671,7 +4671,7 @@
"standard": [
{
"name": "date",
"type": "Union[Union[str, date], List[Union[str, date]]]",
"type": "Union[Union[date, str], List[Union[date, str]]]",
"description": "A specific date to get data for. Default is the latest report. Multiple items allowed for provider(s): fred.",
"default": null,
"optional": true,
@@ -9657,7 +9657,7 @@
"standard": [
{
"name": "date",
"type": "Union[Union[str, date], List[Union[str, date]]]",
"type": "Union[Union[date, str], List[Union[date, str]]]",
"description": "A specific date to get data for. Default is the latest report. Multiple items allowed for provider(s): fred.",
"default": null,
"optional": true,
@@ -33795,7 +33795,7 @@
"fmp": [
{
"name": "date",
"type": "Union[Union[str, date], str]",
"type": "Union[Union[date, str], str]",
"description": "A specific date to get data for. Entering a date will attempt to return the NPORT-P filing for the entered date. This needs to be _exactly_ the date of the filing. Use the holdings_date command/endpoint to find available filing dates for the ETF.",
"default": null,
"optional": true,
@@ -33823,7 +33823,7 @@
"sec": [
{
"name": "date",
"type": "Union[Union[str, date], str]",
"type": "Union[Union[date, str], str]",
"description": "A specific date to get data for. The date represents the period ending. The date entered will return the closest filing.",
"default": null,
"optional": true,
@@ -36674,7 +36674,7 @@
"standard": [
{
"name": "date",
"type": "Union[Union[None, date, str], List[Union[None, date, str]]]",
"type": "Union[Union[date, str], List[Union[date, str]]]",
"description": "A specific date to get data for. By default is the current data. Multiple items allowed for provider(s): econdb, federal_reserve, fmp, fred.",
"default": null,
"optional": true,
@@ -36684,14 +36684,17 @@
"econdb": [
{
"name": "country",
"type": "Literal['australia', 'canada', 'china', 'hong_kong', 'india', 'japan', 'mexico', 'new_zealand', 'russia', 'saudi_arabia', 'singapore', 'south_africa', 'south_korea', 'taiwan', 'thailand', 'united_kingdom', 'united_states']",
"description": "The country to get data. New Zealand, Mexico, Singapore, and Thailand have only monthly data. The nearest date to the requested one will be used.",
"type": "Union[str, List[str]]",
"description": "The country to get data. New Zealand, Mexico, Singapore, and Thailand have only monthly data. The nearest date to the requested one will be used. Multiple items allowed for provider(s): econdb.",
"default": "united_states",
"optional": true,
"choices": [
"australia",
"canada",
"china",
"ecb_instantaneous_forward",
"ecb_par_yield",
"ecb_spot_rate",
"hong_kong",
"india",
"japan",
@@ -36783,14 +36786,6 @@
"default": "",
"optional": false,
"choices": null
},
{
"name": "rate",
"type": "float",
"description": "The yield as a normalized percent (0.05 is 5%)",
"default": "",
"optional": false,
"choices": null
}
],
"econdb": [],
@@ -37456,7 +37451,7 @@
"standard": [
{
"name": "date",
"type": "Union[Union[str, date], List[Union[str, date]]]",
"type": "Union[Union[date, str], List[Union[date, str]]]",
"description": "A specific date to get data for. Multiple items allowed for provider(s): fred.",
"default": null,
"optional": true,
@@ -38767,7 +38762,7 @@
},
{
"name": "date_first_added",
"type": "Union[str, date]",
"type": "Union[date, str]",
"description": "Date the constituent company was added to the index.",
"default": null,
"optional": true,
@@ -38783,7 +38778,7 @@
},
{
"name": "founded",
"type": "Union[str, date]",
"type": "Union[date, str]",
"description": "Founding year of the constituent company in the index.",
"default": null,
"optional": true,

View File

@@ -338,7 +338,7 @@ class ROUTER_fixedincome_government(Container):
def yield_curve(
self,
date: Annotated[
Union[str, datetime.date, None, List[Union[str, datetime.date, None]]],
Union[datetime.date, str, None, List[Union[datetime.date, str, None]]],
OpenBBField(
description="A specific date to get data for. By default is the current data. Multiple comma separated items allowed for provider(s): econdb, federal_reserve, fmp, fred."
),
@@ -355,12 +355,12 @@ class ROUTER_fixedincome_government(Container):
Parameters
----------
date : Union[str, date, None, List[Union[str, date, None]]]
date : Union[date, str, None, List[Union[date, str, None]]]
A specific date to get data for. By default is the current data. Multiple comma separated items allowed for provider(s): econdb, federal_reserve, fmp, fred.
provider : Optional[Literal['econdb', 'federal_reserve', 'fmp', 'fred']]
The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: econdb, federal_reserve, fmp, fred.
country : Literal['australia', 'canada', 'china', 'hong_kong', 'india', 'japan', 'mexico', 'new_zealand', 'russia', 'saudi_arabia', 'singapore', 'south_africa', 'south_korea', 'taiwan', 'thailand', 'united_kingdom', 'united_states']
The country to get data. New Zealand, Mexico, Singapore, and Thailand have only monthly data. The nearest date to the requested one will be used. (provider: econdb)
country : str
The country to get data. New Zealand, Mexico, Singapore, and Thailand have only monthly data. The nearest date to the requested one will be used. Multiple comma separated items allowed. (provider: econdb)
use_cache : bool
If true, cache the request for four hours. (provider: econdb)
yield_curve_type : Literal['nominal', 'real', 'breakeven', 'treasury_minus_fed_funds', 'corporate_spot', 'corporate_par']
@@ -386,8 +386,6 @@ class ROUTER_fixedincome_government(Container):
The date of the data.
maturity : str
Maturity length of the security.
rate : float
The yield as a normalized percent (0.05 is 5%)
Examples
--------
@@ -421,7 +419,34 @@ class ROUTER_fixedincome_government(Container):
},
"fmp": {"multiple_items_allowed": True, "choices": None},
"fred": {"multiple_items_allowed": True, "choices": None},
}
},
"country": {
"econdb": {
"multiple_items_allowed": True,
"choices": [
"australia",
"canada",
"china",
"ecb_instantaneous_forward",
"ecb_par_yield",
"ecb_spot_rate",
"hong_kong",
"india",
"japan",
"mexico",
"new_zealand",
"russia",
"saudi_arabia",
"singapore",
"south_africa",
"south_korea",
"taiwan",
"thailand",
"united_kingdom",
"united_states",
],
}
},
},
)
)

View File

@@ -14,7 +14,7 @@ from openbb_core.provider.standard_models.yield_curve import (
)
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from openbb_core.provider.utils.errors import EmptyDataError
from openbb_econdb.utils.yield_curves import COUNTRIES, COUNTRIES_DICT, COUNTRIES_LIST
from openbb_econdb.utils.yield_curves import COUNTRIES_DICT, COUNTRIES_LIST
from pydantic import Field, field_validator
@@ -22,14 +22,14 @@ class EconDbYieldCurveQueryParams(YieldCurveQueryParams):
"""EconDB Economic Indicators Query."""
__json_schema_extra__ = {
"date": ["multiple_items_allowed"],
"date": {"multiple_items_allowed": True},
"country": {"multiple_items_allowed": True, "choices": COUNTRIES_LIST},
}
country: COUNTRIES = Field(
country: str = Field(
default="united_states",
description=QUERY_DESCRIPTIONS.get("country", "")
+ " New Zealand, Mexico, Singapore, and Thailand have only monthly data."
+ " The nearest date to the requested one will be used.",
json_schema_extra={"choices": COUNTRIES_LIST},
)
use_cache: bool = Field(
default=True,
@@ -42,9 +42,18 @@ class EconDbYieldCurveQueryParams(YieldCurveQueryParams):
"""Validate the country."""
if v is None:
return "united_states"
if v not in COUNTRIES_DICT:
raise OpenBBError(f"Country must be one of {COUNTRIES_DICT}")
return v
countries = v.split(",")
new_countries: list = []
for country in countries:
if country not in COUNTRIES_DICT:
raise ValueError(
f"Invalid country, {country}, must be one of {list(COUNTRIES_DICT)}"
)
new_countries.append(country)
return ",".join(new_countries)
class EconDbYieldCurveData(YieldCurveData):
@@ -59,7 +68,7 @@ class EconDbYieldCurveFetcher(
require_credentials = False
@staticmethod
def transform_query(params: Dict[str, Any]) -> EconDbYieldCurveQueryParams:
def transform_query(params: dict[str, Any]) -> EconDbYieldCurveQueryParams:
"""Transform the query parameters."""
if not params.get("date"):
params["date"] = datetime.now().strftime("%Y-%m-%d")
@@ -68,133 +77,194 @@ class EconDbYieldCurveFetcher(
@staticmethod
async def aextract_data( # pylint: disable=R0914.R0912,R0915
query: EconDbYieldCurveQueryParams,
credentials: Optional[Dict[str, str]],
credentials: Optional[dict[str, str]],
**kwargs: Any,
) -> List[Dict]:
) -> dict:
"""Extract the data."""
# pylint: disable=import-outside-toplevel
import asyncio # noqa
from openbb_econdb.utils import helpers
from warnings import warn
token = credentials.get("econdb_api_key") if credentials else "" # type: ignore
# Attempt to create a temporary token if one is not supplied.
if not token:
token = await helpers.create_token(use_cache=query.use_cache)
credentials.update({"econdb_api_key": token}) # type: ignore
base_url = "https://www.econdb.com/api/series/?ticker="
symbols = list(COUNTRIES_DICT[query.country].keys())
url = (
base_url
+ f"%5B{','.join(symbols)}%5D&page_size=50&format=json&token={token}"
)
data: List[Dict] = []
response: Union[Dict, List[Dict]] = {}
if query.use_cache is True:
cache_dir = f"{helpers.get_user_cache_directory()}/http/econdb_yield_curve"
async with helpers.CachedSession(
cache=helpers.SQLiteBackend(
cache_dir, expire_after=3600 * 4, ignored_params=["token"]
)
) as session:
try:
response = await helpers.amake_request( # type: ignore
url,
session=session,
timeout=20,
**kwargs,
)
finally:
await session.close()
else:
response = await helpers.amake_request( # type: ignore
url, timeout=20, **kwargs
results: dict = {}
messages: list = []
async def get_one_country(country):
"""Get the data for one country."""
base_url = "https://www.econdb.com/api/series/?ticker="
symbols = list(COUNTRIES_DICT[country].keys())
url = (
base_url
+ f"%5B{','.join(symbols)}%5D&page_size=50&format=json&token={token}"
)
if not response:
raise OpenBBError("No data was returned.")
data = response.get("results") # type: ignore
if not data:
raise EmptyDataError("The response was returned empty.")
return data
data: list = []
response: Union[dict, list[dict]] = {}
if query.use_cache is True:
cache_dir = (
f"{helpers.get_user_cache_directory()}/http/econdb_yield_curve"
)
async with helpers.CachedSession(
cache=helpers.SQLiteBackend(
cache_dir, expire_after=3600 * 4, ignored_params=["token"]
)
) as session:
await session.delete_expired_responses()
try:
response = await helpers.amake_request( # type: ignore
url,
session=session,
timeout=20,
**kwargs,
)
finally:
await session.close()
else:
response = await helpers.amake_request( # type: ignore
url, timeout=20, **kwargs
)
if not response:
messages.append(f"No data was returned for, {country}")
return
data = response.get("results") # type: ignore
if not data:
messages.append(f"The response for, {country}, was returned empty.")
return
results[country] = data
return
_countries = query.country.split(",")
tasks = [asyncio.create_task(get_one_country(c)) for c in _countries]
await asyncio.gather(*tasks)
if not results and messages:
msg_str = "\n".join(messages)
raise OpenBBError(msg_str)
if not results and not messages:
raise OpenBBError("Unexpected outcome -> All requests were returned empty.")
if results and messages:
for message in messages:
warn(message)
return results
@staticmethod
def transform_data(
query: EconDbYieldCurveQueryParams,
data: List[Dict],
data: dict,
**kwargs: Any,
) -> AnnotatedResult[List[EconDbYieldCurveData]]:
) -> AnnotatedResult[list[EconDbYieldCurveData]]:
"""Transform the data."""
# pylint: disable=import-outside-toplevel
from numpy import nan
from pandas import Categorical, DataFrame, DatetimeIndex
maturity_order = list(COUNTRIES_DICT[query.country].values())
dates = query.date.split(",") # type: ignore
dates_list = DatetimeIndex(dates)
new_data: Dict = {}
metadata: Dict = {}
# Unpack the data for each maturity.
for item in data:
ticker = item.get("ticker")
maturity = COUNTRIES_DICT[query.country].get(ticker)
dataset = item.get("dataset")
additional_metadata = item.get("additional_metadata")
units = "percent"
description = item.get("description")
dates = item["data"]["dates"]
rates = item["data"]["values"]
meta = {
"symbol": ticker,
"description": description,
"dataset": dataset,
"units": units,
"additional_metadata": additional_metadata,
}
metadata[maturity] = meta
for d, r in zip(dates, rates):
if maturity not in new_data:
new_data[maturity] = {}
new_data[maturity][d] = r
results_metadata: dict = {}
results_data: list = []
# Create a DataFrame from the data
df = DataFrame(new_data)
def process_country_data(country, country_data):
"""Process the data for one country."""
maturity_order = list(COUNTRIES_DICT[country].values())
dates = query.date.split(",") # type: ignore
dates_list = DatetimeIndex(dates)
new_data: Dict = {}
metadata: Dict = {}
# Unpack the data for each maturity.
for item in country_data:
ticker = item.get("ticker")
maturity = COUNTRIES_DICT[country].get(ticker)
dataset = item.get("dataset")
additional_metadata = item.get("additional_metadata")
units = "percent"
description = item.get("description")
dates = item["data"]["dates"]
rates = item["data"]["values"]
meta = {
"symbol": ticker,
"description": description,
"dataset": dataset,
"units": units,
"additional_metadata": additional_metadata,
}
metadata[maturity] = meta
for d, r in zip(dates, rates):
if maturity not in new_data:
new_data[maturity] = {}
new_data[maturity][d] = r
# Convert the index to a DatetimeIndex
df.index = DatetimeIndex(df.index)
# Create a DataFrame from the data
df = DataFrame(new_data)
# Find the nearest date in the DataFrame to each date in dates_list
def get_nearest_date(df, target_date):
differences = (df.index - target_date).to_series().abs()
nearest_date_index = differences.argmin()
nearest_date = df.index[nearest_date_index]
return nearest_date
# Convert the index to a DatetimeIndex
df.index = DatetimeIndex(df.index)
nearest_dates = [get_nearest_date(df, date) for date in dates_list]
# Find the nearest date in the DataFrame to each date in dates_list
def get_nearest_date(df, target_date):
differences = (df.index - target_date).to_series().abs()
nearest_date_index = differences.argmin()
nearest_date = df.index[nearest_date_index]
return nearest_date
# Filter for only the nearest dates
df = df[df.index.isin(nearest_dates)]
nearest_dates = [get_nearest_date(df, date) for date in dates_list]
# Flatten the DataFrame
flattened_data = df.reset_index().melt(
id_vars="index", var_name="maturity", value_name="rate"
)
flattened_data = flattened_data.rename(columns={"index": "date"}).sort_values(
"date"
)
flattened_data["maturity"] = Categorical(
flattened_data["maturity"], categories=maturity_order, ordered=True
)
flattened_data["rate"] = flattened_data["rate"].astype(float) / 100
flattened_data = flattened_data.sort_values(
by=["date", "maturity"]
).reset_index(drop=True)
flattened_data.loc[:, "date"] = flattened_data["date"].dt.strftime("%Y-%m-%d")
records = flattened_data.copy()
records["rate"] = records["rate"].fillna("N/A").replace("N/A", None)
records = records.to_dict("records")
results: List[EconDbYieldCurveData] = [
EconDbYieldCurveData.model_validate(r) for r in records if r.get("rate")
]
if not results:
# Filter for only the nearest dates
df = df[df.index.isin(nearest_dates)]
# Flatten the DataFrame
flattened_data = df.reset_index().melt(
id_vars="index", var_name="maturity", value_name="rate"
)
flattened_data = flattened_data.rename(
columns={"index": "date"}
).sort_values("date")
flattened_data["maturity"] = Categorical(
flattened_data["maturity"], categories=maturity_order, ordered=True
)
flattened_data["rate"] = flattened_data["rate"].astype(float) / 100
flattened_data = flattened_data.sort_values(
by=["date", "maturity"]
).reset_index(drop=True)
flattened_data.loc[:, "date"] = flattened_data["date"].dt.strftime(
"%Y-%m-%d"
)
new_df = flattened_data.copy()
new_df.loc[:, "country"] = country
def convert_duration(x):
"""Convert the duration to a decimal representation of years."""
period, unit = x.split("_")
if period == "long" and unit == "term":
return 30
if period == "year":
return int(unit)
return int(unit) / 12
new_df.loc[:, "maturity_years"] = new_df.maturity.apply(convert_duration)
new_df = new_df.replace({nan: None})
records = [
EconDbYieldCurveData.model_validate(r)
for r in new_df.to_dict("records")
if r.get("rate")
]
results_data.extend(records)
results_metadata[country] = metadata
for country, country_data in data.items():
process_country_data(country, country_data)
if not results_data:
raise EmptyDataError(
f"No data was found for the country, {query.country},"
f" and dates, {query.date}"
)
return AnnotatedResult(result=results, metadata=metadata)
return AnnotatedResult(result=results_data, metadata=results_metadata)

View File

@@ -1,7 +1,5 @@
"""EconDB Yield Curve Utilities"""
from typing import Literal
DAILY = {
"australia": {
"RBA_F02D.FCMYGBAG2D.D.AU": "year_2",
@@ -20,7 +18,7 @@ DAILY = {
"BOC_BOND_YIELDS_ALL.BD_CDN_5YR_DQ_YLD.D.CA": "year_5",
"BOC_BOND_YIELDS_ALL.BD_CDN_7YR_DQ_YLD.D.CA": "year_7",
"BOC_BOND_YIELDS_ALL.BD_CDN_10YR_DQ_YLD.D.CA": "year_10",
"BOC_BOND_YIELDS_ALL.BD_CDN_LONG_DQ_YLD.D.CA": "long_term",
"BOC_BOND_YIELDS_ALL.BD_CDN_LONG_DQ_YLD.D.CA": "year_30",
},
"china": {
"CCDC_CGB.CHB_3M.D.CN": "month_3",
@@ -134,7 +132,56 @@ DAILY = {
"FRB_H15.C279E.D.US": "year_20",
"FRB_H15.F5280.D.US": "year_30",
},
"ecb_spot_rate": {
"ECBYC.035E9053E2.B.EA": "month_3",
"ECBYC.03610053E2.B.EA": "month_6",
"ECBYC.0354C053E2.B.EA": "year_1",
"ECBYC.035D1053E2.B.EA": "year_2",
"ECBYC.035EA053E2.B.EA": "year_3",
"ECBYC.035F7053E2.B.EA": "year_4",
"ECBYC.03604053E2.B.EA": "year_5",
"ECBYC.03611053E2.B.EA": "year_6",
"ECBYC.0361E053E2.B.EA": "year_7",
"ECBYC.0362B053E2.B.EA": "year_8",
"ECBYC.03638053E2.B.EA": "year_9",
"ECBYC.03558053E2.B.EA": "year_10",
"ECBYC.034D2053E2.B.EA": "year_20",
"ECBYC.035DD053E2.B.EA": "year_30",
},
"ecb_par_yield": {
"ECBYC.0317C053E2.B.EA": "month_3",
"ECBYC.031A3053E2.B.EA": "month_6",
"ECBYC.030DF053E2.B.EA": "year_1",
"ECBYC.03164053E2.B.EA": "year_2",
"ECBYC.0317D053E2.B.EA": "year_3",
"ECBYC.0318A053E2.B.EA": "year_4",
"ECBYC.03197053E2.B.EA": "year_5",
"ECBYC.031A4053E2.B.EA": "year_6",
"ECBYC.031B1053E2.B.EA": "year_7",
"ECBYC.031BE053E2.B.EA": "year_8",
"ECBYC.031CB053E2.B.EA": "year_9",
"ECBYC.03065053E2.B.EA": "year_10",
"ECBYC.030EB053E2.B.EA": "year_20",
"ECBYC.03170053E2.B.EA": "year_30",
},
"ecb_instantaneous_forward": {
"ECBYC.02C71053E2.B.EA": "month_3",
"ECBYC.02C98053E2.B.EA": "month_6",
"ECBYC.02BD4053E2.B.EA": "year_1",
"ECBYC.02C59053E2.B.EA": "year_2",
"ECBYC.02C72053E2.B.EA": "year_3",
"ECBYC.02C7F053E2.B.EA": "year_4",
"ECBYC.02C8C053E2.B.EA": "year_5",
"ECBYC.02C99053E2.B.EA": "year_6",
"ECBYC.02CA6053E2.B.EA": "year_7",
"ECBYC.02CB3053E2.B.EA": "year_8",
"ECBYC.02CC0053E2.B.EA": "year_9",
"ECBYC.02B5A053E2.B.EA": "year_10",
"ECBYC.02BE0053E2.B.EA": "year_20",
"ECBYC.02C65053E2.B.EA": "year_30",
},
}
MONTHLY = {
"thailand": {
"BOTFM_RT_001_S2.36.M.TH": "month_1",
@@ -198,22 +245,3 @@ COUNTRIES_DICT = {
**DAILY,
**MONTHLY,
}
COUNTRIES = Literal[
"australia",
"canada",
"china",
"hong_kong",
"india",
"japan",
"mexico",
"new_zealand",
"russia",
"saudi_arabia",
"singapore",
"south_africa",
"south_korea",
"taiwan",
"thailand",
"united_kingdom",
"united_states",
]