# MetaTrader 4 Trading API

> Index of every docs page as Markdown: [llms.txt](https://fxsocket.com/docs/llms.txt). All pages in one file: [llms-full.txt](https://fxsocket.com/llms-full.txt).

Source: https://fxsocket.com/docs/mt4/trading

Place, modify, and close MetaTrader 4 orders over a REST API: market and pending orders, partial closes, plus margin and profit calculators for position sizing. Every order executes inside your own dedicated MT4 terminal, never a shared gateway.

## How trading works on MT4

- **Six order types.** Buy, Sell, BuyLimit, SellLimit, BuyStop and SellStop. MT4 has no stop-limit orders; BuyStopLimit and SellStopLimit are rejected with a 400 before anything reaches the broker.
- **One ticket per trade.** On MT4 the order you send is the position. The reply's order is that ticket, and deal is always 0 because MT4 has no separate deals.
- **Hedging only.** An opposite order opens its own ticket instead of reducing the open one. To reduce a position, close its ticket fully or partially.
- **Partial closes renumber.** OrderClose with a volume closes part of the ticket. The reply reports the original ticket, which now holds only the closed part; the remainder continues under a new ticket that the reply does not contain. Read /OpenedOrders to find it (MT4 usually comments it "from #<original ticket>").
- **Same retcodes as MT5.** MT4 only returns an error number. The bridge maps it to the matching MT5 retcode (134 not enough money becomes 10019, 138 requote becomes 10004) and keeps the original in retcodeDescription, so one error-handling path covers both platforms. The full table is on Errors & Rate Limits. [MT4 error to retcode table](https://fxsocket.com/docs/mt4/errors.md)
- **One request at a time.** A single Expert Advisor in the MT4 terminal handles every request in turn, reads included, and each order waits for the broker's dealer to answer. A read sent while an order is in flight waits for it. To act on many accounts at once, send one request per account (or use the batch endpoints) rather than many in parallel to one account.
- **Calculators are computed.** MT4 has no margin or profit calculator. OrderCalcMargin multiplies the broker's per-lot margin at the live price by the volume, so the price you pass doesn't change it. OrderCalcProfit uses tick size and today's tick value, which makes it an estimate for symbols quoted in another currency.

Base URL: `https://api.fxsocket.com/mt4/{account_id}`

Order routes are executed inside your own terminal. A 200 response only means MT4 returned a result. Always inspect success, outcome and retcode to confirm the broker accepted it. MT4 itself only reports an error number; the bridge translates it into the same retcode values MT5 uses and keeps the original number in retcodeDescription (see Errors & Rate Limits).

### POST /mt4/{account_id}/OrderSend

Submit a market or pending order. Market (Buy/Sell) needs symbol + volume; price is ignored and the order goes out at the current quote, and the reply reports the broker's actual fill price. Pending (*Limit/*Stop) additionally needs price. MT4 has no stop-limit orders: BuyStopLimit and SellStopLimit are rejected with a 400 before anything reaches the broker. Optional: slippage (default 10 points), stopLoss, takeProfit, expiration for pending orders (absent → good-till-cancelled), comment, expertId (a.k.a. magic). On success the reply's order is the new ticket and deal is always 0.

Parameters:

- `symbol` (required): Symbol to trade, e.g. EURUSD.
- `operation` (required): Buy, Sell, BuyLimit, SellLimit, BuyStop, SellStop (case- and separator-insensitive).
- `volume` (required): Volume in lots.
- `price`: Required for pending orders; ignored for market orders.
- `stopLoss / takeProfit`: Optional SL/TP prices.
- `slippage`: Max slippage in points (default 10).
- `expiration`: Date string; absent → good-till-cancelled.
- `comment / expertId`: Order comment and magic number.

Request body:

```json
{
  "symbol": "EURUSD",
  "operation": "Buy",
  "volume": 0.1,
  "stopLoss": 1.14800,
  "takeProfit": 1.16200,
  "comment": "my-strategy",
  "expertId": 123456
}
```

Example request:

```bash
curl -X POST https://api.fxsocket.com/mt4/{account_id}/OrderSend \
  -H "X-API-Key: fxs_live_..." \
  -H "Content-Type: application/json" \
  -d '{"symbol":"EURUSD","operation":"Buy","volume":0.1,"stopLoss":1.148,"takeProfit":1.162,"comment":"my-strategy","expertId":123456}'
```

Response:

```json
{
  "success": true,
  "outcome": "applied",
  "retcode": 10009,
  "retcodeDescription": "Done",
  "deal": 0,
  "order": 211438761,
  "volume": 0.1,
  "price": 1.15333,
  "bid": 1.15325,
  "ask": 1.15333,
  "comment": ""
}
```

### POST /mt4/{account_id}/OrderModify

Modify an existing position or pending order. The ticket type decides what's modifiable: a position ticket accepts only stopLoss and takeProfit; a pending-order ticket also accepts price and expiration. Omit a field to keep its current value. Sending values that are already set returns retcode 10025 ("No changes") with outcome no_change, which is safe to treat as applied.

Parameters:

- `ticket` (required): Position or pending-order ticket.
- `stopLoss / takeProfit`: New SL/TP, omit to keep current.
- `price`: New price, pending orders only.
- `expiration`: New expiration (date string), pending orders only.

Request body:

```json
{
  "ticket": 211438761,
  "stopLoss": 1.15000,
  "takeProfit": 1.16500
}
```

Example request:

```bash
curl -X POST https://api.fxsocket.com/mt4/{account_id}/OrderModify \
  -H "X-API-Key: fxs_live_..." \
  -H "Content-Type: application/json" \
  -d '{"ticket":211438761,"stopLoss":1.15,"takeProfit":1.165}'
```

Response:

```json
{
  "success": true,
  "outcome": "applied",
  "retcode": 10009,
  "retcodeDescription": "Done",
  "deal": 0,
  "order": 211438761,
  "volume": 0.1,
  "price": 1.15333,
  "bid": 1.15325,
  "ask": 1.15333,
  "comment": ""
}
```

### POST /mt4/{account_id}/OrderClose

Close a position or delete a pending order: the action is inferred from the ticket type. For a position, supply volume for a partial close (must respect the symbol's volumeStep) or omit it for a full close; the close goes out at the current bid or ask. For a pending order, volume is ignored and the order is deleted. On MT4 a partial close renumbers the trade: the part you closed keeps the original ticket, which is what the reply reports, and the remaining volume carries on under a new ticket. Read /OpenedOrders afterwards to find it; MT4 usually marks its comment as "from #<original ticket>".

Parameters:

- `ticket` (required): Position ticket (closes it) or pending-order ticket (deletes it).
- `volume`: Partial close volume; omit or 0 = full close.
- `slippage`: Max slippage in points.

Request body:

```json
{
  "ticket": 211438761,
  "volume": 0.05
}
```

Example request:

```bash
curl -X POST https://api.fxsocket.com/mt4/{account_id}/OrderClose \
  -H "X-API-Key: fxs_live_..." \
  -H "Content-Type: application/json" \
  -d '{"ticket":211438761,"volume":0.05}'
```

Response:

```json
{
  "success": true,
  "outcome": "applied",
  "retcode": 10009,
  "retcodeDescription": "Done",
  "deal": 0,
  "order": 211438761,
  "volume": 0.05,
  "price": 1.15325,
  "bid": 1.15325,
  "ask": 1.15333,
  "comment": ""
}
```

### GET /mt4/{account_id}/OrderCalcMargin

Required margin for a hypothetical order, in the account currency. MT4 has no margin calculator of its own, so the bridge multiplies the broker's per-lot margin requirement (already leverage-adjusted) by the volume. That figure is taken at the live price: the price you pass is accepted but does not change the result, and neither does the direction. Does not place an order, purely a sizing/risk query.

Parameters:

- `symbol` (required): Symbol name as listed by /symbols.
- `operation` (required): Buy, Sell, BuyLimit, SellLimit, BuyStop, SellStop.
- `volume` (required): Volume in lots.
- `price` (required): Hypothetical entry price (ignored on MT4, see above).

Example request:

```bash
curl -H "X-API-Key: fxs_live_..." \
  "https://api.fxsocket.com/mt4/{account_id}/OrderCalcMargin?symbol=EURUSD&operation=Buy&volume=0.1&price=1.15333"
```

Response:

```json
{
  "symbol": "EURUSD",
  "operation": "Buy",
  "volume": 0.1,
  "price": 1.15333,
  "margin": 28.83,
  "currency": "USD"
}
```

### GET /mt4/{account_id}/OrderCalcProfit

Projected P&L for a hypothetical open → close move, returned in the account currency. MT4 has no profit calculator of its own, so the bridge computes it from the symbol's tick size and tick value: (close − open) / tickSize × tickValue × volume, signed by direction. The tick value is today's, so for symbols quoted in another currency the result is an estimate at the current conversion rate. Does not place an order, useful for position sizing and UI.

Parameters:

- `symbol` (required): Symbol name as listed by /symbols.
- `operation` (required): Buy or Sell (pending variants accepted: only the direction is used).
- `volume` (required): Volume in lots.
- `priceOpen` (required): Hypothetical open price.
- `priceClose` (required): Hypothetical close price.

Example request:

```bash
curl -H "X-API-Key: fxs_live_..." \
  "https://api.fxsocket.com/mt4/{account_id}/OrderCalcProfit?symbol=EURUSD&operation=Buy&volume=0.1&priceOpen=1.15333&priceClose=1.16333"
```

Response:

```json
{
  "symbol": "EURUSD",
  "operation": "Buy",
  "volume": 0.1,
  "priceOpen": 1.15333,
  "priceClose": 1.16333,
  "profit": 100.0,
  "currency": "USD"
}
```

## Related

- [Account Data](https://fxsocket.com/docs/mt4/account-data.md)
- [Market Data](https://fxsocket.com/docs/mt4/market-data.md)
- [Errors & Rate Limits](https://fxsocket.com/docs/mt4/errors.md)
