Skip to content

Commit

Permalink
feat: Support changes of options snapshots and chain (#446)
Browse files Browse the repository at this point in the history
* feat: support changes of options snapshots and chain endpoint

* doc: add OptionsGreeks and OptionsSnapshot

* fix: fix lint
  • Loading branch information
hiohiohio authored Apr 26, 2024
1 parent dda0523 commit eae556d
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 21 deletions.
20 changes: 11 additions & 9 deletions alpaca/data/historical/option.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
)
from alpaca.data.models.bars import BarSet
from alpaca.data.models.quotes import Quote
from alpaca.data.models.snapshots import Snapshot
from alpaca.data.models.snapshots import OptionsSnapshot
from alpaca.data.models.trades import Trade, TradeSet
from alpaca.data.requests import (
OptionBarsRequest,
Expand Down Expand Up @@ -197,14 +197,15 @@ def get_option_trades(

def get_option_snapshot(
self, request_params: OptionSnapshotRequest
) -> Union[Dict[str, Snapshot], RawData]:
"""Returns snapshots of queried symbols. Snapshots contain latest trade and latest quote for the queried symbols.
) -> Union[Dict[str, OptionsSnapshot], RawData]:
"""Returns snapshots of queried symbols. OptionsSnapshot contain latest trade,
latest quote, implied volatility, and greeks for the queried symbols.
Args:
request_params (OptionSnapshotRequest): The request object for retrieving snapshot data.
Returns:
Union[SnapshotSet, RawData]: The snapshot data either in raw or wrapped form
Union[Dict[str, OptionsSnapshot], RawData]: The snapshot data either in raw or wrapped form
"""

params = request_params.to_request_fields()
Expand All @@ -220,18 +221,19 @@ def get_option_snapshot(
if self._use_raw_data:
return raw_snapshots

return parse_obj_as_symbol_dict(Snapshot, raw_snapshots)
return parse_obj_as_symbol_dict(OptionsSnapshot, raw_snapshots)

def get_option_chain(
self, request_params: OptionChainRequest
) -> Union[Dict[str, Snapshot], RawData]:
"""The option chain endpoint for underlying symbol provides the latest trade, latest quote for each contract symbol of the underlying symbol.
) -> Union[Dict[str, OptionsSnapshot], RawData]:
"""The option chain endpoint for underlying symbol provides the latest trade, latest quote,
implied volatility, and greeks for each contract symbol of the underlying symbol.
Args:
request_params (OptionChainRequest): The request object for retrieving snapshot data.
Returns:
Union[SnapshotSet, RawData]: The snapshot data either in raw or wrapped form
Union[Dict[str, OptionsSnapshot], RawData]: The snapshot data either in raw or wrapped form
"""

params = request_params.to_request_fields()
Expand All @@ -247,7 +249,7 @@ def get_option_chain(
if self._use_raw_data:
return raw_snapshots

return parse_obj_as_symbol_dict(Snapshot, raw_snapshots)
return parse_obj_as_symbol_dict(OptionsSnapshot, raw_snapshots)

# TODO: Remove duplication
def _data_get(
Expand Down
2 changes: 2 additions & 0 deletions alpaca/data/mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
"minuteBar": "minute_bar",
"dailyBar": "daily_bar",
"prevDailyBar": "previous_daily_bar",
"impliedVolatility": "implied_volatility",
"greeks": "greeks",
}

ORDERBOOK_MAPPING: Dict[str, str] = {
Expand Down
80 changes: 78 additions & 2 deletions alpaca/data/models/snapshots.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

from pydantic import ConfigDict

from alpaca.common.types import RawData
from alpaca.common.models import ValidateBaseModel as BaseModel
from alpaca.data.models import Trade, Quote, Bar
from alpaca.common.types import RawData
from alpaca.data.mappings import SNAPSHOT_MAPPING
from alpaca.data.models import Bar, Quote, Trade


class Snapshot(BaseModel):
Expand Down Expand Up @@ -62,3 +62,79 @@ def __init__(self, symbol: str, raw_data: Dict[str, RawData]) -> None:
)

super().__init__(symbol=symbol, **mapped_snapshot)


class OptionsGreeks(BaseModel):
"""Options Greeks are a set of risk measures that are used in the options market to evaluate the risk and reward of an option.
Attributes:
delta (float): The rate of change of an option's price relative to a change in the price of the underlying asset.
gamma (float): The rate of change in an option's delta relative to a change in the price of the underlying asset.
rho (float): The rate of change in an option's price relative to a change in the risk-free rate of interest.
theta (float): The rate of change in an option's price relative to a change in time.
vega (float): The rate of change in an option's price relative to a change in the volatility of the underlying asset.
"""

delta: float
gamma: float
rho: float
theta: float
vega: float

model_config = ConfigDict(protected_namespaces=tuple())

def __init__(self, raw_data: RawData) -> None:
"""Instantiates an OptionGreeks object.
Args:
raw_data (RawData): The raw API option greeks data
"""
super().__init__(**raw_data)


class OptionsSnapshot(BaseModel):
"""An options snapshot contains the latest trade, latest quote, greeks
and implied volatility data for a given symbol.
Attributes:
symbol (str): The identifier for the snapshot security.
latest_trade (Optional[Trade]): The latest transaction on the price and sales tape
latest_quote (Optional[Quote]): Level 1 ask/bid pair quote data.
implied_volatility (Optional[float]): The implied volatility of the option
greeks (Optional[OptionGreeks]): The option greeks data
"""

symbol: str
latest_trade: Optional[Trade] = None
latest_quote: Optional[Quote] = None
implied_volatility: Optional[float] = None
greeks: Optional[OptionsGreeks] = None

model_config = ConfigDict(protected_namespaces=tuple())

def __init__(self, symbol: str, raw_data: Dict[str, RawData]) -> None:
"""Instantiates a Snapshot.
Args:
symbol (str): The identifier for the snapshot security.
raw_data (Dict[str, RawData]): The raw API snapshot data keyed by symbol
"""
mapped_snapshot = {
SNAPSHOT_MAPPING.get(key): val
for key, val in raw_data.items()
if key in SNAPSHOT_MAPPING
}

# Parse each data type
if mapped_snapshot.get("latest_trade", None) is not None:
mapped_snapshot["latest_trade"] = Trade(
symbol, mapped_snapshot["latest_trade"]
)
if mapped_snapshot.get("latest_quote", None) is not None:
mapped_snapshot["latest_quote"] = Quote(
symbol, mapped_snapshot["latest_quote"]
)
if mapped_snapshot.get("greeks", None) is not None:
mapped_snapshot["greeks"] = OptionsGreeks(mapped_snapshot["greeks"])

super().__init__(symbol=symbol, **mapped_snapshot)
17 changes: 16 additions & 1 deletion alpaca/data/requests.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import date, datetime
from typing import Any, List, Optional, Union

import pytz
Expand All @@ -14,6 +14,7 @@
OptionsFeed,
)
from alpaca.data.timeframe import TimeFrame
from alpaca.trading.enums import ContractType


class BaseTimeseriesDataRequest(NonEmptyRequest):
Expand Down Expand Up @@ -429,10 +430,24 @@ class OptionChainRequest(NonEmptyRequest):
Attributes:
underlying_symbol (str): The underlying_symbol for option contracts.
feed (Optional[OptionsFeed]): The source feed of the data. `opra` or `indicative`. Default: `opra` if the user has the options subscription, `indicative` otherwise.
type (Optional[ContractType]): Filter contracts by the type (call or put).
strike_price_gte (Optional[float]): Filter contracts with strike price greater than or equal to the specified value.
strike_price_lte (Optional[float]): Filter contracts with strike price less than or equal to the specified value.
expiration_date (Optional[Union[date, str]]): Filter contracts by the exact expiration date (format: YYYY-MM-DD).
expiration_date_gte (Optional[Union[date, str]]): Filter contracts with expiration date greater than or equal to the specified date.
expiration_date_lte (Optional[Union[date, str]]): Filter contracts with expiration date less than or equal to the specified date.
root_symbol (Optional[str]): Filter contracts by the root symbol.
"""

underlying_symbol: str
feed: Optional[OptionsFeed] = None
type: Optional[ContractType] = None
strike_price_gte: Optional[float] = None
strike_price_lte: Optional[float] = None
expiration_date: Optional[Union[date, str]] = None
expiration_date_gte: Optional[Union[date, str]] = None
expiration_date_lte: Optional[Union[date, str]] = None
root_symbol: Optional[str] = None

model_config = ConfigDict(protected_namespaces=tuple())

Expand Down
12 changes: 12 additions & 0 deletions docs/api_reference/data/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ Snapshot
.. autoclass:: alpaca.data.models.snapshots.Snapshot


OptionsGreeks
-------------

.. autoclass:: alpaca.data.models.snapshots.OptionsGreeks


OptionsSnapshot
---------------

.. autoclass:: alpaca.data.models.snapshots.OptionsSnapshot


-----

Orderbook
Expand Down
Loading

0 comments on commit eae556d

Please sign in to comment.