The strategy sells monthly delta-neutral TLT ETF strangles, delta-hedged daily, with proceeds earning the 3-month Treasury rate, while managing transaction costs for options and TLT share trades.

I. STRATEGY IN A NUTSHEL

The strategy uses TLT ETF for option selling, forming monthly delta-neutral strangles with the first out-of-the-money calls and puts. Delta-hedging is performed daily, rebalancing with TLT shares when deltas exceed ±500 shares. Option trades are executed at the bid-ask midpoint, with transaction costs of $1 per contract. TLT share trades incur $5 in brokerage fees and a 1-cent bid-ask spread per transaction. Proceeds from shorting options and TLT shares, or funds used to purchase TLT shares, earn the 3-month Treasury bill rate. This approach seeks to profit from option premiums while managing risk and transaction costs.

II. ECONOMIC RATIONALE

Most researchers speculate that the volatility premium is caused by investors who strongly dislike negative asset returns and are therefore willing to pay a premium for portfolio insurance offered by options.

III. SOURCE PAPER

An Examination of Long-Term Bond iShare Option Selling Strategies [Click to Open PDF]

Simon

<Abstract>

This paper examines volatility trades in Lehman Brothers 20+ Year US Treasury Index iShare (TLT) options from July 2003 through May 2007. The results indicate that implied volatility is persistently above actual volatility and that unconditionally selling front contract strangles and straddles and holding for one month is highly profitable after transactions costs. The paper also demonstrates that the profitability of short-term strategies is enhanced when strangles and straddles are sold when implied volatility is high relative to out of sample time series volatility forecasts. Profitability owes both to winning trades outpacing losing trades by 2:1 margins and to profits of winning trades exceeding losses of losing trades, despite the limited return and unlimited risk profiles of short option strategies. A decomposition of the results indicates that most of the profitability can be attributed to theta gains outpacing gamma losses. Risk management strategies such as stop loss strategies detract from the profitability of short term option selling strategies, while take profit orders have only modest favorable effects on the results. Overall, the results demonstrate that TLT option selling strategies offered attractive risk-return tradeoffs over the sample period.

IV. BACKTEST PERFORMANCE

Annualised Return17.44%
Volatility18.41%
Beta0.09
Sharpe Ratio0.73
Sortino Ratio-0.271
Maximum DrawdownN/A
Win Rate45%

V. FULL PYTHON CODE

from AlgorithmImports import *
class SellingOptionsonBondETFs(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2000, 1, 1)
        self.SetCash(100000)
        
        data = self.AddEquity("BIL", Resolution.Minute)
        self.bills = data.Symbol
        data.SetLeverage(5)
        
        data = self.AddEquity("TLT", Resolution.Minute)
        self.symbol = data.Symbol
        data.SetLeverage(5)
        
        option = self.AddOption("TLT", Resolution.Minute)
        option.SetFilter(-20, 20, 25, 35)
        
        self.last_day = -1
        
    def OnData(self,slice):
        # Check once a day.
        if self.Time.day == self.last_day:
            return
        self.last_day = self.Time.day
        
        for i in slice.OptionChains:
            chains = i.Value
            # Only bill position is opened.
            invested = [x.Key for x in self.Portfolio if x.Value.Invested]
            if len(invested) <= 1:
                calls = list(filter(lambda x: x.Right == OptionRight.Call, chains))
                puts = list(filter(lambda x: x.Right == OptionRight.Put, chains))
                
                if not calls or not puts: return
            
                underlying_price = self.Securities[self.symbol].Price
                expiries = [i.Expiry for i in puts]
                
                # Determine expiration date nearly one month.
                expiry = min(expiries, key=lambda x: abs((x.date()-self.Time.date()).days-30))
                strikes = [i.Strike for i in puts]
                
                # Determine at-the-money strike.
                strike = min(strikes, key=lambda x: abs(x-underlying_price))
                
                atm_call = [i for i in calls if i.Expiry == expiry and i.Strike == strike]
                atm_put = [i for i in puts if i.Expiry == expiry and i.Strike == strike]
        
                if atm_call and atm_put:
                    options_q = int(self.Portfolio.MarginRemaining / (underlying_price * 100))
                    # Set max leverage.
                    self.Securities[atm_call[0].Symbol].MarginModel = BuyingPowerModel(5)
                    self.Securities[atm_put[0].Symbol].MarginModel = BuyingPowerModel(5)
                    
                    # Sell at-the-money straddle.
                    self.Sell(atm_call[0].Symbol, options_q)
                    self.Sell(atm_put[0].Symbol, options_q)
                    
                    # Buy treasury bill.
                    self.SetHoldings(self.bills, 1)
        
            if self.Portfolio.Invested:
                self.Liquidate(self.symbol)

VI. Backtest Performance

Leave a Reply

Discover more from Quant Buffet

Subscribe now to keep reading and get access to the full archive.

Continue reading