Overall Statistics |
Total Trades 3 Average Win 1.01% Average Loss 0% Compounding Annual Return -27.872% Drawdown 7.200% Expectancy 0 Net Profit -2.617% Sharpe Ratio -1.31 Probabilistic Sharpe Ratio 23.535% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha -0.1 Beta 0.237 Annual Standard Deviation 0.224 Annual Variance 0.05 Information Ratio 0.731 Tracking Error 0.715 Treynor Ratio -1.238 Total Fees $2.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 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 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)) 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.ID.Date self.dateOfSymbol = 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 #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: call_symbol, call_bid, call_ask, put_symbol, put_bid, put_ask = self.GetOptionContract(self.strike) 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: 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 ''' 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))