Datasets
Equity Options
Create Subscriptions
Follow these steps to subscribe to an Equity Option security:
- Load the assembly files and data types in their own cell.
- Import the data types.
- Create a
QuantBook
. - Subscribe to the underlying Equity with raw data normalization and save a reference to the Equity Symbol.
- Call the
AddOption
method with the underlying EquitySymbol
. - (Optional) Set a contract filter.
- Standard type (exclude weeklys)
- Within 1 strike price of the underlying asset price
- Expire within 31 days
- (Optional) Set the price model.
#load "../Initialize.csx"
#load "../QuantConnect.csx" #r "../Microsoft.Data.Analysis.dll" using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; using QuantConnect.Indicators; using QuantConnect.Securities.Option; using Microsoft.Data.Analysis;
var qb = new QuantBook();
qb = QuantBook()
var equitySymbol = qb.AddEquity("SPY", dataNormalizationMode: DataNormalizationMode.Raw).Symbol;
equity_symbol = qb.AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol
To view the supported underlying assets in the US Equity Options dataset, see the Data Explorer.
var option = qb.AddOption(equitySymbol);
option = qb.AddOption(equity_symbol)
option.SetFilter(-1, 1, 0, 90);
option.SetFilter(-1, 1, 0, 90)
The filter determines which contracts the GetOptionHistory
method returns. If you don't set a filter, the default filter selects the contracts that have the following characteristics:
option.PriceModel = OptionPriceModels.BinomialCoxRossRubinstein();
option.PriceModel = OptionPriceModels.BinomialCoxRossRubinstein()
If you want historical data on individual contracts and their OpenInterest
, follow these steps to subscribe to the individual Equity Option contracts:
- Call the
GetOptionsContractList
method with the underlyingEquity
Symbol
and adatetime
DateTime
. - Select the
Symbol
of theOptionContract
object(s) for which you want to get historical data. - Call the
AddOptionContract
method with anOptionContract
Symbol
and disable fill-forward. - (Optional) Set the price model.
var startDate = new DateTime(2021, 12, 31); var contractSymbols = qb.OptionChainProvider.GetOptionContractList(equitySymbol, startDate);
start_date = datetime(2021, 12, 31) contract_symbols = qb.OptionChainProvider.GetOptionContractList(equity_symbol, start_date)
This method returns a list of Symbol
objects that reference the Option contracts that were trading at the given time. If you set a contract filter with SetFilter
, it doesn't affect the results of GetOptionsContractList
.
To filter and select contracts, you can use the following properties of each Symbol
object:
Property | Description |
---|---|
ID.Date | The expiration date of the contract. |
ID.StrikePrice | The strike price of the contract. |
ID.OptionRight |
The contract type. The OptionRight enumeration has the following members:
|
ID.OptionStyle |
The contract style. The OptionStyle enumeration has the following members:
|
var contractSymbol = contractSymbols.Where(s => s.ID.OptionRight == OptionRight.Call && s.ID.StrikePrice == 477 && s.ID.Date == new DateTime(2022, 1, 21)).First();
contract_symbol = [s for s in contract_symbols if s.ID.OptionRight == OptionRight.Call and s.ID.StrikePrice == 477 and s.ID.Date == datetime(2022, 1, 21)][0]
var optionContract = qb.AddOptionContract(contractSymbol, fillForward: false);
option_contract = qb.AddOptionContract(contract_symbol, fillForward = False)
Disable fill-forward because there are only a few OpenInterest
data points per day.
optionContract.PriceModel = OptionPriceModels.BinomialCoxRossRubinstein();
option_contract.PriceModel = OptionPriceModels.BinomialCoxRossRubinstein()
Get Historical Data
You need a subscription before you can request historical data for Equity Option contracts. On the time dimension, you can request an amount of historical data based on a trailing number of bars, a trailing period of time, or a defined period of time. On the contract dimension, you can request historical data for a single contract, a subset of the contracts you created subscriptions for in your notebook, or all of the contracts in your notebook.
Before you request historical data, call the SetStartDate
method with a datetime
DateTime
to reduce the risk of look-ahead bias.
qb.SetStartDate(startDate);
qb.SetStartDate(start_date)
If you call the SetStartDate
method, the date that you pass to the method is the latest date for which your history requests will return data.
Trailing Number of Bars
To get historical data for a number of trailing bars, call the History
method with the contract Symbol
object(s) and an integer.
// Slice objects var singleHistorySlice = qb.History(contractSymbol, 10); var subsetHistorySlice = qb.History(new[] {contractSymbol}, 10); var allHistorySlice = qb.History(10); // TradeBar objects var singleHistoryTradeBars = qb.History<TradeBar>(contractSymbol, 10); var subsetHistoryTradeBars = qb.History<TradeBar>(new[] {contractSymbol}, 10); var allHistoryTradeBars = qb.History<TradeBar>(qb.Securities.Keys, 10); // QuoteBar objects var singleHistoryQuoteBars = qb.History<QuoteBar>(contractSymbol, 10); var subsetHistoryQuoteBars = qb.History<QuoteBar>(new[] {contractSymbol}, 10); var allHistoryQuoteBars = qb.History<QuoteBar>(qb.Securities.Keys, 10); // OpenInterest objects var singleHistoryOpenInterest = qb.History<OpenInterest>(contractSymbol, 400); var subsetHistoryOpenInterest = qb.History<OpenInterest>(new[] {contractSymbol}, 400); var allHistoryOpenInterest = qb.History<OpenInterest>(qb.Securities.Keys, 400);
# DataFrame of trade and quote data single_history_df = qb.History(contract_symbol, 10) subset_history_df = qb.History([contract_symbol], 10) all_history_df = qb.History(qb.Securities.Keys, 10) # DataFrame of trade data single_history_trade_bar_df = qb.History(TradeBar, contract_symbol, 10) subset_history_trade_bar_df = qb.History(TradeBar, [contract_symbol], 10) all_history_trade_bar_df = qb.History(TradeBar, qb.Securities.Keys, 10) # DataFrame of quote data single_history_quote_bar_df = qb.History(QuoteBar, contract_symbol, 10) subset_history_quote_bar_df = qb.History(QuoteBar, [contract_symbol], 10) all_history_quote_bar_df = qb.History(QuoteBar, qb.Securities.Keys, 10) # DataFrame of open interest data single_history_open_interest_df = qb.History(OpenInterest, contract_symbol, 400) subset_history_open_interest_df = qb.History(OpenInterest, [contract_symbol], 400) all_history_open_interest_df = qb.History(OpenInterest, qb.Securities.Keys, 400) # Slice objects all_history_slice = qb.History(10) # TradeBar objects single_history_trade_bars = qb.History[TradeBar](contract_symbol, 10) subset_history_trade_bars = qb.History[TradeBar]([contract_symbol], 10) all_history_trade_bars = qb.History[TradeBar](qb.Securities.Keys, 10) # QuoteBar objects single_history_quote_bars = qb.History[QuoteBar](contract_symbol, 10) subset_history_quote_bars = qb.History[QuoteBar]([contract_symbol], 10) all_history_quote_bars = qb.History[QuoteBar](qb.Securities.Keys, 10) # OpenInterest objects single_history_open_interest = qb.History[OpenInterest](contract_symbol, 400) subset_history_open_interest = qb.History[OpenInterest]([contract_symbol], 400) all_history_open_interest = qb.History[OpenInterest](qb.Securities.Keys, 400)
The preceding calls return the most recent bars, excluding periods of time when the exchange was closed.
Trailing Period of Time
To get historical data for a trailing period of time, call the History
method with the contract Symbol
object(s) and a TimeSpan
timedelta
.
// Slice objects var singleHistorySlice = qb.History(contractSymbol, TimeSpan.FromDays(3)); var subsetHistorySlice = qb.History(new[] {contractSymbol}, TimeSpan.FromDays(3)); var allHistorySlice = qb.History(10); // TradeBar objects var singleHistoryTradeBars = qb.History<TradeBar>(contractSymbol, TimeSpan.FromDays(3)); var subsetHistoryTradeBars = qb.History<TradeBar>(new[] {contractSymbol}, TimeSpan.FromDays(3)); var allHistoryTradeBars = qb.History<TradeBar>(TimeSpan.FromDays(3)); // QuoteBar objects var singleHistoryQuoteBars = qb.History<QuoteBar>(contractSymbol, TimeSpan.FromDays(3), Resolution.Minute); var subsetHistoryQuoteBars = qb.History<QuoteBar>(new[] {contractSymbol}, TimeSpan.FromDays(3), Resolution.Minute); var allHistoryQuoteBars = qb.History<QuoteBar>(qb.Securities.Keys, TimeSpan.FromDays(3), Resolution.Minute); // OpenInterest objects var singleHistoryOpenInterest = qb.History<OpenInterest>(contractSymbol, TimeSpan.FromDays(2)); var subsetHistoryOpenInterest = qb.History<OpenInterest>(new[] {contractSymbol}, TimeSpan.FromDays(2)); var allHistoryOpenInterest = qb.History<OpenInterest>(qb.Securities.Keys, TimeSpan.FromDays(2));
# DataFrame of trade and quote data single_history_df = qb.History(contract_symbol, timedelta(days=3)) subset_history_df = qb.History([contract_symbol], timedelta(days=3)) all_history_df = qb.History(qb.Securities.Keys, timedelta(days=3)) # DataFrame of trade data single_history_trade_bar_df = qb.History(TradeBar, contract_symbol, timedelta(days=3)) subset_history_trade_bar_df = qb.History(TradeBar, [contract_symbol], timedelta(days=3)) all_history_trade_bar_df = qb.History(TradeBar, qb.Securities.Keys, timedelta(days=3)) # DataFrame of quote data single_history_quote_bar_df = qb.History(QuoteBar, contract_symbol, timedelta(days=3)) subset_history_quote_bar_df = qb.History(QuoteBar, [contract_symbol], timedelta(days=3)) all_history_quote_bar_df = qb.History(QuoteBar, qb.Securities.Keys, timedelta(days=3)) # DataFrame of open interest data single_history_open_interest_df = qb.History(OpenInterest, contract_symbol, timedelta(days=3)) subset_history_open_interest_df = qb.History(OpenInterest, [contract_symbol], timedelta(days=3)) all_history_open_interest_df = qb.History(OpenInterest, qb.Securities.Keys, timedelta(days=3)) # Slice objects all_history_slice = qb.History(timedelta(days=3)) # TradeBar objects single_history_trade_bars = qb.History[TradeBar](contract_symbol, timedelta(days=3)) subset_history_trade_bars = qb.History[TradeBar]([contract_symbol], timedelta(days=3)) all_history_trade_bars = qb.History[TradeBar](qb.Securities.Keys, timedelta(days=3)) # QuoteBar objects single_history_quote_bars = qb.History[QuoteBar](contract_symbol, timedelta(days=3), Resolution.Minute) subset_history_quote_bars = qb.History[QuoteBar]([contract_symbol], timedelta(days=3), Resolution.Minute) all_history_quote_bars = qb.History[QuoteBar](qb.Securities.Keys, timedelta(days=3), Resolution.Minute) # OpenInterest objects single_history_open_interest = qb.History[OpenInterest](contract_symbol, timedelta(days=2)) subset_history_open_interest = qb.History[OpenInterest]([contract_symbol], timedelta(days=2)) all_history_open_interest = qb.History[OpenInterest](qb.Securities.Keys, timedelta(days=2))
The preceding calls return the most recent bars, excluding periods of time when the exchange was closed.
Defined Period of Time
To get historical data for individual Equity Option contracts during a specific period of time, call the History
method with the Equity Option contract Symbol
object(s), a start DateTime
datetime
, and an end DateTime
datetime
. The start and end times you provide are based in the notebook time zone.
var startTime = new DateTime(2021, 12, 1); var endTime = new DateTime(2021, 12, 31); // Slice objects var singleHistorySlice = qb.History(contractSymbol, startTime, endTime); var subsetHistorySlice = qb.History(new[] {contractSymbol}, startTime, endTime); var allHistorySlice = qb.History(startTime, endTime); // TradeBar objects var singleHistoryTradeBars = qb.History<TradeBar>(contractSymbol, startTime, endTime); var subsetHistoryTradeBars = qb.History<TradeBar>(new[] {contractSymbol}, startTime, endTime); var allHistoryTradeBars = qb.History<TradeBar>(qb.Securities.Keys, startTime, endTime); // QuoteBar objects var singleHistoryQuoteBars = qb.History<QuoteBar>(contractSymbol, startTime, endTime, Resolution.Minute); var subsetHistoryQuoteBars = qb.History<QuoteBar>(new[] {contractSymbol}, startTime, endTime, Resolution.Minute); var allHistoryQuoteBars = qb.History<QuoteBar>(qb.Securities.Keys, startTime, endTime, Resolution.Minute); // OpenInterest objects var singleHistoryOpenInterest = qb.History<OpenInterest>(contractSymbol, startTime, endTime); var subsetHistoryOpenInterest = qb.History<OpenInterest>(new[] {contractSymbol}, startTime, endTime); var allHistoryOpenInterest = qb.History<OpenInterest>(qb.Securities.Keys, startTime, endTime);
start_time = datetime(2021, 12, 1) end_time = datetime(2021, 12, 31) # DataFrame of trade and quote data single_history_df = qb.History(contract_symbol, start_time, end_time) subset_history_df = qb.History([contract_symbol], start_time, end_time) all_history_df = qb.History(qb.Securities.Keys, start_time, end_time) # DataFrame of trade data single_history_trade_bar_df = qb.History(TradeBar, contract_symbol, start_time, end_time) subset_history_trade_bar_df = qb.History(TradeBar, [contract_symbol], start_time, end_time) all_history_trade_bar_df = qb.History(TradeBar, qb.Securities.Keys, start_time, end_time) # DataFrame of quote data single_history_quote_bar_df = qb.History(QuoteBar, contract_symbol, start_time, end_time) subset_history_quote_bar_df = qb.History(QuoteBar, [contract_symbol], start_time, end_time) all_history_quote_bar_df = qb.History(QuoteBar, qb.Securities.Keys, start_time, end_time) # DataFrame of open interest data single_history_open_interest_df = qb.History(OpenInterest, contract_symbol, start_time, end_time) subset_history_open_interest_df = qb.History(OpenInterest, [contract_symbol], start_time, end_time) all_history_trade_open_interest_df = qb.History(OpenInterest, qb.Securities.Keys, start_time, end_time) # TradeBar objects single_history_trade_bars = qb.History[TradeBar](contract_symbol, start_time, end_time) subset_history_trade_bars = qb.History[TradeBar]([contract_symbol], start_time, end_time) all_history_trade_bars = qb.History[TradeBar](qb.Securities.Keys, start_time, end_time) # QuoteBar objects single_history_quote_bars = qb.History[QuoteBar](contract_symbol, start_time, end_time, Resolution.Minute) subset_history_quote_bars = qb.History[QuoteBar]([contract_symbol], start_time, end_time, Resolution.Minute) all_history_quote_bars = qb.History[QuoteBar](qb.Securities.Keys, start_time, end_time, Resolution.Minute) # OpenInterest objects single_history_open_interest = qb.History[OpenInterest](contract_symbol, start_time, end_time) subset_history_open_interest = qb.History[OpenInterest]([contract_symbol], start_time, end_time) all_history_open_interest = qb.History[OpenInterest](qb.Securities.Keys, start_time, end_time)
To get historical data for all of the Equity Option contracts that pass your filter during a specific period of time, call the GetOptionHistory
method with the underlying Equity Symbol
object, a start DateTime
datetime
, and an end DateTime
datetime
.
option_history = qb.GetOptionHistory(equity_symbol, end_time-timedelta(days=2), end_time, Resolution.Minute, fillForward=False, extendedMarketHours=False)
var optionHistory = qb.GetOptionHistory(equitySymbol, endTime-TimeSpan.FromDays(2), endTime, Resolution.Minute, fillForward: False, extendedMarketHours: False);
The preceding calls return data that have a timestamp within the defined period of time.
Wrangle Data
You need some historical data to perform wrangling operations. The process to manipulate the historical data depends on its data type. To display pandas
objects, run a cell in a notebook with the pandas
object as the last line. To display other data formats, call the print
method.
You need some historical data to perform wrangling operations. Use LINQ to wrangle the data and then call the Console.WriteLine
method in a Jupyter Notebook to display the data. The process to manipulate the historical data depends on its data type.
DataFrame Objects
If your history request returns a DataFrame
, the DataFrame
has the following index levels:
- Contract expiry
- Contract strike price
- Contract type (call or put)
- Encoded contract Symbol
- The
EndTime
of the data sample
The columns of the DataFrame
are the data properties. Depending on how you request data, the DataFrame
may contain data for the underlying security, which causes some of the index levels to be an empty string for the corresponding rows.

To select the rows of the contract(s) that expire at a specific time, index the loc
property of the DataFrame
with the expiry time.
all_history_df.loc[datetime(2022, 1, 21)]

If you remove the first three index levels, you can index the DataFrame
with just the contract Symbol
, similiar to how you would with non-derivative asset classes. To remove the first three index levels, call the droplevel method.
all_history_df.index = all_history_df.index.droplevel([0,1,2])

To select the historical data of a single Equity Options contract, index the loc
property of the DataFrame
with the contract Symbol
.
all_history_df.loc[contract_symbol]

To select a column of the DataFrame
, index it with the column name.
all_history_df.loc[contract_symbol]['close']

If you request historical data for multiple Equity Option contracts, you can transform the DataFrame
so that it's a time series of close values for all of the Equity Option contracts. To transform the DataFrame
, select the column you want to display for each Equity Option contract and then call the unstack method.
all_history_df['close'].unstack(level=0)
The DataFrame
is transformed so that the column indices are the Symbol
of each security and each row contains the close value.

The historical data methods don't return DataFrame objects, but you can create one for efficient vectorized data wrangling.
using Microsoft.Data.Analysis; var columns = new DataFrameColumn[] { new PrimitiveDataFrameColumn("Time", history.Select(x => x[contractSymbol].EndTime)), new DecimalDataFrameColumn(" Open", history.Select(x => x[contractSymbol].Open)), new DecimalDataFrameColumn(" High", history.Select(x => x[contractSymbol].High)), new DecimalDataFrameColumn(" Low", history.Select(x => x[contractSymbol].Low)), new DecimalDataFrameColumn(" Close", history.Select(x => x[contractSymbol].Close)) }; var df = new DataFrame(columns); df

To select a particular column of the DataFrame, index it with the column name.
df[" close"]

Slice Objects
If the History
method returns Slice
objects, iterate through the Slice
objects to get each one. The Slice
objects may not have data for all of your Equity Options subscriptions. To avoid issues, check if the Slice
contains data for your Equity Option contract before you index it with the Equity Options Symbol
.
foreach (var slice in allHistorySlice) { if (slice.Bars.ContainsKey(contractSymbol)) { var tradeBar = slice.Bars[contractSymbol]; } if (slice.QuoteBars.ContainsKey(contractSymbol)) { var quoteBar = slice.QuoteBars[contractSymbol]; } }
for slice in all_history_slice: if slice.Bars.ContainsKey(contract_symbol): trade_bar = slice.Bars[contract_symbol] if slice.QuoteBars.ContainsKey(contract_symbol): quote_bar = slice.QuoteBars[contract_symbol]
You can also iterate through each TradeBar
and QuoteBar
in the Slice
.
foreach (var slice in allHistorySlice) { foreach (var kvp in slice.Bars) { var symbol = kvp.Key; var tradeBar = kvp.Value; } foreach (var kvp in slice.QuoteBars) { var symbol = kvp.Key; var quoteBar = kvp.Value; } }
for slice in all_history_slice: for kvp in slice.Bars: symbol = kvp.Key trade_bar = kvp.Value for kvp in slice.QuoteBars: symbol = kvp.Key quote_bar = kvp.Value
You can also use LINQ to select each TradeBar
in the Slice
for a given Symbol
.
var tradeBars = allHistorySlice.Where(slice => slice.Bars.ContainsKey(contractSymbol)).Select(slice => slice.Bars[contractSymbol]);
TradeBar Objects
If the History
method returns TradeBar
objects, iterate through the TradeBar
objects to get each one.
foreach (var tradeBar in singleHistoryTradeBars) { Console.WriteLine(tradeBar); }
for trade_bar in single_history_trade_bars: print(trade_bar)
If the History
method returns TradeBars
, iterate through the TradeBars
to get the TradeBar
of each Equity Option contract. The TradeBars
may not have data for all of your Equity Options subscriptions. To avoid issues, check if the TradeBars
object contains data for your security before you index it with the Equity Options Symbol
.
foreach (var tradeBars in allHistoryTradeBars) { if (tradeBars.ContainsKey(contractSymbol)) { var tradeBar = tradeBars[contractSymbol]; } }
for trade_bars in all_history_trade_bars: if trade_bars.ContainsKey(contract_symbol): trade_bar = trade_bars[contract_symbol]
You can also iterate through each of the TradeBars
.
foreach (var tradeBars in allHistoryTradeBars) { foreach (var kvp in tradeBars) { var symbol = kvp.Key; var tradeBar = kvp.Value; } }
for trade_bars in all_history_trade_bars: for kvp in trade_bars: symbol = kvp.Key trade_bar = kvp.Value
QuoteBar Objects
If the History
method returns QuoteBar
objects, iterate through the QuoteBar
objects to get each one.
foreach (var quoteBar in singleHistoryQuoteBars) { Console.WriteLine(quoteBar); }
for quote_bar in single_history_quote_bars: print(quote_bar)
If the History
method returns QuoteBars
, iterate through the QuoteBars
to get the QuoteBar
of each Equity Option contract. The QuoteBars
may not have data for all of your Equity Options subscriptions. To avoid issues, check if the QuoteBars
object contains data for your security before you index it with the Equity Options Symbol
.
foreach (var quoteBars in allHistoryQuoteBars) { if (quoteBars.ContainsKey(contractSymbol)) { var quoteBar = quoteBars[contractSymbol]; } }
for quote_bars in all_history_quote_bars: if quote_bars.ContainsKey(contract_symbol): quote_bar = quote_bars[contract_symbol]
You can also iterate through each of the QuoteBars
.
foreach (var quoteBars in allHistoryQuoteBars) { foreach (var kvp in quoteBars) { var symbol = kvp.Key; var quoteBar = kvp.Value; } }
for quote_bars in all_history_quote_bars: for kvp in quote_bars: symbol = kvp.Key quote_bar = kvp.Value
OpenInterest Objects
If the History
method returns OpenInterest
objects, iterate through the OpenInterest
objects to get each one.
foreach (var openInterest in singleHistoryOpenInterest) { Console.WriteLine(openInterest); }
for open_interest in single_history_open_interest: print(open_interest)
If the History
method returns a dictionary of OpenInterest
objects, iterate through the dictionary to get the OpenInterest
of each Equity Option contract. The dictionary of OpenInterest
objects may not have data for all of your Equity Options contract subscriptions. To avoid issues, check if the dictionary contains data for your contract before you index it with the Equity Options contract Symbol
.
foreach (var openInterestDict in allHistoryOpenInterest) { if (openInterestDict.ContainsKey(contractSymbol)) { var openInterest = openInterestDict[contractSymbol]; } }
for open_interest_dict in all_history_open_interest: if open_interest_dict.ContainsKey(contract_symbol): open_interest = open_interest_dict[contract_symbol]
You can also iterate through each of the OpenInterest
dictionaries.
foreach (var openInterestDict in allHistoryOpenInterest) { foreach (var kvp in openInterestDict) { var symbol = kvp.Key; var openInterest = kvp.Value; } }
for open_interest_dict in all_history_open_interest: for kvp in open_interest_dict: symbol = kvp.Key open_interest = kvp.Value
OptionHistory Objects
The GetOptionHistory
method returns an OptionHistory
object. To get each slice in the OptionHistory
object, iterate through it.
foreach (var slice in optionHistory) { foreach (var kvp in slice.OptionChains) { var canonicalSymbol = kvp.Key; var chain = kvp.Value; foreach (var contract in chain) { } } }
for slice in option_history: for canonical_symbol, chain in slice.OptionChains.items(): for contract in chain: pass
To convert the OptionHistory
object to a DataFrame
that contains the trade and quote information of each contract and the underlying, call the GetAllData
method.
option_history.GetAllData()
To get the expiration dates of all the contracts in an OptionHistory
object, call the GetExpiryDates
method.
option_history.GetExpiryDates()
To get the strike prices of all the contracts in an OptionHistory
object, call the GetStrikes
method.
option_history.GetStrikes()
Plot Data
You need some historical Equity Options data to produce plots. You can use many of the supported plotting librariesPlot.NET
package to visualize data in various formats. For example, you can plot candlestick and line charts.
Candlestick Chart
Follow these steps to plot candlestick charts:
- Get some historical data.
- Drop the first four index levels of the
DataFrame
that returns. - Import the
plotly
Plotly.NET
library. - Create a
Candlestick
. - Create a
Layout
. - Create the
Figure
. - Assign the
Layout
to the chart. - Show the plot.
history = qb.History(contract_symbol, datetime(2021, 12, 30), datetime(2021, 12, 31))
var history = qb.History<TradeBar>(contractSymbol, new DateTime(2021, 12, 30), new DateTime(2021, 12, 31));
history.index = history.index.droplevel([0,1,2,3])
import plotly.graph_objects as go
#r "../Plotly.NET.dll" using Plotly.NET; using Plotly.NET.LayoutObjects;
candlestick = go.Candlestick(x=history.index, open=history['open'], high=history['high'], low=history['low'], close=history['close'])
var chart = Chart2D.Chart.Candlestick<decimal, decimal, decimal, decimal, DateTime, string>( history.Select(x => x.Open), history.Select(x => x.High), history.Select(x => x.Low), history.Select(x => x.Close), history.Select(x => x.EndTime) );
layout = go.Layout(title=go.layout.Title(text=f'{symbol.Value} OHLC'), xaxis_title='Date', yaxis_title='Price', xaxis_rangeslider_visible=False)
LinearAxis xAxis = new LinearAxis(); xAxis.SetValue("title", "Time"); LinearAxis yAxis = new LinearAxis(); yAxis.SetValue("title", "Price ($)"); Title title = Title.init($"{contractSymbol} Price"); Layout layout = new Layout(); layout.SetValue("xaxis", xAxis); layout.SetValue("yaxis", yAxis); layout.SetValue("title", title);
fig = go.Figure(data=[candlestick], layout=layout)
chart.WithLayout(layout);
fig.show()
HTML(GenericChart.toChartHTML(chart))
The Jupyter Notebook displays a candlestick chart of the Option contract's price.


