Skip to navigation

Place Order

View as MarkdownOpen in Claude

Introduction

Orders are submitted via the EClient.placeOrder method.

Immediately after an order is submitted correctly, the TWS will start sending events concerning the order’s activity via EWrapper.openOrder and EWrapper.orderStatus.

Advisors executing allocation orders will receive execution details and commissions for the allocation order itself. To receive allocation details and commissions for a specific subaccount EClient.reqExecutions can be used.

An order can be sent to TWS but not transmitted to the IB server by setting the Order.Transmit flag in the order class to False. Untransmitted orders will only be available within that TWS session (not for other usernames) and will be cleared on restart. Also, they can be cancelled or transmitted from the API but not viewed while they remain in the “untransmitted” state.


Place Order

EClient.placeOrder(id, contract, order)

Places or modifies an order.

id
int

The order’s unique identifier. If a new order is placed with an order ID less than or equal to the order ID of a previous order an error will occur.

contract
Contract

The order’s contract.

order
Order

The order object.


self.placeOrder(orderId, contract, order)

Receive Open Orders

EWrapper.openOrder(orderId, contract, order, orderState)

Bound orders for the current client ID automatically update in real-time. Also can be called explicitly from EClient.reqOpenOrders

orderId
integer

The order’s unique id

<ParamField path=“contract” type=“Contract” The order’s Contract. </ParamField>

<ParamField path=“order” type=“Order” The currently active Order. </ParamField>

orderState
OrderState

The order’s OrderState


def openOrder(self, orderId: OrderId, contract: Contract, order: Order, orderState: OrderState):
print(orderId, contract, order, orderState)

Order Placement Considerations

When placing orders via the API and building a robust trading system, it is important to monitor for callback notifications, specifically for EWrapper.error, EWrapper.orderStatus changes, EWrapper.openOrder warnings, and EWrapper.execDetails to ensure proper operation.

If you experience issues with orders you place via the API, such as orders not filling, the first thing to check is what these callbacks returned. Your order may have been rejected or cancelled. If needed, see the API Log section for information on obtaining your API logs or submitting them for review.

Common cases of order rejections, cancellations, and warnings, and the corresponding message returned:

  • If an order is subject to a large size (LGSZ) reject, the API client would receive Error (201) via EWrapper.error. The error text would indicate that order size too large and suggest another smaller size.

  • If an order is subject to price checks the client may receive status (cancelled) + Error (202) via EWrapper.orderStatus and EWrapper.error. The error text would indicate the price is too far from current price.

  • The client may receive warning Text via EWrapper.openOrder indicating that the order could be subject to price capping.


Order Precautions

By default, the Trader Workstation implements several precautionary settings that will notify customers of potential order risks to make sure users are well informed before transmitting orders. As a result, customers will typically need to acknowledge a precautionary message and manually transmit the orders through the Trader Workstation. These precautionary messages may be disabled if the user is comfortable and aware of the behavior they are disabling.

Disabling Warning Messages

  1. Log in to the Trader Workstation
  2. Open the Global Configuration by selecting the Cog Wheel icon in the top right corner
  3. Navigate to the “Messages” section on the left.
  4. Carefully read each message before disabling it. You can then disable the warning by unchecking the box on the right of the message description.

Modifying Precautionary Settings

  1. Log in to the Trader Workstation
  2. Open the Global Configuration by selecting the Cog Wheel icon in the top right corner
  3. Navigate to the “Presets” section on the left
  4. Select the instrument(s) you are trading
  5. Carefully read each setting before making changes to it. You may modify the values inside the “Precautionary Settings” settings to be more or less restrictive. You may also set the value to ‘0’ to disable the precaution entirely.

Combo Orders

A user may create an order for a combination of symbols, referred to as a Spread or Combo, by the use of a Spread Contract.

Spreads may be priced on a per-leg basis or a complete order.

  • Combo orders may only use price-per-leg on with two legs in a Non-Guaranteed spread.
  • Combo orders with more than 2 legs may only be placed with a price for the overall order and must not be NonGuaranteed.

Combo Price Per Leg

Combination orders may be priced per-leg with no more than 2 legs in a NonGuaranteed order. This is accomplished with the OrderComboLeg class and defining a price in each object. The OrderComboLeg should then be added to the Order object’s OrderComboLegs attribute in an array.

order = Order()
order.orderType = "LMT"
orderLeg1 = OrderComboLeg()
orderLeg1.price = 222
orderLeg2 = OrderComboLeg()
orderLeg2.price = 333
order.orderComboLegs = [orderLeg2, orderLeg1]

Price Overall Order

To price an overall order, users would only need to define the lmtPrice or auxPrice values within the Order object as they would if trading an individual contract.

order = Order()
order.orderType = "LMT"
order.lmtPrice = 555

Adding a Profit Taker and Stop Loss

Users are able to bracket their order in two distinct ways:

  • Manually construct each child of the parent. See Bracket Orders for more details.
  • Adding child orders based on TWS Presets.

Adding a profit taker and stop loss from the same order object automates the order bracket process so that only order ID needs to be provided. This is best for users looking to trade with identical bracket parameters across orders.

Profit Taker

A profit taker can be added to an order using the ptOrderId and ptOrderType Order attributes.

PtOrderId must be a unique order identifier. Consider using EWrapper.nextValidId.

PtOrderType must always be set to “PRESET”. Be sure to review your Presets in Trader Workstation prior to submitting orders as the Profit taker details will mirror these details as set.

order = Order()
order.orderId = 10000
order.action = "BUY"
order.orderType = "LMT"
order.totalQuantity = 100
order.lmtPrice = 256
order.tif = "DAY"
order.ptOrderType = "PRESET"
order.ptOrderId = 10001

Stop Loss

A stop loss can be added to an order using the slOrderId and slOrderType Order attributes.

SlOrderId must be a unique order identifier. Consider using EWrapper.nextValidId.

SlOrderType must always be set to “PRESET”. Be sure to review your Presets in Trader Workstation prior to submitting orders as the Stop loss details will mirror these details as set.

order = Order()
order.orderId = 10000
order.action = "BUY"
order.orderType = "LMT"
order.totalQuantity = 100
order.lmtPrice = 256
order.tif = "DAY"
order.slOrderType = "PRESET"
order.slOrderId = 10002

Trading the Overnight Session

In the event a user would like to designate a trade to take place during the Overnight trading hours, the Order object must set includeOvernight set to True and optionally set the exchange field of Contract object to OVERNIGHT.

Routing Exclusively to the Overnight Market

Users that would like to route orders to Overnight without trading during the regular session must designate the exchange value of a Contract object as "OVERNIGHT".

contract = Contract()
contract.exchange = "OVERNIGHT"

Routing as Overnight+DAY

Users that would like to route orders to Overnight+DAY to trade during the day and the overnight session must set the Order Object’s includeOvernight value as True.

contract = Contract()
contract.exchange = "SMART"
order = Order()
order.includeOvernight = True
Orders routed to the OVERNIGHT exchange with order.includeOvernight = True will behave as "OVERNIGHT+DAY".