Asset Classes
Future Options
Trades
To get historical trade data, call the history
method with the TradeBar
type and a security's Symbol
.
This method returns a DataFrame with columns for the open, high, low, close, and volume.
class FutureOptionsTradeBarHistoryAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2024, 12, 19) # Add a FOP universe. future = self.add_future(Futures.Indices.SP_500_E_MINI) future.set_filter(lambda universe: universe.front_month()) self.add_future_option(future.symbol, lambda universe: universe.front_month().strikes(-1, 0).calls_only()) # Get trailing data whenever a new FOP contract enters the universe. def on_securities_changed(self, changes): for security in changes.added_securities: if security.type == SecurityType.FUTURE_OPTION: # Get the 3 trailing daily TradeBar objects of the security in DataFrame format. history = self.history(TradeBar, security.symbol, 3, Resolution.DAILY)
close | high | low | open | volume | |||||
---|---|---|---|---|---|---|---|---|---|
expiry | strike | type | symbol | time | |||||
2024-12-20 | 5870.0 | 1 | ES 32NKVT5YYX1US|ES YOGVNNAOI1OH | 2024-12-16 17:00:00 | 2.15 | 2.15 | 1.45 | 1.80 | 227.0 |
2024-12-17 17:00:00 | 2.35 | 3.05 | 2.30 | 2.30 | 14.0 | ||||
2024-12-18 17:00:00 | 38.75 | 43.75 | 1.75 | 1.85 | 399.0 |
# Calculate the daily returns. daily_returns = history.close.pct_change().iloc[1:]
expiry strike type symbol time 2024-12-20 5870.0 1 ES 32NKVT5YYX1US|ES YOGVNNAOI1OH 2024-12-17 17:00:00 0.093023 2024-12-18 17:00:00 15.489362 Name: close, dtype: float64
If you intend to use the data in the DataFrame to create TradeBar
objects, request that the history request returns the data type you need.
Otherwise, LEAN consumes unnecessary computational resources populating the DataFrame.
To get a list of TradeBar
objects instead of a DataFrame, call the history[TradeBar]
method.
# Get the 3 trailing daily TradeBar objects of the security in TradeBar format. history = self.history[TradeBar](symbol, 3, Resolution.DAILY) # Iterate through the TradeBar objects and access their volumes. for trade_bar in history: t = trade_bar.end_time volume = trade_bar.volume
Request minute, hour, or daily resolution data. Otherwise, the history request won't return any data.
Quotes
To get historical quote data, call the history
method with the QuoteBar
type and a security's Symbol
.
This method returns a DataFrame with columns for the open, high, low, close, and size of the bid and ask quotes.
The columns that don't start with "bid" or "ask" are the mean of the quote prices on both sides of the market.
class FutureOptionsQuoteBarHistoryAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2024, 12, 19) # Add a FOP universe. future = self.add_future(Futures.Indices.SP_500_E_MINI) future.set_filter(lambda universe: universe.front_month()) self.add_future_option(future.symbol, lambda universe: universe.front_month().strikes(-1, 0).calls_only()) # Get trailing data whenever a new FOP contract enters the universe. def on_securities_changed(self, changes): for security in changes.added_securities: if security.type == SecurityType.FUTURE_OPTION: # Get the 3 trailing daily QuoteBar objects of the security in DataFrame format. history = self.history(QuoteBar, security.symbol, 3, Resolution.DAILY)
askclose | askhigh | asklow | askopen | asksize | bidclose | bidhigh | bidlow | bidopen | bidsize | close | high | low | open | |||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
expiry | strike | type | symbol | time | ||||||||||||||
2024-12-20 | 5870.0 | 1 | ES 32NKVT5YYX1US|ES YOGVNNAOI1OH | 2024-12-16 17:00:00 | 2.5 | 2.55 | 1.45 | 1.85 | 2.0 | 2.35 | 2.40 | 1.35 | 1.75 | 46.0 | 2.425 | 2.475 | 1.4 | 1.800 |
2024-12-17 17:00:00 | 2.7 | 3.15 | 2.15 | 3.05 | 179.0 | 2.45 | 3.05 | 2.05 | 2.90 | 46.0 | 2.575 | 3.100 | 2.1 | 2.975 | ||||
2024-12-18 17:00:00 | 40.0 | 215.50 | 1.55 | 2.30 | 3.0 | 36.50 | 60.50 | 0.05 | 2.15 | 2.0 | 38.250 | 138.000 | 0.8 | 2.225 |
# Calculate the spread. spread = history.askclose - history.bidclose
expiry strike type symbol time 2024-12-20 5870.0 1 ES 32NKVT5YYX1US|ES YOGVNNAOI1OH 2024-12-16 17:00:00 0.15 2024-12-17 17:00:00 0.25 2024-12-18 17:00:00 3.50 dtype: float64
If you intend to use the data in the DataFrame to create QuoteBar
objects, request that the history request returns the data type you need.
Otherwise, LEAN consumes unnecessary computational resources populating the DataFrame.
To get a list of QuoteBar
objects instead of a DataFrame, call the history[QuoteBar]
method.
# Get the 3 trailing daily QuoteBar objects of the security in QuoteBar format. history = self.history[QuoteBar](symbol, 3, Resolution.DAILY) # Iterate through each QuoteBar and calculate the dollar volume on the bid. for quote_bar in history: t = quote_bar.end_time bid_dollar_volume = quote_bar.last_bid_size * quote_bar.bid.close
Request minute, hour, or daily resolution data. Otherwise, the history request won't return any data.
Slices
To get historical Slice data, call the history
method without passing any Symbol
objects.
This method returns Slice
objects, which contain data points from all the datasets in your algorithm.
If you omit the resolution
argument, it uses the resolution that you set for each security and dataset when you created the subscriptions.
class SliceHistoryAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2024, 12, 19) # Add some securities and datasets. future = self.add_future(Futures.Indices.SP_500_E_MINI) future.set_filter(lambda universe: universe.front_month()) self.add_future_option(future.symbol, lambda universe: universe.front_month().strikes(-1, 0).calls_only()) # Add a Scheduled Event that runs at the start of each month. self.schedule.on(self.date_rules.month_start(future.symbol), self.time_rules.after_market_open(future.symbol, 60), self._trade) def _trade(self): # Get the historical Slice objects over the last 30 minutes for all the subcriptions in your algorithm. for slice_ in self.history(30, Resolution.MINUTE): # Iterate through each TradeBar in this Slice. for symbol, trade_bar in slice_.bars.items(): close = trade_bar.close
Indicators
To get historical indicator values, call the indicator_history
method with an indicator and the security's Symbol
.
class FutureOptionIndicatorHistoryAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2024, 12, 19) # Add a FOP universe. future = self.add_future(Futures.Indices.SP_500_E_MINI) future.set_filter(lambda universe: universe.front_month()) self.add_future_option(future.symbol, lambda universe: universe.front_month().strikes(0, 0).calls_only()) def on_securities_changed(self, changes): for security in changes.added_securities: if security.type != SecurityType.FUTURE_OPTION: continue # Get the 21-day SMA values of the contract for the last 5 trading days. history = self.indicator_history(SimpleMovingAverage(21), security.symbol, 5, Resolution.DAILY)
To organize the data into a DataFrame, use the data_frame
property of the result.
# Organize the historical indicator data into a DataFrame to enable pandas wrangling. history_df = history.data_frame
current | rollingsum | |
---|---|---|
2024-12-12 17:00:00 | 131.404762 | 2759.500 |
2024-12-13 17:00:00 | 132.101190 | 2774.125 |
2024-12-16 17:00:00 | 135.779762 | 2851.375 |
2024-12-17 17:00:00 | 138.047619 | 2899.000 |
2024-12-18 17:00:00 | 134.095238 | 2816.000 |
# Get the maximum of the SMA values. sma_max = history_df.current.max()
The indicator_history
method resets your indicator, makes a history request, and updates the indicator with the historical data.
Just like with regular history requests, the indicator_history
method supports time periods based on a trailing number of bars, a trailing period of time, or a defined period of time.
If you don't provide a resolution
argument, it defaults to match the resolution of the security subscription.
To make the indicator_history
method update the indicator with an alternative price field instead of the close (or mid-price) of each bar, pass a selector
argument.
# Get the historical values of an indicator over the last 30 days, applying the indicator to the contract's volume. history = self.indicator_history(indicator, symbol, timedelta(30), selector=Field.VOLUME)
Some indicators require the prices of multiple securities to compute their value (for example, the indicators for the Greeks and implied volatility).
In this case, pass a list of the Symbol
objects to the method.
class FutureOptionMultiAssetIndicatorHistoryAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2024, 12, 19) # Add a FOP universe. future = self.add_future(Futures.Indices.SP_500_E_MINI) future.set_filter(lambda universe: universe.front_month()) self.add_future_option(future.symbol, lambda universe: universe.front_month().strikes(0, 0).calls_only()) def on_securities_changed(self, changes): for security in changes.added_securities: if security.type != SecurityType.FUTURE_OPTION: continue option = security.symbol # Get the Symbol of the mirror contract. mirror = Symbol.create_option( option.underlying, option.id.market, option.id.option_style, OptionRight.Call if option.id.option_right == OptionRight.PUT else OptionRight.PUT, option.id.strike_price, option.id.date ) # Create the indicator. indicator = ImpliedVolatility( option, self.risk_free_interest_rate_model, ConstantDividendYieldModel(0), mirror, OptionPricingModelType.FORWARD_TREE ) # Get the historical values of the indicator over the last 10 minutes. history = self.indicator_history(indicator, [option.underlying, option, mirror], 10, Resolution.MINUTE) # Get the average IV value. iv_avg = history.data_frame.current.mean()