Option Strategies

Iron Condor

Introduction

The Iron Condor is an option strategy which involves four option contracts, where all options have the same underlying stock and expiration. The order of strike prices for the four contracts is $A>B>C>D$.

PositionStrike
1 far-OTM call $A$
1 near-OTM call $B, where B > underlying\ price$
1 near-OTM put $C, where C < underlying\ price$
1 far-OTM put $D, where C-D = A-B$

Long Iron Butterfly

It consists of selling an OTM call, selling an OTM put, buying an ATM call and buying an ATM put. It is a option strategy profitting from an decrease in price movement (implied volatility).

This is a limited-reward-limited-risk strategy. The payoff is as follows:

$Payoff_{far\ OTM\ call}=(Price_{underlying}-Strike_{far\ OTM\ call})^{+}$

$Payoff_{near\ OTM\ call}=(Price_{underlying}-Strike_{near\ OTM\ call})^{+}$

$Payoff_{far\ OTM\ put}=(Strike_{far\ OTM\ put}-Price_{underlying})^{+}$

$Payoff_{near\ OTM\ put}=(Strike_{near\ OTM\ put}-Price_{underlying})^{+}$

$$Profit/Loss=(Payoff_{near\ OTM\ call}+Payoff_{near\ OTM\ put}-Payoff_{far\ OTM\ call}-Payoff_{far\ OTM\ put}\\ \quad+credit\ received_{far\ OTM\ call}+credit\ received_{far\ OTM\ put}-debit\ paid_{near\ OTM\ call}-debit\ paid_{near\ OTM\ put})\\ \quad\times multiplier-commissions$$

The maximum profit is $Strike_{far\ OTM\ call}-Strike_{near\ OTM\ call}$ minus net debit paid when opening the trade, where the underlying price fell below the OTM put strike or above the OTM call strike price at expiration.

Maximum loss is the net debit paid after commission when opening the trade, where $Strike_{near\ OTM\ put} < underlying price < Strike_{near\ OTM\ call}$.

If the option is American option, there will be a risk of early assignment on the shorted option.

Short Call Butterfly

It consists of buying an OTM call, buying an OTM put, selling an ATM call and selling an ATM put. It is a option strategy profitting from an increase in price movement (implied volatility), as well as time decay value since ATM options decay sharper.

This is a limited-reward-limited-risk strategy. The payoff is as follows:

$$Profit/Loss=(Payoff_{OTM\ call}+Payoff_{OTM\ put}-Payoff_{ATM\ call}-Payoff_{ATM\ put}\\ \quad+credit\ received_{ATM\ call}+credit\ received_{ATM\ put}-debit\ paid_{OTM\ call}-debit\ paid_{OTM\ put})\\ \quad\times multiplier-commissions$$

The maximum profit is the net credit received after commission when opening the trade, where $Strike_{near\ OTM\ put} < underlying price < Strike_{near\ OTM\ call}$.

Maximum loss is $Strike_{far\ OTM\ call}-Strike_{near\ OTM\ call}$ minus net credit received when opening the trade, where the underlying price fell below the OTM put strike or above the OTM call strike price at expiration.

If the option is American option, there will be a risk of early assignment on the shorted option.

Implementation

