API Tutorials

Using Options in QuantConnect

Introduction

QuantConnect provides US options trade and quotes price data for approximately 4000 symbols, each of which has roughly 10 strikes on average. Data is available starting January 1st, 2008. In this tutorial, we will discuss how to use QuantConnect to start your options trading algorithm.

Add Options

Before trading options, you need to add options for a given underlying equity and set the resolution in step Initialize with AddOption method. The commonly used parameters will be explained in the method table. Please refer to the link below for details of each method.

Method Parameters
AddOption(underlying, resolution, fillDataForward)underlying(string): The underlying equity symbol resolution: Tick, Second, Minute, Hour, or Daily. Default is minute fillDataForward(bool): If true, returns the last available data even if none in that time slice. The default value is true.
def Initialize(self):
    self.SetStartDate(2017, 01, 01)  #Set Start Date
    self.SetEndDate(2017, 06, 30)  #Set End Date
    self.SetCash(50000)  #Set Strategy Cash
    equity = self.AddEquity("GOOG", Resolution.Daily) # Add the underlying stock: Google
    option = self.AddOption("GOOG", Resolution.Daily) # Add the option corresponding to underlying stock
    self.symbol = option.Symbol

The return value of AddOption method is an option security object , please refer to the link for detailed properties and methods of option class.

Filter Contracts

After adding the options for specific underlying stock,  you can set the filter criteria with SetFilter method to pull contracts using the specified min and max strike and expiration range values you need for a given symbol.

Method Parameters
SetFilter( min strike, max strike, minexpiry, maxExpiry)min Strike, max Strike: The min and max strike rank relative to market price min Expiry, max Expiry: The range of time to expiration to include, for example, TimeSpan.FromDays(10) would exclude contracts expiring in less than 10 days

Here parameters min Strike and max Strike are the relative values with respect to the market price. We use Google(NASDAQ: GOOG) as an example to describe the filter criteria. If today is 01/03/2017, the market price of underlying stock is $776, the strike prices of GOOG options are spaced $2.5. Then SetFilter(-1, +2, timedelta(0), timedelta(90)) will fist look up at the money contracts with strike being K=$777.5 (Here K might not being $100 since rarely will option be ATM exactly). Then  filter will looks for options with strikes between and including (777.5 + 2.5*2, 777.5 - 2.5*1). The time to expiration of these options are restricted within 90 days from now on. 

For the strike, the exchange normally chooses the strike prices at which options can be written so that they are spaced $2.50, $5, or $10 apart. Typically the spacing is $2.50 when the stock price is between $5 and $25, $5 when the stock price is between $25 and $200, and $10 for stock prices above $200. So you should carefully choose the parameters of min strike and max Strike in case there is no contracts satisfy the filter criteria if the range is too small, less than the minimum units of strike prices change.

For the expiry, there are many expiration dates that apply to the different series of options. An option cycle is the pattern of months in which options contracts expire. There are three kinds of common option cycles. The options on the January cycle have contracts available in the first month of each quarter (January, April, July and October). Options assigned to the February cycle use the middle month of each quarter (February, May, August and November). And options in the March cycle have options available during the last month of each quarter (March, June, September and December). In addition, individual stock options typically expire in the current month and the subsequent month.

# filter the contracts with strikes between (market price - 10, market price + 10)
option.SetFilter(-10,10)
# filter the contracts which expires more than 30 days but no longer than 60 days
option.SetFilter(TimeSpan.FromDays(30),TimeSpan.FromDays(60))
# filter the contracts with strikes between(ATM Strike - 10 * strike space value, market price + 10 * strike space value) and with expiration days less than 180 days
option.SetFilter(-10, +10, timedelta(0), timedelta(180))

Select Contracts

For QuantConnect API, Slice class provides a data structure for all of an algorithm's data at a single time step. So you need use property Slice.OptionChains to request options data for this slice. OptionChains is a collection of  OptionChain keyed by the option's underlying symbol. The elements in Slice.OptionChains have properties Key(the underlying symbol object) Value(the option chain). OptionChain  represents an entire chain of option contracts for a single underlying security. In other words, It is a list of option contracts. OptionContract defines a single option contract at a specific expiration and strike price. For any contract x in option chain, you can use the following statements to check different options properties.

