# Order Execution Service
This service allows you to place, modify, cancel, and confirm orders for various asset types.
## Setup
First, ensure you have an initialized `TradeStationClient`:
```python
import asyncio
from dotenv import load_dotenv
from tradestation.client import TradeStationClient
from tradestation.ts_types.order_execution import OrderRequest, OrderReplaceRequest, GroupOrderRequest # etc.
# Load environment variables
load_dotenv()
# Create the client
client = TradeStationClient()
# Access the order execution service
order_execution = client.order_execution
# --- Your code using order_execution methods goes here ---
# Remember to close the client when finished
async def main():
# --- Get account ID first ---
accounts = await client.brokerage.get_accounts()
if not accounts:
print("No accounts found. Cannot proceed.")
await client.close()
return
# Use the first available account ID for examples
account_id = accounts[0].AccountID
print(f"Using Account ID: {account_id}")
# --- Place order example ---
# try:
# market_order = OrderRequest(
# AccountID=account_id,
# Symbol="F",
# Quantity="1",
# OrderType="Market",
# TradeAction="BUY",
# TimeInForce={"Duration": "DAY"},
# Route="Intelligent"
# )
# order_response = await order_execution.place_order(market_order)
# print(f"Order placed: {order_response}")
# except Exception as e:
# print(f"Error placing order: {e}")
await client.close()
if __name__ == "__main__":
asyncio.run(main())
```
**Note:** Many examples require an `AccountID`. You can retrieve this using the `BrokerageService.get_accounts()` method.
---
## Methods
### `place_order(request)`
Places a single order (Market, Limit, Stop Market, Stop Limit).
* **Parameters:**
* `request` (`OrderRequest`): An `OrderRequest` object containing all necessary order parameters (AccountID, Symbol, Quantity, OrderType, TradeAction, TimeInForce, Route, etc.).
* **Returns:** `OrderResponse` containing the OrderID and status.
* **Example:** (See `examples/OrderExecution/place_and_cancel_order.py`)
```python
# (Requires account_id)
market_order = OrderRequest(
AccountID=account_id,
Symbol="F", # Example symbol
Quantity="1",
OrderType="Market",
TradeAction="BUY",
TimeInForce={"Duration": "DAY"},
Route="Intelligent"
)
try:
order_response = await order_execution.place_order(market_order)
print(f"Market Order Response: {order_response}")
# Store order_response.Orders[0].OrderID for cancellation/replacement
except Exception as e:
print(f"Error placing order: {e}")
```
### `replace_order(order_id, request)`
Replaces an existing, open order with new parameters.
* **Parameters:**
* `order_id` (`str`): The ID of the order to replace (without dashes).
* `request` (`OrderReplaceRequest`): An `OrderReplaceRequest` object containing the modified order parameters (e.g., new Quantity, LimitPrice).
* **Returns:** `ReplaceOrderResponse` containing the new OrderID and status.
* **Example:** (See `examples/OrderExecution/place_replace_cancel_order.py`)
```python
# Assume limit_order_id is the ID of an existing open limit order
# (Requires account_id)
replace_request = OrderReplaceRequest(
AccountID=account_id,
Symbol="MSFT", # Must match original order
Quantity="15", # New quantity
OrderType="Limit", # Must match original order
LimitPrice="295.00", # New limit price
TradeAction="BUY", # Must match original order
TimeInForce={"Duration": "GTC"},
Route="Intelligent"
)
try:
replace_response = await order_execution.replace_order(limit_order_id, replace_request)
print(f"Replace Order Response: {replace_response}")
except Exception as e:
print(f"Error replacing order {limit_order_id}: {e}")
```
### `confirm_order(request)`
Creates an Order Confirmation *without* placing the order. Returns estimated cost and commission.
* **Parameters:**
* `request` (`OrderRequest`): The order request details to confirm.
* **Returns:** `GroupOrderConfirmationResponse` containing estimated cost and commission.
* **Example:** (See `examples/OrderExecution/confirm_order.py`)
```python
# (Requires account_id)
order_to_confirm = OrderRequest(
AccountID=account_id,
Symbol="AAPL",
Quantity="10",
OrderType="Limit",
LimitPrice="180.00",
TradeAction="BUY",
TimeInForce={"Duration": "DAY"},
Route="Intelligent"
)
try:
confirmation = await order_execution.confirm_order(order_to_confirm)
print("Order Confirmation Details:")
if confirmation.Confirmations:
conf = confirmation.Confirmations[0]
print(f"- Estimated Cost: {conf.EstimatedCost}")
print(f"- Commission: {conf.CommissionFee}")
print(f"- Buying Power Effect: {conf.BuyingPowerEffect}")
else:
print("Could not get confirmation details.")
except Exception as e:
print(f"Error confirming order: {e}")
```
### `cancel_order(order_id)`
Sends a cancellation request for an open order.
* **Parameters:**
* `order_id` (`str`): The ID of the order to cancel (without dashes).
* **Returns:** `CancelOrderResponse` containing the OrderID and cancellation status.
* **Example:** (See `examples/OrderExecution/place_and_cancel_order.py`)
```python
# Assume market_order_id contains the ID from a placed order
# if market_order_id:
# try:
# # Allow time for order to potentially reach exchange
# await asyncio.sleep(2)
# cancel_response = await order_execution.cancel_order(market_order_id)
# print(f"Cancel Order Response: {cancel_response}")
# except Exception as e:
# print(f"Error cancelling order {market_order_id}: {e}")
```
### `confirm_group_order(request)`
Creates an Order Confirmation for a group order (OCO or Bracket) *without* placing it. Returns estimated costs for each order in the group.
* **Parameters:**
* `request` (`GroupOrderRequest`): A `GroupOrderRequest` object containing the `Type` ("OCO" or "BRK") and a list of `Orders` (each an `OrderRequest`).
* **Returns:** `GroupOrderConfirmationResponse` containing confirmations for each order in the group.
* **Example:** (See `examples/OrderExecution/confirm_group_order.py`)
```python
# (Requires account_id)
oco_order1 = OrderRequest(...)
oco_order2 = OrderRequest(...)
group_request = GroupOrderRequest(
Type="OCO",
Orders=[oco_order1, oco_order2]
)
try:
group_confirmation = await order_execution.confirm_group_order(group_request)
print("Group Order Confirmation Details:")
for conf in group_confirmation.Confirmations:
print(f"- Order Est Cost: {conf.EstimatedCost}, Commission: {conf.CommissionFee}")
except Exception as e:
print(f"Error confirming group order: {e}")
```
### `place_group_order(request)`
Places a group order (OCO or Bracket).
* **Parameters:**
* `request` (`GroupOrderRequest`): The group order request containing `Type` and `Orders`.
* **Returns:** `GroupOrderResponse` containing responses for each individual order placed within the group.
* **Example:** (See `examples/OrderExecution/place_and_cancel_group_order.py`)
```python
# (Requires account_id)
# Build bracket_order_entry, bracket_order_profit, bracket_order_stoploss as OrderRequest objects
bracket_request = GroupOrderRequest(
Type="BRK",
Orders=[bracket_order_entry, bracket_order_profit, bracket_order_stoploss]
)
try:
group_response = await order_execution.place_group_order(bracket_request)
print("Place Group Order Response:")
for order_resp in group_response.Orders:
print(f"- OrderID: {order_resp.OrderID}, Status: {order_resp.Status}")
# Store order IDs if needed for cancellation
except Exception as e:
print(f"Error placing group order: {e}")
```
### `get_routes()`
Returns a list of valid routes that can be specified when placing an order.
* **Parameters:** None
* **Returns:** `Routes` object containing a list of available routes.
* **Example:** (See `examples/OrderExecution/get_routes.py`)
```python
routes_response = await order_execution.get_routes()
print("Available Routes:")
for route in routes_response.Routes:
print(f"- ID: {route.Id}, Name: {route.Name}, AssetTypes: {route.AssetTypes}")
```
### `get_activation_triggers()`
Gets a list of activation triggers that can be used when placing advanced orders (e.g., conditional orders).
* **Parameters:** None
* **Returns:** `ActivationTriggers` object containing a list of available triggers.
* **Example:** (See `examples/OrderExecution/get_activation_triggers.py`)
```python
triggers_response = await order_execution.get_activation_triggers()
print("Available Activation Triggers:")
for trigger in triggers_response.ActivationTriggers:
print(f"- Name: {trigger.Name}, DisplayName: {trigger.DisplayName}")
```
---
**Important Considerations:**
* **Order IDs:** When cancelling or replacing orders, ensure you provide the `OrderID` *without* any dashes.
* **Group Orders:** Bracket orders placed via `place_group_order` cannot be updated as a single transaction; each leg must be replaced individually using `replace_order`.
* **Error Handling:** Always wrap API calls in `try...except` blocks to handle potential API errors (e.g., invalid parameters, rate limits, non-cancellable orders).
* **Account ID:** Most methods require a valid `AccountID`. Retrieve this using `BrokerageService.get_accounts()`.