Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
<li><a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-market-orders'>Combo market</a></li>
<li><a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-limit-orders'>Combo limit</a></li>
<li><a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-leg-limit-orders'>Combo leg limit</a></li>
<li><a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/contingent-orders'>Contingent</a></li>
<li><a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/option-exercise-orders'>Option exercise</a></li>
</ul>
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"10" : "",
"11" : "",
"12" : "",
"13" : "",
"20" : "",
"99" : ""
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<p>Contingent orders are sets of orders with related lifecycles. When an order in the set fills or you cancel it, the brokerage triggers, cancels, or resizes the other orders in the set. The brokerage manages the whole set, so a fill and a cancel request can't race each other and leave a position without its exit orders. LEAN supports the following contingency types:</p>

<ul>
<li>One Cancels Other (OCO) orders cancel the rest of the set when one of them fills, even partially.</li>
<li>One Triggers Other (OTO) orders hold the child orders until the parent order completely fills.</li>
<li>One Updates Other (OUO) orders reduce the remaining quantity of the rest of the set when one of them partially fills.</li>
</ul>

<p>You can compose these types. For example, a bracket order is an entry order that triggers a take-profit order and a stop-loss order, which cancel each other. The members of a set can be <a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-market-orders'>combo orders</a>.</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<p>To place a bracket order, call the <code class="csharp">BracketOrder</code><code class="python">bracket_order</code> method with the <code>Symbol</code>, the entry quantity, the take-profit price, and the stop-loss price. When the entry order completely fills, LEAN triggers a take-profit limit order and a stop-loss stop market order with the opposite quantity. When one of these exit orders fills, LEAN cancels the other one. The method returns a list with the order tickets of the entry order, the take-profit order, and the stop-loss order.</p>

<div class="section-example-container">
<pre class="csharp">var price = Securities[_symbol].Price;
var tickets = BracketOrder(_symbol, 100, takeProfitPrice: price * 1.02m, stopLossPrice: price * 0.99m);</pre>
<pre class="python">price = self.securities[self._symbol].price
tickets = self.bracket_order(self._symbol, 100, take_profit_price=price * 1.02, stop_loss_price=price * 0.99)</pre>
</div>

<p>By default, the entry is a <a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/market-orders'>market order</a>. To use a <a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/limit-orders'>limit order</a> for the entry, pass a <code class="csharp">limitPrice</code><code class="python">limit_price</code> argument. You can also provide a tag, <a href='/docs/v2/writing-algorithms/trading-and-orders/order-properties'>order properties</a>, and an <code>asynchronous</code> flag.</p>

<div class="section-example-container">
<pre class="csharp">BracketOrder(_symbol, 100, takeProfitPrice, stopLossPrice, limitPrice: limitPrice, tag: tag, orderProperties: orderProperties);</pre>
<pre class="python">self.bracket_order(self._symbol, 100, take_profit_price, stop_loss_price, limit_price=limit_price, tag=tag, order_properties=order_properties)</pre>
</div>

<p>To bracket other entry order types, create the entry order request with the <a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/contingent-orders#06-Compose-Contingent-Orders'>order factory</a>. Call its <code class="csharp">Bracket</code><code class="python">bracket</code> method and pass the request to the <code class="csharp">Order</code><code class="python">order</code> method. The <code class="csharp">Bracket</code><code class="python">bracket</code> method accepts a <code class="csharp">stopLossLimitPrice</code><code class="python">stop_loss_limit_price</code> argument to use a stop limit order for the stop loss. To reduce the stop-loss quantity when the take-profit order partially fills, pass <code class="csharp">ContingencyType.OneUpdatesOther</code><code class="python">ContingencyType.ONE_UPDATES_OTHER</code> as the <code class="csharp">contingencyType</code><code class="python">contingency_type</code> argument.</p>

<div class="section-example-container">
<pre class="csharp">var entry = OrderFactory.StopMarketOrder(_symbol, 100, price * 1.01m)
.Bracket(price * 1.03m, price * 0.99m, stopLossLimitPrice: price * 0.985m, contingencyType: ContingencyType.OneUpdatesOther);
var tickets = Order(entry);</pre>
<pre class="python">entry = self.order_factory.stop_market_order(self._symbol, 100, price * 1.01).bracket(
price * 1.03, price * 0.99, stop_loss_limit_price=price * 0.985, contingency_type=ContingencyType.ONE_UPDATES_OTHER)
tickets = self.order(entry)</pre>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<p>To place a set of OCO orders, create an order request for each order with the <a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/contingent-orders#06-Compose-Contingent-Orders'>order factory</a>. Pass a list of the requests to the <code class="csharp">OneCancelsOtherOrder</code><code class="python">one_cancels_other_order</code> method. All the orders start working right away. When one of them fills, even partially, LEAN cancels the rest of the set. The method returns a list with the order ticket of each order.</p>

<div class="section-example-container">
<pre class="csharp">// Exit an existing long position at the first price level the market reaches.
var price = Securities[_symbol].Price;
var tickets = OneCancelsOtherOrder(new List&lt;SubmitOrderRequest&gt;
{
OrderFactory.LimitOrder(_symbol, -100, price * 1.02m, tag: "Take profit"),
OrderFactory.StopMarketOrder(_symbol, -100, price * 0.99m, tag: "Stop loss")
});</pre>
<pre class="python"># Exit an existing long position at the first price level the market reaches.
price = self.securities[self._symbol].price
tickets = self.one_cancels_other_order([
self.order_factory.limit_order(self._symbol, -100, price * 1.02, tag="Take profit"),
self.order_factory.stop_market_order(self._symbol, -100, price * 0.99, tag="Stop loss")
])</pre>
</div>

<p>The following images show the two outcomes of an OCO set that exits a long position. In the first image, the price rises to the take-profit price, so the take-profit order fills and LEAN cancels the stop-loss order:</p>
<img class="docs-image" src="https://cdn.quantconnect.com/i/tu/oco-take-profit-filled.webp" alt="An OCO set has a take-profit sell limit order at 60,000 and a stop-loss sell stop order at 40,000. The price rises to 60,000, the take-profit order fills, and LEAN cancels the stop-loss order.">

<p>In the second image, the price falls to the stop price, so the stop-loss order fills and LEAN cancels the take-profit order:</p>
<img class="docs-image" src="https://cdn.quantconnect.com/i/tu/oco-stop-loss-filled.webp" alt="An OCO set has a take-profit sell limit order at 60,000 and a stop-loss sell stop order at 40,000. The price falls to 40,000, the stop-loss order fills, and LEAN cancels the take-profit order.">
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<p>To place a set of OTO orders, create the parent and child order requests with the <a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/contingent-orders#06-Compose-Contingent-Orders'>order factory</a> and pass them to the <code class="csharp">OneTriggersOtherOrder</code><code class="python">one_triggers_other_order</code> method. The brokerage holds the child orders until the parent order completely fills. If the parent order is canceled or invalid, LEAN cancels the child orders, even if the parent partially filled. The method returns a list with the order ticket of each order, starting with the parent.</p>

<div class="section-example-container">
<pre class="csharp">// Buy IBM and BAC after the SPY entry fills.
var parent = OrderFactory.LimitOrder(_spy, 100, limitPrice);
var tickets = OneTriggersOtherOrder(parent, new List&lt;SubmitOrderRequest&gt;
{
OrderFactory.MarketOrder(_ibm, 10),
OrderFactory.MarketOrder(_bac, 20)
});</pre>
<pre class="python"># Buy IBM and BAC after the SPY entry fills.
parent = self.order_factory.limit_order(self._spy, 100, limit_price)
tickets = self.one_triggers_other_order(parent, [
self.order_factory.market_order(self._ibm, 10),
self.order_factory.market_order(self._bac, 20)
])</pre>
</div>

<p>The child orders are independent of each other and can be for different securities. To relate the child orders, pass them through the <code class="csharp">OrderFactory.OneCancelsOther</code><code class="python">order_factory.one_cancels_other</code> or <code class="csharp">OrderFactory.OneUpdatesOther</code><code class="python">order_factory.one_updates_other</code> method first. A child order can trigger other orders in turn. To create a chain, call the <code class="csharp">Triggers</code><code class="python">triggers</code> method on the child order request.</p>