Follow these steps to implement the Long Iron Condor strategy.

  1. In the Initialize method, set the start date, end date, cash, and Option universe.
  2. private Symbol _symbol;
    
    public override void Initialize()
    {
        SetStartDate(2017, 2, 1);
        SetEndDate(2017, 3, 1);
        SetCash(100000);
    
        var option = AddOption("GOOG", Resolution.Minute);
        _symbol = option.Symbol;
        option.SetFilter(universe => universe.Strikes(-10, 10)
                                                .Expiration(TimeSpan.FromDays(0), TimeSpan.FromDays(30)));
    }
    def Initialize(self) -> None:
        self.SetStartDate(2017, 2, 1)
        self.SetEndDate(2017, 3, 1)
        self.SetCash(300000)
    
        option = self.AddOption("GOOG", Resolution.Minute)
        self.symbol = option.Symbol
        option.SetFilter(-10, 10, timedelta(0), timedelta(30))
  3. Break the candidate contracts into the call and put options.
  4. public override void OnData(Slice slice)
    {
        if (Portfolio.Invested) return;
    
        // Get the OptionChain of the symbol
        var chain = slice.OptionChains.get(_symbol, null);
        if (chain == null || chain.Count() == 0) return;
    
        // filter the call options from the contracts which is ATM in the option chain.
        var calls = chain.Where(x => x.Right == OptionRight.Call);
        var puts = chain.Where(x => x.Right == OptionRight.Put);
        if (calls.Count() == 0 || puts.Count() == 0) return;
    def OnData(self, slice: Slice) -> None:
        # avoid extra orders
        if self.Portfolio.Invested: return
    
        # Get the OptionChain of the self.symbol
        chain = slice.OptionChains.get(self.symbol, None)
        if not chain: return
    
        # filter the call and put options from the contracts
        call = [i for i in chain if i.Right == 0]
        put = [i for i in chain if i.Right == 1]
        if len(call) == 0 or len(put) == 0 : continue
  5. Find the specific contracts to trade.
  6.     // sort the contracts by strike prices
        var callContracts = calls.OrderByDescending(x => x.Strike);
        var putContracts = puts.OrderBy(x => x.Strike);
    
        // Get the nearer OTM contracts by strike prices
        var farCallContract = callContracts.First();
        var farPutContract = putContracts.First();
        var nearCallContract = callContracts.Skip(2).First();
        var nearPutContract = putContracts.Skip(2).First();
    
        // Sell 1 near-OTM Call
        Sell(nearCallContract.Symbol, 1);
        // Sell 1 near-OTM Put 
        Sell(nearPutContract.Symbol, 1);
        // Buy 1 far-OTM Call 
        Buy(farCallContract.Symbol, 1);
        // Buy 1 far-OTM Put 
        Buy(farPutContract.Symbol, 1);
    }
    call_contracts = sorted(call, key = lambda x: x.Strike)
    put_contracts = sorted(put, key = lambda x: x.Strike)
    
    # Buy 1 near-OTM Put 
    near_put = call_contracts[-2]
    self.Buy(near_put.Symbol, 1)
    # Buy 1 near-OTM Call
    near_call = put_contracts[1]
    self.Buy(near_call.Symbol, 1)
    # Sell 1 far-OTM Call 
    far_call = call_contracts[-1]
    self.Sell(far_call.Symbol, 1)
    # Sell 1 far-OTM Put 
    far_put = put_contracts[0]
    self.Sell(far_put.Symbol, 1)

Summary

In this algorithm, we've realised the below payout at expiration (2017-4-22).

ItemsPrice
Price of far-OTM call$ 1.85
Price of far-OTM put$ 2.75
Price of near-OTM call$ 1.35
Price of near-OTM put$ 2.15
Strike of far-OTM call$ 857.50
Strike of far-OTM put$ 810.00
Strike of near-OTM call$ 855.00
Strike of near-OTM put$ 815.00
Price of underlying at expiration$ 851.20
Commission per trade$ 1.00
$Payoff_{far\ OTM\ call}=(851.20-857.50)^{+}=0$

$Payoff_{near\ OTM\ call}=(851.20-855.00)^{+}=0$

$Payoff_{near\ OTM\ put}=(815.00-851.20)^{+}=0$

$Payoff_{far\ OTM\ put}=(810.00-851.20)^{+}=0$

$Profit/Loss=(0+0-0-0+1.35+2.15-1.85-2.75)\times100-1\times4=-114$

So, the strategy losses $114.

Algorithm

Backtesing using SetFilter

Backtest using OptionChainProvider

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: