summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbb_platform/core/openbb_core/app/model/obbject.py81
-rw-r--r--openbb_platform/core/openbb_core/provider/standard_models/country_interest_rates.py43
-rw-r--r--openbb_platform/core/openbb_core/provider/standard_models/options_chains.py392
-rw-r--r--openbb_platform/core/openbb_core/provider/utils/options_chains_properties.py1820
-rw-r--r--openbb_platform/extensions/derivatives/integration/test_derivatives_python.py13
-rw-r--r--openbb_platform/extensions/econometrics/poetry.lock186
-rw-r--r--openbb_platform/extensions/econometrics/pyproject.toml2
-rw-r--r--openbb_platform/extensions/economy/integration/test_economy_api.py27
-rw-r--r--openbb_platform/extensions/economy/integration/test_economy_python.py26
-rw-r--r--openbb_platform/extensions/economy/openbb_economy/economy_router.py57
-rw-r--r--openbb_platform/openbb/assets/reference.json340
-rw-r--r--openbb_platform/openbb/package/derivatives_options.py108
-rw-r--r--openbb_platform/openbb/package/economy.py205
-rw-r--r--openbb_platform/openbb/package/equity.py2
-rw-r--r--openbb_platform/providers/cboe/openbb_cboe/models/options_chains.py24
-rw-r--r--openbb_platform/providers/cboe/tests/record/http/test_cboe_fetchers/test_cboe_options_chains_fetcher_urllib3_v1.yaml12944
-rw-r--r--openbb_platform/providers/cboe/tests/record/http/test_cboe_fetchers/test_cboe_options_chains_fetcher_urllib3_v2.yaml13369
-rw-r--r--openbb_platform/providers/cboe/tests/test_cboe_fetchers.py1
-rw-r--r--openbb_platform/providers/fmp/openbb_fmp/models/etf_info.py18
-rw-r--r--openbb_platform/providers/intrinio/openbb_intrinio/models/options_chains.py66
-rw-r--r--openbb_platform/providers/intrinio/tests/record/http/test_intrinio_fetchers/test_intrinio_options_chains_fetcher_urllib3_v1.yaml9478
-rw-r--r--openbb_platform/providers/intrinio/tests/record/http/test_intrinio_fetchers/test_intrinio_options_chains_fetcher_urllib3_v2.yaml9028
-rw-r--r--openbb_platform/providers/intrinio/tests/test_intrinio_fetchers.py1
-rw-r--r--openbb_platform/providers/oecd/openbb_oecd/__init__.py14
-rw-r--r--openbb_platform/providers/oecd/openbb_oecd/models/country_interest_rates.py169
-rw-r--r--openbb_platform/providers/oecd/tests/record/http/test_oecd_fetchers/test_oecd_country_interest_rates_fetcher_urllib3_v1.yaml53
-rw-r--r--openbb_platform/providers/oecd/tests/record/http/test_oecd_fetchers/test_oecd_country_interest_rates_fetcher_urllib3_v2.yaml44
-rw-r--r--openbb_platform/providers/oecd/tests/test_oecd_fetchers.py17
-rw-r--r--openbb_platform/providers/tmx/openbb_tmx/models/options_chains.py38
-rw-r--r--openbb_platform/providers/tmx/tests/record/http/test_tmx_fetchers/test_tmx_options_chains_fetcher_urllib3_v1.yaml2575
-rw-r--r--openbb_platform/providers/tmx/tests/record/http/test_tmx_fetchers/test_tmx_options_chains_fetcher_urllib3_v2.yaml2281
-rw-r--r--openbb_platform/providers/tmx/tests/test_tmx_fetchers.py3
-rw-r--r--openbb_platform/providers/tradier/openbb_tradier/models/options_chains.py159
-rw-r--r--openbb_platform/providers/tradier/tests/record/http/test_tradier_fetchers/test_tradier_derivatives_options_chains_fetcher_urllib3_v1.yaml6543
-rw-r--r--openbb_platform/providers/tradier/tests/record/http/test_tradier_fetchers/test_tradier_derivatives_options_chains_fetcher_urllib3_v2.yaml7019
-rw-r--r--openbb_platform/providers/tradier/tests/test_tradier_fetchers.py1
-rw-r--r--openbb_platform/providers/yfinance/openbb_yfinance/models/options_chains.py35
-rw-r--r--openbb_platform/providers/yfinance/tests/record/http/test_yfinance_fetchers/test_y_finance_options_chains_fetcher_urllib3_v1.yaml7708
-rw-r--r--openbb_platform/providers/yfinance/tests/record/http/test_yfinance_fetchers/test_y_finance_options_chains_fetcher_urllib3_v2.yaml2606
-rw-r--r--openbb_platform/providers/yfinance/tests/test_yfinance_fetchers.py1
40 files changed, 55797 insertions, 21700 deletions
diff --git a/openbb_platform/core/openbb_core/app/model/obbject.py b/openbb_platform/core/openbb_core/app/model/obbject.py
index 48dabce4f75..2b10fac38cb 100644
--- a/openbb_platform/core/openbb_core/app/model/obbject.py
+++ b/openbb_platform/core/openbb_core/app/model/obbject.py
@@ -84,17 +84,54 @@ class OBBject(Tagged, Generic[T]):
return f"{self.__class__.__name__}\n\n" + "\n".join(items)
def to_df(
- self, index: Optional[Union[str, None]] = "date", sort_by: Optional[str] = None
+ self,
+ index: Optional[Union[str, None]] = "date",
+ sort_by: Optional[str] = None,
+ ascending: Optional[bool] = None,
) -> "DataFrame":
- """Alias for `to_dataframe`."""
- return self.to_dataframe(index=index, sort_by=sort_by)
+ """Alias for `to_dataframe`.
+
+ Supports converting creating Pandas DataFrames from the following
+ serializable data formats:
+
+ - List[BaseModel]
+ - List[Dict]
+ - List[List]
+ - List[str]
+ - List[int]
+ - List[float]
+ - Dict[str, Dict]
+ - Dict[str, List]
+ - Dict[str, BaseModel]
+
+ Other supported formats:
+ - str
+
+ Parameters
+ ----------
+ index : Optional[str]
+ Column name to use as index.
+ sort_by : Optional[str]
+ Column name to sort by.
+ ascending: Optional[bool]
+ Sort by ascending for each column specified in `sort_by`.
+
+ Returns
+ -------
+ DataFrame
+ Pandas DataFrame.
+ """
+ return self.to_dataframe(index=index, sort_by=sort_by, ascending=ascending)
def to_dataframe(
- self, index: Optional[Union[str, None]] = "date", sort_by: Optional[str] = None
+ self,
+ index: Optional[Union[str, None]] = "date",
+ sort_by: Optional[str] = None,
+ ascending: Optional[bool] = None,
) -> "DataFrame":
- """Convert results field to pandas dataframe.
+ """Convert results field to Pandas DataFrame.
- Supports converting creating pandas DataFrames from the following
+ Supports converting creating Pandas DataFrames from the following
serializable data formats:
- List[BaseModel]
@@ -116,11 +153,13 @@ class OBBject(Tagged, Generic[T]):
Column name to use as index.
sort_by : Optional[str]
Column name to sort by.
+ ascending: Optional[bool]
+ Sort by ascending for each column specified in `sort_by`.
Returns
-------
DataFrame
- Pandas dataframe.
+ Pandas DataFrame.
"""
# pylint: disable=import-outside-toplevel
from pandas import DataFrame, concat # noqa
@@ -142,8 +181,13 @@ class OBBject(Tagged, Generic[T]):
df = None
sort_columns = True
+ # BaseModel
+ if isinstance(res, BaseModel):
+ df = DataFrame(res.model_dump(exclude_unset=True, exclude_none=True))
+ sort_columns = False
+
# List[Dict]
- if isinstance(res, list) and len(res) == 1 and isinstance(res[0], dict):
+ elif isinstance(res, list) and len(res) == 1 and isinstance(res[0], dict):
r = res[0]
dict_of_df = {}
@@ -178,10 +222,6 @@ class OBBject(Tagged, Generic[T]):
else:
try:
df = DataFrame(res) # type: ignore[call-overload]
- # Set index, if any
- if df is not None and index is not None and index in df.columns:
- df.set_index(index, inplace=True)
-
except ValueError:
if isinstance(res, dict):
df = DataFrame([res])
@@ -189,6 +229,10 @@ class OBBject(Tagged, Generic[T]):
if df is None:
raise OpenBBError("Unsupported data format.")
+ # Set index, if any
+ if index is not None and index in df.columns:
+ df.set_index(index, inplace=True)
+
# Drop columns that are all NaN, but don't rearrange columns
if sort_columns:
df.sort_index(axis=1, inplace=True)
@@ -196,7 +240,11 @@ class OBBject(Tagged, Generic[T]):
# Sort by specified column
if sort_by:
- df.sort_values(by=sort_by, inplace=True)
+ df.sort_values(
+ by=sort_by,
+ ascending=ascending if ascending is not None else True,
+ inplace=True,
+ )
except OpenBBError as e:
raise e
@@ -213,7 +261,7 @@ class OBBject(Tagged, Generic[T]):
return df
- def to_polars(self) -> "PolarsDataFrame":
+ def to_polars(self) -> "PolarsDataFrame": # type: ignore
"""Convert results field to polars dataframe."""
try:
from polars import from_pandas # type: ignore # pylint: disable=import-outside-toplevel
@@ -234,14 +282,13 @@ class OBBject(Tagged, Generic[T]):
"dict", "list", "series", "split", "tight", "records", "index"
] = "list",
) -> Union[Dict[Hashable, Any], List[Dict[Hashable, Any]]]:
- """Convert results field to a dictionary using any of pandas to_dict options.
+ """Convert results field to a dictionary using any of Pandas `to_dict` options.
Parameters
----------
orient : Literal["dict", "list", "series", "split", "tight", "records", "index"]
Value to pass to `.to_dict()` method
-
Returns
-------
Union[Dict[Hashable, Any], List[Dict[Hashable, Any]]]
@@ -278,7 +325,7 @@ class OBBject(Tagged, Generic[T]):
date_unit="s",
)
- return results
+ return results # type: ignore
def show(self, **kwargs: Any) -> None:
"""Display chart."""
diff --git a/openbb_platform/core/openbb_core/provider/standard_models/country_interest_rates.py b/openbb_platform/core/openbb_core/provider/standard_models/country_interest_rates.py
new file mode 100644
index 00000000000..bea3d0b361f
--- /dev/null
+++ b/openbb_platform/core/openbb_core/provider/standard_models/country_interest_rates.py
@@ -0,0 +1,43 @@
+"""Country Interest Rates 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 CountryInterestRatesQueryParams(QueryParams):
+ """Country Interest Rates Query."""
+
+ country: str = Field(
+ default="united_states",
+ description=QUERY_DESCRIPTIONS.get("country"),
+ )
+ 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 CountryInterestRatesData(Data):
+ """Country Interest Rates Data."""
+
+ date: dateType = Field(default=None, description=DATA_DESCRIPTIONS.get("date"))
+ value: float = Field(
+ default=None,
+ description="The interest rate value.",
+ json_schema_extra={"x-unit_measurment": "percent", "x-frontend_multiply": 100},
+ )
+ country: Optional[str] = Field(
+ default=None,
+ description="Country for which the interest rate is given.",
+ )
diff --git a/openbb_platform/core/openbb_core/provider/standard_models/options_chains.py b/openbb_platform/core/openbb_core/provider/standard_models/options_chains.py
index 38aca52b57d..b09a900d4e5 100644
--- a/openbb_platform/core/openbb_core/provider/standard_models/options_chains.py
+++ b/openbb_platform/core/openbb_core/provider/standard_models/options_chains.py
@@ -4,16 +4,16 @@ from datetime import (
date as dateType,
datetime,
)
-from typing import Optional
+from typing import List, 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 openbb_core.provider.utils.options_chains_properties import OptionsChainsProperties
class OptionsChainsQueryParams(QueryParams):
@@ -28,161 +28,323 @@ class OptionsChainsQueryParams(QueryParams):
return v.upper()
-class OptionsChainsData(Data):
- """Options Chains Data."""
+class OptionsChainsData(OptionsChainsProperties):
+ """Options Chains Data.
- underlying_symbol: Optional[str] = Field(
- default=None,
+ Note: The attached properties and methods are available only when working with an instance of this class,
+ initialized with validated provider data. The items below bind to the `results` object in the function's output.
+
+ Properties
+ ----------
+ dataframe: DataFrame
+ Return all data as a Pandas DataFrame, with additional computed columns (Breakeven, GEX, DEX) if available.
+ expirations: List[str]
+ Return a list of unique expiration dates, as strings.
+ strikes: List[float]
+ Return a list of unique strike prices.
+ has_iv: bool
+ Return True if the data contains implied volatility.
+ has_greeks: bool
+ Return True if the data contains greeks.
+ total_oi: Dict
+ Return open interest stats as a nested dictionary with keys: total, expiration, strike.
+ Both, "expiration" and "strike", contain a list of records with fields: Calls, Puts, Total, Net Percent, PCR.
+ total_volume: Dict
+ Return volume stats as a nested dictionary with keys: total, expiration, strike.
+ Both, "expiration" and "strike", contain a list of records with fields: Calls, Puts, Total, Net Percent, PCR.
+ total_dex: Dict
+ Return Delta Dollars (DEX), if available, as a nested dictionary with keys: total, expiration, strike.
+ Both, "expiration" and "strike", contain a list of records with fields: Calls, Puts, Total, Net Percent, PCR.
+ total_gex: Dict
+ Return Gamma Exposure (GEX), if available, as a nested dictionary with keys: total, expiration, strike.
+ Both, "expiration" and "strike", contain a list of records with fields: Calls, Puts, Total, Net Percent, PCR.
+ last_price: float
+ Manually set the underlying price by assigning a float value to this property.
+ Certain provider/symbol combinations may not return the underlying price,
+ and it may be necessary, or desirable, to set it post-initialization.
+ This property can be used to override the underlying price returned by the provider.
+ It is not set automatically, and this property will return None if it is not set.
+
+ Methods
+ -------
+ filter_data(
+ date: Optional[Union[str, int]] = None, column: Optional[str] = None,
+ option_type: Optional[Literal["call", "put"]] = None,
+ moneyness: Optional[Literal["otm", "itm"]] = None,
+ value_min: Optional[float] = None,
+ value_max: Optional[float] = None,
+ stat: Optional[Literal["open_interest", "volume", "dex", "gex"]] = None,
+ by: Literal["expiration", "strike"] = "expiration",
+ ) -> DataFrame:
+ Return statistics by strike or expiration; or, the filtered chains data.
+ skew(
+ days: Optional[int] = None, underlying_price: Optional[float] = None)
+ -> DataFrame:
+ Return skewness of the options, either vertical or horizontal, by nearest DTE.
+ straddle(
+ days: Optional[int] = None, strike: Optional[float] = None, underlying_price: Optional[float] = None
+ ) -> DataFrame:
+ Calculates the cost of a straddle, by nearest DTE. Use a negative strike price for short options.
+ strangle(
+ days: Optional[int] = None, moneyness: Optional[float] = None, underlying_price: Optional[float] = None
+ ) -> DataFrame:
+ Calculates the cost of a strangle, by nearest DTE and % moneyness.
+ Use a negative value for moneyness for short options.
+ synthetic_long(
+ days: Optional[int] = None, strike: Optional[float] = None, underlying_price: Optional[float] = None
+ ) -> DataFrame:
+ Calculates the cost of a synthetic long position, by nearest DTE and strike price.
+ synthetic_short(
+ days: Optional[int] = None, strike: Optional[float] = None, underlying_price: Optional[float] = None
+ ) -> DataFrame:
+ Calculates the cost of a synthetic short position, by nearest DTE and strike price.
+ vertical_call(
+ days: Optional[int] = None, sold: Optional[float] = None, bought: Optional[float] = None,
+ underlying_price: Optional[float] = None
+ ) -> DataFrame:
+ Calculates the cost of a vertical call spread, by nearest DTE and strike price to sold and bought levels.
+ vertical_put(
+ days: Optional[int] = None, sold: Optional[float] = None, bought: Optional[float] = None,
+ underlying_price: Optional[float] = None
+ ) -> DataFrame:
+ Calculates the cost of a vertical put spread, by nearest DTE and strike price to sold and bought levels.
+ strategies(
+ days: Optional[int] = None,
+ straddle_strike: Optional[float] = None,
+ strangle_moneyness: Optional[List[float]] = None,
+ synthetic_longs: Optional[List[float]] = None,
+ synthetic_shorts: Optional[List[float]] = None,
+ vertical_calls: Optional[List[tuple]] = None,
+ vertical_puts: Optional[List[tuple]] = None,
+ underlying_price: Optional[float] = None,
+ ) -> DataFrame:
+ Method for combining multiple strategies and parameters in a single DataFrame.
+ To get all expirations, set days to -1.
+
+ Raises
+ ------
+ OpenBBError
+ OpenBBError will raise when accessing properties and methods if required, specific, data was not found.
+ """
+
+ underlying_symbol: List[Union[str, None]] = Field(
+ default_factory=list,
description="Underlying symbol for the option.",
)
- underlying_price: Optional[float] = Field(
- default=None,
+ underlying_price: List[Union[float, None]] = Field(
+ default_factory=list,
description="Price of the underlying stock.",
+ json_schema_extra={"x-unit_measurement": "currency"},
+ )
+ contract_symbol: List[str] = Field(description="Contract symbol for the option.")
+ eod_date: List[Union[dateType, None]] = Field(
+ default_factory=list,
+ description="Date for which the options chains are returned.",
)
- contract_symbol: str = Field(description="Contract symbol for the option.")
- eod_date: Optional[dateType] = Field(
- default=None, description="Date for which the options chains are returned."
+ expiration: List[dateType] = Field(description="Expiration date of the contract.")
+ dte: List[Union[int, None]] = Field(
+ default_factory=list, description="Days to expiration of the contract."
)
- expiration: dateType = Field(description="Expiration date of the contract.")
- dte: Optional[int] = Field(
- default=None, description="Days to expiration of the contract."
+ strike: List[float] = Field(
+ description="Strike price of the contract.",
+ json_schema_extra={"x-unit_measurement": "currency"},
)
- strike: float = Field(description="Strike price of the contract.")
- option_type: str = Field(description="Call or Put.")
- open_interest: Optional[int] = Field(
- default=0, description="Open interest on the contract."
+ option_type: List[str] = Field(description="Call or Put.")
+ open_interest: List[Union[int, None]] = Field(
+ default_factory=list, description="Open interest on the contract."
)
- volume: Optional[int] = Field(
- default=0, description=DATA_DESCRIPTIONS.get("volume", "")
+ volume: List[Union[int, None]] = Field(
+ default_factory=list, description=DATA_DESCRIPTIONS.get("volume", "")
)
- theoretical_price: Optional[float] = Field(
- default=None, description="Theoretical value of the option."
+ theoretical_price: List[Union[float, None]] = Field(
+ default_factory=list,
+ description="Theoretical value of the option.",
+ json_schema_extra={"x-unit_measurement": "currency"},
)
- last_trade_price: Optional[float] = Field(
- default=None, description="Last trade price of the option."
+ last_trade_price: List[Union[float, None]] = Field(
+ default_factory=list,
+ description="Last trade price of the option.",
+ json_schema_extra={"x-unit_measurement": "currency"},
)
- last_trade_size: Optional[int] = Field(
- default=None, description="Last trade size of the option."
+ last_trade_size: List[Union[int, None]] = Field(
+ default_factory=list, description="Last trade size of the option."
)
- last_trade_time: Optional[datetime] = Field(
- default=None,
+ last_trade_time: List[Union[datetime, None]] = Field(
+ default_factory=list,
description="The timestamp of the last trade.",
)
- tick: Optional[str] = Field(
- default=None, description="Whether the last tick was up or down in price."
+ tick: List[Union[str, None]] = Field(
+ default_factory=list,
+ description="Whether the last tick was up or down in price.",
)
- bid: Optional[float] = Field(
- default=None, description="Current bid price for the option."
+ bid: List[Union[float, None]] = Field(
+ default_factory=list,
+ description="Current bid price for the option.",
+ json_schema_extra={"x-unit_measurement": "currency"},
)
- bid_size: Optional[int] = Field(
- default=None, description="Bid size for the option."
+ bid_size: List[Union[int, None]] = Field(
+ default_factory=list, description="Bid size for the option."
)
- bid_time: Optional[datetime] = Field(
- default=None,
+ bid_time: List[Union[datetime, None]] = Field(
+ default_factory=list,
description="The timestamp of the bid price.",
)
- bid_exchange: Optional[str] = Field(
- default=None, description="The exchange of the bid price."
+ bid_exchange: List[Union[str, None]] = Field(
+ default_factory=list, description="The exchange of the bid price."
)
- ask: Optional[float] = Field(
- default=None, description="Current ask price for the option."
+ ask: List[Union[float, None]] = Field(
+ default_factory=list,
+ description="Current ask price for the option.",
+ json_schema_extra={"x-unit_measurement": "currency"},
)
- ask_size: Optional[int] = Field(
- default=None, description="Ask size for the option."
+ ask_size: List[Union[int, None]] = Field(
+ default_factory=list, description="Ask size for the option."
)
- ask_time: Optional[datetime] = Field(
- default=None,
+ ask_time: List[Union[datetime, None]] = Field(
+ default_factory=list,