summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Radovanovic <74266147+IgorWounds@users.noreply.github.com>2024-06-17 00:03:21 +0200
committerGitHub <noreply@github.com>2024-06-17 00:03:21 +0200
commit41a26d3224615cb33ee13e2ab02f71ea1bc532c5 (patch)
treed34c221f320d1a120cf5a794bba2b8171fa1b78a
parent839094e506f4b99e6682ff46f496d273feae32a2 (diff)
parent650912bf0c21714a109ff50ff8ed94651eaf1d63 (diff)
Merge branch 'develop' into feature/intrinio-delayed-optionsfeature/intrinio-delayed-options
-rw-r--r--openbb_platform/core/openbb_core/provider/standard_models/mortgage_indices.py46
-rw-r--r--openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py26
-rw-r--r--openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py25
-rw-r--r--openbb_platform/extensions/fixedincome/openbb_fixedincome/fixedincome_router.py26
-rw-r--r--openbb_platform/openbb/assets/reference.json185
-rw-r--r--openbb_platform/openbb/package/fixedincome.py127
-rw-r--r--openbb_platform/providers/fred/openbb_fred/__init__.py2
-rw-r--r--openbb_platform/providers/fred/openbb_fred/models/mortgage_indices.py312
-rw-r--r--openbb_platform/providers/fred/tests/record/http/test_fred_fetchers/test_fred_bond_mortgage_fetcher.yaml105
-rw-r--r--openbb_platform/providers/fred/tests/test_fred_fetchers.py15
10 files changed, 869 insertions, 0 deletions
diff --git a/openbb_platform/core/openbb_core/provider/standard_models/mortgage_indices.py b/openbb_platform/core/openbb_core/provider/standard_models/mortgage_indices.py
new file mode 100644
index 00000000000..bfba892bb2d
--- /dev/null
+++ b/openbb_platform/core/openbb_core/provider/standard_models/mortgage_indices.py
@@ -0,0 +1,46 @@
+"""Mortgage Indices Standard Model."""
+
+from datetime import (
+ date as dateType,
+)
+from typing import Optional
+
+from pydantic import Field
+
+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,
+)
+
+
+class MortgageIndicesQueryParams(QueryParams):
+ """Mortgage Indices Query."""
+
+ start_date: Optional[dateType] = Field(
+ default=None,
+ description=QUERY_DESCRIPTIONS.get("start_date", ""),
+ )
+ end_date: Optional[dateType] = Field(
+ default=None,
+ description=QUERY_DESCRIPTIONS.get("end_date", ""),
+ )
+
+
+class MortgageIndicesData(Data):
+ """Mortgage Indices Data."""
+
+ date: dateType = Field(description=DATA_DESCRIPTIONS.get("date", ""))
+ symbol: Optional[str] = Field(
+ default=None,
+ description=DATA_DESCRIPTIONS.get("symbol", ""),
+ )
+ name: Optional[str] = Field(
+ default=None,
+ description="Name of the index.",
+ )
+ rate: float = Field(
+ description="Mortgage rate.",
+ json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
+ )
diff --git a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py
index 1e9844767f3..521040398c2 100644
--- a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py
+++ b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py
@@ -694,3 +694,29 @@ def test_fixedincome_bond_indices(params, headers):
result = requests.get(url, headers=headers, timeout=10)
assert isinstance(result, requests.Response)
assert result.status_code == 200
+
+
+@parametrize(
+ "params",
+ [
+ {
+ "provider": "fred",
+ "index": "usda_30y,fha_30y",
+ "start_date": "2023-05-31",
+ "end_date": "2024-06-01",
+ "transform": None,
+ "frequency": None,
+ "aggregation_method": "avg",
+ },
+ ],
+)
+@pytest.mark.integration
+def test_fixedincome_mortgage_indices(params, headers):
+ """Test the mortgage indices endpoint."""
+ params = {p: v for p, v in params.items() if v}
+
+ query_str = get_querystring(params, [])
+ url = f"http://0.0.0.0:8000/api/v1/fixedincome/mortgage_indices?{query_str}"
+ result = requests.get(url, headers=headers, timeout=10)
+ assert isinstance(result, requests.Response)
+ assert result.status_code == 200
diff --git a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py
index 433b96a3d8f..6058c18ecc9 100644
--- a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py
+++ b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py
@@ -647,3 +647,28 @@ def test_fixedincome_bond_indices(params, obb):
assert result
assert isinstance(result, OBBject)
assert len(result.results) > 0
+
+
+@parametrize(
+ "params",
+ [
+ {
+ "provider": "fred",
+ "index": "usda_30y,fha_30y",
+ "start_date": "2023-05-31",
+ "end_date": "2024-06-01",
+ "transform": None,
+ "frequency": None,
+ "aggregation_method": "avg",
+ },
+ ],
+)
+@pytest.mark.integration
+def test_fixedincome_mortgage_indices(params, obb):
+ """Test the mortgage indices endpoint."""
+ params = {p: v for p, v in params.items() if v}
+
+ result = obb.fixedincome.mortgage_indices(**params)
+ assert result
+ assert isinstance(result, OBBject)
+ assert len(result.results) > 0
diff --git a/openbb_platform/extensions/fixedincome/openbb_fixedincome/fixedincome_router.py b/openbb_platform/extensions/fixedincome/openbb_fixedincome/fixedincome_router.py
index fb346dd3cc3..f7d62a1b16b 100644
--- a/openbb_platform/extensions/fixedincome/openbb_fixedincome/fixedincome_router.py
+++ b/openbb_platform/extensions/fixedincome/openbb_fixedincome/fixedincome_router.py
@@ -81,3 +81,29 @@ async def bond_indices(
) -> OBBject: # type: ignore
"""Bond Indices."""
return await OBBject.from_query(Query(**locals()))
+
+
+@router.command(
+ model="MortgageIndices",
+ examples=[
+ APIEx(
+ description="The default state for FRED are the primary mortgage indices from Optimal Blue.",
+ parameters={"provider": "fred"},
+ ),
+ APIEx(
+ description="Multiple indices can be requested.",
+ parameters={
+ "index": "jumbo_30y,conforming_30y,conforming_15y",
+ "provider": "fred",
+ },
+ ),
+ ],
+)
+async def mortgage_indices(
+ cc: CommandContext,
+ provider_choices: ProviderChoices,
+ standard_params: StandardParams,
+ extra_params: ExtraParams,
+) -> OBBject: # type: ignore
+ """Mortgage Indices."""
+ return await OBBject.from_query(Query(**locals()))
diff --git a/openbb_platform/openbb/assets/reference.json b/openbb_platform/openbb/assets/reference.json
index 4fc15862c20..efdab571fc0 100644
--- a/openbb_platform/openbb/assets/reference.json
+++ b/openbb_platform/openbb/assets/reference.json
@@ -32666,6 +32666,191 @@
},
"model": "BondIndices"
},
+ "/fixedincome/mortgage_indices": {
+ "deprecated": {
+ "flag": null,
+ "message": null
+ },
+ "description": "Mortgage Indices.",
+ "examples": "\nExamples\n--------\n\n```python\nfrom openbb import obb\n# The default state for FRED are the primary mortgage indices from Optimal Blue.\nobb.fixedincome.mortgage_indices(provider='fred')\n# Multiple indices can be requested.\nobb.fixedincome.mortgage_indices(index=jumbo_30y,conforming_30y,conforming_15y, provider='fred')\n```\n\n",
+ "parameters": {
+ "standard": [
+ {
+ "name": "start_date",
+ "type": "Union[date, str]",
+ "description": "Start date of the data, in YYYY-MM-DD format.",
+ "default": null,
+ "optional": true,
+ "choices": null
+ },
+ {
+ "name": "end_date",
+ "type": "Union[date, str]",
+ "description": "End date of the data, in YYYY-MM-DD format.",
+ "default": null,
+ "optional": true,
+ "choices": null
+ },
+ {
+ "name": "provider",
+ "type": "Literal['fred']",
+ "description": "The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: f, r, e, d.",
+ "default": null,
+ "optional": true
+ }
+ ],
+ "fred": [
+ {
+ "name": "index",
+ "type": "Union[Union[Literal['primary', 'ltv_lte_80', 'ltv_gt_80', 'conforming_30y', 'conforming_30y_na', 'jumbo_30y', 'fha_30y', 'va_30y', 'usda_30y', 'conforming_15y', 'ltv_lte80_fico_ge740', 'ltv_lte80_fico_a720b739', 'ltv_lte80_fico_a700b719', 'ltv_lte80_fico_a680b699', 'ltv_lte80_fico_lt680', 'ltv_gt80_fico_ge740', 'ltv_gt80_fico_a720b739', 'ltv_gt80_fico_a700b719', 'ltv_gt80_fico_a680b699', 'ltv_gt80_fico_lt680'], str], List[Union[Literal['primary', 'ltv_lte_80', 'ltv_gt_80', 'conforming_30y', 'conforming_30y_na', 'jumbo_30y', 'fha_30y', 'va_30y', 'usda_30y', 'conforming_15y', 'ltv_lte80_fico_ge740', 'ltv_lte80_fico_a720b739', 'ltv_lte80_fico_a700b719', 'ltv_lte80_fico_a680b699', 'ltv_lte80_fico_lt680', 'ltv_gt80_fico_ge740', 'ltv_gt80_fico_a720b739', 'ltv_gt80_fico_a700b719', 'ltv_gt80_fico_a680b699', 'ltv_gt80_fico_lt680'], str]]]",
+ "description": "The specific index, or index group, to query. Default is the 'primary' group. Multiple items allowed for provider(s): fred.",
+ "default": "primary",
+ "optional": true,
+ "choices": [
+ "primary",
+ "ltv_lte_80",
+ "ltv_gt_80",
+ "conforming_30y",
+ "conforming_30y_na",
+ "jumbo_30y",
+ "fha_30y",
+ "va_30y",
+ "usda_30y",
+ "conforming_15y",
+ "ltv_lte80_fico_ge740",
+ "ltv_lte80_fico_a720b739",
+ "ltv_lte80_fico_a700b719",
+ "ltv_lte80_fico_a680b699",
+ "ltv_lte80_fico_lt680",
+ "ltv_gt80_fico_ge740",
+ "ltv_gt80_fico_a720b739",
+ "ltv_gt80_fico_a700b719",
+ "ltv_gt80_fico_a680b699",
+ "ltv_gt80_fico_lt680"
+ ]
+ },
+ {
+ "name": "frequency",
+ "type": "Literal['a', 'q', 'm', 'w', 'd', 'wef', 'weth', 'wew', 'wetu', 'wem', 'wesu', 'wesa', 'bwew', 'bwem']",
+ "description": "Frequency aggregation to convert daily data to lower frequency. None = No change a = Annual q = Quarterly m = Monthly w = Weekly d = Daily wef = Weekly, Ending Friday weth = Weekly, Ending Thursday wew = Weekly, Ending Wednesday wetu = Weekly, Ending Tuesday wem = Weekly, Ending Monday wesu = Weekly, Ending Sunday wesa = Weekly, Ending Saturday bwew = Biweekly, Ending Wednesday bwem = Biweekly, Ending Monday",
+ "default": null,
+ "optional": true,
+ "choices": [
+ "a",
+ "q",
+ "m",
+ "w",
+ "d",
+ "wef",
+ "weth",
+ "wew",
+ "wetu",
+ "wem",
+ "wesu",
+ "wesa",
+ "bwew",
+ "bwem"
+ ]
+ },
+ {
+ "name": "aggregation_method",
+ "type": "Literal['avg', 'sum', 'eop']",
+ "description": "A key that indicates the aggregation method used for frequency aggregation. This parameter has no affect if the frequency parameter is not set, default is 'avg'. avg = Average sum = Sum eop = End of Period",
+ "default": "avg",
+ "optional": true,
+ "choices": [
+ "avg",
+ "sum",
+ "eop"
+ ]
+ },
+ {
+ "name": "transform",
+ "type": "Literal['chg', 'ch1', 'pch', 'pc1', 'pca', 'cch', 'cca', 'log']",
+ "description": "Transformation type None = No transformation chg = Change ch1 = Change from Year Ago pch = Percent Change pc1 = Percent Change from Year Ago pca = Compounded Annual Rate of Change cch = Continuously Compounded Rate of Change cca = Continuously Compounded Annual Rate of Change log = Natural Log",
+ "default": null,
+ "optional": true,
+ "choices": [
+ "chg",
+ "ch1",
+ "pch",
+ "pc1",
+ "pca",
+ "cch",
+ "cca",
+ "log"
+ ]
+ }
+ ]
+ },
+ "returns": {
+ "OBBject": [
+ {
+ "name": "results",
+ "type": "List[MortgageIndices]",
+ "description": "Serializable results."
+ },
+ {
+ "name": "provider",
+ "type": "Optional[Literal['fred']]",
+ "description": "Provider name."
+ },
+ {
+ "name": "warnings",
+ "type": "Optional[List[Warning_]]",
+ "description": "List of warnings."
+ },
+ {
+ "name": "chart",
+ "type": "Optional[Chart]",
+ "description": "Chart object."
+ },
+ {
+ "name": "extra",
+ "type": "Dict[str, Any]",
+ "description": "Extra info."
+ }
+ ]
+ },
+ "data": {
+ "standard": [
+ {
+ "name": "date",
+ "type": "date",
+ "description": "The date of the data.",
+ "default": "",
+ "optional": false,
+ "choices": null
+ },
+ {
+ "name": "symbol",
+ "type": "str",
+ "description": "Symbol representing the entity requested in the data.",
+ "default": null,
+ "optional": true,
+ "choices": null
+ },
+ {
+ "name": "name",
+ "type": "str",
+ "description": "Name of the index.",
+ "default": null,
+ "optional": true,
+ "choices": null
+ },
+ {
+ "name": "rate",
+ "type": "float",
+ "description": "Mortgage rate.",
+ "default": "",
+ "optional": false,
+ "choices": null
+ }
+ ],
+ "fred": []
+ },
+ "model": "MortgageIndices"
+ },
"/index/price/historical": {
"deprecated": {
"flag": null,
diff --git a/openbb_platform/openbb/package/fixedincome.py b/openbb_platform/openbb/package/fixedincome.py
index 456845abcf0..6f5dbb27f60 100644
--- a/openbb_platform/openbb/package/fixedincome.py
+++ b/openbb_platform/openbb/package/fixedincome.py
@@ -16,6 +16,7 @@ class ROUTER_fixedincome(Container):
bond_indices
/corporate
/government
+ mortgage_indices
/rate
sofr
/spreads
@@ -184,6 +185,132 @@ class ROUTER_fixedincome(Container):
command_runner=self._command_runner
)
+ @exception_handler
+ @validate
+ def mortgage_indices(
+ self,
+ start_date: Annotated[
+ Union[datetime.date, None, str],
+ OpenBBField(description="Start date of the data, in YYYY-MM-DD format."),
+ ] = None,
+ end_date: Annotated[
+ Union[datetime.date, None, str],
+ OpenBBField(description="End date of the data, in YYYY-MM-DD format."),
+ ] = None,
+ provider: Annotated[
+ Optional[Literal["fred"]],
+ OpenBBField(
+ description="The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: fred."
+ ),
+ ] = None,
+ **kwargs
+ ) -> OBBject:
+ """Mortgage Indices.
+
+ Parameters
+ ----------
+ start_date : Union[datetime.date, None, str]
+ Start date of the data, in YYYY-MM-DD format.
+ end_date : Union[datetime.date, None, str]
+ End date of the data, in YYYY-MM-DD format.
+ provider : Optional[Literal['fred']]
+ The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: fred.
+ index : Union[Literal['primary', 'ltv_lte_80', 'ltv_gt_80', 'conforming_30y', 'conforming_30y_na', 'jumbo_30y', 'fha_30y', 'va_30y', 'usda_30y', 'conforming_15y', 'ltv_lte80_fico_ge740', 'ltv_lte80_fico_a720b739', 'ltv_lte80_fico_a700b719', 'ltv_lte80_fico_a680b699', 'ltv_lte80_fico_lt680', 'ltv_gt80_fico_ge740', 'ltv_gt80_fico_a720b739', 'ltv_gt80_fico_a700b719', 'ltv_gt80_fico_a680b699', 'ltv_gt80_fico_lt680'], str]
+ The specific index, or index group, to query. Default is the 'primary' group. Multiple comma separated items allowed. (provider: fred)
+ frequency : Optional[Literal['a', 'q', 'm', 'w', 'd', 'wef', 'weth', 'wew', 'wetu', 'wem', 'wesu', 'wesa', 'bwew', 'bwem']]
+
+ Frequency aggregation to convert daily data to lower frequency.
+ None = No change
+ a = Annual
+ q = Quarterly
+ m = Monthly
+ w = Weekly
+ d = Daily
+ wef = Weekly, Ending Friday
+ weth = Weekly, Ending Thursday
+ wew = Weekly, Ending Wednesday
+ wetu = Weekly, Ending Tuesday
+ wem = Weekly, Ending Monday
+ wesu = Weekly, Ending Sunday
+ wesa = Weekly, Ending Saturday
+ bwew = Biweekly, Ending Wednesday
+ bwem = Biweekly, Ending Monday
+ (provider: fred)
+ aggregation_method : Literal['avg', 'sum', 'eop']
+
+ A key that indicates the aggregation method used for frequency aggregation.
+ This parameter has no affect if the frequency parameter is not set, default is 'avg'.
+ avg = Average
+ sum = Sum
+ eop = End of Period
+ (provider: fred)
+ transform : Optional[Literal['chg', 'ch1', 'pch', 'pc1', 'pca', 'cch', 'cca', 'log']]
+
+ Transformation type
+ None = No transformation
+ chg = Change
+ ch1 = Change from Year Ago
+ pch = Percent Change
+ pc1 = Percent Change from Year Ago
+ pca = Compounded Annual Rate of Change
+ cch = Continuously Compounded Rate of Change
+ cca = Continuously Compounded Annual Rate of Change
+ log = Natural Log
+ (provider: fred)
+
+ Returns
+ -------
+ OBBject
+ results : List[MortgageIndices]
+ Serializable results.
+ provider : Optional[Literal['fred']]
+ Provider name.
+ warnings : Optional[List[Warning_]]
+ List of warnings.
+ chart : Optional[Chart]
+ Chart object.
+ extra : Dict[str, Any]
+ Extra info.
+
+ MortgageIndices
+ ---------------
+ date : date
+ The date of the data.
+ symbol : Optional[str]
+ Symbol representing the entity requested in the data.
+ name : Optional[str]
+ Name of the index.
+ rate : float
+ Mortgage rate.
+
+ Examples
+ --------
+ >>> from openbb import obb
+ >>> # The default state for FRED are the primary mortgage indices from Optimal Blue.
+ >>> obb.fixedincome.mortgage_indices(provider='fred')
+ >>> # Multiple indices can be requested.
+ >>> obb.fixedincome.mortgage_indices(index='jumbo_30y,conforming_30y,conforming_15y', provider='fred')
+ """ # noqa: E501
+
+ return self._run(
+ "/fixedincome/mortgage_indices",
+ **filter_inputs(
+ provider_choices={
+ "provider": self._get_provider(
+ provider,
+ "fixedincome.mortgage_indices",
+ ("fred",),
+ )
+ },
+ standard_params={
+ "start_date": start_date,
+ "end_date": end_date,
+ },
+ extra_params=kwargs,
+ info={"index": {"fred": {"multiple_items_allowed": True}}},
+ )
+ )
+
@property
def rate(self):
# pylint: disable=import-outside-toplevel
diff --git a/openbb_platform/providers/fred/openbb_fred/__init__.py b/openbb_platform/providers/fred/openbb_fred/__init__.py
index d68a8d1558e..c55e2d55e16 100644
--- a/openbb_platform/providers/fred/openbb_fred/__init__.py
+++ b/openbb_platform/providers/fred/openbb_fred/__init__.py
@@ -18,6 +18,7 @@ from openbb_fred.models.hqm import FREDHighQualityMarketCorporateBondFetcher
from openbb_fred.models.ice_bofa import FREDICEBofAFetcher
from openbb_fred.models.iorb_rates import FREDIORBFetcher
from openbb_fred.models.moody import FREDMoodyCorporateBondIndexFetcher
+from openbb_fred.models.mortgage_indices import FredMortgageIndicesFetcher
from openbb_fred.models.regional import FredRegionalDataFetcher
from openbb_fred.models.retail_prices import FredRetailPricesFetcher
from openbb_fred.models.search import (
@@ -57,6 +58,7 @@ Research division of the Federal Reserve Bank of St. Louis that has more than
"EuropeanCentralBankInterestRates": FREDEuropeanCentralBankInterestRatesFetcher,
"ICEBofA": FREDICEBofAFetcher,
"MoodyCorporateBondIndex": FREDMoodyCorporateBondIndexFetcher,
+ "MortgageIndices": FredMortgageIndicesFetcher,
"CommercialPaper": FREDCommercialPaperFetcher,
"FredSearch": FredSearchFetcher,
"FredSeries": FredSeriesFetcher,
diff --git a/openbb_platform/providers/fred/openbb_fred/models/mortgage_indices.py b/openbb_platform/providers/fred/openbb_fred/models/mortgage_indices.py
new file mode 100644
index 00000000000..68a59dca4fd
--- /dev/null
+++ b/openbb_platform/providers/fred/openbb_fred/models/mortgage_indices.py
@@ -0,0 +1,312 @@
+"""FRED Mortgage Indices Model."""
+
+# pylint: disable=unused-argument
+
+from typing import Any, Dict, List, Literal, Optional, Union
+from warnings import warn
+
+from openbb_core.app.model.abstract.error import OpenBBError
+from openbb_core.provider.abstract.annotated_result import AnnotatedResult
+from openbb_core.provider.abstract.fetcher import Fetcher
+from openbb_core.provider.standard_models.mortgage_indices import (
+ MortgageIndicesData,
+ MortgageIndicesQueryParams,
+)
+from openbb_core.provider.utils.errors import EmptyDataError
+from openbb_fred.models.series import FredSeriesFetcher
+from pandas import Categorical, DataFrame
+from pydantic import Field, field_validator
+
+MORTGAGE_ID_TO_TITLE = {
+ "OBMMIC30YF": "30-Year Fixed Rate Conforming",
+ "OBMMIC30YFNA": "30-Year Fixed Rate Conforming Non-Adjusted",
+ "OBMMIJUMBO30YF": "30-Year Fixed Rate Jumbo",
+ "OBMMIFHA30YF": "30-Year Fixed Rate FHA",
+ "OBMMIVA30YF": "30-Year Fixed Rate Veterans Affairs",
+ "OBMMIUSDA30YF": "30-Year Fixed Rate USDA",
+ "OBMMIC15YF": "15-Year Fixed Rate Conforming",
+ "OBMMIC30YFLVLE80FGE740": "30-Year Fixed Rate Conforming LTV <= 80 FICO >= 740",
+ "OBMMIC30YFLVLE80FB720A739": "30-Year Fixed Rate Conforming LTV <= 80 FICO 720-739",
+ "OBMMIC30YFLVLE80FB700A719": "30-Year Fixed Rate Conforming LTV <= 80 FICO 700-719",
+ "OBMMIC30YFLVLE80FB680A699": "30-Year Fixed Rate Conforming LTV <= 80 FICO 680-699",
+ "OBMMIC30YFLVLE80FLT680": "30-Year Fixed Rate Conforming LTV <= 80 FICO < 680",
+ "OBMMIC30YFLVGT80FGE740": "30-Year Fixed Rate Conforming LTV > 80 FICO >= 740",
+ "OBMMIC30YFLVGT80FB720A739": "30-Year Fixed Rate Conforming LTV > 80 FICO 720-739",
+ "OBMMIC30YFLVGT80FB700A719": "30-Year Fixed Rate Conforming LTV > 80 FICO 700-719",
+ "OBMMIC30YFLVGT80FB680A699": "30-Year Fixed Rate Conforming LTV > 80 FICO 680-699",
+ "OBMMIC30YFLVGT80FLT680": "30-Year Fixed Rate Conforming LTV > 80 FICO < 680",
+}
+
+MORTGAGE_GROUPS = {
+ "primary": [
+ "OBMMIC30YF",
+ "OBMMIC30YFNA",
+ "OBMMIJUMBO30YF",
+ "OBMMIFHA30YF",
+ "OBMMIVA30YF",
+ "OBMMIUSDA30YF",
+ "OBMMIC15YF",
+ ],
+ "ltv_lte_80": [
+ "OBMMIC30YFLVLE80FGE740",
+ "OBMMIC30YFLVLE80FB720A739",
+ "OBMMIC30YFLVLE80FB700A719",
+ "OBMMIC30YFLVLE80FB680A699",
+ "OBMMIC30YFLVLE80FLT680",
+ ],
+ "ltv_gt_80": [
+ "OBMMIC30YFLVGT80FGE740",
+ "OBMMIC30YFLVGT80FB720A739",
+ "OBMMIC30YFLVGT80FB700A719",
+ "OBMMIC30YFLVGT80FB680A699",
+ "OBMMIC30YFLVGT80FLT680",
+ ],
+}
+
+MORTGAGE_CHOICES_TO_ID = {
+ "primary": ",".join(MORTGAGE_GROUPS["primary"]),
+ "ltv_lte_80": ",".join(MORTGAGE_GROUPS["ltv_lte_80"]),
+ "ltv_gt_80": ",".join(MORTGAGE_GROUPS["ltv_gt_80"]),
+ "conforming_30y": "OBMMIC30YF",
+ "conforming_30y_na": "OBMMIC30YFNA",
+ "jumbo_30y": "OBMMIJUMBO30YF",
+ "fha_30y": "OBMMIFHA30YF",
+ "va_30y": "OBMMIVA30YF",
+ "usda_30y": "OBMMIUSDA30YF",
+ "conforming_15y": "OBMMIC15YF",
+ "ltv_lte80_fico_ge740": "OBMMIC30YFLVLE80FGE740",
+ "ltv_lte80_fico_a720b739": "OBMMIC30YFLVLE80FB720A739",
+ "ltv_lte80_fico_a700b719": "OBMMIC30YFLVLE80FB700A719",
+ "ltv_lte80_fico_a680b699": "OBMMIC30YFLVLE80FB680A699",
+ "ltv_lte80_fico_lt680": "OBMMIC30YFLVLE80FLT680",
+ "ltv_gt80_fico_ge740": "OBMMIC30YFLVGT80FGE740",
+ "ltv_gt80_fico_a720b739": "OBMMIC30YFLVGT80FB720A739",
+ "ltv_gt80_fico_a700b719": "OBMMIC30YFLVGT80FB700A719",
+ "ltv_gt80_fico_a680b699": "OBMMIC30YFLVGT80FB680A699",
+ "ltv_gt80_fico_lt680": "OBMMIC30YFLVGT80FLT680",
+}
+
+MortgageChoices = Literal[
+ "primary",
+ "ltv_lte_80",
+ "ltv_gt_80",
+ "conforming_30y",
+ "conforming_30y_na",
+ "jumbo_30y",
+ "fha_30y",
+ "va_30y",
+ "usda_30y",
+ "conforming_15y",
+ "ltv_lte80_fico_ge740",
+ "ltv_lte80_fico_a720b739",
+ "ltv_lte80_fico_a700b719",
+ "ltv_lte80_fico_a680b699",
+ "ltv_lte80_fico_lt680",
+ "ltv_gt80_fico_ge740",
+ "ltv_gt80_fico_a720b739",
+ "ltv_gt80_fico_a700b719",
+ "ltv_gt80_fico_a680b699",
+ "ltv_gt80_fico_lt680",
+]
+
+
+class FredMortgageIndicesQueryParams(MortgageIndicesQueryParams):
+ """FRED Mortgage Indices Query."""
+
+ __json_schema_extra__ = {"index": {"multiple_items_allowed": True}}
+
+ index: Union[MortgageChoices, str] = Field(
+ default="primary",
+ description="The specific index, or index group, to query. Default is the 'primary' group.",
+ choices=list(MORTGAGE_CHOICES_TO_ID.keys()),
+ )
+ frequency: Union[
+ None,
+ Literal[
+ "a",
+ "q",
+ "m",
+ "w",
+ "d",
+ "wef",
+ "weth",
+ "wew",
+ "wetu",