-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
260 additions
and
4 deletions.
There are no files selected for viewing
40 changes: 40 additions & 0 deletions
40
openbb_platform/core/openbb_core/provider/standard_models/share_price.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
"""Share Prices 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 SharePriceQueryParams(QueryParams): | ||
"""Share Price 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 SharePriceData(Data): | ||
"""Share Price Data.""" | ||
|
||
date: Optional[dateType] = Field( | ||
default=None, description=DATA_DESCRIPTIONS.get("date") | ||
) | ||
value: Optional[float] = Field( | ||
default=None, | ||
description="Interest rate (given as a whole number, i.e 10=10%)", | ||
) | ||
country: Optional[str] = Field( | ||
default=None, | ||
description="Country for which interest rate is given", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
138 changes: 138 additions & 0 deletions
138
openbb_platform/providers/oecd/openbb_oecd/models/share_price.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
"""OECD Short Term Interest Rate Data.""" | ||
|
||
# pylint: disable=unused-argument | ||
|
||
import re | ||
from datetime import date, timedelta | ||
from typing import Any, Dict, List, Literal, Optional, Union | ||
|
||
from openbb_core.provider.abstract.fetcher import Fetcher | ||
from openbb_core.provider.standard_models.share_price import ( | ||
SharePriceData, | ||
SharePriceQueryParams, | ||
) | ||
from openbb_oecd.utils import helpers | ||
from openbb_oecd.utils.constants import CODE_TO_COUNTRY_SHARES, COUNTRY_TO_CODE_SHARES | ||
from pydantic import Field, field_validator | ||
|
||
countries = tuple(CODE_TO_COUNTRY_SHARES.values()) + ("all",) | ||
CountriesLiteral = Literal[countries] # type: ignore | ||
|
||
|
||
class OECDSharePriceQueryParams(SharePriceQueryParams): | ||
"""OECD Share Price Rate Query.""" | ||
|
||
country: CountriesLiteral = Field( | ||
description="Country to get share price for.", default="united_states" | ||
) | ||
|
||
frequency: Literal["monthly", "quarterly", "annual"] = Field( | ||
description="Frequency to get share price for for.", default="monthly" | ||
) | ||
|
||
units: Literal["yoy", "pop"] = Field( | ||
description="Units to get share price for. Either change over period (pop) or change over year (yoy)", | ||
default="yoy", | ||
) | ||
|
||
|
||
class OECDSharePriceData(SharePriceData): | ||
"""OECD Share Price Rate Data.""" | ||
|
||
@field_validator("date", mode="before") | ||
@classmethod | ||
def date_validate(cls, in_date: Union[date, str]): # pylint: disable=E0213 | ||
"""Validate value.""" | ||
if isinstance(in_date, str): | ||
# i.e 2022-Q1 | ||
if re.match(r"\d{4}-Q[1-4]$", in_date): | ||
year, quarter = in_date.split("-") | ||
_year = int(year) | ||
if quarter == "Q1": | ||
return date(_year, 3, 31) | ||
if quarter == "Q2": | ||
return date(_year, 6, 30) | ||
if quarter == "Q3": | ||
return date(_year, 9, 30) | ||
if quarter == "Q4": | ||
return date(_year, 12, 31) | ||
# Now match if it is monthly, i.e 2022-01 | ||
elif re.match(r"\d{4}-\d{2}$", in_date): | ||
year, month = map(int, in_date.split("-")) # type: ignore | ||
if month == 12: | ||
return date(year, month, 31) # type: ignore | ||
next_month = date(year, month + 1, 1) # type: ignore | ||
return date(next_month.year, next_month.month, 1) - timedelta(days=1) | ||
# Now match if it is yearly, i.e 2022 | ||
elif re.match(r"\d{4}$", in_date): | ||
return date(int(in_date), 12, 31) | ||
# If the input date is a year | ||
if isinstance(in_date, int): | ||
return date(in_date, 12, 31) | ||
|
||
return in_date | ||
|
||
|
||
class OECDSharePriceFetcher( | ||
Fetcher[OECDSharePriceQueryParams, List[OECDSharePriceData]] | ||
): | ||
"""Transform the query, extract and transform the data from the OECD endpoints.""" | ||
|
||
@staticmethod | ||
def transform_query(params: Dict[str, Any]) -> OECDSharePriceQueryParams: | ||
"""Transform the query.""" | ||
transformed_params = params.copy() | ||
if transformed_params["start_date"] is None: | ||
transformed_params["start_date"] = date(1950, 1, 1) | ||
if transformed_params["end_date"] is None: | ||
transformed_params["end_date"] = date(date.today().year, 12, 31) | ||
|
||
return OECDSharePriceQueryParams(**transformed_params) | ||
|
||
@staticmethod | ||
def extract_data( | ||
query: OECDSharePriceQueryParams, | ||
credentials: Optional[Dict[str, str]], | ||
**kwargs: Any, | ||
) -> List[Dict]: | ||
"""Return the raw data from the OECD endpoint.""" | ||
frequency = query.frequency[0].upper() | ||
country = ( | ||
"" if query.country == "all" else COUNTRY_TO_CODE_SHARES[query.country] | ||
) | ||
transform = {"pop": "G1", "yoy": "GY"}[query.units] | ||
query_dict = { | ||
k: v | ||
for k, v in query.__dict__.items() | ||
if k not in ["start_date", "end_date"] | ||
} | ||
|
||
url = f"https://sdmx.oecd.org/public/rest/data/OECD.SDD.STES,DSD_KEI@DF_KEI,4.0/{country}.{frequency}.SHARE....{transform}" | ||
data = helpers.get_possibly_cached_data( | ||
url, function="economy_share_price", query_dict=query_dict | ||
) | ||
url_query = f"FREQ=='{frequency}' & TRANSFORMATION=='{transform}'" | ||
url_query = url_query + f" & REF_AREA=='{country}'" if country else url_query | ||
# Filter down | ||
data = ( | ||
data.query(url_query) | ||
.reset_index(drop=True)[["REF_AREA", "TIME_PERIOD", "VALUE"]] | ||
.rename( | ||
columns={"REF_AREA": "country", "TIME_PERIOD": "date", "VALUE": "value"} | ||
) | ||
) | ||
data["country"] = data["country"].map(CODE_TO_COUNTRY_SHARES) | ||
data = data.fillna("N/A").replace("N/A", None) | ||
data["date"] = data["date"].apply(helpers.oecd_date_to_python_date) | ||
data = data[ | ||
(data["date"] <= query.end_date) & (data["date"] >= query.start_date) | ||
] | ||
|
||
return data.to_dict(orient="records") | ||
|
||
@staticmethod | ||
def transform_data( | ||
query: OECDSharePriceQueryParams, data: List[Dict], **kwargs: Any | ||
) -> List[OECDSharePriceData]: | ||
"""Transform the data from the OECD endpoint.""" | ||
return [OECDSharePriceData.model_validate(d) for d in data] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters