Skip to content

Commit

Permalink
Merge pull request #1778 from QuantConnect/feature-1356-combo-oreder-…
Browse files Browse the repository at this point in the history
…option-strategies

Combo Order in Option Strategies
  • Loading branch information
AlexCatarino authored May 31, 2024
2 parents 5f42c26 + de3fc48 commit d218806
Show file tree
Hide file tree
Showing 23 changed files with 1,128 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
self._symbol = option.symbol
option.set_filter(lambda universe: universe.include_weeklys().strikes(-15, 15).expiration(0, 31))</pre>
</div>
</ol>

<h4>Using Helper strategies</h4>
<ol>
<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, select the expiration and strikes of the contracts in the strategy legs.</li>
<div class="section-example-container">
<pre class="csharp">public override void OnData(Slice slice)
Expand Down Expand Up @@ -77,5 +80,62 @@
include(DOCS_RESOURCES."/trading-and-orders/option-strategy-extra-args.php");
?>

</ol>

<h4>Using Combo Orders</h4>
<ol>
<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, select the strategy legs.</li>
<div class="section-example-container">
<pre class="csharp">public override void OnData(Slice slice)
{
if (Portfolio.Invested) return;

// Get the OptionChain
var chain = slice.OptionChains.get(_symbol, null);
if (chain.Count() == 0) return;

// Select the call Option contracts with the furthest expiry
var expiry = chain.OrderByDescending(x =&gt; x.Expiry).First().Expiry;
var calls = chain.Where(x =&gt; x.Expiry == expiry &amp;&amp; x.Right == OptionRight.Call);
if (calls.Count() == 0) return;

// Select the ITM and OTM contract strike prices from the remaining contracts
var orderedCalls = calls.OrderBy(x =&gt; x.Strike);
var itmCall = orderedCalls.First();
var otmCall = orderedCalls.Last();</pre>
<pre class="python">def on_data(self, slice: Slice) -&gt; None:
if self.portfolio.invested: return

# Get the OptionChain
chain = slice.option_chains.get(self._symbol, None)
if not chain: return

# Get the furthest expiry date of the contracts
expiry = sorted(chain, key = lambda x: x.expiry, reverse=True)[0].expiry

# Select the call Option contracts with the furthest expiry
calls = [i for i in chain if i.expiry == expiry and i.right == OptionRight.CALL]
if len(calls) == 0: return

# Select the ITM and OTM contract strike prices from the remaining contracts
ordered_calls = sorted(calls, key=lambda x: x.strike)
itm_call = ordered_calls[0]
otm_call = ordered_calls[-1]</pre>
</div>

<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, create <code>Leg</code> and call the <a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-market-orders">Combo Market Order</a>/<a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-limit-orders">Combo Limit Order</a>/<a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-leg-limit-orders">Combo Leg Limit Order</a> to submit the order.</li>
<div class="section-example-container">
<pre class="csharp">var legs = new List&lt;Leg&gt;()
{
Leg.Create(itmCall.Symbol, -1),
Leg.Create(otmCall.Symbol, 1)
};
ComboMarketOrder(legs, 1);</pre>
<pre class="python">legs = [
Leg.create(itm_call.symbol, -1),
Leg.create(otm_call.symbol, 1)
]
self.combo_market_order(legs, 1)</pre>
</div>

</ol>
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
self._symbol = option.symbol
option.set_filter(lambda universe: universe.include_weeklys().strikes(-15, 15).expiration(0, 31))</pre>
</div>
</ol>

<h4>Using Helper strategies</h4>
<ol>
<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, select the expiration and strikes of the contracts in the strategy legs.</li>
<div class="section-example-container">
<pre class="csharp">public override void OnData(Slice slice)
Expand Down Expand Up @@ -80,3 +83,61 @@
?>

</ol>

<h4>Using Combo Orders</h4>
<ol>
<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, select the strategy legs.</li>
<div class="section-example-container">
<pre class="csharp">public override void OnData(Slice slice)
{
if (Portfolio.Invested) return;

// Get the OptionChain
var chain = slice.OptionChains.get(_symbol, null);
if (chain.Count() == 0) return;

// Select the call Option contracts with the furthest expiry
var expiry = chain.OrderByDescending(x =&gt; x.Expiry).First().Expiry;
var puts = chain.Where(x =&gt; x.Expiry == expiry &amp;&amp; x.Right == OptionRight.Put);
if (puts.Count() == 0) return;

// Select the ITM and OTM contract strike prices from the remaining contracts
var orderedPuts = puts.OrderBy(x =&gt; x.Strike);
var otmPut = orderedPuts.First();
var itmPut = orderedPuts.Last();</pre>
<pre class="python">def on_data(self, slice: Slice) -&gt; None:
if self.portfolio.invested: return

# Get the OptionChain
chain = slice.option_chains.get(self._symbol, None)
if not chain: return

# Get the furthest expiry date of the contracts
expiry = sorted(chain, key = lambda x: x.expiry, reverse=True)[0].expiry

# Select the call Option contracts with the furthest expiry
puts = [i for i in chain if i.expiry == expiry and i.right == OptionRight.PUT]
if len(puts) == 0: return

# Select the ITM and OTM contract strike prices from the remaining contracts
ordered_puts = sorted(puts, key=lambda x: x.strike)
otm_put = ordered_puts[0]
itm_put = ordered_puts[-1]</pre>
</div>

<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, create <code>Leg</code> and call the <a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-market-orders">Combo Market Order</a>/<a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-limit-orders">Combo Limit Order</a>/<a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-leg-limit-orders">Combo Leg Limit Order</a> to submit the order.</li>
<div class="section-example-container">
<pre class="csharp">var legs = new List&lt;Leg&gt;()
{
Leg.Create(itmPut.Symbol, 1),
Leg.Create(otmPut.Symbol, -1)
};
ComboMarketOrder(legs, 1);</pre>
<pre class="python">legs = [
Leg.create(itm_put.symbol, 1),
Leg.create(otm_put.symbol, -1)
]
self.combo_market_order(legs, 1)</pre>
</div>

</ol>
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
self._symbol = option.symbol
option.set_filter(lambda universe: universe.include_weeklys().strikes(-15, 15).expiration(0, 31))</pre>
</div>
</ol>

<h4>Using Helper strategies</h4>
<ol>
<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, select the expiration and strikes of the contracts in the strategy legs.</li>
<div class="section-example-container">
<pre class="csharp">public override void OnData(Slice slice)
Expand Down Expand Up @@ -80,3 +83,61 @@
?>

</ol>

<h4>Using Combo Orders</h4>
<ol>
<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, select the strategy legs.</li>
<div class="section-example-container">
<pre class="csharp">public override void OnData(Slice slice)
{
if (Portfolio.Invested) return;

// Get the OptionChain
var chain = slice.OptionChains.get(_symbol, null);
if (chain.Count() == 0) return;

// Select the call Option contracts with the furthest expiry
var expiry = chain.OrderByDescending(x =&gt; x.Expiry).First().Expiry;
var calls = chain.Where(x =&gt; x.Expiry == expiry &amp;&amp; x.Right == OptionRight.Call);
if (calls.Count() == 0) return;

// Select the ITM and OTM contract strike prices from the remaining contracts
var orderedCalls = calls.OrderBy(x =&gt; x.Strike);
var itmCall = orderedCalls.First();
var otmCall = orderedCalls.Last();</pre>
<pre class="python">def on_data(self, slice: Slice) -&gt; None:
if self.portfolio.invested: return

# Get the OptionChain
chain = slice.option_chains.get(self._symbol, None)
if not chain: return

# Get the furthest expiry date of the contracts
expiry = sorted(chain, key = lambda x: x.expiry, reverse=True)[0].expiry

# Select the call Option contracts with the furthest expiry
calls = [i for i in chain if i.expiry == expiry and i.right == OptionRight.CALL]
if len(calls) == 0: return

# Select the ITM and OTM contract strike prices from the remaining contracts
ordered_calls = sorted(calls, key=lambda x: x.strike)
itm_call = ordered_calls[0]
otm_call = ordered_calls[-1]</pre>
</div>

<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, create <code>Leg</code> and call the <a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-market-orders">Combo Market Order</a>/<a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-limit-orders">Combo Limit Order</a>/<a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-leg-limit-orders">Combo Leg Limit Order</a> to submit the order.</li>
<div class="section-example-container">
<pre class="csharp">var legs = new List&lt;Leg&gt;()
{
Leg.Create(itmCall.Symbol, 1),
Leg.Create(otmCall.Symbol, -1)
};
ComboMarketOrder(legs, 1);</pre>
<pre class="python">legs = [
Leg.create(itm_call.symbol, 1),
Leg.create(otm_call.symbol, -1)
]
self.combo_market_order(legs, 1)</pre>
</div>

</ol>
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
self._symbol = option.symbol
option.set_filter(lambda universe: universe.include_weeklys().strikes(-15, 15).expiration(0, 31))</pre>
</div>
</ol>

<h4>Using Helper strategies</h4>
<ol>
<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, select the expiration and strikes of the contracts in the strategy legs.</li>
<div class="section-example-container">
<pre class="csharp">public override void OnData(Slice slice)
Expand Down Expand Up @@ -80,3 +83,61 @@
?>

</ol>

<h4>Using Combo Orders</h4>
<ol>
<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, select the strategy legs.</li>
<div class="section-example-container">
<pre class="csharp">public override void OnData(Slice slice)
{
if (Portfolio.Invested) return;

// Get the OptionChain
var chain = slice.OptionChains.get(_symbol, null);
if (chain.Count() == 0) return;

// Select the call Option contracts with the furthest expiry
var expiry = chain.OrderByDescending(x =&gt; x.Expiry).First().Expiry;
var puts = chain.Where(x =&gt; x.Expiry == expiry &amp;&amp; x.Right == OptionRight.Put);
if (puts.Count() == 0) return;

// Select the ITM and OTM contract strike prices from the remaining contracts
var orderedPuts = puts.OrderBy(x =&gt; x.Strike);
var otmPut = orderedPuts.First();
var itmPut = orderedPuts.Last();</pre>
<pre class="python">def on_data(self, slice: Slice) -&gt; None:
if self.portfolio.invested: return

# Get the OptionChain
chain = slice.option_chains.get(self._symbol, None)
if not chain: return

# Get the furthest expiry date of the contracts
expiry = sorted(chain, key = lambda x: x.expiry, reverse=True)[0].expiry

# Select the call Option contracts with the furthest expiry
puts = [i for i in chain if i.expiry == expiry and i.right == OptionRight.PUT]
if len(puts) == 0: return

# Select the ITM and OTM contract strike prices from the remaining contracts
ordered_puts = sorted(puts, key=lambda x: x.strike)
otm_put = ordered_puts[0]
itm_put = ordered_puts[-1]</pre>
</div>

<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, create <code>Leg</code> and call the <a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-market-orders">Combo Market Order</a>/<a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-limit-orders">Combo Limit Order</a>/<a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-leg-limit-orders">Combo Leg Limit Order</a> to submit the order.</li>
<div class="section-example-container">
<pre class="csharp">var legs = new List&lt;Leg&gt;()
{
Leg.Create(itmPut.Symbol, -1),
Leg.Create(otmPut.Symbol, 1)
};
ComboMarketOrder(legs, 1);</pre>
<pre class="python">legs = [
Leg.create(itm_put.symbol, -1),
Leg.create(otm_put.symbol, 1)
]
self.combo_market_order(legs, 1)</pre>
</div>

</ol>
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
self._symbol = option.symbol
option.set_filter(lambda universe: universe.include_weeklys().strikes(-15, 15).expiration(0, 31))</pre>
</div>
</ol>

<h4>Using Helper strategies</h4>
<ol>
<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, select the expiration and strikes of the contracts in the strategy legs.</li>
<div class="section-example-container">
<pre class="csharp">public override void OnData(Slice slice)
Expand Down Expand Up @@ -92,3 +95,63 @@
?>

</ol>

<h4>Using Combo Orders</h4>
<ol>
<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, select the strategy legs.</li>
<div class="section-example-container">
<pre class="csharp">public override void OnData(Slice slice)
{
if (Portfolio.Invested) return;

// Get the OptionChain
var chain = slice.OptionChains.get(_symbol, null);
if (chain.Count() == 0) return;

// Select the call Option contracts with the furthest expiry
var expiry = chain.OrderByDescending(x =&gt; x.Expiry).First().Expiry;
var calls = chain.Where(x =&gt; x.Expiry == expiry &amp;&amp; x.Right == OptionRight.Call);
if (calls.Count() == 0) return;

// Select the ATM, ITM and OTM contract strike prices from the remaining contracts
var atmCall = calls.OrderBy(x =&gt; Math.Abs(x.Strike - chain.Underlying.Price)).First();
var itmCall = calls.OrderBy(x =&gt; x.Strike).Skip(1).First();
var otmCall = calls.Single(x =&gt; x.Strike == atmCall.Strike * 2 - itmCall.Strike);</pre>
<pre class="python">def on_data(self, slice: Slice) -&gt; None:
if self.portfolio.invested: return

# Get the OptionChain
chain = slice.option_chains.get(self._symbol, None)
if not chain: return

# Get the furthest expiry date of the contracts
expiry = sorted(chain, key = lambda x: x.expiry, reverse=True)[0].expiry

# Select the call Option contracts with the furthest expiry
calls = [i for i in chain if i.expiry == expiry and i.right == OptionRight.CALL]
if len(calls) == 0: return

# Select the ATM, ITM and OTM contract strike prices from the remaining contracts
atm_call = sorted(calls, key=lambda x: abs(x.strike - chain.underlying.price))[0]
itm_call = sorted(calls, key=lambda x: x.strike)[1]
otm_call = [x for x in calls if x.strike == atm_call.strike * 2 - itm_call.strike][0]</pre>
</div>

<li>In the <code class="csharp">OnData</code><code class="python">on_data</code> method, create <code>Leg</code> and call the <a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-market-orders">Combo Market Order</a>/<a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-limit-orders">Combo Limit Order</a>/<a href="/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-leg-limit-orders">Combo Leg Limit Order</a> to submit the order.</li>
<div class="section-example-container">
<pre class="csharp">var legs = new List&lt;Leg&gt;()
{
Leg.Create(atmCall.Symbol, -2),
Leg.Create(itmCall.Symbol, 1),
Leg.Create(otmCall.Symbol, 1)
};
ComboMarketOrder(legs, 1);</pre>
<pre class="python">legs = [
Leg.create(atm_call.symbol, -2),
Leg.create(itm_call.symbol, 1),
Leg.create(otm_call.symbol, 1)
]
self.combo_market_order(legs, 1)</pre>
</div>

</ol>
Loading

0 comments on commit d218806

Please sign in to comment.