Introduction

The market moves through regimes of high volatility and low volatility. To bet on the regime the market is currently in, you can utilize the S&P 500 Index, the Cboe Volatility Index, and Option straddles. In this research post, we’ll review what each of these components are and how you can use them in a strategy to trade volatility.

Background

This strategy trades S&P 500 Index (SPX) Options based on the Cboe Volatility Index (VIX) to profit from the difference between expected future volatility and actual future volatility. The SPX is a market-capitalization-weighted index of the 500 largest publicly-traded companies in the U.S. It is not an exact list of the top 500 U.S. companies by market capitalization because there are other criteria included in the index. The index is widely regarded as the best gauge of large-cap U.S. Equities.

The VIX is a real-time index that represents the market's expectations for the relative strength of near-term price changes of the SPX. Because it's derived from the prices of SPX Index Options with near-term expiration dates, it generates a 30-day forward projection of volatility. Volatility, or how fast prices change, is often seen as a way to gauge market sentiment, and in particular, the degree of fear among market participants.

A long straddle is an Options trading strategy that consists of buying an ATM call and an ATM put, where both contracts have the same underlying asset, strike price, and expiration date. This strategy aims to profit from volatile movements in the underlying stock, either positive or negative.

Strategy payoff decomposition and analysis of long straddle

A short straddle consists of selling a call and a put, where both contracts have the same underlying asset, strike price (normally at-the-money), and expiration date. If you enter a short straddle, you bet that the underlying asset will remain relatively stable and not experience significant price movements before the Option expires.

Strategy payoff decomposition and analysis of short straddle

The idea behind this trading strategy is to trade in the opposite direction of market expectations. That is, if the VIX is relatively high (the market expects relatively high volatility), we open a short straddle, betting the upcoming volatility will be low. Conversely, if the VIX is relatively low (the market expects relatively low volatility), we open a long straddle, betting the upcoming volatility will be high.

Implementation

To implement this strategy, we start by subscribing to the VIX and creating some indicators so that we can calculate the VIX z-score.

self._vix = self.add_index('VIX')
self._vix.std = self.std(self._vix.symbol, 24*21, resolution=Resolution.DAILY)
self._vix.sma = self.sma(self._vix.symbol, 24*21, resolution=Resolution.DAILY)

We then subscribe to SPX Index Options and set the filter to select contracts that can form a straddle.

self._spx = self.add_index_option('SPX')
self._spx.set_filter(lambda universe: universe.straddle(30))

To ensure the algorithm is responsive to the latest market activity, we look to rebalance the portfolio 30 minutes after every market open.

self.schedule.on(self.date_rules.every_day(self._spx.symbol), self.time_rules.after_market_open(self._spx.symbol, 30), self._trade)

During each rebalance, we calculate the VIX z-score. We want our position size to be inversely correlated with the z-score, so we set our order quantity to be the integer form of the z-score, multiplied by -1. If the resulting quantity is zero, we liquidate the portfolio. If it’s not zero and we have no open positions, we open a straddle on the SPX Index.

def _trade(self):        
    z_score = (self._vix.price - self._vix.sma.current.value) / self._vix.std.current.value
    quantity = -int(z_score)
    if quantity == 0:
        self.liquidate()
    elif not self.portfolio.invested:
        chain = self.current_slice.option_chains.get(self._spx.symbol, None)
        if not chain: return
        chain = [c for c in chain if c.expiry > self.time]
        expiry = min([x.expiry for x in chain])
        strike = sorted([c for c in chain if c.expiry == expiry], key=lambda x: abs(x.strike - self._spx.price))[0].strike
        strategy = OptionStrategies.straddle(self._spx.symbol, strike, expiry)
        self.order(strategy, quantity)

Since the quantity is the negative integer value of the z-score, the algorithm opens a long straddle when the VIX is relatively low and opens a short straddle when the VIX is relatively high. The long straddle profits when the underlying asset is volatile after opening the trade and the short straddle profits when the underlying asset is not volatile. 

A short straddle consists of selling Option contracts, so there is a chance that the buyer exercises their Option. To ensure we always have both legs of the straddle in the market, we liquidate all our positions when we are assigned.

def on_order_event(self, order_event):
    if order_event.status == OrderStatus.FILLED and order_event.is_assignment:
        self.liquidate()

Conclusion

Combining together the SPX, VIX, and Option straddles, it’s possible to trade market volatility. The strategy we implemented effectively trades in the opposite direction of market expectations, betting future volatility will be high when the market expects it to be low, and vice versa. The strategy is profitable, but it generates a negative Sharpe ratio when the risk-free rate is the primary credit rate from the Federal Open Market Committee.