Properties of Option Contract x
x.Symbol.Value Get the string of option contract's symbol
x.AskPrice, x.BidPrice Get the ask price,  Get the bid price
x.Expiry Get the expiration date
x.Strike Get the strike price
x.ImpliedVolatility Get the implied volatility
x.GreeksGet the Greeks letter
x.RightGet the right being purchased x.Right = 1  call option[right to buy] x.Right = 0  put option[right to sell]
x.UnderlyingLastPriceGet the last price the underlying security traded at
x.UnderlyingSymbolGets the underlying security's symbol

We can print out the details of the contract after filtering with Python data frame to show these properties. Assume today is 01/03/2017.  The stock price at 01/03/2017 09:31:00 is $776.01 per share. Here we use  SetFilter(-1, +1, timedelta(0), timedelta(60)) to filter the contracts.

def OnData(self,slice):
    for i in slice.OptionChains:
        if i.Key != self.symbol: continue
	optionchain = i.Value
	self.Log("underlying price:" + str(optionchain.Underlying.Price))
	df = pd.DataFrame([[x.Right,float(x.Strike),x.Expiry,float(x.BidPrice),float(x.AskPrice)] for x in optionchain],
			   index=[x.Symbol.Value for x in optionchain],
			   columns=['type(call 0, put 1)', 'strike', 'expiry', 'ask price', 'bid price'])
        self.Log(str(df))
Symbol type(call 0, put 1) Strike Expiry Ask Price Bid Price
GOOG 170217C007800000780.02017-02-1726.427.9
GOOG 170120P007825001782.52017-01-2014.716.3
GOOG 170120C007825000782.52017-01-209.410.2
GOOG 170120P007800001780.02017-01-2013.415.0
GOOG 170120C007800000780.02017-01-2010.611.5
GOOG 170217P007800001780.02017-02-1728.930.8
GOOG 170120P007775001777.52017-01-2012.213.7
GOOG 170120C007775000777.52017-01-2011.812.9

Here we give an example of how to find ATM, ITM OTM contracts for trading. First, we need to extract the OptionChain from OptionChains according to symbols we added in Initialize step. Secondly, we extract ATM, ITM and OTM contracts by using UnderlyingLastPrice and Strike properties. Note here the strikes of ATM options are not exactly the same as the market price of underlying stocks, thus here we first sort the contracts by the absolute values of the difference between the UnderlyingLastPrice and the Strike. Then we choose the contract with the minimum absolute value as the ATM contract.

for i in slice.OptionChains:
    if i.Key != self.symbol: continue
    chain = i.Value
# differentiate the call and put options
call = [x for x in optionchain if chain.Right == 0]
put = [x for x in optionchain if chain.Right == 1]
# choose ITM contracts
contracts = [x for x in call if call.UnderlyingLastPrice - x.Strike > 0]
# or choose ATM contracts
contracts = sorted(optionchain, key = lambda x: abs(optionchain.Underlying.Price - x.Strike))[0]
# or choose OTM contracts
contracts = [x for x in call if call.UnderlyingLastPrice - x.Strike < 0]
# sort the contracts by their expiration dates
contracts = sorted(contracts, key = lambda x:x.Expiry, reverse = True)

Finally, we trade the options by using the contract's symbol.

if len(contracts) == 0: continue
# trade the contracts with the farthest expiration
symbol = contracts[0].Symbol
self.MarketOrder(symbol, 1)
self.MarketOnCloseOrder(symbol, -1)

Algorithm

This simple example demonstrates how you can inspect the option chain to pick a specific option contract to trade.

Summary

After mastering the basic knowledge of options market, this tutorial we take a close at how to use Quantconnect to customize your own options trading. For example, how you can access an option chain, how to view the details of the contract as a Python data frame, and the most important how to trade the specific option contract.

You can also see our Documentation and Videos. You can also get in touch with us via Chat.

Did you find this page Helpful ?