summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanglewood <85772166+deeleeramone@users.noreply.github.com>2024-06-16 15:13:46 -0700
committerGitHub <noreply@github.com>2024-06-16 22:13:46 +0000
commitc5e16684baab63ce93deeb7641169ae4d3a1cf4a (patch)
treed34c221f320d1a120cf5a794bba2b8171fa1b78a
parent650912bf0c21714a109ff50ff8ed94651eaf1d63 (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>
-rw-r--r--openbb_platform/core/openbb_core/provider/standard_models/options_chains.py42
-rw-r--r--openbb_platform/core/openbb_core/provider/standard_models/options_snapshots.py75
-rw-r--r--openbb_platform/extensions/derivatives/integration/test_derivatives_api.py37
-rw-r--r--openbb_platform/extensions/derivatives/integration/test_derivatives_python.py34
-rw-r--r--openbb_platform/extensions/derivatives/openbb_derivatives/options/options_router.py18
-rw-r--r--openbb_platform/openbb/assets/reference.json483
-rw-r--r--openbb_platform/openbb/package/derivatives_options.py168
-rw-r--r--openbb_platform/providers/cboe/openbb_cboe/models/options_chains.py22
-rw-r--r--openbb_platform/providers/intrinio/openbb_intrinio/__init__.py2
-rw-r--r--openbb_platform/providers/intrinio/openbb_intrinio/models/options_chains.py253
-rw-r--r--openbb_platform/providers/intrinio/openbb_intrinio/models/options_snapshots.py329
-rw-r--r--openbb_platform/providers/intrinio/tests/record/http/test_intrinio_fetchers/test_intrinio_options_chains_fetcher.yaml5941
-rw-r--r--openbb_platform/providers/intrinio/tests/test_intrinio_fetchers.py11
-rw-r--r--openbb_platform/providers/tmx/openbb_tmx/models/options_chains.py14
-rw-r--r--openbb_platform/providers/tmx/openbb_tmx/utils/helpers.py2
-rw-r--r--openbb_platform/providers/tmx/tests/record/http/test_tmx_fetchers/test_tmx_options_chains_fetcher.yaml2541
-rw-r--r--openbb_platform/providers/tradier/openbb_tradier/models/options_chains.py70
-rw-r--r--openbb_platform/providers/tradier/tests/record/http/test_tradier_fetchers/test_tradier_derivatives_options_chains_fetcher.yaml4189
-rw-r--r--openbb_platform/providers/yfinance/openbb_yfinance/models/options_chains.py29
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": [
{
-