summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanglewood <85772166+deeleeramone@users.noreply.github.com>2024-06-14 17:13:09 -0700
committerDanglewood <85772166+deeleeramone@users.noreply.github.com>2024-06-14 17:13:09 -0700
commitfc70fb9f317b3a3acbd8f725cc072f4c1dd43f8d (patch)
tree3f15f00c02aab9562313e997b331e02dc21e3abc
parent071c60f04d5cf3983230fe7cae14be20838e632d (diff)
intrinio delayed options
-rw-r--r--openbb_platform/core/openbb_core/provider/standard_models/options_chains.py14
-rw-r--r--openbb_platform/extensions/derivatives/integration/test_derivatives_api.py19
-rw-r--r--openbb_platform/extensions/derivatives/integration/test_derivatives_python.py19
-rw-r--r--openbb_platform/providers/cboe/openbb_cboe/models/options_chains.py22
-rw-r--r--openbb_platform/providers/intrinio/openbb_intrinio/models/options_chains.py63
-rw-r--r--openbb_platform/providers/tmx/openbb_tmx/models/options_chains.py14
-rw-r--r--openbb_platform/providers/tradier/openbb_tradier/models/options_chains.py70
-rw-r--r--openbb_platform/providers/yfinance/openbb_yfinance/models/options_chains.py29
8 files changed, 151 insertions, 99 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 b6dd8b845ed..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,6 +31,14 @@ class OptionsChainsQueryParams(QueryParams):
class OptionsChainsData(Data):
"""Options Chains Data."""
+ 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."
@@ -73,6 +81,9 @@ class OptionsChainsData(Data):
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."
)
@@ -83,6 +94,9 @@ class OptionsChainsData(Data):
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."
)
diff --git a/openbb_platform/extensions/derivatives/integration/test_derivatives_api.py b/openbb_platform/extensions/derivatives/integration/test_derivatives_api.py
index 210ab79190c..23089fe9f1b 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"}),
diff --git a/openbb_platform/extensions/derivatives/integration/test_derivatives_python.py b/openbb_platform/extensions/derivatives/integration/test_derivatives_python.py
index 1bc0597855f..c03cc32d6a7 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"}),
diff --git a/openbb_platform/providers/cboe/openbb_cboe/models/options_chains.py b/openbb_platform/providers/cboe/openbb_cboe/models/options_chains.py
index c1c0602d3cc..ca049ee80a7 100644
--- a/openbb_platform/providers/cboe/openbb_cboe/models/options_chains.py
+++ b/openbb_platform/providers/cboe/openbb_cboe/models/options_chains.py
@@ -39,11 +39,6 @@ class CboeOptionsChainsQueryParams(OptionsChainsQueryParams):
class CboeOptionsChainsData(OptionsChainsData):
"""CBOE Options Chains Data."""
- last_trade_timestamp: Optional[datetime] = Field(
- description="Last trade timestamp of the option.", default=None
- )
- dte: int = Field(description="Days to expiration for the option.")
-
class CboeOptionsChainsFetcher(
Fetcher[
@@ -51,7 +46,7 @@ class CboeOptionsChainsFetcher(
List[CboeOptionsChainsData],
]
):
- """Transform the query, extract and transform the data from the CBOE endpoints."""
+ """Cboe Options Chains Fetcher."""
@staticmethod
def transform_query(params: Dict[str, Any]) -> CboeOptionsChainsQueryParams:
@@ -137,7 +132,6 @@ class CboeOptionsChainsFetcher(
"theo": "theoretical_price",
"percent_change": "change_percent",
"prev_day_close": "prev_close",
- "last_trade_time": "last_trade_timestamp",
}
)
@@ -162,7 +156,9 @@ class CboeOptionsChainsFetcher(
option_df_index.expiration = DatetimeIndex(
option_df_index.expiration, yearfirst=True
).astype(str)
- option_df_index = option_df_index.drop(columns=["Ticker"])
+ option_df_index = option_df_index.rename(
+ columns={"Ticker": "underlying_symbol"}
+ )
# Joins the parsed symbol into the dataframe.
@@ -173,20 +169,22 @@ class CboeOptionsChainsFetcher(
temp_ = (temp - now).days + 1
quotes["dte"] = temp_
- quotes["last_trade_timestamp"] = (
- to_datetime(quotes["last_trade_timestamp"], format="%Y-%m-%dT%H:%M:%S")
+ quotes["last_trade_time"] = (
+ to_datetime(quotes["last_trade_time"], format="%Y-%m-%dT%H:%M:%S")
.fillna(value="-")
.replace("-", None)
)
quotes = quotes.set_index(
keys=["expiration", "strike", "option_type"]
).sort_index()
+ if results_metadata.get("current_price"):
+ quotes["underlying_price"] = results_metadata["current_price"]
quotes["open_interest"] = quotes["open_interest"].astype("int64")
quotes["volume"] = quotes["volume"].astype("int64")
quotes["bid_size"] = quotes["bid_size"].astype("int64")
quotes["ask_size"] = quotes["ask_size"].astype("int64")
- quotes["prev_close"] = round(quotes["prev_close"], 2)
- quotes["change_percent"] = round(quotes["change_percent"] / 100, 4)
+ quotes["prev_close"] = quotes["prev_close"]
+ quotes["change_percent"] = quotes["change_percent"] / 100
return AnnotatedResult(
result=[
diff --git a/openbb_platform/providers/intrinio/openbb_intrinio/models/options_chains.py b/openbb_platform/providers/intrinio/openbb_intrinio/models/options_chains.py
index ef58527bb5d..d2f253b5c4a 100644
--- a/openbb_platform/providers/intrinio/openbb_intrinio/models/options_chains.py
+++ b/openbb_platform/providers/intrinio/openbb_intrinio/models/options_chains.py
@@ -51,11 +51,13 @@ class IntrinioOptionsChainsQueryParams(OptionsChainsQueryParams):
option_type: Literal[None, Union["call", "put"]] = Field(
default=None,
description="The option type, call or put, 'None' is both (default).",
+ json_schema_extra={"choices": ["call", "put"]},
)
moneyness: Literal["otm", "itm", "all"] = Field(
default="all",
description="Return only contracts that are in or out of the money, default is 'all'."
+ " Parameter is ignored when a date is supplied.",
+ json_schema_extra={"choices": ["otm", "itm", "all"]},
)
strike_gt: Optional[int] = Field(
default=None,
@@ -70,22 +72,22 @@ class IntrinioOptionsChainsQueryParams(OptionsChainsQueryParams):
volume_gt: Optional[int] = Field(
default=None,
description="Return options with a volume greater than the given value."
- + " Parameter is ignored when a date is supplied."
+ + " Parameter is ignored when a date is supplied.",
)
volume_lt: Optional[int] = Field(
default=None,
description="Return options with a volume less than the given value."
- + " Parameter is ignored when a date is supplied."
+ + " Parameter is ignored when a date is supplied.",
)
oi_gt: Optional[int] = Field(
default=None,
description="Return options with an open interest greater than the given value."
- + " Parameter is ignored when a date is supplied."
+ + " Parameter is ignored when a date is supplied.",
)
oi_lt: Optional[int] = Field(
default=None,
description="Return options with an open interest less than the given value."
- + " Parameter is ignored when a date is supplied."
+ + " Parameter is ignored when a date is supplied.",
)
model: Literal["black_scholes", "bjerk"] = Field(
default="black_scholes",
@@ -95,12 +97,12 @@ class IntrinioOptionsChainsQueryParams(OptionsChainsQueryParams):
show_extended_price: bool = Field(
default=True,
description="Whether to include OHLC type fields, default is True."
- + " Parameter is ignored when a date is supplied."
+ + " Parameter is ignored when a date is supplied.",
)
include_related_symbols: bool = Field(
default=False,
description="Include related symbols that end in a 1 or 2 because of a corporate action,"
- + " default is False."
+ + " default is False.",
)
@@ -137,7 +139,7 @@ class IntrinioOptionsChainsData(OptionsChainsData):
def date_validate(cls, v):
"""Return the datetime object from the date string."""
if isinstance(v, str):
- dt = parser.parse(v)
+ dt = parser.parse(v)
dt = dt.replace(tzinfo=timezone("UTC"))
dt = dt.astimezone(timezone("America/New_York"))
return dt.replace(microsecond=0)
@@ -176,7 +178,9 @@ class IntrinioOptionsChainsFetcher(
async def get_urls(date: str) -> List[str]:
"""Return the urls for the given date."""
- date = (datetime.strptime(date, "%Y-%m-%d") - timedelta(days=1)).strftime("%Y-%m-%d")
+ date = (datetime.strptime(date, "%Y-%m-%d") - timedelta(days=1)).strftime(
+ "%Y-%m-%d"
+ )
url = (
f"{base_url}/expirations/{query.symbol}/eod?"
f"after={date}&api_key={api_key}"
@@ -197,21 +201,17 @@ class IntrinioOptionsChainsFetcher(
"moneyness",
"open_interest_greater_than",
"open_interest_less_than",
- "strike_greater_than",
- "strike_less_than",
"show_extended_price",
- "include_related_symbols",
- ]
+ ],
)
- url = url+f"eod?date={date}&{query_string}"
+ url = url + f"eod?date={date}&{query_string}"
else:
query_string = get_querystring(
query.model_dump(exclude_none=True), ["symbol", "date"]
)
- query_string = (
- query_string.replace("otm", "out_of_the_money")
- .replace("itm", "in_the_money")
- )
+ query_string = query_string.replace(
+ "otm", "out_of_the_money"
+ ).replace("itm", "in_the_money")
url = url + f"realtime?{query_string}"
return url + f"&api_key={api_key}"
@@ -244,14 +244,16 @@ class IntrinioOptionsChainsFetcher(
temp = None
try:
temp = await IntrinioEquityHistoricalFetcher.fetch_data(
- {"symbol": query.symbol, "start_date": date, "end_date": date}, credentials
+ {"symbol": query.symbol, "start_date": date, "end_date": date},
+ credentials,
)
temp = temp[0]
# If the symbol is SPX, or similar, try to get the underlying price from the index.
except Exception as e:
try:
temp = await IntrinioIndexHistoricalFetcher.fetch_data(
- {"symbol": query.symbol, "start_date": date, "end_date": date}, credentials
+ {"symbol": query.symbol, "start_date": date, "end_date": date},
+ credentials,
)
temp = temp[0]
except Exception:
@@ -275,6 +277,7 @@ class IntrinioOptionsChainsFetcher(
results: List[IntrinioOptionsChainsData] = []
chains = data.get("data", [])
underlying = data.get("underlying", {})
+ last_price = underlying.get("price")
if query.date is not None:
for item in chains:
new_item = {**item["option"], **item["prices"]}
@@ -282,19 +285,29 @@ class IntrinioOptionsChainsFetcher(
datetime.strptime(new_item["expiration"], "%Y-%m-%d").date()
- datetime.strptime(new_item["date"], "%Y-%m-%d").date()
).days
- _ = new_item.pop("ticker", None)
+ if last_price:
+ new_item["underlying_price"] = last_price
_ = new_item.pop("exercise_style", None)
+ new_item["underlying_symbol"] = new_item.pop("ticker")
results.append(IntrinioOptionsChainsData.model_validate(new_item))
else:
for item in chains:
- new_item = {**item["option"], **item["price"], **item["stats"], **item["extended_price"]}
+ new_item = {
+ **item["option"],
+ **item["price"],
+ **item["stats"],
+ **item["extended_price"],
+ }
dte = (
- datetime.strptime(new_item["expiration"], "%Y-%m-%d").date() - datetime.now().date()
+ datetime.strptime(new_item["expiration"], "%Y-%m-%d").date()
+ - datetime.now().date()
).days
new_item["dte"] = dte
- underlying["underlying_symbol"] = new_item.pop("underlying_price_ticker", None)
+ new_item["underlying_symbol"] = new_item.pop(
+ "underlying_price_ticker", None
+ )
underlying["date"] = datetime.now().date()
- underlying["underlying_price"] = new_item.pop("underlying_price", None)
+ new_item["underlying_price"] = new_item.pop("underlying_price", None)
_ = new_item.pop("ticker", None)
_ = new_item.pop("trade_exchange", None)
_ = new_item.pop("exercise_style", None)
@@ -306,5 +319,5 @@ class IntrinioOptionsChainsFetcher(
key=lambda x: (x.expiration, x.strike, x.option_type),
reverse=False,
),
- metadata=underlying
+ metadata=underlying,
)
diff --git a/openbb_platform/providers/tmx/openbb_tmx/models/options_chains.py b/openbb_platform/providers/tmx/openbb_tmx/models/options_chains.py
index 7e5e455a48d..2368b3f9942 100644
--- a/openbb_platform/providers/tmx/openbb_tmx/models/options_chains.py
+++ b/openbb_platform/providers/tmx/openbb_tmx/models/options_chains.py
@@ -15,6 +15,7 @@ from openbb_core.provider.standard_models.options_chains import (
from openbb_core.provider.utils.descriptions import (
QUERY_DESCRIPTIONS,
)
+from openbb_tmx.models.equity_quote import TmxEquityQuoteFetcher
from openbb_tmx.utils.helpers import download_eod_chains, get_current_options
from pydantic import Field, field_validator
@@ -48,12 +49,6 @@ class TmxOptionsChainsData(OptionsChainsData):
settlement_price: Optional[float] = Field(
description="Settlement price on that date.", default=None
)
- underlying_price: Optional[float] = Field(
- description="Price of the underlying stock on that date.", default=None
- )
- dte: Optional[int] = Field(
- description="Days to expiration for the option.", default=None
- )
@field_validator("expiration", mode="before", check_fields=False)
@classmethod
@@ -89,6 +84,13 @@ class TmxOptionsChainsFetcher(
)
else:
chains = await get_current_options(query.symbol, use_cache=query.use_cache)
+ underlying_quote = await TmxEquityQuoteFetcher.fetch_data(
+ {"symbol": query.symbol}, credentials
+ )
+ underlying_price = underlying_quote[0].last_price
+ if underlying_price and not chains.empty:
+ chains["underlying_price"] = underlying_price
+ chains["underlying_symbol"] = query.symbol + ":CA"
if not chains.empty:
results = chains.to_dict(orient="records")
diff --git a/openbb_platform/providers/tradier/openbb_tradier/models/options_chains.py b/openbb_platform/providers/tradier/openbb_tradier/models/options_chains.py
index 16cdbab51f0..ace5e50e68f 100644
--- a/openbb_platform/providers/tradier/openbb_tradier/models/options_chains.py
+++ b/openbb_platform/providers/tradier/openbb_tradier/models/options_chains.py
@@ -14,6 +14,7 @@ from openbb_core.provider.standard_models.options_chains import (
)
from openbb_core.provider.utils.errors import EmptyDataError
from openbb_core.provider.utils.helpers import amake_request, safe_fromtimestamp
+from openbb_tradier.models.equity_quote import TradierEquityQuoteFetcher
from openbb_tradier.utils.constants import OPTIONS_EXCHANGES, STOCK_EXCHANGES
from pydantic import Field, field_validator, model_validator
from pytz import timezone
@@ -34,6 +35,7 @@ class TradierOptionsChainsData(OptionsChainsData):
__alias_dict__ = {
"expiration": "expiration_date",
+ "underlying_symbol": "underlying",
"contract_symbol": "symbol",
"last_trade_price": "last",
"bid_size": "bidsize",
@@ -41,16 +43,16 @@ class TradierOptionsChainsData(OptionsChainsData):
"change_percent": "change_percentage",
"orats_final_iv": "smv_vol",
"implied_volatility": "mid_iv",
- "greeks_timestamp": "updated_at",
+ "greeks_time": "updated_at",
"prev_close": "prevclose",
"year_high": "week_52_high",
"year_low": "week_52_low",
- "last_trade_timestamp": "trade_date",
- "last_trade_volume": "last_volume",
+ "last_trade_time": "trade_date",
+ "last_trade_size": "last_volume",
"ask_exchange": "askexch",
- "ask_timestamp": "ask_date",
+ "ask_time": "ask_date",
"bid_exchange": "bidexch",
- "bid_timestamp": "bid_date",
+ "bid_time": "bid_date",
}
phi: Optional[float] = Field(
@@ -77,48 +79,21 @@ class TradierOptionsChainsData(OptionsChainsData):
default=None,
description="52-week low price of the option.",
)
- last_trade_volume: Optional[int] = Field(
- default=None,
- description="Volume of the last trade.",
- )
- dte: Optional[int] = Field(
- default=None,
- description="Days to expiration.",
- )
contract_size: Optional[int] = Field(
default=None,
description="Size of the contract.",
)
- bid_exchange: Optional[str] = Field(
- default=None,
- description="Exchange of the bid price.",
- )
- bid_timestamp: Optional[datetime] = Field(
- default=None,
- description="Timestamp of the bid price.",
- )
- ask_exchange: Optional[str] = Field(
- default=None,
- description="Exchange of the ask price.",
- )
- ask_timestamp: Optional[datetime] = Field(
- default=None,
- description="Timestamp of the ask price.",
- )
- greeks_timestamp: Optional[datetime] = Field(
+ greeks_time: Optional[datetime] = Field(
default=None,
description="Timestamp of the last greeks update."
+ " Greeks/IV data is updated once per hour.",
)
- last_trade_timestamp: Optional[datetime] = Field(
- default=None, description="Timestamp of the last trade."
- )
@field_validator(
- "last_trade_timestamp",
- "greeks_timestamp",
- "ask_timestamp",
- "bid_timestamp",
+ "last_trade_time",
+ "greeks_time",
+ "ask_time",
+ "bid_time",
mode="before",
check_fields=False,
)
@@ -162,7 +137,12 @@ class TradierOptionsChainsData(OptionsChainsData):
"""Check for zero values and replace with None."""
return (
{
- k: None if (v == 0 or str(v) == "0") and k != "dte" else v
+ k: (
+ None
+ if (v == 0 or str(v) == "0")
+ and k not in ["dte", "open_interest", "volume"]
+ else v
+ )
for k, v in values.items()
}
if isinstance(values, dict)
@@ -231,14 +211,19 @@ class TradierOptionsChainsFetcher(
results = []
- async def get_one(url):
+ underlying_quote = await TradierEquityQuoteFetcher.fetch_data(
+ {"symbol": query.symbol}, credentials
+ )
+ underlying_price = underlying_quote[0].last_price
+
+ async def get_one(url, underlying_price):
"""Get the chain for a single expiration."""
chain = await amake_request(url, headers=HEADERS)
if chain.get("options") and isinstance(chain["options"].get("option", []), list): # type: ignore
data = chain["options"]["option"] # type: ignore
for d in data.copy():
# Remove any strikes returned without data.
- keys = ["volume", "open_interest", "last", "bid", "ask"]
+ keys = ["last", "bid", "ask"]
if all(d.get(key) in [0, "0", None] for key in keys):
data.remove(d)
continue
@@ -252,7 +237,6 @@ class TradierOptionsChainsFetcher(
"exch",
"type",
"expiration_type",
- "underlying",
"description",
"average_volume",
]
@@ -262,6 +246,8 @@ class TradierOptionsChainsFetcher(
datetime.strptime(d["expiration_date"], "%Y-%m-%d").date()
- datetime.now().date()
).days
+ if underlying_price is not None:
+ d["underlying_price"] = underlying_price
results.extend(data)
@@ -270,7 +256,7 @@ class TradierOptionsChainsFetcher(
for expiration in expirations # type: ignore
]
- tasks = [get_one(url) for url in urls]
+ tasks = [get_one(url, underlying_price) for url in urls]
await asyncio.gather(*tasks)
diff --git a/openbb_platform/providers/yfinance/openbb_yfinance/models/options_chains.py b/openbb_platform/providers/yfinance/openbb_yfinance/models/options_chains.py
index 62651b94c84..ba4a09fd051 100644
--- a/openbb_platform/providers/yfinance/openbb_yfinance/models/options_chains.py
+++ b/openbb_platform/providers/yfinance/openbb_yfinance/models/options_chains.py
@@ -28,24 +28,21 @@ class YFinanceOptionsChainsData(OptionsChainsData):
__alias_dict__ = {
"contract_symbol": "contractSymbol",
- "last_trade_timestamp": "lastTradeDate",
+ "last_trade_time": "lastTradeDate",
"last_trade_price": "lastPrice",
"change_percent": "percentChange",
"open_interest": "openInterest",
"implied_volatility": "impliedVolatility",
"in_the_money": "inTheMoney",
}
- dte: Optional[int] = Field(
- default=None,
- description="Days to expiration.",
- )
+
in_the_money: Optional[bool] = Field(
default=None,
description="Whether the option is in the money.",
)
- last_trade_timestamp: Optional[datetime] = Field(
+ currency: Optional[str] = Field(
default=None,
- description="Timestamp for when the option was last traded.",
+ description="Currency of the option.",
)
@@ -67,6 +64,7 @@ class YFinanceOptionsChainsFetcher(
) -> Dict:
"""Extract the raw data from YFinance."""
symbol = query.symbol.upper()
+ symbol = "^" + symbol if symbol in ["VIX", "RUT", "SPX", "NDX"] else symbol
ticker = yf.Ticker(symbol)
expirations = list(ticker.options)
if not expirations or len(expirations) == 0:
@@ -107,7 +105,9 @@ class YFinanceOptionsChainsFetcher(
}
tz = timezone(underlying_output.get("exchange_tz", "UTC"))
- async def get_chain(ticker, expiration, tz):
+ underlying_price = underlying_output.get("last_price")
+
+ async def get_chain(ticker, expiration, tz, underlying_price):
"""Get the data for one expiration."""
exp = datetime.strptime(expiration, "%Y-%m-%d").date()
now = datetime.now().date()
@@ -124,18 +124,23 @@ class YFinanceOptionsChainsFetcher(
.sort_index()
.reset_index()
)
+ chain = chain.drop(columns=["contractSize"])
chain["dte"] = dte
+ if underlying_price is not None:
+ chain["underlying_price"] = underlying_price
+ chain["underlying_symbol"] = symbol
chain["percentChange"] = chain["percentChange"] / 100
- for col in ["currency", "contractSize"]:
- if col in chain.columns:
- chain = chain.drop(col, axis=1)
+
if len(chain) > 0:
chains_output.extend(
chain.fillna("N/A").replace("N/A", None).to_dict("records")
)
await asyncio.gather(
- *[get_chain(ticker, expiration, tz) for expiration in expirations]
+ *[
+ get_chain(ticker, expiration, tz, underlying_price)
+ for expiration in expirations
+ ]
)
if not chains_output: