> ## Documentation Index
> Fetch the complete documentation index at: https://docs.matambaintelligence.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Trade for a customer

> Find a symbol and where prices for your customers come from, estimate an order, place it, follow it until it ends, cancel it, and read what it cost.

Once a customer's account is open and funded, you trade for it with orders. This page takes one order from its symbol to its contract note. [Orders](/orders) explains the states, order types and times in force it meets on the way.

## 1. Find the symbol

There's no endpoint that lists symbols. The exchange publishes its own lists, by symbol: its [listed companies](https://ngxgroup.com/exchange/trade/equities/listed-companies/) and its [exchange-traded products](https://ngxgroup.com/exchange/trade/exchange-traded-funds/listed-etp/).

Before we store a market order or a sell, we check its symbol against the broker's price list. A symbol that isn't on it is refused with [`422 unknown_symbol`](/errors#unknown_symbol), and nothing is stored. A limit buy isn't checked first: it's sent, and if the broker doesn't list the symbol, it comes back `rejected` with `reject_reason` `unknown_symbol`. The sandbox lists only its own few symbols: see the [sandbox reference](/sandbox).

### Prices to show your customers

The API gives no prices or quotes. To show your customers prices, use a licensed market data source: the exchange's data portal or a registered data vendor. The prices on the exchange's own [price list](https://ngxgroup.com/exchange/data/equities-price-list/) page are delayed by 30 minutes.

For a symbol the account holds, `GET /v1/accounts/{account}/positions` gives `market_price_kobo`, the broker's figure, and `market_value_kobo`, the position's worth at that price.

Never show an estimate as a price. It's the most an order can cost: a market buy is priced at the day's upper limit, plus charges.

## 2. Estimate the order

`POST /v1/orders/estimate` takes the same body as `POST /v1/orders` and returns `estimated_total_kobo` without placing or storing anything. For a buy, it's the estimated cost. For a sell, it's the estimated proceeds. The figure is the broker's estimate: it includes the consideration, statutory charges and commission, and it's indicative. An estimate meets neither daily limit and still works while trading is paused. A symbol the broker doesn't list comes back `422 order_rejected` with `reject_reason` `unknown_symbol`, not `422 unknown_symbol`.

A market order is priced at the day's price limit, so a market buy's estimate uses the upper limit, which nothing trades above. The [quickstart](/quickstart) works one out.

Before a market buy, check that the account's `available_kobo` covers the estimate, not the cost you expect at the fill: we send the order to the broker at the upper limit. If you fund the account first, allocate at least the estimate. In the sandbox, a buy the balance can't cover at that price gets `422 order_rejected` with `reject_reason` `insufficient_funds`.

## 3. Place the order

Send `POST /v1/orders` with the same body and a new [`Idempotency-Key`](/idempotency). The [quickstart](/quickstart) shows the request and its answer. [Order types](/orders#order-types) says when to send `limit` and when `market`.

If the answer is `503 outcome_not_recorded`, the order the error's `order` names reads `sending` until it resolves, as an [uncertain](/handling-uncertain) order does. Retrieve it, or wait for its event, and don't place it again under a new key. [Idempotency](/idempotency#when-to-use-a-new-key) lists every other answer.

Send a market order as `day`, never `gtc`: [Time in force](/orders#time-in-force) says why.

### Sell only what the account holds

Before a sell, read `GET /v1/accounts/{account}/positions`, and sell no more than the position's `quantity`.

In live, the broker publishes no refusal for a sell of more shares than the account holds. If it refuses one with a reason it doesn't publish, the order is `uncertain` until our operations team reconciles it: see [Handle an uncertain result](/handling-uncertain). In the sandbox such a sell doesn't fill: an `ioc` or `fok` order expires at once, a `day` order expires at midnight West Africa Time (WAT), and a `gtc` order stays open until the sandbox restarts, when it ends `expired`. A market sell cannot be cancelled: only a limit order can.

## 4. Follow the order

We check the broker for changes to your open orders about every 30 seconds. Each change sends an [event](/webhooks), or you can retrieve the order with `GET /v1/orders/{id}`. The order is finished once it's `filled`, `rejected`, `refused`, `cancelled` or `expired`. [Order states](/orders#order-states) explains each.

If it's `uncertain`, or still `sending` after its request has ended, don't place it again under a new key. See [Handle an uncertain result](/handling-uncertain).

## 5. Cancel an order

Send `DELETE /v1/orders/{id}`. You can cancel only a limit order that is `pending` or `partially_filled`.

| Response                   | Meaning                                                                                                                      | What to do                                                               |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `202`                      | The broker accepted the cancel request. The order isn't cancelled yet. The body shows the order as it was before the cancel. | Wait for `order.cancelled`, or `order.filled` if the order filled first. |
| `409 order_not_cancelable` | The order is a market order, is in a final state, isn't yet confirmed at the exchange, or the broker refused the cancel.     | Retrieve the order to see its state.                                     |
| `503 exchange_unavailable` | We didn't send the cancel.                                                                                                   | Send it again.                                                           |
| `503 cancel_unconfirmed`   | The broker did not confirm receipt of the cancel.                                                                            | Send it again. Repeating a cancel is safe.                               |

## 6. Read what it cost

Each fill becomes a trade in `GET /v1/accounts/{account}/trades`, carrying your order's `order_id`. Once the trade settles, its contract note appears in `GET /v1/accounts/{account}/contract-notes` with the charges, matched to the trade by `ticket`. [After a fill](/orders#after-a-fill) explains each figure and when each appears.

## Then take money out

Withdrawals aren't in the API yet. See [Take money out](/wallet#take-money-out).
