---
title: "Order Tickets"
description: "When you create an order, you get an OrderTicket object to manage your order."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/order-management/order-tickets
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/order-management/order-tickets.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/22%20Trading%20and%20Orders/02%20Order%20Management/02%20Order%20Tickets
modified: 2026-11-01
index: https://www.quantconnect.com/llms.txt
---

# Order Tickets

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Writing Algorithms](https://www.quantconnect.com/docs/v2/writing-algorithms.md) > Trading and Orders > Order Management > Order Tickets

> Code examples are shown in Python. Append `?lang=csharp` to this URL for the C# version of this page.

## Introduction

When you create an order, you get an `OrderTicket` object to manage your order.

## Properties

`OrderTicket` objects have the following attributes:

*Members of `QuantConnect.Orders.OrderTicket` (JSON): https://www.quantconnect.com/services/inspector?type=T:QuantConnect.Orders.OrderTicket&language=python*

## Track Orders

As the state of your order updates over time, your order ticket automatically updates. To track an order, you can check any of the preceding order ticket properties.

To get an order field, call the `get` method with an `OrderField`.

```python
def initialize(self) -> None:
    self._symbol = self.add_equity("SPY").symbol
    self._ticket = None

def on_data(self, slice: Slice) -> 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)
```

The `OrderField` enumeration has the following members:

*Members of `QuantConnect.Orders.OrderField` (JSON): https://www.quantconnect.com/services/inspector?type=T:QuantConnect.Orders.OrderField&language=python*

To check whether an order is open, closed, or filled, compare the order status to the `OrderStatus` enumeration members. An order is closed when its status is filled, canceled, or invalid.

```python
is_closed = self._ticket.status in (OrderStatus.FILLED, OrderStatus.CANCELED, OrderStatus.INVALID)
is_open = not is_closed
is_fill = self._ticket.status in (OrderStatus.FILLED, OrderStatus.PARTIALLY_FILLED)
```

In addition to using order tickets to track orders, you can receive [order events](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/order-events.md) through the `on_order_event` event handler.

## Update Orders

To update an order, use its `OrderTicket`. You can update other orders until they are filled or the brokerage prevents modifications. You just can't update orders during [warm up](https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/warm-up-periods.md) and [initialization](https://www.quantconnect.com/docs/v2/writing-algorithms/initialization.md).

### Updatable Properties

The specific properties you can update depends on the order type. The following table shows the properties you can update for each order type.

| Order Type Order Type | Updatable Properties Tag | Quantity | LimitPrice | TriggerPrice | StopPrice |
| --- | --- | --- | --- | --- | --- |
| Market Order |  |  |  |  |  |
| Limit Order | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  |  |
| Limit If Touched Order | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  |
| Stop Market Order | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  |  | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |
| Stop Limit Order | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |
| Market On Open Order | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  |  |  |
| Market On Close Order | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  |  |  |

### Update Methods

To update an order, pass an `UpdateOrderFields` object to the `update` method. The method returns an `OrderResponse` to signal the success or failure of the update request.

```python
def initialize(self) -> None:
    self._symbol = self.add_equity("SPY").symbol
    self._ticket = None

def on_data(self, slice: Slice) -> 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")
```

To update individual fields of an order, call any of the following methods:

- `update_limit_price`
- `update_quantity`
- `update_stop_price`
- `update_tag`

```python
response = ticket.update_limit_price(limit_price, tag)

response = ticket.update_quantity(quantity, tag)

response = ticket.update_stop_price(stop_price, tag)

response = ticket.update_tag(tag)
```

### Update Order Requests

When you update an order, LEAN creates an `UpdateOrderRequest` object, which have the following attributes:

*Members of `QuantConnect.Orders.UpdateOrderRequest` (JSON): https://www.quantconnect.com/services/inspector?type=T:QuantConnect.Orders.UpdateOrderRequest&language=python*

To get a list of `UpdateOrderRequest` objects for an order, call the `update_requests` method.

```python
update_requests = ticket.update_requests()
```

### Workaround for Brokerages That Don't Support Updates

Not all brokerages fully support order updates. To check what functionality your brokerage supports for order updates, see the **Orders** section of the documentation for your [brokerage model](https://www.quantconnect.com/docs/v2/writing-algorithms/reality-modeling/brokerages/supported-models.md). If your brokerage doesn't support order updates and you want to update an order, [cancel the order](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/order-management/order-tickets.md#05-Cancel-Orders). When you get an [order event](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/order-events.md) that confirms the order is no longer active, place a new order.

```python
def initialize(self) -> None:
    self._symbol = self.add_equity("SPY").symbol
    self._ticket = None

def on_data(self, slice: Slice) -> 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) -> None:
    if (self._ticket and order_event.order_id == self._ticket.order_id and
        order_event.status == OrderStatus.CANCELED):
        # Place a new order
        quantity = self._ticket.quantity - self._ticket.quantity_filled
        limit_price = self.securities[self._ticket.symbol].price + 1
        self._ticket = self.limit_order(self._ticket.symbol, quantity, limit_price)
```

## Cancel Orders

To cancel an order, call the `cancel` method on the `OrderTicket`. The method returns an `OrderResponse` object to signal the success or failure of the cancel request.

```python
def initialize(self) -> None:
    self._symbol = self.add_equity("SPY").symbol
    self._ticket = None

def on_data(self, slice: Slice) -> 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 < 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")
```

You can't cancel market orders because they are immediately transmitted to the brokerage. You also can't cancel any orders during [warm up](https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/warm-up-periods.md) and [initialization](https://www.quantconnect.com/docs/v2/writing-algorithms/initialization.md).

When you cancel an order, LEAN creates a `CancelOrderRequest`, which have the following attributes:

*Members of `QuantConnect.Orders.CancelOrderRequest` (JSON): https://www.quantconnect.com/services/inspector?type=T:QuantConnect.Orders.CancelOrderRequest&language=python*

To get the `CancelOrderRequest` for an order, call the `cancel_order_request` method. The method returns `None` if the order hasn't been cancelled.

```python
request = ticket.cancel_order_request()
```

## Order Response

When you update or cancel an order, LEAN returns an `OrderReponse` object, which have the following attributes:

*Members of `QuantConnect.Orders.OrderResponse` (JSON): https://www.quantconnect.com/services/inspector?type=T:QuantConnect.Orders.OrderResponse&language=python*

If your order changes fail, check the `ErrorCode` or `ErrorMessage`. For more information about specific order errors, see the [Order Response Error Reference](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/order-errors.md#20-Order-Response-Error-Reference).

To get most recent order response, call the `get_most_recent_order_response` method.

```python
response = ticket.get_most_recent_order_response()
```

## Examples

The following examples demonstrate some common practices for order ticket management.

### Example 1: Timed Exit

The following algorithm is an EMA-crossover strategy. Using the filled time of the order ticket, we can control to exit the position after 45 minutes.

```python
class OrderTicketExampleAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self._symbol = self.add_equity("SPY").symbol
        self._ticket = None
        # Set up EMA indicator for trade signal generation.
        self._ema = self.ema("SPY", 20, Resolution.DAILY)
        # Warm up the indicator for its readiness to use immediately.
        self.warm_up_indicator(self._symbol, self._ema)

    def on_data(self, slice: Slice) -> None:
        bar = slice.bars.get(self._symbol)
        # Place order if not order yet and save the order ticket for later retrival.
        if not self._ticket and bar:
            # EMA crossover: buy if price is above EMA, which indicate uptrend.
            if self._ema.current.value < bar.close:
                self._ticket = self.limit_order("SPY", 100, slice.bars[self._symbol].close * 0.995)
            # EMA crossover: sell if price is below EMA, which indicate down trend.
            else:
                self._ticket = self.limit_order("SPY", -100, slice.bars[self._symbol].close * 1.005)
        # Exit position if it is in the portfolio for more than 45 minutes.
        elif self._ticket and self._ticket.time + timedelta(minutes=45) < self.utc_time:
            self.liquidate()
            self._ticket = None
```

### Example 2: Intraday Stop Loss

The following algorithm demonstrates an intraday long position with a 10% stop loss order. Before the market closes, cancel the stop loss order if it is not filled and exit the position at market close with a market on close order.

```python
class OrderTicketExampleAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self._symbol = self.add_equity("QQQ").symbol
        self._ticket = None
        self._day = -1

        # Schedule an event to handle exiting position before market close if stop loss is not hit.
        # Market on close order requires ordering 15 minutes before market close.
        self.schedule.on(
            self.date_rules.every_day(self._symbol),
            self.time_rules.before_market_close(self._symbol, 16),
            self.exit_position
        )

    def on_data(self, slice: Slice) -> None:
        bar = slice.bars.get(self._symbol)
        # Place order if not invested. Make sure only trade once a day to avoid chasing the loss.
        if not self.portfolio.invested and self._day != slice.time.day and bar:
            self.market_order(self._symbol, 10)
            # Update the day variable to avoid repeat ordering.
            self._day = slice.time.day

    def on_order_event(self, order_event: OrderEvent) -> None:
        # Make sure to order the stop loss order on the filled market order only.
        if order_event.status == OrderStatus.FILLED and order_event.fill_quantity > 0:
            # Place a 10% stop loss order to avoid large loss. Save the order ticket for tracking its status later.
            self._ticket = self.stop_market_order(order_event.symbol, -order_event.fill_quantity, order_event.fill_price*0.9)

    def exit_position(self) -> None:
        # Only need to cancel the order and handle exit position if the stop loss order is not fully filled.
        if self._ticket and self._ticket.status != OrderStatus.FILLED:
            self._ticket.cancel()
            # Market on close order to exit position at market close with the remaining quantity.
            self.market_on_close_order(self._symbol, -10 - self._ticket.quantity_filled)
```

### Example 3: Crypto Trailing Stop Order

This example trades BTCUSD with a similar logic of Example 2, but apply a trailing stop loss of 10% instead. Crypto exchanges does not support trailing stop loss order. Yet, we can cancel and reorder a stop loss order with the updated stop loss price. If the market price of the crypto pair is above the previous level, update the stop loss order by the above.

```python
class OrderTicketExampleAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        # Set the market argument to trade in specific exchange.
        self._symbol = self.add_crypto("BTCUSD", market=Market.COINBASE).symbol
        # A variable to hold the stop loss order to track if it should be updated.
        self._ticket = None
        # A day variable to avoid over-ordering (trade once per day)
        self._day = -1
        # A variable to hold the price of the high price in the lifetime of the open position for updating the stop loss price.
        self.high_price = 0
        # Update the stop loss when new high is 1% higher
        self.update_step = 1.01

    def on_data(self, slice: Slice) -> None:
        bar = slice.bars.get(self._symbol)
        if not bar: return
        # Place order if not invested. Make sure only trade once a day to avoid chasing the loss.
        if not self.portfolio.invested and self._day != self.time.day:
            self.market_order(self._symbol, 1)
            # Place a 10% stop loss order to avoid large loss. Save the order ticket for tracking its status later.
            self._ticket = self.stop_market_order(self._symbol, -1, bar.close*0.9)
            self.high_price = bar.high * self.update_step
            # Update the day variable to avoid repeat ordering.
            self._day = self.time.day

        # Update the trailing stop order. Since order updating is not supported in crypto exchanges, we cancel and reorder.
        # Trailing stop price will only need to be updated when the market price is higher than the current price.
        if self._ticket and self._ticket.status in [OrderStatus.SUBMITTED, OrderStatus.PARTIALLY_FILLED] and bar.high > self.high_price:
            self._ticket.cancel()
            self._ticket = self.stop_market_order(self._symbol, -self.portfolio[self._symbol].quantity, bar.high*0.9)
            self.high_price = bar.high * self.update_step
```

### Other Examples

For more examples, see the following algorithms:

**Demonstration Algorithms**

- [OrderTicketDemoAlgorithm.py](https://github.com/QuantConnect/Lean/blob/master/Algorithm.Python/OrderTicketDemoAlgorithm.py) (Python)
