Runtime Error: Exception has been thrown by the target of an invocation. symbol must not contain the characters '|' or ' '.

Back

Hello guys, can you help me plzzzz..
While testing one options based strategy I encountered an error:

Runtime Error: Exception has been thrown by the target of an invocation. symbol must not contain the characters '|' or ' '.
Parameter name: symbol     (Open Stacktrace)

I had the same error before and found out that somehow the options chain request returned a option symbol with a outdated expiry.
This time the symbol (expiry) is ok, but when I place market order, I get this error. 

Here I attached the script. It's simplified and does the following:
1. If not invested, it shorts (-1) ATM PUT on SPY with expiry around 1 month.
2. If the PUT is assigned and  I get 100 shares of SPY, I place a short ATM CALL option (on SPY) market order. 

In this specifically attached script this CALL encounters the error, although I see that the symbol wise it looks ok (when looking in Debug mode).. I couldn't attach backtest by some reason.

Thank you! pls look below for the code:

import pandas as pd
import datetime

class LtShortPuts(QCAlgorithm):

def Initialize(self):

self.SetStartDate(2020, 3, 2) # Set Start Date
self.SetEndDate(2020, 3 , 31)
self.SetCash(100000) # Set Strategy Cash

self.last_slice = None
self.strike = 0

self.stock = "SPY"
self.fillPrice = 0

self.tradingAllowed = False
self.tradingDay = False
self.dt = None

#self.optTrades = pd.DataFrame(columns = ['type', 'symbol', 'price', 'qty', 'underPrice'])

equity = self.AddEquity(self.stock, Resolution.Minute)
equity.SetDataNormalizationMode(DataNormalizationMode.Raw)
option = self.AddOption(self.stock, Resolution.Minute)
self.symbol = option.Symbol
option.SetFilter(lambda universe: universe.IncludeWeeklys().Strikes(-1, 1).Expiration(timedelta(27), timedelta(35)))

# Init
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(9, 30), Action(self.Init))

# check SPY closing price
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(15, 59), Action(self.CheckClose))


def GetOptionContract(self, strike):
# Returns call/put contracts and their details for the given strike

for i in self.last_slice.OptionChains:
if i.Key != self.symbol: continue
optionchain = i.Value

call = [x for x in optionchain if x.Right == 0]
callContract = [x for x in call if x.Strike == strike][0]
call_symbol = callContract.Symbol.Value

put = [x for x in optionchain if x.Right == 1]
putContract = [x for x in put if x.Strike == strike][0]
put_symbol = putContract.Symbol.Value

call_bid = callContract.BidPrice
call_ask = callContract.AskPrice

put_ask = putContract.AskPrice
put_bid = putContract.BidPrice

return(call_symbol, call_bid, call_ask, put_symbol, put_bid, put_ask)


def Init(self):
self.call_ready = False
self.put_ready = False
self.call_symb = None
self.put_symb = None


def CheckClose(self):
stockPrice = self.Securities[self.stock].Close
self.Log("Closing price: " + str(stockPrice))



def CheckOptions(self):
stockPrice = self.Securities[self.stock].Close
self.strike = round(stockPrice)
self.Log("Strike: " + str(self.strike))
self.dt = self.Time.date()
self.Log("Today: " + str(self.dt))


try:
call_symbol, call_bid, call_ask, put_symbol, put_bid, put_ask = self.GetOptionContract(self.strike)
self.tradingDay = True
self.Log("Trading day lah! Call_symbol: {0}, Put symbol: {1}".format(call_symbol, put_symbol))
d = call_symbol[6:12]
self.dateOfSymbol = datetime.datetime.strptime(d, "%y%m%d").date()
self.Log("Date of symbol: " + str(self.dateOfSymbol))

# I encountered problem before with the same error, and found out that algorithm tried to call options with expired dates
# so here I check whether the expiration date is ahead of the current date
if self.dateOfSymbol < self.dt:
self.Log("Problem!!!!!!! Today is: {0}, but option requested is: {1} ".format(str(self.Time.date(), call_symbol)) )
self.tradingDay = False

except:
self.Log("Not a trading day lahh!")
self.tradingDay = False

#self.Log("CheckOption tradingDay: " + str(self.tradingDay))


def OnData(self, slice):

if (self.Time.hour == 10 and self.Time.minute == 00):

invested = [ x.Symbol.Value for x in self.Portfolio.Values if x.Invested ]
self.Log("invested: " + str(invested))
if len(invested) == 0:
self.last_slice = slice
self.CheckOptions()

if self.tradingDay:
try:
call_symbol, call_bid, call_ask, put_symbol, put_bid, put_ask = self.GetOptionContract(self.strike)
except:
self.Log("Exception!")

marketTicket = self.MarketOrder(put_symbol, -1)
#marketTicket = self.MarketOrder(call_symbol, -1)
#marketTicket = self.MarketOrder(self.stock, 100)
self.fillPrice = marketTicket.AverageFillPrice
self.Debug("Open position Fill Price: {0}".format(self.fillPrice))

elif len(invested)>2: # something went wrong
self.Log("SOMETHING WENT WRONG. LIQUIDATING ALL POSITIONS!")
self.Liquidate()

else:
for opt in invested:

if (opt == 'SPY' and len(invested) == 1):
price = self.Portfolio[self.stock].Price
self.Log("We have only SPY position priced at {0} and need to add CALL".format(price))

self.last_slice = slice
self.CheckOptions()


if self.tradingDay:
try:
call_symbol, call_bid, call_ask, put_symbol, put_bid, put_ask = self.GetOptionContract(self.strike)
self.call_ready = True
self.call_symb = call_symbol
except:
self.Log("Exception!")

'''
try:
marketTicket = self.MarketOrder(call_symbol, -1)
self.fillPrice = marketTicket.AverageFillPrice
self.Debug("Opened short CALL for: {0}".format(self.fillPrice))
except:
pass
'''
# !!!!!!!!!!!!!!!!!!
# This is where it get error about wrong symbol
# ---------------------------------------------

if (self.Time.hour == 10 and self.Time.minute == 10):
if self.call_ready:
marketTicket = self.MarketOrder(self.call_symb, -1)
self.fillPrice = marketTicket.AverageFillPrice
self.Debug("Opened short CALL for: {0}".format(self.fillPrice))

 

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.


I think I found the solution. I expanded number of strikes in option.SetFilter .. Seems like it helped:

option.SetFilter(lambda universe: universe.IncludeWeeklys().Strikes(-40, 40).Expiration(timedelta(27), timedelta(35)))

 

0

When doing wider dates backtest, the error still pops up even with strikes pool from -60 to 60 from ATM.. So, unfortunately, problem persists :( 

0

Hey Iouri,

The error is being caused because self.call_symb refers to the ticker of the contract rather than the Symbol object. It is best practice to use the Symbol object to identify securities rather than the ticker. I updated self.GetOptionContract with

call_symbol = callContract.Symbol
put_symbol = putContract.Symbol

and self.CheckOptions with

d = call_symbol.ID.Date

This lets you access the expiry date for that contract.

Learn more about symbols and tickers in the security identifiers documentation.

Best
Rahul

1

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.


Hi Rahul,

Thanks a lot !

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