diff --git a/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/22 Long Straddle/03 Strategy Payoff.html b/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/22 Long Straddle/03 Strategy Payoff.html index 39ab3f1494..29731f476a 100644 --- a/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/22 Long Straddle/03 Strategy Payoff.html +++ b/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/22 Long Straddle/03 Strategy Payoff.html @@ -30,5 +30,5 @@
The following chart shows the payoff at expiration:
-The maximum profit is unlimited if the underlying price rises to infinity at expiration.
+The maximum profit is unlimited if the underlying price rises to infinity or substantial, $K^{P} - C^{OTM}_0 - P^{OTM}_0$, if it drops to zero at expiration.
The maximum loss is the net debit paid, $C^{ATM}_0 + P^{ATM}_0$. It occurs when the underlying price is the same at expiration as it was when you opened the trade. In this case, both Options expire worthless.
\ No newline at end of file diff --git a/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Strangle/01 Introduction.html b/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/01 Introduction.html similarity index 63% rename from 03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Strangle/01 Introduction.html rename to 03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/01 Introduction.html index 9d50a490e1..5528fad134 100644 --- a/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Strangle/01 Introduction.html +++ b/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/01 Introduction.html @@ -1,2 +1,2 @@Long Strangle is an Options trading strategy that consists of simultaneously buying an OTM put and an OTM call, where both contracts have the same underlying asset and expiration date. This strategy aims to profit from volatile movements in the underlying stock, either positive or negative.
-Compared to a long straddle, the net debit of a long strangle is lower since OTM Options are cheaper. Additionally, the losing range of a long straddle is wider and the strike spread is wider.
+Compared to a long straddle, the net debit of a long strangle is lower since OTM Options are cheaper. Additionally, the losing range of a long straddle is wider and the strike spread is wider.
diff --git a/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/02 Implementation.php b/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/02 Implementation.php new file mode 100644 index 0000000000..3bd41879a2 --- /dev/null +++ b/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/02 Implementation.php @@ -0,0 +1,103 @@ +Follow these steps to implement the long strangle strategy:
+ +Initialize
method, set the start date, end date, cash, and Option universe.private Symbol _symbol; + +public override void Initialize() +{ + SetStartDate(2017, 4, 1); + SetEndDate(2017, 4, 30); + SetCash(100000); + + var option = AddOption("GOOG"); + _symbol = option.Symbol; + option.SetFilter(-5, 5, 0, 30); +}+
def Initialize(self) -> None: + self.SetStartDate(2017, 4, 1) + self.SetEndDate(2017, 4, 30) + self.SetCash(100000) + + option = self.AddOption("GOOG") + self.symbol = option.Symbol + option.SetFilter(-5, 5, 0, 30)+
OnData
method, select the expiration date and strike prices of the contracts in the strategy legs.public override void OnData(Slice slice) +{ + if (Portfolio.Invested || + !slice.OptionChains.TryGetValue(_symbol, out var chain)) + { + return; + } + + // Find options with the farthest expiry + var expiry = chain.Max(contract => contract.Expiry); + var contracts = chain.Where(contract => contract.Expiry == expiry).ToList(); + + // Order the OTM calls by strike to find the nearest to ATM + var callContracts = contracts + .Where(contract => contract.Right == OptionRight.Call && + contract.Strike > chain.Underlying.Price) + .OrderBy(contract => contract.Strike).ToArray(); + if (callContracts.Length == 0) return; + + // Order the OTM puts by strike to find the nearest to ATM + var putContracts = contracts + .Where(contract => contract.Right == OptionRight.Put && + contract.Strike < chain.Underlying.Price) + .OrderByDescending(contract => contract.Strike).ToArray(); + if (putContracts.Length == 0) return; + + var callStrike = callContracts[0].Strike; + var putStrike = putContracts[0].Strike; +}+
def OnData(self, slice: Slice) -> None: + if self.Portfolio.Invested: + return + + chain = slice.OptionChains.get(self.symbol) + if not chain: + return + + # Find options with the farthest expiry + expiry = max([x.Expiry for x in chain]) + contracts = [contract for contract in chain if contract.Expiry == expiry] + + # Order the OTM calls by strike to find the nearest to ATM + call_contracts = sorted([contract for contract in contracts + if contract.Right == OptionRight.Call and + contract.Strike > chain.Underlying.Price], + key=lambda x: x.Strike) + if not call_contracts: + return + + # Order the OTM puts by strike to find the nearest to ATM + put_contracts = sorted([contract for contract in contracts + if contract.Right == OptionRight.Put and + contract.Strike < chain.Underlying.Price], + key=lambda x: x.Strike, reverse=True) + if not put_contracts: + return + + call_strike = call_contracts[0].Strike + put_strike = put_contracts[0].Strike+
OnData
method, call the OptionStrategies.Strangle
method and then submit the order.var longStrangle = OptionStrategies.Strangle(_symbol, callStrike, putStrike, expiry); +Buy(longStrangle, 1);+
long_strangle = OptionStrategies.Strangle(self.symbol, call_strike, put_strike, expiry) +self.Buy(long_strangle, 1)+
The maximum profit is unlimited if the underlying price rises to infinity at expiration.
-The maximum loss is the net debit paid, $C^{OTM}_0 + P^{OTM}_0$. It occurs when the underlying price at expiration is the same as when you opened the trade. In this case, both Options expire worthless.
- +The maximum loss is the net debit paid, $C^{OTM}_0 + P^{OTM}_0$. It occurs when the underlying price at expiration is the same as when you opened the trade. In this case, both Options expire worthless.
\ No newline at end of file diff --git a/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/99 Example.php b/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/99 Example.php new file mode 100644 index 0000000000..f50c49295d --- /dev/null +++ b/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/99 Example.php @@ -0,0 +1,52 @@ + + + +The following table shows the price details of the assets in the algorithm at Option expiration (2017-04-22):
+ +Asset | Price ($) | Strike ($) |
---|---|---|
Call | 8.80 | 835.00 |
Put | 9.50 | 832.50 |
Underlying Equity at expiration | 843.19 | - |
Therefore, the payoff is
+ +$$ +\begin{array}{rcll} +C^{OTM}_T & = & (S_T - K^{C})^{+}\\ +& = & (843.19-835.00)^{+}\\ +& = & 8.19\\ +P^{OTM}_T & = & (K^{P} - S_T)^{+}\\ +& = & (832.50-843.19)^{+}\\ +& = & 0\\ +P_T & = & (C^{OTM}_T + P^{OTM}_T - C^{OTM}_0 - P^{OTM}_0)\times m - fee\\ +& = & (8.19+0-8.80-9.50)\times100-2.00\times2\\ +& = & -1013 +\end{array} +$$So, the strategy losses $1,013.
+ + +$optionStrategyName = "a long straddle"; +$pythonBacktestHash = "2803b574abb88853879060ba5224b026" ; +$csharpBacktestHash = "126b5aeb4be7a8bc2e15e10f54ee4894" ; +include(DOCS_RESOURCES."/trading-and-orders/option-strategy-embedded-backtest.php"); +?> \ No newline at end of file diff --git a/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Strangle/metadata.json b/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/metadata.json similarity index 79% rename from 03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Strangle/metadata.json rename to 03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/metadata.json index e7c8758a3c..811230b91c 100644 --- a/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Strangle/metadata.json +++ b/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Long Strangle/metadata.json @@ -4,9 +4,9 @@ "description": "A Long Strangle consists of simultaneously buying an OTM put and an OTM call, where both contracts have the same underlying asset and expiration date.", "keywords": "Long Strangle Options trading strategy, out-the-money call, out-the-money put, profit from volatile movements in the underlying stock, long straddle, contracts in the strategy legs, Strategy Payoff, maximum profit is unlimited", "og:description": "A Long Strangle consists of simultaneously buying an OTM put and an OTM call, where both contracts have the same underlying asset and expiration date.", - "og:title": "Strangle - Documentation QuantConnect.com", + "og:title": "Long Strangle - Documentation QuantConnect.com", "og:type": "website", - "og:site_name": "Strangle - QuantConnect.com", - "og:image": "https://cdn.quantconnect.com/docs/i/writing-algorithms/trading-and-orders/option-strategies/strangle.png" + "og:site_name": "Long Strangle - QuantConnect.com", + "og:image": "https://cdn.quantconnect.com/docs/i/writing-algorithms/trading-and-orders/option-strategies/long-strangle.png" } -} +} \ No newline at end of file diff --git a/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Strangle/02 Implementation.php b/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Strangle/02 Implementation.php deleted file mode 100644 index 6f05125e0d..0000000000 --- a/03 Writing Algorithms/22 Trading and Orders/07 Option Strategies/24 Strangle/02 Implementation.php +++ /dev/null @@ -1,98 +0,0 @@ -Follow these steps to implement the long strangle strategy:
- -Initialize
method, set the start date, end date, cash, and Option universe.private Symbol _symbol; - -public override void Initialize() -{ - SetStartDate(2017, 4, 1); - SetEndDate(2017, 4, 30); - SetCash(100000); - - var option = AddOption("GOOG", Resolution.Minute); - _symbol = option.Symbol; - option.SetFilter(-5, 5, TimeSpan.FromDays(0), TimeSpan.FromDays(30)); -}-
def Initialize(self) -> None: - self.SetStartDate(2017, 4, 1) - self.SetEndDate(2017, 4, 30) - self.SetCash(100000) - - option = self.AddOption("GOOG", Resolution.Minute) - self.symbol = option.Symbol - option.SetFilter(-5, 5, timedelta(0), timedelta(30))-
OnData
method, select the expiration date and strike prices of the contracts in the strategy legs.public override void OnData(Slice slice) -{ - if (Portfolio.Invested) return; - - // Get the OptionChain - var chain = slice.OptionChains.get(_symbol, null); - if (chain == null || chain.Count() == 0) return; - - // Select an expiration date - var expiry = chain.OrderBy(contract => contract.Expiry).Last().Expiry; - - // Select the OTM call strike - var callStrikes = chain.Where(contract => contract.Expiry == expiry - && contract.Right == OptionRight.Call - && contract.Strike > chain.Underlying.Price) - .Select(contract => contract.Strike); - if (callStrikes.Count() == 0) return; - var callStrike = callStrikes.Min(); - - // Select the OTM put strike - var putStrikes = chain.Where(contract => contract.Expiry == expiry - && contract.Right == OptionRight.Put - && contract.Strike < chain.Underlying.Price) - .Select(contract => contract.Strike); - if (putStrikes.Count() == 0) return; - var putStrike = putStrikes.Max(); -}-
def OnData(self, slice: Slice) -> None: - if self.Portfolio.Invested: return - - # Get the OptionChain - chain = slice.OptionChains.get(self.symbol, None) - if not chain: return - - # Select an expiration date - expiry = sorted(chain, key=lambda contract: contract.Expiry, reverse=True)[0].Expiry - - # Select the OTM call strike - strikes = [contract.Strike for contract in chain if contract.Expiry == expiry] - call_strikes = [contract.Strike for contract in chain - if contract.Expiry == expiry - and contract.Right == OptionRight.Call - and contract.Strike > chain.Underlying.Price] - if len(call_strikes) == 0: return - call_strike = min(call_strikes) - - # Select the OTM put strike - put_strikes = [contract.Strike for contract in chain - if contract.Expiry == expiry - and contract.Right == OptionRight.Put - and contract.Strike < chain.Underlying.Price] - if len(put_strikes) == 0: return - put_strike = max(put_strikes)-
OnData
method, call the OptionStrategies.Strangle
method and then submit the order.var optionStrategy = OptionStrategies.Strangle(_symbol, callStrike, putStrike, expiry); -Buy(optionStrategy, 1);-
option_strategy = OptionStrategies.Strangle(self.symbol, call_strike, put_strike, expiry) -self.Buy(option_strategy, 1)-
The following table shows the price details of the assets in the algorithm at Option expiration (2017-04-22):
- -Asset | Price ($) | Strike ($) |
---|---|---|
Call | 8.80 | 835.00 |
Put | 9.50 | 832.50 |
Underlying Equity at expiration | 843.19 | - |
Therefore, the payoff is
- -$$ -\begin{array}{rcll} -C^{OTM}_T & = & (S_T - K^{C})^{+}\\ -& = & (843.19-835.00)^{+}\\ -& = & 8.19\\ -P^{OTM}_T & = & (K^{P} - S_T)^{+}\\ -& = & (832.50-843.19)^{+}\\ -& = & 0\\ -P_T & = & (C^{OTM}_T + P^{OTM}_T - C^{OTM}_0 - P^{OTM}_0)\times m - fee\\ -& = & (8.19+0-8.80-9.50)\times100-1.00\times2\\ -& = & -1013 -\end{array} -$$So, the strategy losses $1,013.
- -The following algorithm implements a long strangle Option strategy:
- -