Hello, and welcome to this lesson on the Interactive Brokers Client Portal API. In this lesson, we will be discussing how to place market, limit, and stop orders. We will also be discussing order confirmation using the reply endpoint.
Placing a Market order
To begin, let’s start with placing a market order. I will start with the general framework, along with my method, orderRequest(). In the orderRequest() method, I will create the base_url variable, along with an endpoint variable, which should be set to ‘iserver/account/{accountId}/orders’.
Once we have built our URL, we will need to use a JSON body, so I will go ahead with constructing that. I will call it ‘json_body’ and set it equal to a set of curly brackets for the array value. Inside these brackets, I will need to set the “orders” field and set it to a list with an array inside. Then we need to create a few fields in this case including “conid, orderType, side, tif, quantity”. All available fields can be found on the client portal API documentation page under account/{accountID}/orders endpoint. With that said, I will use my AAPL conId. Then set “MKT” for market order, “buy” for side, “day” for “tif”, and finally, I will set my “quantity” to 10.
With the body set, I will create a reference to our coming request. I’ll create the variable ‘order_req’ and set it equal to requests.post. Here we can set the URL to our base_url+endpoint, verify to False and then the ‘json’ tag to the variable json_body.
You are welcome to explore the full return, but we will use json.dumps to help with the display. I can set order_json equal to “json.dumps(order_req.json()”, and then “indent=2”. After establishing our pretty print, I will print out the order_req.status_code and order_json variables.
Once we have added these initial parameters we can now run this code and view the returned values. Initially our status Response code [200] indicates that the request has succeeded.
In this case the values return are our unique system generated “order id”, “order status” and “encrypt message”. The order status presubmitted indicates that a simulated order type has been accepted by the IBKR system and this order has yet to be elected.
Placing a Limit order
As with our previously placed market order in this case we will need to define and change some additional parameters in the body. Here we can change the order type from MKT to LMT as this will now be a limit order. Since we are placing a limit order, we must also define a limit price by adding the price parameter. As mentioned previously a full list of order parameters is available on our documentation.
If we run this code, we will see a successful order placement, followed by our order_id and order status.
Placing a Stop order
A Stop order becomes a market order to buy or sell securities or commodities once the specified stop price is attained or penetrated. A Stop order is not guaranteed a specific execution price.
To create a Stop order, we will change the order type from “LMT” to “STP”. As with our limit order we need to define our STP price. We will still use our “price” field to designate our stop price. It is important to note that instead of the “price” field, STP_LMT and TRAIL orders will use the “auxPrice” field to designate a stop price.
In this case, if we run the code, we will receive a notable response. We can see a reply-id message along with a message clearly explaining that we are trying to submit a stop order and to be aware of the stop order precautions. It asks us whether we are sure we want to submit the order. This is a warning that requires we submit a confirmation message, similar to how they may appear in Trader Workstation. To approve this order and acknowledge the precaution, we can use the /iserver/reply/{replyid} endpoint.
Placing an order reply
Moving into a new file, orderReply.py, I can build out my initial framework. After that, I will use an orderReply() method structured like usual with a base_url and endpoint. I will set the endpoint variable to iserver/reply/ endpoint. I can create an ‘replyId’ variable and set it equal our our “id” field from the prior return. I can set a variable, reply_url, equal to all of these values joined together.
Then, I can create a json_body variable, which simply includes “confirmed”:True inside an array. Now I will just build our typical post request to the reply_url variable, passing our ‘verify=False’ and json_body variables. And to help read this, I can set up my json.dumps method once again. Printing out these values, I can see a 200 OK status, and our new status.
In some cases, you might receive another “id” and “message” value back. This is typical if more precautions are set. Simply feed these “id” values back into our reply program, and you should be able to approve these orders.
Thank you for watching this lesson on placing orders and order confirmations in the Client Portal API. If you found this lesson helpful, please check out our other lessons in the Client Portal API tutorial series.
Code Snippet – placeOrder
import requests import json import urllib3 # Ignore insecure error messages urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def orderRequest(): base_url = "https://localhost:5000/v1/api/" endpoint = "iserver/account/DU5240685/orders" json_body = { "orders": [ { "conid": 265598, "orderType": "STP", "price":185, "side": "SELL", "tif": "DAY", "quantity":10, } ] } order_req = requests.post(url = base_url+endpoint, verify=False, json=json_body) order_json = json.dumps(order_req.json(), indent=2) print(order_req.status_code) print(order_json) if __name__ == "__main__": orderRequest()
Code Snippet – orderReply.py
import requests import json import urllib3 # Ignore insecure error messages urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def orderRequest(): base_url = "https://localhost:5000/v1/api/" endpoint = "iserver/reply/" replyId = "7a45bf17-ae07-430f-9888-a4d79539aaa0" reply_url = "".join([base_url,endpoint,replyId]) json_body = { "confirmed":True } order_req = requests.post(url = reply_url, verify=False, json=json_body) order_json = json.dumps(order_req.json(), indent=2) print(order_req.status_code) print(order_json) if __name__ == "__main__": orderRequest()
do you allow short sales
D ou have a list of short stocks ??
Hello Yegal. If you don’t already hold a long position and enter a sell order, your order will be treated as a short sale (as accounts cannot simultaneously hold both a long and short position in the same security). A short position will reflect in your portfolio with a negative sign as a negative position. Other items of note regarding short selling can be found here: https://www.ibkr.com/faq?id=28230467. Additionally, we do have a short stock availability list which represents the inventory of shares which IBKR has available to lend and which other brokers have indicated that they have available to lend. https://www.ibkrguides.com/clientportal/support_shortstock.htm
How to set delayed market data?
In tws api it was ib.reqMarketDataType(3)
Hello Michael, thank you for reaching out. It is possible to set delayed market data. You can switch between live, Frozen, Delayed, and Delayed Frozen market data from Trader workstation by switching market data type via the IBApi.EClient.reqMarketDataType before making a market data request with reqMktData. The link below will provide you with more information.
https://interactivebrokers.github.io/tws-api/market_data_type.html
Hello, i want to setup a trailing-stop-buy-limit-order. In my mind its a buy-limit-order with a trailing price level. It should be used by buying at the moment of an shorttime price setback.
This is my order definition:
{ # Trailing-Stop-Buy-Limit-Order
“cOID”: f”{contract[‘cOID’]}”,
“conid”: contract[“conid”],
“orderType”: “TRAILLMT”,
“price”: round( # auxPrice failse
float(contract[“price”]) / 1.05, 2
), # Trail-Stop-Limit-Price
“trailingAmt”: 5,
“trailingType”: “%”, # “%” or “amt”
“side”: “BUY”,
“tif”: “GTC”, # Time in Force: GTC – Good till Cancelled
“quantity”: contract[“quantity”],
“listingExchange”: “SMART”,
}
I got an {‘error’: ‘Invalid order price fields’} .
Could you please support with more complex orders?
Kind regards
Hello, thank you for your feedback. Trailing Stop Limit orders assign the limit price using the “price” field, and the “auxPrice” will designate the stop trigger price. You can find this information in our documentation, here: https://www.ibkrcampusdev.wpengine.com/campus/ibkr-api-page/order-types/#trailing-stop-limit-order. If you ever have questions, please feel free to reach out to the Client Service department directly. We will look to incorporate additional order types in the series over time.
Hello, is there a way to dismiss confirm Message as Price Cap and 3% etc.. I tried to disable via TWS or IB Gateway but have no effect on Client Portal Rest APIs. Thank you
Hello Marco, thank you for reaching out. Please view this link for instructions to disable the “confirm” message for Client Portal APIs:
https://www.ibkrcampusdev.wpengine.com/campus/ibkr-api-page/cpapi/#place-order-reply
How to place an order for trading stock contracts?
Hello Ken, thank you for reaching out. You can view this FAQ with more information on how to place an order in TWS: https://www.ibkr.com/faq?id=23298941. Please reach back out if you have any more questions. We are here to help!
Not on TWS but Client Portal API.
Hello again, Ken. The Youtube video on the attached lesson has specific examples reviewing how to place a stock order on Client Portal API. If you need more assistance, please reach out to Client Services via web ticket and select “API”: https://www.interactivebrokers.com/sso/resolver?action=NEW_TICKET
They would be happy to help.
Hi, I’m using the Client Portal Web API and experiencing issues on placing an order for US stocks in the NASDAQ exchange. Can you provide some guidance why this request is receiving a error 400 – Contract does not match supplied contract parameters.
ContractId: ‘265598’,
CustomerOrderId: ‘1374d454-bd75-4217-a9d3-87e138019313_1708103199275’,
Quantity: 70,
OrderType: ‘Market’,
InstrumentType: ‘STK’,
TimeInForce: ‘DAY’,
Ticker: ‘AAPL’,
ListingExchange: ‘NASDAQ’,
Side: ‘BUY’
}
Hello Alex, thank you for reaching out. Thank you for reaching out. Please create a web ticket for this inquiry; we have a category specifically for “API.” One of our API experts will be happy to guide you! https://www.interactivebrokers.com/sso/resolver?action=NEW_TICKET
There appears to be a bug in your support request service. whenever I lodge a ticket I recieve this message
“Notice! We are sorry, but your request could not be processed at this time. Please try again later.”
Please advise how to send this request through
Thank you for taking the time to reach out, and please accept our apologies. We could not replicate the issue. Please send additional details so we can investigate further. We would appreciate the opportunity to turn around your experience.
I am having the same issue as Alex; when I log into the Secure Message Center I get this pop-up Warning message “We are sorry, but your request could not be processed at this time. Please try again later.” How can I get this fixed?
Thanks
Hello, thank you for reaching out. We have passed along this information to the appropriate team. If you are still experiencing issues, please contact Client Services by phone:
http://spr.ly/IBKR_ClientServicesCampus
How to place a market open buy order (bracket order) including stop profit and stop loss? and also how to change the stop profit and stop loss for an existing bracket order?
Hello, thank you for reaching out. To place a bracket market open buy order with a profit taker and stop loss in TWS:
Create a buy Market order and set it to activate on open.
In the Advanced panel, tick Bracket and define your profit taker and stop loss prices.
Transmit the order.
To modify the profit taker and stop loss on an existing bracket order:
Right click on the parent order line.
Select Modify followed by Attach Profit Taker/Stop Loss.
Adjust the prices as needed and click OK.
Transmit the changes.
You can review our order types on this webpage: https://spr.ly/IBKR_OrdersCampus
We hope this helps!