Skip to content

Order Types

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 price parameter
  • 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 stopPrice parameter
  • 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 is not supported by the cTrader broker. Attempting to use it will result in a broker rejection. Use STOP or LIMIT orders separately instead.

ValueNameBehavior
GTCGood Till CancelStays active until filled or manually cancelled (default)
DAYDay OrderExpires at end of trading day
IOCImmediate or CancelFill what you can immediately, cancel the rest
FOKFill or KillFill entire order immediately or cancel completely
GTDGood Till DateStays active until expireTime is reached, then auto-cancelled

Critical: All volumes are specified in UNITS, not lots.

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.

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"
}
  • positionId is REQUIRED — without it, STOP/LIMIT orders open a new independent position instead of protecting the existing one. Get it from the place_order MARKET fill response (data.positionId field), or from get_positions for 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 stopPrice must be below entry price, TP price must be above entry price
    • SELL position: SL stopPrice must be above entry price, TP price must be below entry price
    • Placing SL/TP at the wrong side of entry may cause immediate trigger or broker rejection
  • 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_orders to verify linked pending orders are active after placing them.

Example 1: Market Buy with Risk Parameters

Section titled “Example 1: Market Buy with Risk Parameters”
{
"symbol": "EURUSD",
"side": "BUY",
"volume": 100000,
"orderType": "MARKET"
}
{
"symbol": "GBPUSD",
"side": "SELL",
"volume": 50000,
"orderType": "LIMIT",
"price": 1.2650,
"timeInForce": "GTC"
}
{
"positionId": "12345"
}

Side is inferred automatically (LONG -> SELL, SHORT -> BUY).

{
"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" }

Use get_orders to view all pending orders (LIMIT, STOP) that have not yet been filled or cancelled.

{ }
{ "symbol": "EURUSD" }
{ "status": "PARTIALLY_FILLED" }
{ "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 }

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.

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 TypeUse Case
LIMITEnter at a specific price when market opens (e.g., BUY LIMIT below expected open)
STOPEnter on a breakout above/below a level once trading resumes
STOP_LIMITNot 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.

{
"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.

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.

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.