Option Strategies
Conversion
Introduction
A Conversion is a special case of a protective collar. It consist of holding one lot of the underlying security, shorting a call, and longing a put with lower strike price. However, the strategy now serves as an delta-neutral arbitration from Option mispricing instead of a hedge strategy. Note that it only attains a true profit when the risk-free return is greater than the risk-free interest rate.
Implementation
Follow these steps to implement the conversion strategy:
- In the
Initialize
initialize
method, set the start date, set the end date, subscribe to the underlying Equity, and create an Option universe. - In the
OnData
on_data
method, select the strike and expiry of the contracts in the strategy legs. - In the
OnData
on_data
method, select the contracts and place the orders.
private Symbol _symbol; public override void Initialize() { SetStartDate(2017, 4, 1); SetEndDate(2017, 4, 30); SetCash(100000); UniverseSettings.Asynchronous = true; var option = AddOption("GOOG", Resolution.Minute); _symbol = option.Symbol; option.SetFilter(universe => universe.IncludeWeeklys().Conversion(30, -5)); }
def initialize(self) -> None: self.set_start_date(2017, 4, 1) self.set_end_date(2017, 4, 30) self.set_cash(100000) self.universe_settings.asynchronous = True option = self.add_option("GOOG", Resolution.MINUTE) self._symbol = option.symbol option.set_filter(lambda universe: universe.include_weeklys().conversion(30, -5))
The Conversion
conversion
filter narrows the universe down to just the two contracts you need to form a conversion.
public override void OnData(Slice slice) { if (Portfolio.Invested) return; // Get the OptionChain if (!slice.OptionChains.TryGetValue(_symbol, out var chain)) return; // Select an expiry date and ATM strike price var expiry = chain.Max(x => x.Expiry); var strike = chain.OrderBy(x => Math.Abs(x.Strike - chain.Underlying.Price)).First().Strike;
def on_data(self, slice: Slice) -> None: if self.portfolio.invested: return # Get the OptionChain chain = slice.option_chains.get(self._symbol, None) if not chain: return # Select an expiry date and ATM strike price expiry = max([x.expiry for x in chain]) strike = sorted(chain, key = lambda x: abs(x.strike - chain.underlying.price))[0].strike
Approach A: Call the OptionStrategies.Conversion
OptionStrategies.conversion
method with the details of each leg and then pass the result to the Buy
buy
method.
var conversion = OptionStrategies.Conversion(_symbol, strike, expiry); Buy(conversion, 1);
conversion = OptionStrategies.conversion(self._symbol, strike, expiry) self.buy(conversion, 1)
Approach B: Create a list of Leg
objects and then call the Combo Market Ordercombo_market_order, Combo Limit Ordercombo_limit_order, or Combo Leg Limit Ordercombo_leg_limit_order method.
// Select the call and put contracts var call = chain.Single(x => x.Expiry == expiry && x.Strike == strike && x.Right == OptionRight.Call); var put = chain.Single(x => x.Expiry == expiry && x.Strike == strike && x.Right == OptionRight.Put); var legs = new List<Leg>() { Leg.Create(call.Symbol, -1), Leg.Create(put.Symbol, 1), Leg.Create(chain.Underlying.Symbol, chain.Underlying.SymbolProperties.ContractMultiplier) }; ComboMarketOrder(legs, 1);
# Select the call and put contracts call = [x for x in chain if x.right == OptionRight.CALL and x.expiry == expiry and x.strike == strike][0] put = [x for x in chain if x.right == OptionRight.PUT and x.expiry == expiry and x.strike == strike][0] legs = [ Leg.create(call.symbol, -1), Leg.create(put.symbol, 1), Leg.create(chain.underlying.symbol, chain.underlying.symbol_properties.contract_multiplier) ] self.combo_market_order(legs, 1)
Strategy Payoff
This is a fixed payoff, delta-neutral strategy. The payoff is
$$ \begin{array}{rcll} C_T & = & (S_T - K)^{+}\\ P_T & = & (K - S_T)^{+}\\ Payoff_T & = & (S_T - S_0 - C_T + P_T + C_0 - P_0)\times m - fee\\ & = & (K - S_0 + C_0 - P_0)\times m - fee \end{array} $$ $$ \begin{array}{rcll} \textrm{where} & C_T & = & \textrm{Call value at time T}\\ & P_T & = & \textrm{Put value at time T}\\ & S_T & = & \textrm{Underlying asset price at time T}\\ & K & = & \textrm{Strike price}\\ & Payoff_T & = & \textrm{Payout total at time T}\\ & S_0 & = & \textrm{Underlying asset price when the trade opened}\\ & C_0 & = & \textrm{Call price when the trade opened (credit received)}\\ & P_0 & = & \textrm{Put price when the trade opened (debit paid)}\\ & m & = & \textrm{Contract multiplier}\\ & T & = & \textrm{Time of expiration} \end{array} $$The following chart shows the payoff at expiration:
The payoff is only dependent on the strike price and the initial asset prices.
If the Option is American Option, there is a risk of early assignment on the contract you sell.
Example
The following table shows the price details of the assets in the algorithm:
Asset | Price ($) | Strike ($) |
---|---|---|
Call | 8.10 | 832.50 |
Put | 9.50 | 832.50 |
Underlying Equity at position opens | 833.17 | - |
Therefore, the payoff is
$$ \begin{array}{rcll} Payoff_T & = & (K - S_0 + C_0 - P_0)\times m - fee\\ & = & (832.50 - 833.17 + 8.10 - 9.50)\times100-1.00\times3\\ & = & -210.00\\ \end{array} $$So, the strategy loses $210.
The following algorithm implements a conversion Option strategy: