Skip to content

Commit

Permalink
Merge pull request #1955 from QuantConnect/feature-order-tickets-exam…
Browse files Browse the repository at this point in the history
…ples

Writing Algorithms / Trading and Orders / Order Management / Order Tickets Examples
  • Loading branch information
AlexCatarino authored Nov 13, 2024
2 parents f3fd97e + 1a53a2f commit c0a4077
Show file tree
Hide file tree
Showing 4 changed files with 421 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,38 @@
<p>To get an order field, call the <code class="csharp">Get</code><code class="python">get</code> method with an <code>OrderField</code>.</p>

<div class="section-example-container">
<pre class="csharp">var limitPrice = ticket.Get(OrderField.LimitPrice);</pre>
<pre class="python">limit_price = ticket.get(OrderField.LIMIT_PRICE)</pre>
<pre class="csharp">private Symbol _symbol;
private OrderTicket _ticket;

public override void Initialize()
{
_symbol = AddEquity("SPY").Symbol;
}

public override void OnData(Slice slice)
{
// Place order if not invested and save the order ticket for later retrival.
if (!Portfolio.Invested && slice.Bars.TryGetValue(_symbol, out var bar))
{
_ticket = LimitOrder(_symbol, 10, bar.Close);
}
// Get the limit price if the order is filled.
else if (Portfolio.Invested)
{
var limitPrice = _ticket.Get(OrderField.LimitPrice);
}
}</pre>
<pre class="python">def initialize(self) -&gt; None:
self._symbol = self.add_equity("SPY").symbol
self._ticket = None

def on_data(self, slice: Slice) -&gt; None:
# Place order if not invested and save the order ticket for later retrival.
if not self.portfolio.invested and self._symbol in slice.bars:
self._ticket = self.limit_order(self._symbol, 10, slice.bars[self._symbol].close)
# Get the limit price if the order is filled.
elif self.portfolio.invested:
limit_price = self._ticket.get(OrderField.LIMIT_PRICE)</pre>
</div>

<p>The <code>OrderField</code> enumeration has the following members:</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,33 +99,59 @@
</p>

<div class="section-example-container">
<pre class="csharp">// Create an order
var ticket = LimitOrder("SPY", 100, 221.05, tag: "New SPY trade");

// Update the order tag and limit price
var response = ticket.Update(new UpdateOrderFields()
{
Tag = "Our New Tag for SPY Trade",
LimitPrice = 222.00
});

// Check the OrderResponse
if (response.IsSuccess)
{
Debug("Order updated successfully");
<pre class="csharp">private Symbol _symbol;
private OrderTicket _ticket;

public override void Initialize()
{
_symbol = AddEquity("SPY").Symbol;
}

public override void OnData(Slice slice)
{
// Place order if not order yet and save the order ticket for later retrival.
if (_ticket == null && slice.Bars.TryGetValue(_symbol, out var bar))
{
_ticket = LimitOrder(_symbol, 10, bar.Close * 0.98m);
}
// If order is placed, update the limit price to be 90% of the orginal.
else if (_ticket != null && _ticket.Status == OrderStatus.Submitted)
{
// Update the order tag and limit price
var response = _ticket.Update(new UpdateOrderFields()
{
Tag = "Our New Tag for SPY Trade",
LimitPrice = _ticket.Get(OrderField.LimitPrice * 0.9m)
});

// Check if the update request is successfully submitted to the broker.
// Note that it may not represent the order is updated successfully: during the order updating process, it may be filled or canceled.
if (response.IsSuccess)
{
Debug("Order update request is submitted successfully");
}
}
}</pre>
<pre class="python"> # Create an order
ticket = self.limit_order("SPY", 100, 221.05, False, "New SPY trade")

# Update the order tag and limit price
updateSettings = UpdateOrderFields()
updateSettings.limit_price = 222.00
updateSettings.tag = "Limit Price Updated for SPY Trade"
response = ticket.update(updateSettings)

# Check the OrderResponse
if response.is_success:
self.debug("Order updated successfully")</pre>
<pre class="python">def initialize(self) -&gt; None:
self._symbol = self.add_equity("SPY").symbol
self._ticket = None

def on_data(self, slice: Slice) -&gt; None:
# Place order if not invested and save the order ticket for later retrival.
if not self._ticket and self._symbol in slice.bars:
self._ticket = self.limit_order("SPY", 100, slice.bars[self._symbol].close * 0.98)
# If order is placed, update the limit price to be 90% of the orginal.
elif self._ticket != None and self._ticket.status == OrderStatus.SUBMITTED:
# Update the order tag and limit price
update_settings = UpdateOrderFields()
update_settings.limit_price = self._ticket.get(OrderField.LIMIT_PRICE) * 0.9
update_settings.tag = "Limit Price Updated for SPY Trade"
response = self._ticket.update(update_settings)

# Check if the update request is successfully submitted to the broker.
# Note that it may not represent the order is updated successfully: during the order updating process, it may be filled or canceled.
if response.is_success:
self.debug("Order update request is submitted successfully")</pre>
</div>

<?
Expand All @@ -139,15 +165,32 @@
include(DOCS_RESOURCES."/order-types/update-requests.html");
?>

<h4>Workaround for Brokerages That Dont Support Updates</h4>
<h4>Workaround for Brokerages That Don't Support Updates</h4>

<p>Not all brokerages fully support order updates. To check what functionality your brokerage supports for order updates, see the <span class='page-section-name'>Orders</span> section of the documentation for your <a href="/docs/v2/writing-algorithms/reality-modeling/brokerages/supported-models">brokerage model</a>. If your brokerage doesn't support order updates and you want to update an order, <a href='/docs/v2/writing-algorithms/trading-and-orders/order-management/order-tickets#05-Cancel-Orders'>cancel the order</a>. When you get an <a href='/docs/v2/writing-algorithms/trading-and-orders/order-events'>order event</a> that confirms the order is no longer active, place a new order.</p>

<div class="section-example-container">
<pre class="csharp">public override void OnData(Slice slice)
<pre class="csharp">private Symbol _symbol;
private OrderTicket _ticket;

public override void Initialize()
{
// Cancel the order
_ticket.Cancel();
_symbol = AddEquity("SPY").Symbol;
}

public override void OnData(Slice slice)
{
// Place order if not order yet and save the order ticket for later retrival.
if (_ticket == null && slice.Bars.TryGetValue(_symbol, out var bar))
{
_ticket = LimitOrder(_symbol, 10, bar.Close);
}
// If order is placed, cancel the order and place a new one as substituent.
else if (_ticket != null && _ticket.Status == OrderStatus.Submitted)
{
// Cancel the order
_ticket.Cancel();
}
}

public override void OnOrderEvent(OrderEvent orderEvent)
Expand All @@ -162,11 +205,19 @@
_ticket = LimitOrder(_ticket.Symbol, quantity, limitPrice);
}
}</pre>
<pre class="python">def on_data(self, slice: Slice) -> None:
# Cancel the order
self._ticket.cancel()

def on_order_event(self, order_event: OrderEvent) -> None:
<pre class="python">def initialize(self) -&gt; None:
self._symbol = self.add_equity("SPY").symbol
self._ticket = None

def on_data(self, slice: Slice) -&gt; None:
# Place order if not invested and save the order ticket for later retrival.
if not self._ticket and self._symbol in slice.bars:
self._ticket = self.limit_order("SPY", 100, slice.bars[self._symbol].close)
# If order is placed, cancel the order and place a new one as substituent.
elif self._ticket != None and self._ticket.status == OrderStatus.SUBMITTED:
self._ticket.cancel()

def on_order_event(self, order_event: OrderEvent) -&gt; None:
if (self._ticket and order_event.order_id == self._ticket.order_id and
order_event.status == OrderStatus.CANCELED):
# Place a new order
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,51 @@
<p>To cancel an order, call the <code class="csharp">Cancel</code><code class="python">cancel</code> method on the <code>OrderTicket</code>. The method returns an <code>OrderResponse</code> object to signal the success or failure of the cancel request.</p>

<div class="section-example-container">
<pre class="csharp">// Create an order and save its ticket
var ticket = LimitOrder("SPY", 100, 221.05, tag: "SPY Trade to Cancel");
<pre class="csharp">private Symbol _symbol;
private OrderTicket _ticket;

// Cancel the order
var response = ticket.Cancel("Canceled SPY trade");
public override void Initialize()
{
_symbol = AddEquity("SPY").Symbol;
}

// Use the order response object to read the status
if (response.IsSuccess)
public override void OnData(Slice slice)
{
Debug("Order successfully canceled");
// Place order if not order yet and save the order ticket for later retrival.
if (_ticket == null && slice.Bars.TryGetValue(_symbol, out var bar))
{
_ticket = LimitOrder(_symbol, 10, bar.Close);
}
// If order is placed, cancel the order if it is not filled within 2 minutes.
else if (_ticket != null && _ticket.Time &lt;= slice.Time.AddMinutes(-2) && _ticket.Status == OrderStatus.Submitted)
{
// Cancel the order
var response = ticket.Cancel("Canceled SPY trade");

// Check if the cancel request is successfully submitted to the broker.
// Note that it may not represent the order is canceled successfully: during the order updating process, it may be filled.
if (response.IsSuccess)
{
Debug("Order cancel request successfully submitted");
}
}
}</pre>
<pre class="python"> # Create an order and save its ticket
ticket = self.limit_order("SPY", 100, 221.05, False, "SPY Trade to Cancel")

# Cancel the order
response = ticket.cancel("Canceled SPY Trade")

# Use the order response object to read the status
if response.is_success:
self.debug("Order successfully canceled")</pre>
<pre class="python">def initialize(self) -&gt; None:
self._symbol = self.add_equity("SPY").symbol
self._ticket = None

def on_data(self, slice: Slice) -&gt; None:
# Place order if not invested and save the order ticket for later retrival.
if not self._ticket and self._symbol in slice.bars:
self._ticket = self.limit_order("SPY", 100, slice.bars[self._symbol].close)
# If order is placed, cancel the order if it is not filled within 2 minutes.
elif self._ticket != None and self._ticket.time &lt; slice.time - timedelta(minutes=2) and self._ticket.status == OrderStatus.SUBMITTED:
response = self._ticket.cancel("Canceled SPY trade")

# Check if the cancel request is successfully submitted to the broker.
# Note that it may not represent the order is canceled successfully: during the order updating process, it may be filled.
if response.is_success:
self.debug("Order cancel request successfully submitted")</pre>
</div>

<p>You can't cancel market orders because they are immediately transmitted to the brokerage. You also can't cancel any orders during <a href='/docs/v2/writing-algorithms/historical-data/warm-up-periods'>warm up</a> and <a href='/docs/v2/writing-algorithms/initialization'>initialization</a>.</p>
Expand Down
Loading

0 comments on commit c0a4077

Please sign in to comment.