Line Chart
Follow these steps to plot line charts using built-in methodsPlotly.NET
package:
- Get some historical data.
- Drop the first three index levels of the
DataFrame
that returns. - Select the open interest data.
- Rename the column to the
Symbol
of the contract. - Call the
plot
method with a title. - Create a
Line
chart. - Create a
Layout
. - Assign the
Layout
to the chart. - Show the plot.
history = qb.History(OpenInterest, contract_symbol, datetime(2021, 12, 1), datetime(2021, 12, 31))
var history = qb.History<OpenInterest>(contract_symbol, new DateTime(2021, 12, 1), new DateTime(2021, 12, 31));
history.index = history.index.droplevel([0, 1, 2])
history = history['openinterest'].unstack(level=0)
history.columns = [ Symbol.GetAlias(SecurityIdentifier.Parse(x), equity_symbol) for x in history.columns]
history.plot(title="Open Interest")
var chart = Chart2D.Chart.Line<DateTime, decimal, string>( history.Select(x => x.EndTime), history.Select(x => x.Value) );
LinearAxis xAxis = new LinearAxis(); xAxis.SetValue("title", "Time"); LinearAxis yAxis = new LinearAxis(); yAxis.SetValue("title", "Open Interest"); Title title = Title.init("SPY Open Interest"); Layout layout = new Layout(); layout.SetValue("xaxis", xAxis); layout.SetValue("yaxis", yAxis); layout.SetValue("title", title);
chart.WithLayout(layout);
plt.show()
HTML(GenericChart.toChartHTML(chart))
The Jupyter Notebook displays a line chart of open interest data.


