Market Surveillance
AEX includes automated surveillance monitors that run continuously within the market engine. These monitors protect market integrity by detecting patterns associated with market manipulation, runaway automation, and position risk. This page describes each monitor, the thresholds that trigger action, and what traders should expect when a monitor fires.
Self-match prevention
Self-match (or wash trade) detection prevents an entity from inadvertently — or deliberately — trading with an affiliated entity on the opposite side of the same contract.
How it works
The monitor tracks affiliations between entities. When an order is submitted (or a side change is requested on an existing order), the engine checks whether any affiliated entity already has a live order on the opposite side of the same contract:
- If a potential cross is detected, the order is rejected immediately
- The rejection message identifies the affiliated entity and the contract
What traders see
Order submission or modification fails with a rejection message:
Self-match prevention: affiliated entity <name> has opposing order on <contractId>
If your organisation's trading systems manage orders on behalf of multiple affiliated entities, ensure your strategy accounts for which entity is on which side of each contract.
Self-match rejection is enforced at order submission and at modification time when a side change would create a cross. The engine does not warn before rejection — the order is declined immediately.
Cancel ratio monitoring
The cancel ratio monitor tracks each entity's order cancellation behaviour over a rolling 5-minute window. A high ratio of cancellations to submissions may indicate quote-stuffing or runaway automation.
Thresholds
| Window | Threshold | Action |
|---|---|---|
| 5 minutes (rolling) | Cancels / submits ≥ 80% | Warning emitted |
The monitor uses a sliding window: only order events in the past 5 minutes count. Events older than 5 minutes are automatically pruned.
What triggers the monitor
Every order submission increments the submit count. Every cancellation increments the cancel count and recalculates the ratio. If the ratio reaches or exceeds 80% within the current window, a warning is logged and emitted to the platform's observability layer.
The cancel ratio monitor emits a warning — it does not automatically reject orders. Platform operators may investigate or take manual action based on the warning.
For traders: if your strategy involves rapid quote refreshing (e.g. reacting to market data by cancelling and resubmitting), be aware that cancel ratios are monitored. A ratio above 80% over a 5-minute window will draw operator attention.
Position limit tracking
The position limit tracker monitors each entity's net open position per contract, updated on every fill. When a configured position limit would be breached by a new order, the order is rejected before it reaches the order book.
Position tracking
For each entity and contract, the tracker maintains:
- Long — cumulative MW bought (filled buys)
- Short — cumulative MW sold (filled sells)
- Net — long minus short (positive = net long, negative = net short)
- VWAP — volume-weighted average price for both buy and sell fills
- P&L — realised profit and loss from offsetting trades
Position limit check
When a new order is submitted, the engine calculates the net position that would result if the order were filled in full. If the absolute value of the resulting net position exceeds the entity's configured maximum (in MW), the order is rejected:
Position limit breach: order would result in net position <X> MW, limit is <Y> MW
Position limits apply symmetrically — the check uses |wouldBeNet| > maxPositionMW, so both large long and large short positions are constrained.
Entities with no configured position limit have unlimited position capacity by default.
Viewing positions
Your current positions per contract are visible in AEM via the Positions pane, and in the Excel add-in using the =AEX.POSITION() and =AEX.POSITIONS() functions.
Amendment storm detection
The amendment storm tracker protects the order book from runaway Excel formulas or automation that re-amends orders at extremely high frequency. Sustained high-rate amendments can destabilise the book.
Thresholds
| Condition | Action |
|---|---|
| 10 amendments to the same order within 2 seconds | Warning — amendment proceeds |
| Another 10 amendments within the next 2 seconds (sustained) | Reject — amendment blocked |
The tracker uses a per-order ring buffer of the last 10 amendment timestamps.
Two-stage response
The monitor uses a two-stage escalation:
- First storm — the 10th amendment within 2 seconds triggers a warning. The amendment is allowed but the order enters warning state.
- Sustained storm — if another burst of 10 amendments occurs within 2 seconds while the order is in warning state, the amendment is rejected with HTTP 429 (
amendment_storm).
Once the amendment rate normalises (10 amendments span more than 2 seconds), the warning state clears automatically.
What traders see
On rejection, the order modify operation fails with:
Amendment storm detected on order <orderId>: 10 amendments in <N>ms (sustained). Modify rejected.
If you use the Excel add-in with formula-driven order management, be aware that volatile cell recalculations can trigger rapid amendments. The amendment storm detector protects against runaway loops, but may reject legitimate rapid corrections during burst recalculations. Use the held flag (liveFlag = FALSE) to stage changes before releasing them to the market.
How warnings reach operators
Surveillance events are logged to the platform's structured logging system (Pino) and emitted to the observability layer (Prometheus metrics + Grafana dashboards). Platform operators monitor these through:
- Log aggregation — all
warn-level surveillance events include structured context (entityId, contractId, ratio, limits) - Observability dashboards — order error counters labelled by reason (e.g.
amendment_storm,position_breach)
Operators can also query the AEX MCP server for live position data, pending surveillance state, and entity-level credit status.
Summary of actions by monitor
| Monitor | Detection | Order impact |
|---|---|---|
| Self-match | Affiliated entity on opposite side of same contract | Order rejected |
| Cancel ratio | Cancels/submits ≥ 80% in 5 minutes | Warning only (no automatic rejection) |
| Position limit | Net position would exceed configured max MW | Order rejected |
| Amendment storm | 10 amendments in <2 s (first occurrence) | Warning, amendment proceeds |
| Amendment storm | 10 amendments in <2 s (sustained) | Amendment rejected (429) |