Overall Statistics |
Total Trades 25 Average Win 2.38% Average Loss -4.72% Compounding Annual Return 29.714% Drawdown 13.200% Expectancy 0.094 Net Profit 20.114% Sharpe Ratio 1.176 Probabilistic Sharpe Ratio 50.389% Loss Rate 27% Win Rate 73% Profit-Loss Ratio 0.50 Alpha -0.228 Beta 1.981 Annual Standard Deviation 0.292 Annual Variance 0.085 Information Ratio 0.269 Tracking Error 0.204 Treynor Ratio 0.173 Total Fees $788.39 Estimated Strategy Capacity $1100000.00 Lowest Capacity Asset VIX 31Q7PYN2B6EB2|VIX 31 |
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, 1), \ 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): self.Debug("option less than 2 days before expiry") self.Liquidate(self.contract) self.contract = None if self.trade: 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