Get Price Model Data
Follow these steps to get the values of theoretical prices, implied volatility, and Greeks:
- Create subscriptions and set the price model.
- Set the underlying volatility model.
- Get historical data for the underlying Equity and the Option contract(s).
- Iterate through the historical data and calculate the values.
qb.Securities[equity_symbol].VolatilityModel = StandardDeviationOfReturnsVolatilityModel(30, Resolution.Daily)
You need to reset the volatility before you start calculating the theoretical prices, implied volatility, and Greeks.
df = pd.DataFrame() for slice in history: underlying_price = None underlying_volatility = None # Update the security with QuoteBar information for bar in slice.QuoteBars.Values: qb.Securities[bar.Symbol].SetMarketPrice(bar) # Update the security with TradeBar information for bar in slice.Bars.Values: symbol = bar.Symbol security = qb.Securities[symbol] security.SetMarketPrice(bar) if security.Type == SecurityType.Equity: underlying_volatility = security.VolatilityModel.Volatility underlying_price = security.Price continue # Create the Option contract contract = OptionContract.Create(symbol, symbol.Underlying, bar.EndTime, security, underlying_price) contract.LastPrice = bar.Close # Evaluate the price model to get the IV, Greeks, and theoretical price result = security.PriceModel.Evaluate(security, None, contract) greeks = result.Greeks # Append the data to the DataFrame data = { "IV" : result.ImpliedVolatility, "Delta": greeks.Delta, "Gamma": greeks.Gamma, "Vega": greeks.Vega, "Rho": greeks.Rho, "Theta": greeks.Theta, "LastPrice": contract.LastPrice, "Close": security.Close, "theoreticalPrice" : result.TheoreticalPrice, "underlyingPrice": underlying_price, "underlyingVolatility": underlying_volatility } right = "Put" if symbol.ID.OptionRight == 1 else "Call" index = pd.MultiIndex.from_tuples([(symbol.ID.Date, symbol.ID.StrikePrice, right, symbol.Value, bar.EndTime)], names=["expiry", "strike", "type", "symbol", "endTime"]) df = pd.concat([df, pd.DataFrame(data, index=index)])
For a full example, see the following project: