Order Types
Order Types
Section titled “Order Types”MARKET
Section titled “MARKET”Immediate execution at the best available price.
- No price parameter needed
- Fills immediately (or rejects if no liquidity)
- Best for: Entering/exiting positions quickly
Pending order at a specific price level.
- Requires
priceparameter - BUY LIMIT: Placed below current price (buy cheaper)
- SELL LIMIT: Placed above current price (sell higher)
- Default TimeInForce: GTC (stays until filled or cancelled)
Becomes a market order when the stop price is reached.
- Requires
stopPriceparameter - BUY STOP: Placed above current price (breakout buy)
- SELL STOP: Placed below current price (breakout sell)
- Used for: Breakout strategies, stop-loss implementation
STOP_LIMIT (NOT SUPPORTED)
Section titled “STOP_LIMIT (NOT SUPPORTED)”⚠️ STOP_LIMIT is not supported by the cTrader broker. Attempting to use it will result in a broker rejection. Use STOP or LIMIT orders separately instead.
Time In Force
Section titled “Time In Force”| Value | Name | Behavior |
|---|---|---|
GTC | Good Till Cancel | Stays active until filled or manually cancelled (default) |
DAY | Day Order | Expires at end of trading day |
IOC | Immediate or Cancel | Fill what you can immediately, cancel the rest |
FOK | Fill or Kill | Fill entire order immediately or cancel completely |
GTD | Good Till Date | Stays active until expireTime is reached, then auto-cancelled |
Volume: Units, Not Lots!
Section titled “Volume: Units, Not Lots!”Critical: All volumes are specified in UNITS, not lots.
How to calculate volume
Section titled “How to calculate volume”The lot size for each symbol is available via the get_symbols tool or the ctrader://symbols resource.
To convert lots to units: volume = desired_lots × LOT_SIZE
Example: EURUSD has a lot size of 100,000, so:
- 1 lot = 100,000 units →
volume: 100000 - 0.5 lot = 50,000 units →
volume: 50000 - 0.01 lot = 1,000 units →
volume: 1000
Always call get_symbols to verify the actual lot size before placing an order.
Stop-Loss and Take-Profit (via Linked Orders)
Section titled “Stop-Loss and Take-Profit (via Linked Orders)”SL/TP is implemented using linked pending orders connected to a position via positionId.
When a STOP or LIMIT order includes a positionId, it closes/reduces that specific position when triggered,
instead of opening a new independent position.
3-Step SL/TP Workflow
Section titled “3-Step SL/TP Workflow”Step 1: Open the position
{ "symbol": "EURUSD", "side": "BUY", "volume": 100000, "orderType": "MARKET"}The response includes positionId (e.g., "12345") — save this for the next steps.
Step 2: Place Stop-Loss (STOP order linked to position)
{ "symbol": "EURUSD", "side": "SELL", "volume": 100000, "orderType": "STOP", "stopPrice": 1.0750, "positionId": "12345"}Step 3: Place Take-Profit (LIMIT order linked to position)
{ "symbol": "EURUSD", "side": "SELL", "volume": 100000, "orderType": "LIMIT", "price": 1.0950, "positionId": "12345"}Important Notes
Section titled “Important Notes”- positionId is REQUIRED — without it, STOP/LIMIT orders open a new independent position instead of protecting the existing one. Get it from the
place_orderMARKET fill response (data.positionIdfield), or fromget_positionsfor pre-existing positions. - Side must be opposite to the position: BUY position → SELL SL/TP orders, and vice versa.
- Price direction rules:
- BUY position: SL
stopPricemust be below entry price, TPpricemust be above entry price - SELL position: SL
stopPricemust be above entry price, TPpricemust be below entry price - Placing SL/TP at the wrong side of entry may cause immediate trigger or broker rejection
- BUY position: SL
- Volume should match the position volume for full SL/TP, or be smaller for partial.
- OCO auto-cancel: When a position closes (SL/TP fill,
close_position, or manual close), the server automatically cancels all remaining pending orders linked to that positionId. No manual cleanup needed. - Use
get_ordersto verify linked pending orders are active after placing them.
Order Workflow Examples
Section titled “Order Workflow Examples”Example 1: Market Buy with Risk Parameters
Section titled “Example 1: Market Buy with Risk Parameters”{ "symbol": "EURUSD", "side": "BUY", "volume": 100000, "orderType": "MARKET"}Example 2: Limit Sell Order
Section titled “Example 2: Limit Sell Order”{ "symbol": "GBPUSD", "side": "SELL", "volume": 50000, "orderType": "LIMIT", "price": 1.2650, "timeInForce": "GTC"}Example 3: Close Full Position
Section titled “Example 3: Close Full Position”{ "positionId": "12345"}Side is inferred automatically (LONG -> SELL, SHORT -> BUY).
Example 4: Partial Close
Section titled “Example 4: Partial Close”{ "positionId": "12345", "volume": 50000, "comment": "Take partial profit"}Example 5: Close All Positions (Flatten Book)
Section titled “Example 5: Close All Positions (Flatten Book)”{ }Closes every open position with opposing market orders. Use the close_all_positions tool.
Filter by symbol to close only specific positions:
{ "symbol": "EURUSD" }Viewing Pending Orders
Section titled “Viewing Pending Orders”Use get_orders to view all pending orders (LIMIT, STOP) that have not yet been filled or cancelled.
View all pending orders
Section titled “View all pending orders”{ }Filter by symbol
Section titled “Filter by symbol”{ "symbol": "EURUSD" }Filter by status
Section titled “Filter by status”{ "status": "PARTIALLY_FILLED" }Query a specific order by ClOrdID
Section titled “Query a specific order by ClOrdID”{ "clOrdId": "lq1x5k4fa3b2c1d9" }Without refresh, filters from local state. With refresh: true, sends a targeted status request for that single order instead of a bulk refresh:
{ "clOrdId": "lq1x5k4fa3b2c1d9", "refresh": true }Refresh from broker
Section titled “Refresh from broker”When orders may have been placed or cancelled outside this server (e.g., via cTrader UI):
{ "refresh": true }This fetches fresh order data from the broker and returns the current order snapshot.
When you only need one order’s status, use clOrdId + refresh: true instead — it sends a targeted request for just that order.
Tip: Always call get_orders before modify_order or cancel_order to verify the order exists and check its current state.
Trading When the Market Is Closed
Section titled “Trading When the Market Is Closed”MARKET orders require an active trading session and will be rejected if the market is closed (e.g., weekends for FX, outside trading hours for specific instruments).
What to do instead: Use a pending order type that queues your trade for execution when the market reopens:
| Order Type | Use Case |
|---|---|
| LIMIT | Enter at a specific price when market opens (e.g., BUY LIMIT below expected open) |
| STOP | Enter on a breakout above/below a level once trading resumes |
| Not supported by broker (rejected) |
Set timeInForce: "GTC" so the order stays active until filled or manually cancelled.
Alternatively, use timeInForce: "GTD" with an expireTime to auto-cancel at a specific time.
Example: Place a pending BUY LIMIT before the weekend:
{ "symbol": "EURUSD", "side": "BUY", "volume": 100000, "orderType": "LIMIT", "price": 1.0800, "timeInForce": "GTC"}This order will wait until the market reopens and execute if the price reaches 1.0800.
Example 6: GTD Order with Expiry
Section titled “Example 6: GTD Order with Expiry”{ "symbol": "EURUSD", "side": "BUY", "volume": 100000, "orderType": "LIMIT", "price": 1.0800, "timeInForce": "GTD", "expireTime": "2025-12-31T23:59:59Z"}The order auto-cancels at the specified UTC time if not filled. The expireTime must be in ISO 8601 UTC format (YYYY-MM-DDTHH:MM:SSZ).
Note: cTrader auto-detects GTD when expireTime is present, so setting timeInForce: "GTD" is optional but recommended for clarity.
Reviewing Past Trades
Section titled “Reviewing Past Trades”Use get_trade_history to see recently closed positions:
- Default: last 20 trades, most recent first
- Filter by symbol:
{ "symbol": "EURUSD" } - Include statistics:
{ "includeStats": true }→ win rate, profit factor, avg P&L
Note: Only positions closed through this MCP server are tracked. See limitations topic for details.
Risk Checks on Orders
Section titled “Risk Checks on Orders”Every order goes through 11 risk checks automatically:
- Kill switch must be inactive
- Rate limits must not be exceeded
- Symbol must be in the whitelist
- Volume must be within limits
- Position size must stay within limits
- Daily loss limit must not be exceeded
If any check fails, the order is rejected with a detailed error message including the reason and a suggestion for how to fix it.
