# QFEX — account reads, equity, leverage, and fees

This file covers signed positions, complete open-order pagination, snapshot trust, account equity, symbol-level leverage, and documented fee/funding mechanics. Protocol observations were made on 2026-10-01; no individual account values appear here.

## TL;DR

1. Position quantity is signed. There is no separate position-side field to multiply into it.
2. Zero rows can remain after closing, and a flat symbol with orders may have no position row.
3. Open orders come from the trade socket; completeness requires a final short page.
4. REST order counts can lag the socket by tens of seconds.
5. Leverage is locked per symbol while that symbol has an order or position.
6. Available balance is not equity; use consistent snapshot fields and expose ambiguity.

## 1. Position and balance decoding

`GET /user/positions` returns `positions` and `balance`. Positions include symbol, signed position, realized/unrealized PnL, net funding, open-order count, open quantity, leverage, initial and maintenance margin, and average price. REST permits a null position list; an observed empty account used an empty array.

Balance includes deposit, realized/unrealized PnL, net funding, order margin, position margin, available balance, and builder rewards. It has no explicit equity field. Parse required fields and validate finite numbers and record shapes; malformed data invalidates the whole read.

Long quantities were positive and shorts negative in both REST and the positions stream on 2026-10-01. A zero row persisted after closing; an order-only flat symbol could be omitted. Normalize these valid shape differences without using them as freshness evidence.

## 2. Complete orders and consistent snapshots

`get_user_orders` takes `limit`, `offset`, and optional symbol. Reply `all_orders_response` contains orders and possibly TWAP rows. There is no documented total/has-more flag: only a page shorter than the requested limit proves completion. A full page requires another page. Any timeout, interruption, malformed page, or pagination ambiguity leaves completeness unknown.

An order-ownership predicate is caller supplied; it can use an exact neutral client tag. Separate complete account orders from an owned subset. Never use a filtered subset to conclude the entire account is empty.

REST positions reflected tested IoC fills after a short delay. Open-order counts lagged more: one placement observation took about 35 seconds and one cancellation observation about 60 seconds to agree with the socket. These are samples, not guaranteed bounds. A mismatch inside such a period is insufficient evidence of wrong account selection.

The account snapshot helper combines independent sources and reports trust/completeness rather than silently assembling a plausible empty account. Read-fresh-position helpers need caller-selected timing and pending-write context. Even an accepted consistent read is not a universal proof that every recent fill has reached REST. The optional ledger's limitations are in [orders.md](orders.md) §6.

## 3. Equity and free margin

Documentation defines equity as cash plus realized and unrealized PnL, and available balance as equity minus margin. A same-response derived candidate is:

```text
equityCandidate = available_balance + order_margin + position_margin
```

Whether available balance is floored at zero remains unverified. If it is zero while margins are positive, the formula may overstate equity. Preserve that uncertainty; do not label the candidate as independently verified equity.

`GET /user/subaccounts/equity` returns account ID, equity, and primary-account marker from the latest balance snapshot. `/user/subaccounts/balance` returns available balance. Preserve canonical IDs and require an exact selected-account match. Freshness is undocumented, and a one-account listing does not prove key scope independently.

## 4. Leverage, fees, and funding

Leverage is a per-symbol setting. A fresh account used the symbol's reference-data maximum in observations on 2026-10-01; applications should read it rather than assume a low default.

REST `POST /user/leverage` returns the resulting leverage synchronously. The socket setter returned a generic acknowledgement; documented acknowledgement variants also exist. Socket leverage-read rows use string leverage while REST position rows use numbers. Available-level responses should be decoded without assuming optional notional-tier fields are present.

Changing leverage on a symbol with an open order or position failed with generic `ServerError`, while another empty symbol remained configurable. Set it before the first order, or after proving that symbol is flat and has no orders. Account-wide scope is not the observed lock rule.

Fees vary by product and volume tier. Query `/user/fees` for applicable maker/taker rates rather than embed promotions or an individual tier. Its integer fee representation uses a millionth scale in the examined CLI behavior; verify against current API data. Fill events contain charged fee evidence, while REST position/balance fields do not contain every stream fee/reward field. Fee amounts were not independently measured here.

Funding is documented as hourly within the product's funding session. Funding, fee, transfer, and PnL data are distinct. Deposit, withdrawal, and transfer workflows are documented venue capabilities but are not implemented by this toolkit's account helpers.

## 5. Risk scope

The documented account uses cross margin. A margin rejection concerns account collateral; position and open-interest constraints can concern one symbol. The toolkit exposes a pure rejection-scope classifier.

## Pitfalls

| What breaks | Why | Correct approach |
|---|---|---|
| Short is turned into long | Signed size was multiplied by an inferred side | Keep signed semantics |
| A full order page is called complete | No total/has-more field | Continue to a short page |
| Wrong-account alarm follows a cancel | REST count lag | Compare after catch-up and disclose uncertainty |
| Equity equals available balance | Margin was omitted | Use consistent fields and ambiguity checks |
| Leverage loops on generic errors | Symbol is occupied | Read position and complete orders before setting |

## Open questions / not verified

- Equity endpoint freshness and an available-balance floor.
- Multi-subaccount auth/event selection and balance/position push cadence; documentation gives conflicting cadences.
- Fee-scale changes and independently reconciled charged rates.
- Liquidation-event variants and external account changes during a fresh-position read.

## Sources

[User positions](https://docs.qfex.com/api-reference/rest/user/user-positions); [List account equities](https://docs.qfex.com/api-reference/rest/user/list-account-equities); [Get user orders](https://docs.qfex.com/websocket/channels/trade/get_user_orders); [Set user leverage](https://docs.qfex.com/api-reference/rest/user/set-user-leverage); [Definitions](https://docs.qfex.com/qfex/definitions); [Fees](https://docs.qfex.com/qfex/fees); [Liquidation margin call](https://docs.qfex.com/qfex/liquidation-margin-call). Signed-position and leverage-lock observations: 2026-10-01. Snapshot and scope judgments are implementation safeguards.

<!-- license-footer -->
_© markpaper authors. Licensed under [CC BY 4.0](LICENSE.md): when publishing or adapting this material, credit “markpaper — QFEX knowledge base” and link to the original and the license._
