Hi all-
I was hoping for a bit of help with my algorithm- I'm new to QuantConnect and still learning the ropes a bit!
My strategy is simple: Every day at 10:00AM, sell a straddle and delta hedge it every 30 minutes for the remainder of the day. At 3:55 PM, liquidate everything. I would repeat this process every trading day. Executed correctly, this strategy’s P/L would solely be variance premia.
Straddle Specifics:
- Underlying: SPY
- Expiry: day-of (SPY has contracts expiring every day. We always want to trade the contract expiring at the end of the same day)
- Strike: Whatever the nearest available to the current underlying price is
- Quantity to sell: This would be dynamically calculated and rounded to the nearest whole number based on my current bankroll.
Further Details:
- Notification every time an order is placed, along with its specifics
- Notification every time underlying shares are bought or sold to delta hedge and in what quantity
- Notification when all positions are liquidated
I seem to be having issues with my delta hedging and for some reason trades only seem to be placed a couple times a month in my backtest, rather than every day, and I can't seem to figure out why this is happening
All input greatly appreciated!
# region imports
from AlgorithmImports import *
# endregion
class VariancePremium(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2023, 7, 1)
self.SetEndDate(2023, 12, 1)
self.SetCash(100000)
self.spy = self.AddEquity("SPY", Resolution.Minute)
self.option = self.AddOption("SPY", Resolution.Minute)
self.option_symbol = self.option.Symbol
self.option.SetFilter(-2, 2, 0, 1)
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.At(10, 0), self.SellStraddle)
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.Every(TimeSpan.FromMinutes(30)), self.DeltaHedge)
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.At(15, 55), self.LiquidatePositions)
# Determine straddle order quantity
def OrderSizing(self):
spy_price = self.Securities["SPY"].Price
size = int(self.Portfolio.Cash / (spy_price * 50))
return size
# Place short straddle order
def SellStraddle(self):
if not self.Portfolio.Invested:
if self.CurrentSlice.OptionChains.ContainsKey(self.option_symbol):
chain = self.CurrentSlice.OptionChains[self.option_symbol]
contracts_expiring_today = [i for i in chain if i.Expiry.date() == self.Time.date()]
if len(contracts_expiring_today) == 0:
contracts_expiring_today = [i for i in chain if i.Expiry.date() == self.Time.date() + timedelta(days=1)]
if len(contracts_expiring_today) == 0:
return
spy_price = self.Securities["SPY"].Price
contract = min(contracts_expiring_today, key=lambda x: abs(x.Strike - spy_price))
straddle = OptionStrategies.Straddle(self.option_symbol, contract.Strike, contract.Expiry)
order_size = self.OrderSizing()
self.Sell(straddle, order_size)
self.Debug(f"Sold straddle: strike = {contract.Strike}, expiry = {contract.Expiry}, quantity = {order_size}")
# Dynamically hedge straddle by adjusting position in the underlying
def DeltaHedge(self):
if not self.Portfolio.Invested:
return
total_delta = 0
for holding in self.Portfolio.Values:
if holding.Symbol.SecurityType == SecurityType.Option:
if self.CurrentSlice.OptionChains.ContainsKey(holding.Symbol.Underlying):
option_contract = self.CurrentSlice.OptionChains[holding.Symbol.Underlying].Contracts[holding.Symbol]
total_delta += holding.Quantity * option_contract.Greeks.Delta
spy_holding = self.Portfolio["SPY"]
spy_quantity = spy_holding.Quantity
target_spy_quantity = -total_delta
if spy_quantity != target_spy_quantity:
self.MarketOrder("SPY", target_spy_quantity - spy_quantity)
self.Debug("Adjusted Underlying Hedge Position")
# Liquidate all positions
def LiquidatePositions(self):
self.Liquidate()
self.Debug("Portfolio Liquidated")
Mia Alissi
Hi Jack,
From your code, it seems like you're on the right track. However, there are a few things that might be causing the issues you're experiencing.
Delta Hedging: In your
DeltaHedge
method, you're only adjusting your position in the underlying if your portfolio is invested. However, you're not checking if the portfolio is invested in the underlying specifically. It's possible that your portfolio is invested in options, but not in the underlying, which would prevent your delta hedging from executing. You might want to adjust your condition to check if the portfolio is invested in the underlying specifically.Trading Frequency: The issue with your trades not being placed every day could be due to the conditions in your
SellStraddle
method. You're only placing trades if there are options contracts expiring today or tomorrow. However, not all options have daily expirations. For example, SPY options only have expirations on Monday, Wednesday, and Friday. This could be why your trades are not being placed every day. You might want to adjust your strategy to account for this.Here's a snippet from the QuantConnect documentation that shows how to select options contracts based on their expiration date:
You can modify this code to select options contracts that expire today or tomorrow.
OrderSubmitted
event handler. This event is triggered every time an order is submitted. You can use it to log the order details. Here's an example:You can do something similar for your delta hedging and liquidation notifications. Just add a
Debug
statement in the relevant methods.I hope this helps! Let me know if you have any other questions.
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Jack
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!