Overall Statistics |
Total Trades 2 Average Win 1.01% Average Loss 0% Compounding Annual Return -27.560% Drawdown 7.200% Expectancy 0 Net Profit -2.562% Sharpe Ratio -1.253 Probabilistic Sharpe Ratio 24.735% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha -0.099 Beta 0.237 Annual Standard Deviation 0.229 Annual Variance 0.053 Information Ratio 0.692 Tracking Error 0.733 Treynor Ratio -1.213 Total Fees $1.00 |
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))