| 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)}")