<div class="section-example-container">
<pre class="csharp">// The IBM order triggers the BAC order once it fills.
var child = OrderFactory.MarketOrder(_ibm, 10).Triggers(OrderFactory.MarketOrder(_bac, 20));
var tickets = OneTriggersOtherOrder(parent, new List&lt;SubmitOrderRequest&gt; { child });</pre>
<pre class="python"># The IBM order triggers the BAC order once it fills.
child = self.order_factory.market_order(self._ibm, 10).triggers(self.order_factory.market_order(self._bac, 20))
tickets = self.one_triggers_other_order(parent, [child])</pre>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<p>To place a set of OUO orders, create an order request for each order with the <a href='/docs/v2/writing-algorithms/trading-and-orders/order-types/contingent-orders#06-Compose-Contingent-Orders'>order factory</a>. Pass a list of the requests to the <code class="csharp">OneUpdatesOtherOrder</code><code class="python">one_updates_other_order</code> method. All the orders start working right away. When one of them partially fills, LEAN reduces the remaining quantity of the rest of the set by the same proportion. For example, if a take-profit order for -100 shares fills -40 shares, LEAN reduces the stop-loss order from -100 shares to -60 shares. When one of the orders completely fills, LEAN cancels the rest of the set. The method returns a list with the order ticket of each order.</p>

<div class="section-example-container">
<pre class="csharp">var tickets = OneUpdatesOtherOrder(new List&lt;SubmitOrderRequest&gt;
{
OrderFactory.LimitOrder(_symbol, -100, price * 1.02m, tag: "Take profit"),
OrderFactory.StopMarketOrder(_symbol, -100, price * 0.99m, tag: "Stop loss")
});</pre>
<pre class="python">tickets = self.one_updates_other_order([
self.order_factory.limit_order(self._symbol, -100, price * 1.02, tag="Take profit"),
self.order_factory.stop_market_order(self._symbol, -100, price * 0.99, tag="Stop loss")
])</pre>
</div>

<p>LEAN rounds the new quantities to the lot size of the security. If a new quantity rounds to zero, LEAN cancels the order.</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<p>The order factory creates <code>SubmitOrderRequest</code> objects without submitting them, so you can relate them before you place them. The order factory has a method for each <a href='/docs/v2/writing-algorithms/trading-and-orders/order-types'>order type</a>, with the same arguments as the method that places the order. For example, <code class="csharp">OrderFactory.LimitOrder</code><code class="python">order_factory.limit_order</code> accepts the same arguments as <code class="csharp">LimitOrder</code><code class="python">limit_order</code>. To relate the order requests, use the following methods:</p>

<table class="table qc-table">
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="csharp">request.Triggers(children)</code><code class="python">request.triggers(children)</code></td>
<td>The request triggers the child orders when it completely fills (OTO).</td>
</tr>
<tr>
<td><code class="csharp">request.Bracket(takeProfitPrice, stopLossPrice)</code><code class="python">request.bracket(take_profit_price, stop_loss_price)</code></td>
<td>The request triggers a take-profit order and a stop-loss order that cancel each other.</td>
</tr>
<tr>
<td><code class="csharp">OrderFactory.OneCancelsOther(requests)</code><code class="python">order_factory.one_cancels_other(requests)</code></td>
<td>The first fill of a request cancels the others (OCO).</td>
</tr>
<tr>
<td><code class="csharp">OrderFactory.OneUpdatesOther(requests)</code><code class="python">order_factory.one_updates_other(requests)</code></td>
<td>A partial fill of a request reduces the quantity of the others (OUO).</td>
</tr>
</tbody>
</table>

<p>The <code class="csharp">Triggers</code><code class="python">triggers</code> and <code class="csharp">Bracket</code><code class="python">bracket</code> methods return the same request. The <code class="csharp">OneCancelsOther</code><code class="python">one_cancels_other</code> and <code class="csharp">OneUpdatesOther</code><code class="python">one_updates_other</code> methods return the list of requests. You can pass the result of one method to another to build any composition. To place the orders, pass any request of the set to the <code class="csharp">Order</code><code class="python">order</code> method. The method places every order in the set and returns their order tickets, with each parent before the orders it triggers.</p>

<div class="section-example-container">
<pre class="csharp">// A limit entry that triggers a take profit and a stop loss that cancel each other.
var entry = OrderFactory.LimitOrder(_symbol, 100, price * 0.999m);
var takeProfit = OrderFactory.LimitOrder(_symbol, -100, price * 1.02m);
var stopLoss = OrderFactory.StopMarketOrder(_symbol, -100, price * 0.99m);
entry.Triggers(OrderFactory.OneCancelsOther(takeProfit, stopLoss));
var tickets = Order(entry);</pre>
<pre class="python"># A limit entry that triggers a take profit and a stop loss that cancel each other.
entry = self.order_factory.limit_order(self._symbol, 100, price * 0.999)
take_profit = self.order_factory.limit_order(self._symbol, -100, price * 1.02)
stop_loss = self.order_factory.stop_market_order(self._symbol, -100, price * 0.99)
entry.triggers(self.order_factory.one_cancels_other(take_profit, stop_loss))
tickets = self.order(entry)</pre>
</div>

