Overall Statistics |
Total Trades 26 Average Win 3.83% Average Loss -10.96% Compounding Annual Return 36.681% Drawdown 13.500% Expectancy -0.264 Net Profit 25.642% Sharpe Ratio 1.395 Probabilistic Sharpe Ratio 55.555% Loss Rate 45% Win Rate 55% Profit-Loss Ratio 0.35 Alpha -0.149 Beta 2.005 Annual Standard Deviation 0.298 Annual Variance 0.089 Information Ratio 0.644 Tracking Error 0.207 Treynor Ratio 0.207 Total Fees $977.22 Estimated Strategy Capacity $15000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X |
class VirtualRedDogfish(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 1, 1) # self.SetEndDate(2012, 1, 30) self.SetCash(1000000) self.stock_wt = 0.80 self.option_wt = 0.15 self.trade = False #Setup flag to trade self.stock = self.AddEquity("SPY", Resolution.Minute).Symbol self.option = self.AddIndex('VIX', Resolution.Minute) self.option.SetDataNormalizationMode(DataNormalizationMode.Raw) self.SetSecurityInitializer(lambda x: x.SetMarketPrice(self.GetLastKnownPrice(x))) self.contract = None # initialize the option contract self.call_premium = 0.85 # % strike price premium on option call hedge self.put_premium = 1.5 # % strike price premium on option put hedge self.Schedule.On(self.DateRules.EveryDay(self.stock), \ self.TimeRules.AfterMarketOpen(self.stock, 30), \ self.SetupTrade) def OnData(self, slice): #Liquidate any options that are within 1.5 days of expiration option_invested = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.IndexOption] if option_invested: expirydate = self.contract.ID.Date if (expirydate - self.Time) < timedelta(1.5): if slice.ContainsKey(self.contract) and slice[self.contract] is not None and not slice[self.contract].IsFillForward: self.Debug("option less than 2 days before expiry") self.Liquidate(self.contract) self.contract = None if self.trade and self.Time.hour == 11: self.InitiateTrade() def SetupTrade(self): #Check to see if already invested in option option_invested = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.IndexOption] #If no option held, select and purchase contract if not option_invested: self.contract = self.GetPut() self.trade = True def GetPut(self): targetStrike = self.Securities[self.option.Symbol].Price * self.put_premium contracts = self.OptionChainProvider.GetOptionContractList(self.option.Symbol, self.Time) self.Debug(f"VIX Total Contracts Found: {len(contracts)}") puts = [x for x in contracts if x.ID.OptionRight == OptionRight.Put] puts = sorted(sorted(puts, key = lambda x: x.ID.Date), key = lambda x: x.ID.StrikePrice, reverse = False) self.Debug(f"VIX Puts found: {len(puts)}") puts = [x for x in puts if abs(targetStrike - x.ID.StrikePrice) <= 1] puts = [x for x in puts if 7 < (x.ID.Date - self.Time).days <= 35] if len(puts) == 0: self.Debug(f"!!! no put options available") return None # Use AddOptionContract() to subscribe the data for specified contract self.AddOptionContract(puts[0], Resolution.Minute) return puts[0] def InitiateTrade(self): if self.contract is not None: self.SetHoldings([PortfolioTarget(self.stock, self.stock_wt), \ PortfolioTarget(self.contract, self.option_wt)]) self.trade = False #reset trading flag