Positions & Settlement API
Positions live on-chain, not in the relayer. The relayer gives one firm summary; the full position set, marks, PnL, and settlement state are read on-chain over RPC. The questions below cover each read.
How do I read an address's positions?
From the chain. Positions live in the core contract, keyed by ACA id. The authoritative read is on-chain over RPC, not from the relayer.
NoteThe relayer does not serve a positions endpoint. There is noGET /positions. The off-chain API gives a firm summary; the full position set, marks, and PnL are read on-chain.
What does the relayer give me for an address?
One read: a firm's off-chain summary.
| Method | Path | Auth | Params | Returns |
|---|---|---|---|---|
GET | /firm/:addr | no | addr (path), firm wallet address | { general_balance, general_balances, open_aca_count, acas_with_maker } (hex) |
It returns how much free margin a firm holds and how many relationships it has open. It does not list the positions. The full field list and a sample response live with the endpoint in the CRX API reference (~4 min).
GET /firm/:addrRead a firm's free margin and open-agreement count. Paste a firm address, or read the zero-address shape.
Path params
Bearer token · optional
curl -X GET "https://app.crxfx.com/svc/relayer/firm/0x0000000000000000000000000000000000000000"ResponsePress Try It! to run the call and read the live response.
How do I read the positions themselves?
On-chain, in three layers, the same three the model defines.
| Read | What it tells you | Where |
|---|---|---|
| General balance | Free, multi-asset margin shared across all the firm's agreements | _generalBalance[party][token] in the core |
| Account Control Agreement (ACA) | One per-relationship netting set: the positions held under one account control agreement | _acas[acaId], keyed acaId = keccak256(address(this), chainid, party1, party2, number, csa) |
| SCA (Segregated Collateral Account) | One party's initial margin inside one ACA | _sca[acaId][party][token] |
Read these from the core contract over RPC. Positions can also be read via GraphQL from the indexer, Indexer (~3 min). The model behind them: How CRX works (~6 min).
How do I compute PnL?
From the mark, not from the relayer. CRX is NDF-only; the payoff is linear both ways.
- The position carries a
lockedRate(the entry forward rate). - The on-chain mark gives the current forward rate (per-pair FX oracle,
expo = −8). - Mark-to-market PnL =
(mark − lockedRate) × notional, signed by side. - Variation margin clears this PnL continuously: the loser pays from its SCA; the winner receives into its general balance. So an SCA holds only initial margin, never accumulated PnL.
A routine move raises no margin call; VM is the continuous recycling. A breach does, cure-windowed per the relationship's credit mode. The detail: Margin (VM) (~4 min) and Credit Model (~8 min).
How do I read settlement state?
On-chain. Each position carries the calendar fields that govern settlement.
| Field | Meaning |
|---|---|
deliveryTime | The delivery date, the single date the NDF settles on. settle is allowed at or after it, and the oracle must publish on or after it. |
calendarId | The FX business-day calendar the relayer resolved the date from. |
- A trade can
settleonly at or afterdeliveryTime. - The settled rate must have an oracle
publishTimeon or afterdeliveryTime; an earlier observation is rejected (FixingTooEarly). - Settlement clears in cash (USDC). Nothing is paid in the foreign currency.
The price model for settlement: Oracle & Rate Sources (~3 min).
What is the firm's default flag?
A credit flag, read on-chain. A party liquidated at least once carries the contract-stamped DEFAULT role. It is never operator-granted, and it gates nothing; it is a marker, not a lock. See Credit Model (~8 min).