<p>You can submit each order request once. After you submit the request, its <code class="csharp">OrderId</code><code class="python">order_id</code> property holds the order Id. To get the order ticket of a request, <a href='/docs/v2/writing-algorithms/trading-and-orders/order-management/transaction-manager#02-Get-a-Single-Order-Ticket'>get it from the transaction manager</a>.</p>

<div class="section-example-container">
<pre class="csharp">var stopLossTicket = Transactions.GetOrderTicket(stopLoss.OrderId);</pre>
<pre class="python">stop_loss_ticket = self.transactions.get_order_ticket(stop_loss.order_id)</pre>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<p>The combo methods of the order factory return a list with one order request for each leg. LEAN treats the legs of a combo order as a single member of the set. Pass all the legs whenever you relate or submit a combo order. When a combo order is the parent of an OTO set, LEAN triggers the child orders when all the legs completely fill. To use a combo order as the parent, pass the list of legs to the <code class="csharp">OneTriggersOtherOrder</code><code class="python">one_triggers_other_order</code> method. The <code class="csharp">Bracket</code><code class="python">bracket</code> method doesn't support combo orders.</p>

<div class="section-example-container">
<pre class="csharp">// Buy a butterfly spread and sell it when its net price reaches the take-profit level.
var legs = new List&lt;Leg&gt;
{
Leg.Create(calls[0].Symbol, 1),
Leg.Create(calls[1].Symbol, -2),
Leg.Create(calls[2].Symbol, 1)
};
var entry = OrderFactory.ComboMarketOrder(legs, 2);
var takeProfit = OrderFactory.ComboLimitOrder(legs, -2, takeProfitPrice);
var tickets = OneTriggersOtherOrder(entry, takeProfit);</pre>
<pre class="python"># Buy a butterfly spread and sell it when its net price reaches the take-profit level.
legs = [
Leg.create(calls[0].symbol, 1),
Leg.create(calls[1].symbol, -2),
Leg.create(calls[2].symbol, 1)
]
entry = self.order_factory.combo_market_order(legs, 2)
take_profit = self.order_factory.combo_limit_order(legs, -2, take_profit_price)
tickets = self.one_triggers_other_order(entry, take_profit)</pre>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<p>Each contingent order has its own <a href="/docs/v2/writing-algorithms/trading-and-orders/order-management/order-tickets">order ticket</a>, which fills and closes independently. A child order that waits for its parent to fill has the <code class="csharp">OrderStatus.Submitted</code><code class="python">OrderStatus.SUBMITTED</code> status. To check if the brokerage still holds the order, use the <code class="csharp">IsWaitingForTrigger</code><code class="python">is_waiting_for_trigger</code> property of the <code class="csharp">Contingency</code><code class="python">contingency</code> on the order ticket.</p>

<div class="section-example-container">
<pre class="csharp">foreach (var ticket in tickets)
{
Debug($"{ticket.OrderId} held: {ticket.Contingency.IsWaitingForTrigger}; Quantity filled: {ticket.QuantityFilled}");
}</pre>
<pre class="python">for ticket in tickets:
self.debug(f"{ticket.order_id} held: {ticket.contingency.is_waiting_for_trigger}; Quantity filled: {ticket.quantity_filled}")</pre>
</div>

<p>The <code class="csharp">Contingency</code><code class="python">contingency</code> property is an <code>OrderContingency</code> object, which has the following attributes:</p>
<div data-tree='QuantConnect.Orders.OrderContingency'></div>

<p>The <code class="csharp">Links</code><code class="python">links</code> property holds a <code>ContingencyLink</code> object for each relationship of the order, which has the following attributes:</p>
<div data-tree='QuantConnect.Orders.ContingencyLink'></div>

<p>The <code class="csharp">GetOpenOrdersRemainingQuantity</code><code class="python">get_open_orders_remaining_quantity</code> method of the <a href='/docs/v2/writing-algorithms/trading-and-orders/order-management/transaction-manager#06-Get-Remaining-Order-Quantity'>transaction manager</a> excludes the orders that wait for their parent to fill. At most one order of an OCO or OUO set fills, so the method includes only the largest remaining quantity of each set.</p>
Loading