Introduction
The Wheel strategy is a popular trading strategy for Options that enables traders to build a steady flow of income from Equity assets they want to hold for the long term. In this research post, we’ll discuss the basic trading rules of the Wheel strategy, walk through how we can easily implement it on QuantConnect, and review the recent risk-adjusted returns of the strategy.
Background
The Wheel is a strategy that rotates between selling cash-secured puts and covered calls. In this strategy, the algorithm sells cash-secured out-of-the-money (OTM) puts until it’s assigned shares in the underlying Equity. While it holds the underlying shares, it sells OTM covered calls until the buyer exercises their Option contract and the algorithm loses its underlying shares. In both phases of the strategy, the algorithm generates income by collecting the premium from selling Option contracts.
The underlying Equity that is chosen should be a company that you don’t mind owning. When selling put contracts, the strike that’s selected should be the price below the current price that you’re comfortable buying the underlying stock. To make the position “cash-secured”, keep enough cash so that you can buy the underlying shares when you're assigned. After you write the put contracts, if the stock price stays above the strike price, the Option expires worthless and you keep the premium as profit. Otherwise, you’re obligated to buy the stock at the strike price and you rotate into selling covered calls.
When selling call contracts, the strike that’s selected should be the price above the current price that you’re comfortable selling the underlying stock. To make the position “covered”, the position size should be the same quantity you used when selling the put contracts. After you write the call contracts, if the stock price stays below the strike price, the Option expires worthless and you keep the premium as profit. Otherwise, you’re obligated to sell the stock at the strike price and you rotate into selling cash-secured puts again.
Implementation
To implement this strategy, we used SPY as the underlying Equity. It’s important to select an asset that’s relatively stable and that you’re willing to hold for the long term.
self._equity = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.Raw)
To calculate the price at which we would be comfortable selling contracts relative to the current underlying price, we chose an OTM threshold rate of 5%.
self._otm_threshold = 0.05
The _get_target_contract helper method is where we select the contracts we want to sell.
def _get_target_contract(self, right, target_price):
contract_symbols = self.option_chain_provider.get_option_contract_list(self._equity.symbol, self.time)
expiry = min([s.id.date for s in contract_symbols if s.id.date.date() > self.time.date() + timedelta(30)])
filtered_symbols = [
s for s in contract_symbols
if (s.id.date == expiry and s.id.option_right == right and
(s.id.strike_price <= target_price if right == OptionRight.PUT else s.id.strike_price >= target_price))
]
symbol = sorted(filtered_symbols, key=lambda s: s.id.strike_price, reverse=right == OptionRight.PUT)[0]
self.add_option_contract(symbol)
return symbol
This method works through the following procedure:
- Get all the Option contracts that are currently trading for the SPY.
- Select the closest expiration date that’s at least 30 days away.
- Select the call/put contract that has the expiry we want and is at least 5% OTM.
- Subscribe to the contract so we can trade it.
The on_data method contains the trading logic, condensed down to just 6 lines of code.
if not self.portfolio.invested and self.is_market_open(self._equity.symbol):
symbol = self._get_target_contract(OptionRight.PUT, self._equity.price * (1-self._otm_threshold))
self.set_holdings(symbol, -0.2)
elif [self._equity.symbol] == [symbol for symbol, holding in self.portfolio.items() if holding.invested]:
symbol = self._get_target_contract(OptionRight.CALL, self._equity.price * (1+self._otm_threshold))
self.market_order(symbol, -self._equity.holdings.quantity / 100)
Conclusion
The Wheel strategy generates income through collecting the premiums of selling Option contracts. The backtest results show the Wheel strategy out-performs buy-and-hold in the underlying Equity, SPY. The algorithm achieved a Sharpe ratio of 1.083 while the SPY produced a Sharpe ratio of 0.7 over the same time period.
To test if the strategy's performance was reliant on the specific parameters chosen, we ran an optimization job. We varied the _otm_threshold from 10% to 20% in steps of 2%. We also varied the minimum number of days before the selected contract expires from 15 days to 60 days in steps of 15. All parameter combinations outperformed the benchmark, suggesting the strategy is robust.
Kersten Kriegbaum
This is really nice
William Sell
How about applying this to crypto like BTC/ETH? Are those options available for backtesting in QuantConnect?
Eli Johnson
Nicely done. When running it for an earlier period (2007-2011), there is a backtest handled error: 5/06/2010 Executed Margin Call. I thought perhaps this might be due to potentially overwriting the put qty so I changed the following line but am still getting the error. Any insight as to why this might be?
self.set_holdings(symbol, -0.2)
to:
quantity = int(self.Portfolio.TotalPortfolioValue / (symbol.id.strike_price * 100))
self.market_order(symbol, -quantity)
Pavel Fedorov
so it feels like the classic OTM put selling with a little risk mitigation but not enough to protect against market collapse
Derek Melchin
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!