diff options
author | Danglewood <85772166+deeleeramone@users.noreply.github.com> | 2024-06-16 15:13:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-16 22:13:46 +0000 |
commit | c5e16684baab63ce93deeb7641169ae4d3a1cf4a (patch) | |
tree | d34c221f320d1a120cf5a794bba2b8171fa1b78a | |
parent | 650912bf0c21714a109ff50ff8ed94651eaf1d63 (diff) |
[Feature] Intrinio Delayed Options (#6505)
* stashing
* intrinio delayed options
* stuff and things
* test cassettes and static assets
* options snapshots
* description
* commit intrinio files
---------
Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com>
19 files changed, 8073 insertions, 6187 deletions
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 6a23f687f5d..38aca52b57d 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 @@ -31,23 +31,29 @@ class OptionsChainsQueryParams(QueryParams): class OptionsChainsData(Data): """Options Chains Data.""" - symbol: Optional[str] = Field( - description=DATA_DESCRIPTIONS.get("symbol", "") - + " Here, it is the underlying symbol for the option.", + underlying_symbol: Optional[str] = Field( default=None, + description="Underlying symbol for the option.", + ) + underlying_price: Optional[float] = Field( + default=None, + description="Price of the underlying stock.", ) 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: dateType = Field(description="Expiration date of the contract.") + dte: Optional[int] = Field( + default=None, description="Days to expiration of the contract." + ) strike: float = Field(description="Strike price of the contract.") option_type: str = Field(description="Call or Put.") open_interest: Optional[int] = Field( - default=None, description="Open interest on the contract." + default=0, description="Open interest on the contract." ) volume: Optional[int] = Field( - default=None, description=DATA_DESCRIPTIONS.get("volume", "") + default=0, description=DATA_DESCRIPTIONS.get("volume", "") ) theoretical_price: Optional[float] = Field( default=None, description="Theoretical value of the option." @@ -55,6 +61,13 @@ class OptionsChainsData(Data): last_trade_price: Optional[float] = Field( default=None, description="Last trade price of the option." ) + last_trade_size: Optional[int] = Field( + default=None, description="Last trade size of the option." + ) + last_trade_time: Optional[datetime] = Field( + default=None, + description="The timestamp of the last trade.", + ) tick: Optional[str] = Field( default=None, description="Whether the last tick was up or down in price." ) @@ -64,12 +77,26 @@ class OptionsChainsData(Data): bid_size: Optional[int] = Field( default=None, description="Bid size for the option." ) + bid_time: Optional[datetime] = Field( + default=None, + description="The timestamp of the bid price.", + ) + bid_exchange: Optional[str] = Field( + default=None, description="The exchange of the bid price." + ) ask: Optional[float] = Field( default=None, description="Current ask price for the option." ) ask_size: Optional[int] = Field( default=None, description="Ask size for the option." ) + ask_time: Optional[datetime] = Field( + default=None, + description="The timestamp of the ask price.", + ) + ask_exchange: Optional[str] = Field( + default=None, description="The exchange of the ask price." + ) mark: Optional[float] = Field( default=None, description="The mid-price between the latest bid and ask." ) @@ -138,7 +165,8 @@ class OptionsChainsData(Data): ) change_percent: Optional[float] = Field( default=None, - description="Change, in normalizezd percentage points, of the option.", + description="Change, in normalized percentage points, of the option.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, ) implied_volatility: Optional[float] = Field( default=None, description="Implied volatility of the option." @@ -151,7 +179,7 @@ class OptionsChainsData(Data): @field_validator("expiration", mode="before", check_fields=False) @classmethod - def date_validate(cls, v): # pylint: disable=E0213 + def date_validate(cls, v): """Return the datetime object from the date string.""" if isinstance(v, datetime): return datetime.strftime(v, "%Y-%m-%d") diff --git a/openbb_platform/core/openbb_core/provider/standard_models/options_snapshots.py b/openbb_platform/core/openbb_core/provider/standard_models/options_snapshots.py new file mode 100644 index 00000000000..8c14af09ffd --- /dev/null +++ b/openbb_platform/core/openbb_core/provider/standard_models/options_snapshots.py @@ -0,0 +1,75 @@ +"""Options Snapshots Standard Model.""" + +from datetime import ( + date as dateType, + datetime, +) +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 + + +class OptionsSnapshotsQueryParams(QueryParams): + """Options Snapshots Query.""" + + +class OptionsSnapshotsData(Data): + """Options Snapshots Data.""" + + underlying_symbol: str = Field(description="Ticker symbol of the underlying asset.") + contract_symbol: str = Field(description="Symbol of the options contract.") + expiration: dateType = Field(description="Expiration date of the options contract.") + dte: Optional[int] = Field( + default=None, + description="Number of days to expiration of the options contract.", + ) + strike: float = Field( + description="Strike price of the options contract.", + json_schema_extra={"x-unit_measurement": "currency"}, + ) + option_type: str = Field(description="The type of option.") + volume: Optional[int] = Field( + default=None, + description=DATA_DESCRIPTIONS.get("volume", ""), + ) + open_interest: Optional[int] = Field( + default=None, + description="Open interest at the time.", + ) + last_price: Optional[float] = Field( + default=None, + description="Last trade price at the time.", + json_schema_extra={"x-unit_measurement": "currency"}, + ) + last_size: Optional[int] = Field( + default=None, + description="Lot size of the last trade.", + ) + last_timestamp: Optional[datetime] = Field( + default=None, + description="Timestamp of the last price.", + ) + open: Optional[float] = Field( + default=None, + description=DATA_DESCRIPTIONS.get("open", ""), + json_schema_extra={"x-unit_measurement": "currency"}, + ) + high: Optional[float] = Field( + default=None, + description=DATA_DESCRIPTIONS.get("high", ""), + json_schema_extra={"x-unit_measurement": "currency"}, + ) + low: Optional[float] = Field( + default=None, + description=DATA_DESCRIPTIONS.get("low", ""), + json_schema_extra={"x-unit_measurement": "currency"}, + ) + close: Optional[float] = Field( + default=None, + description=DATA_DESCRIPTIONS.get("close", ""), + json_schema_extra={"x-unit_measurement": "currency"}, + ) diff --git a/openbb_platform/extensions/derivatives/integration/test_derivatives_api.py b/openbb_platform/extensions/derivatives/integration/test_derivatives_api.py index 210ab79190c..97e9a3551eb 100644 --- a/openbb_platform/extensions/derivatives/integration/test_derivatives_api.py +++ b/openbb_platform/extensions/derivatives/integration/test_derivatives_api.py @@ -24,7 +24,24 @@ def headers(): @parametrize( "params", [ - ({"provider": "intrinio", "symbol": "AAPL", "date": "2023-01-25"}), + ( + { + "provider": "intrinio", + "symbol": "AAPL", + "date": "2023-01-25", + "option_type": None, + "moneyness": "all", + "strike_gt": None, + "strike_lt": None, + "volume_gt": None, + "volume_lt": None, + "oi_gt": None, + "oi_lt": None, + "model": "black_scholes", + "show_extended_price": False, + "include_related_symbols": False, + } + ), ({"provider": "cboe", "symbol": "AAPL", "use_cache": False}), ({"provider": "tradier", "symbol": "AAPL"}), ({"provider": "yfinance", "symbol": "AAPL"}), @@ -125,3 +142,21 @@ def test_derivatives_futures_curve(params, headers): result = requests.get(url, headers=headers, timeout=60) assert isinstance(result, requests.Response) assert result.status_code == 200 + + +@parametrize( + "params", + [ + ({"provider": "intrinio", "date": None, "only_traded": True}), + ], +) +@pytest.mark.integration +def test_derivatives_options_snapshots(params, headers): + """Test the options snapshots 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/derivatives/options/snapshots?{query_str}" + result = requests.get(url, headers=headers, timeout=60) + assert isinstance(result, requests.Response) + assert result.status_code == 200 diff --git a/openbb_platform/extensions/derivatives/integration/test_derivatives_python.py b/openbb_platform/extensions/derivatives/integration/test_derivatives_python.py index 1bc0597855f..4e04039bc7a 100644 --- a/openbb_platform/extensions/derivatives/integration/test_derivatives_python.py +++ b/openbb_platform/extensions/derivatives/integration/test_derivatives_python.py @@ -20,7 +20,24 @@ def obb(pytestconfig): @parametrize( "params", [ - ({"provider": "intrinio", "symbol": "AAPL", "date": "2023-01-25"}), + ( + { + "provider": "intrinio", + "symbol": "AAPL", + "date": "2023-01-25", + "option_type": None, + "moneyness": "all", + "strike_gt": None, + "strike_lt": None, + "volume_gt": None, + "volume_lt": None, + "oi_gt": None, + "oi_lt": None, + "model": "black_scholes", + "show_extended_price": False, + "include_related_symbols": False, + } + ), ({"provider": "cboe", "symbol": "AAPL", "use_cache": False}), ({"provider": "tradier", "symbol": "AAPL"}), ({"provider": "yfinance", "symbol": "AAPL"}), @@ -109,3 +126,18 @@ def test_derivatives_futures_curve(params, obb): assert result assert isinstance(result, OBBject) assert len(result.results) > 0 + + +@parametrize( + "params", + [ + ({"provider": "intrinio", "date": None, "only_traded": True}), + ], +) +@pytest.mark.integration +def test_derivatives_options_snapshots(params, obb): + """Test the options snapshots endpoint.""" + result = obb.derivatives.options.snapshots(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 diff --git a/openbb_platform/extensions/derivatives/openbb_derivatives/options/options_router.py b/openbb_platform/extensions/derivatives/openbb_derivatives/options/options_router.py index dbed2aa674d..bcdb00be4b7 100644 --- a/openbb_platform/extensions/derivatives/openbb_derivatives/options/options_router.py +++ b/openbb_platform/extensions/derivatives/openbb_derivatives/options/options_router.py @@ -54,3 +54,21 @@ async def unusual( ) -> OBBject: """Get the complete options chain for a ticker.""" return await OBBject.from_query(Query(**locals())) + + +@router.command( + model="OptionsSnapshots", + examples=[ + APIEx( + parameters={"provider": "intrinio"}, + ), + ], +) +async def snapshots( + cc: CommandContext, + provider_choices: ProviderChoices, + standard_params: StandardParams, + extra_params: ExtraParams, +) -> OBBject: + """Get a snapshot of the options market universe.""" + return await OBBject.from_query(Query(**locals())) diff --git a/openbb_platform/openbb/assets/reference.json b/openbb_platform/openbb/assets/reference.json index ca1dcb3f376..efdab571fc0 100644 --- a/openbb_platform/openbb/assets/reference.json +++ b/openbb_platform/openbb/assets/reference.json @@ -1213,6 +1213,101 @@ "default": null, "optional": true, "choices": null + }, + { + "name": "option_type", + "type": "Literal[None, Union[ForwardRef('call'), ForwardRef('put')]]", + "description": "The option type, call or put, 'None' is both (default).", + "default": null, + "optional": true, + "choices": [ + "call", + "put" + ] + }, + { + "name": "moneyness", + "type": "Literal['otm', 'itm', 'all']", + "description": "Return only contracts that are in or out of the money, default is 'all'. Parameter is ignored when a date is supplied.", + "default": "all", + "optional": true, + "choices": [ + "otm", + "itm", + "all" + ] + }, + { + "name": "strike_gt", + "type": "int", + "description": "Return options with a strike price greater than the given value. Parameter is ignored when a date is supplied.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "strike_lt", + "type": "int", + "description": "Return options with a strike price less than the given value. Parameter is ignored when a date is supplied.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "volume_gt", + "type": "int", + "description": "Return options with a volume greater than the given value. Parameter is ignored when a date is supplied.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "volume_lt", + "type": "int", + "description": "Return options with a volume less than the given value. Parameter is ignored when a date is supplied.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "oi_gt", + "type": "int", + "description": "Return options with an open interest greater than the given value. Parameter is ignored when a date is supplied.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "oi_lt", + "type": "int", + "description": "Return options with an open interest less than the given value. Parameter is ignored when a date is supplied.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "model", + "type": "Literal['black_scholes', 'bjerk']", + "description": "The pricing model to use for options chains data, default is 'black_scholes'. Parameter is ignored when a date is supplied.", + "default": "black_scholes", + "optional": true, + "choices": null + }, + { + "name": "show_extended_price", + "type": "bool", + "description": "Whether to include OHLC type fields, default is True. Parameter is ignored when a date is supplied.", + "default": true, + "optional": true, + "choices": null + }, + { + "name": "include_related_symbols", + "type": "bool", + "description": "Include related symbols that end in a 1 or 2 because of a corporate action, default is False.", + "default": false, + "optional": true, + "choices": null } ], "yfinance": [] @@ -1249,9 +1344,17 @@ "data": { "standard": [ { - "name": "symbol", + "name": "underlying_symbol", "type": "str", - "description": "Symbol representing the entity requested in the data. Here, it is the underlying symbol for the option.", + "description": "Underlying symbol for the option.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "underlying_price", + "type": "float", + "description": "Price of the underlying stock.", "default": null, "optional": true, "choices": null @@ -1281,6 +1384,14 @@ "choices": null }, { + "name": "dte", + "type": "int", + "description": "Days to expiration of the contract.", + "default": null, + "optional": true, + "choices": null + }, + { "name": "strike", "type": "float", "description": "Strike price of the contract.", @@ -1300,7 +1411,7 @@ "name": "open_interest", "type": "int", "description": "Open interest on the contract.", - "default": null, + "default": 0, "optional": true, "choices": null }, @@ -1308,7 +1419,7 @@ "name": "volume", "type": "int", "description": "The trading volume.", - "default": null, + "default": 0, "optional": true, "choices": null }, @@ -1329,6 +1440,22 @@ "choices": null }, { + "name": "last_trade_size", + "type": "int", + "description": "Last trade size of the option.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "last_trade_time", + "type": "datetime", + "description": "The timestamp of the last trade.", + "default": null, + "optional": true, + "choices": null + }, + { "name": "tick", "type": "str", "description": "Whether the last tick was up or down in price.", @@ -1353,6 +1480,22 @@ "choices": null }, { + "name": "bid_time", + "type": "datetime", + "description": "The timestamp of the bid price.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "bid_exchange", + "type": "str", + "description": "The exchange of the bid price.", + "default": null, + "optional": true, + "choices": null + }, + { "name": "ask", "type": "float", "description": "Current ask price for the option.", @@ -1369,6 +1512,22 @@ "choices": null }, { + "name": "ask_time", + "type": "datetime", + "description": "The timestamp of the ask price.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "ask_exchange", + "type": "str", + "description": "The exchange of the ask price.", + "default": null, + "optional": true, + "choices": null + }, + { "name": "mark", "type": "float", "description": "The mid-price between the latest bid and ask.", @@ -1539,7 +1698,7 @@ { "name": "change_percent", "type": "float", - "description": "Change, in normalizezd percentage points, of the option.", + "description": "Change, in normalized percentage points, of the option.", "default": null, "optional": true, "choices": null @@ -1593,26 +1752,9 @@ "choices": null } ], - "intrinio": [ - { - "name": "exercise_style", - "type": "str", - "description": "The exercise style of the option, American or European.", - "default": null, - "optional": true, - "choices": null - } - ], + "intrinio": [], "yfinance": [ { - |