place_order
Execute buy or sell orders for stocks through Interactive Brokers trading accounts using market, limit, or stop order types.
Instructions
Place a trading order. Examples:
Market buy:
{ "accountId":"abc","symbol":"AAPL","action":"BUY","orderType":"MKT","quantity":1 }Limit sell:
{ "accountId":"abc","symbol":"AAPL","action":"SELL","orderType":"LMT","quantity":1,"price":185.5 }Stop sell:
{ "accountId":"abc","symbol":"AAPL","action":"SELL","orderType":"STP","quantity":1,"stopPrice":180 }Suppress confirmations:
{ "accountId":"abc","symbol":"AAPL","action":"BUY","orderType":"MKT","quantity":1,"suppressConfirmations":true }
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| accountId | Yes | ||
| symbol | Yes | ||
| action | Yes | ||
| orderType | Yes | ||
| quantity | Yes | ||
| price | No | ||
| stopPrice | No | ||
| suppressConfirmations | No |
Implementation Reference
- src/tool-handlers.ts:404-442 (handler)Main MCP tool handler for place_order. Ensures prerequisites (gateway, auth) and delegates order placement to IBClient, returning formatted result or error.async placeOrder(input: PlaceOrderInput): Promise<ToolHandlerResult> { try { // Ensure Gateway is ready await this.ensureGatewayReady(); // Ensure authentication in headless mode if (this.context.config.IB_HEADLESS_MODE) { await this.ensureAuth(); } const result = await this.context.ibClient.placeOrder({ accountId: input.accountId, symbol: input.symbol, action: input.action, orderType: input.orderType, quantity: input.quantity, // Already converted by Zod schema price: input.price, stopPrice: input.stopPrice, suppressConfirmations: input.suppressConfirmations, }); return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { return { content: [ { type: "text", text: this.formatError(error), }, ], }; } }
- src/tool-definitions.ts:120-134 (schema)Zod schema for place_order input validation, including refinements to ensure required fields for order types (price for LMT, stopPrice for STP).export const PlaceOrderZodSchema = z.object(PlaceOrderZodShape).refine( (data) => { if (data.orderType === "LMT" && data.price === undefined) { return false; } if (data.orderType === "STP" && data.stopPrice === undefined) { return false; } return true; }, { message: "LMT orders require price, STP orders require stopPrice", path: ["price", "stopPrice"] } );
- src/tools.ts:74-83 (registration)MCP server registration of the 'place_order' tool, including description, input shape, and handler reference.server.tool( "place_order", "Place a trading order. Examples:\n" + "- Market buy: `{ \"accountId\":\"abc\",\"symbol\":\"AAPL\",\"action\":\"BUY\",\"orderType\":\"MKT\",\"quantity\":1 }`\n" + "- Limit sell: `{ \"accountId\":\"abc\",\"symbol\":\"AAPL\",\"action\":\"SELL\",\"orderType\":\"LMT\",\"quantity\":1,\"price\":185.5 }`\n" + "- Stop sell: `{ \"accountId\":\"abc\",\"symbol\":\"AAPL\",\"action\":\"SELL\",\"orderType\":\"STP\",\"quantity\":1,\"stopPrice\":180 }`\n" + "- Suppress confirmations: `{ \"accountId\":\"abc\",\"symbol\":\"AAPL\",\"action\":\"BUY\",\"orderType\":\"MKT\",\"quantity\":1,\"suppressConfirmations\":true }`", PlaceOrderZodShape, async (args) => await handlers.placeOrder(args) );
- src/ib-client.ts:391-459 (helper)Low-level IBClient method that performs symbol lookup, constructs the order payload, submits to IB Gateway API, and handles confirmations if suppressed.async placeOrder(orderRequest: OrderRequest): Promise<any> { try { // First, get the contract ID for the symbol const searchResponse = await this.client.get( `/iserver/secdef/search?symbol=${orderRequest.symbol}` ); if (!searchResponse.data || searchResponse.data.length === 0) { throw new Error(`Symbol ${orderRequest.symbol} not found`); } const contract = searchResponse.data[0]; const conid = contract.conid; // Prepare order object const order = { conid: Number(conid), // Ensure conid is number orderType: orderRequest.orderType, side: orderRequest.action, quantity: Number(orderRequest.quantity), // Ensure quantity is number tif: "DAY", // Time in force }; // Add price for limit orders if (orderRequest.orderType === "LMT" && orderRequest.price !== undefined) { (order as any).price = Number(orderRequest.price); } // Add stop price for stop orders if (orderRequest.orderType === "STP" && orderRequest.stopPrice !== undefined) { (order as any).auxPrice = Number(orderRequest.stopPrice); } // Place the order const response = await this.client.post( `/iserver/account/${orderRequest.accountId}/orders`, { orders: [order], } ); // Check if we received confirmation messages that need to be handled if (response.data && Array.isArray(response.data) && response.data.length > 0) { const firstResponse = response.data[0]; // Check if this is a confirmation message response if (firstResponse.id && firstResponse.message && firstResponse.messageIds && orderRequest.suppressConfirmations) { Logger.log("Order confirmation received, automatically confirming...", firstResponse); // Automatically confirm all messages const confirmResponse = await this.confirmOrder(firstResponse.id, firstResponse.messageIds); return confirmResponse; } } return response.data; } catch (error) { Logger.error("Failed to place order:", error); // Check if this is likely an authentication error if (this.isAuthenticationError(error)) { const authError = new Error("Authentication required to place orders. Please authenticate with Interactive Brokers first."); (authError as any).isAuthError = true; throw authError; } throw new Error("Failed to place order"); } }
- src/tool-definitions.ts:29-38 (schema)Base Zod shape definition for place_order input parameters, used in tool registration and schema.export const PlaceOrderZodShape = { accountId: z.string(), symbol: z.string(), action: z.enum(["BUY", "SELL"]), orderType: z.enum(["MKT", "LMT", "STP"]), quantity: IntegerOrStringIntegerZod, price: z.number().optional(), stopPrice: z.number().optional(), suppressConfirmations: z.boolean().optional() };