Back

Trading options for multiple symbols

Hello everyone,

I took a look into options on Quantconnect and found the introductory tutorials really helpful. All of these examples trade only options for one symbol though. I'd like to try something with multiple symbols but I don't know how to do that with the Slice class. Could someone maybe post any such algorithm? A simple one like the first example just with two or three symbols would do. Thank you in advance.

Kind regards,

Christian

Update Backtest







You can add multiple options with a list of underlying tickers and save the option symbols in a new list.

for ticker in ["IBM", "AAPL"]:
     option = self.AddOption(ticker)
     self.symbols.append(option.Symbol)
     option.SetFilter(-2, +2, timedelta(0), timedelta(180))

 

In OnData(self, slice), you can get the option chain for the specified symbol with 

for symbol in self.symbols:
      for kvp in slice.OptionChains:
          if kvp.Key == symbol:
             chain = kvp.Value

1


Thank you very much for your answer, Jing! I have another question: How do I access the prices of the options in my portfolio? Let's say I'd like to sell the options bought by your algorithm when their current price is 10 percent higher than the price they were bought for. 

Kind regards,

Christian

0

We have quoteBar(with bid/ask) data for options. There are a few methods to get the option contract price:

contract = contracts[0]
contract_symbol = contracts[0].Symbol

1) self.Securities[contract_symbol].Price returns the mid-price = (bid+ask)/2

2) contracts.AskPrice / contracts.BidPrice returns the ask/bid price. 

3) The order is filled based on bid/ask price. If you are selling a stock, you are going to get the bid price, if you are buying a stock you are going to get the ask price.

You can get the order filling price with 

ticket = self.MarketOrder(symbol, 1)
fill_price = ticket.AverageFillPrice

Then you can place a limit sell order to sell the contract when their current price is 10 percent higher than the price they were bought for. 

self.LimitOrder(contract_symbol, -1, fill_price*1.1)

For details about limit orders, please refer to this algorithm

https://github.com/QuantConnect/Lean/blob/master/Algorithm.Python/OrderTicketDemoAlgorithm.py
0

Hello Jing,

thank you very much for your answer! It's working now. I have another question concerning the algorithm you posted: You use the line

if self.Portfolio.Invested: return

If I remove this. There are multiple trades for the same symbol. Why is that? Shouldn't

if not self.Portfolio[symbol].Invested:

prevent the algorithm from odering if the option for that symbol is already in the portfolio? I need to remove the first line but I only want each option once, so I need to fix this.

Kind regards,

Christian

0

"if self.Portfolio.Invested: return" means if there are any positions in your portfolio invested, the code after this line will not be executed in the current time slice. 

"if not self.Portfolio[symbol].Invested" specified the symbol, it returns the boolean value to decide if there are holdings for this symbol in the portfolio. 

To just show you a simple example. I added this line "if self.Portfolio.Invested: return" so the code for option contract selection part won't be executed each minute to speed up the algorithm. 

0

Hello Jing,

thank you for your answer. My issue is that I want to have each option only once in my portfolio. When removing the line "if self.Portfolio.Invested: return" like in the attached backtest, this is not the case anymore. I thought to achieve this by using "if not self.Portfolio[symbol].Invested" which should be false so that the following code should not be executed if already invested in that stock but apparantly this is not the case. So what do I have to change?

0


You can get a list of all option holdings in the portfolio and check if the underlying asset of the invested contract equals the symbol. Please see the attached algorithm

option_invested = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.Option]
for symbol in self.symbols:
invested = [option for option in option_invested if option.Underlying == symbol.Underlying]
if len(invested) > 0: return
for kvp in slice.OptionChains:
####
0


Hello Jing,

thank you for your help again!

if len(invested) > 0: return

works fine to avoid selling the same option twice. Now I need a buying condition too. I think here something like

if self.Portfolio[contract_symbol].Invested:

is also not working properly. (When checking the logs of my algorithm it should log every invested symbol every minute which it is not doing.) Which line should be used instead?

Also I wonder whether it's possible to create only one option chain for all symbols and then invest in the first ten or something after it's been sorted by certain criteria. How would I have to modify my algorithm in order to do that?

Kind regards,

Christian

0


1) After you trade the option contract for a specified symbol, In the next time step, you filtered the contract again. "contracts" might change in the next time step, then "contract_symbol" might change as well. If you use "self.Portfolio[contract_symbol].Invested", you can not guarantee "contract_symbol" here is still the contract when you place the order with "self.MarketOrder(contract_symbol, -1)". You can save the contract you've already invested in a dictionary (keyed by the underlying symbol) once you place the order over it and use this symbol to decide   "if self.Portfolio[contract_symbol].Invested". Otherwise,  contract_symbol might change over time because you filtered the contract at each time step. 

# check this part of your code, contract_symbol might change over time
contracts = sorted(sorted(sorted(contracts_iv,
key = lambda x: -x.AskPrice/(x.AskPrice+
max(20*chain.Underlying.Price - (chain.Underlying.Price - x.Strike), 10*x.Strike))),
key = lambda x: x.Expiry, reverse=True),
key = lambda x: x.Right, reverse=True)

if len(contracts) == 0: continue
contract_symbol = contracts[0].Symbol
symbol = contracts[0].Symbol
if self.Portfolio[contract_symbol].Invested:
self.Debug()

self.Portfolio[contrat_symbol].IsLong and self.Portfolio[contrat_symbol].IsShort can help you decide if it is a long or short position in your portfolio.

2) You can save option contracts for all the underlying symbols in a list and sort them by your criteria.

all_contracts = []
for i in self.symbols:
# get a list of contracts for the specified underlying asset
chain = slice.OptionChains.GetValue(i)
if chain is None: return
all_contracts += chain

 

  
0

"self.SetFilter(minStrike, maxStrike, minExpiry, maxExpiry)" does not include the weekly contracts. To add the weekly contracts, you can use 

option.SetFilter(self.UniverseFunc)

def UniverseFunc(self, universe):
return universe.IncludeWeeklys().Strikes(-3, 3).Expiration(timedelta(0), timedelta(180))

Please see this example

https://github.com/QuantConnect/Lean/blob/master/Algorithm.Python/OptionChainConsistencyRegressionAlgorithm.py

For option data in Data Explorer, each file contains the price data for a single contract in a single day. For example

20180904_ibm_minute_quote_american_call_1000000_20181221.csv

It is the quote data on 20180904 for the IBM call option contract with the strike 100 and the expiry 12/21/2018.

0

Update Backtest





0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Loading...

This discussion is closed