Overall Statistics |
Total Orders 4 Average Win 0% Average Loss -0.68% Compounding Annual Return 11.545% Drawdown 5.600% Expectancy -0.5 Start Equity 100000 End Equity 120969 Net Profit 20.969% Sharpe Ratio 0.513 Sortino Ratio 0.628 Probabilistic Sharpe Ratio 77.543% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 0 Alpha -0.034 Beta 0.438 Annual Standard Deviation 0.052 Annual Variance 0.003 Information Ratio -1.734 Tracking Error 0.064 Treynor Ratio 0.061 Total Fees $2.00 Estimated Strategy Capacity $0 Lowest Capacity Asset QQQ RIWIV7K5Z9LX Portfolio Turnover 0.04% |
from AlgorithmImports import * class VIXShortStraddleAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2023, 1, 1) self.SetEndDate(2024, 12, 1) self.SetCash(100000) # Set proper universe settings for options self.UniverseSettings.Resolution = Resolution.Minute self.UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw # Add QQQ with minute resolution self.qqq = self.AddEquity("QQQ", Resolution.Minute).Symbol # Add QQQ Options self.qqq_option = self.AddOption("QQQ", Resolution.Minute) # Widen the filter to ensure we get contracts self.qqq_option.SetFilter(lambda u: u.IncludeWeeklys() .Strikes(-5, +5) # Wider strike range .Expiration(15, 45)) self.Schedule.On(self.DateRules.EveryDay(self.qqq), self.TimeRules.At(9, 31), self.TradeOptions) def TradeOptions(self): if self.Portfolio.Invested: self.Log("Already invested, skipping trade") return chain = self.CurrentSlice.OptionChains.get(self.qqq_option.Symbol) if chain is None or not chain: self.Log(f"No option chain data available") return self.Log(f"Number of contracts in chain: {chain}") try: # Filter for valid contracts contracts = [x for x in chain if 15 <= (x.Expiry - self.Time).days <= 45] if not contracts: self.Log("No valid contracts found after filtering") return # Find ATM strike underlying_price = chain.Underlying.Price self.Log(f"Underlying price: {underlying_price}") atm_strike = min([x.Strike for x in contracts], key=lambda s: abs(s - underlying_price)) self.Log(f"Selected ATM strike: {atm_strike}") # Get nearest expiry expiry = min(x.Expiry for x in contracts if x.Strike == atm_strike) self.Log(f"Selected expiry: {expiry}") short_straddle = OptionStrategies.ShortStraddle(self.qqq_option.Symbol, atm_strike, expiry) # Calculate quantity based on notional value option_notional = underlying_price * 100 # One contract = 100 shares quantity = max(1, int(self.Portfolio.TotalPortfolioValue * 0.02 / option_notional)) self.Log(f"Attempting to sell straddle with quantity: {quantity}") self.Sell(short_straddle, quantity) except Exception as e: self.Log(f"Error in TradeOptions: {str(e)}")