Skip to content

Commit fcc57d1

Browse files
committed
Document event types on dedicated pages
- Break the events guide into an index and per-event pages - Give each page a field table and a strategy handler example - Correct position event field matrix and pending-order transitions - Repoint sibling concept links to the new events directory
1 parent 49a6fcc commit fcc57d1

26 files changed

Lines changed: 737 additions & 45 deletions
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# AccountState
2+
3+
`AccountState` carries a snapshot of an account's balances and margins. It fires when the
4+
venue reports an account update (via the execution client), or when the `Portfolio`
5+
recalculates account state after a position update (for margin accounts with
6+
`calculate_account_state` enabled). The `Portfolio` subscribes to these events internally
7+
to maintain exposure and balance tracking.
8+
9+
The `is_reported` flag distinguishes venue-reported snapshots from system-calculated ones.
10+
11+
## Fields
12+
13+
| Field | Python type | Required/default | Description |
14+
|-----------------|------------------------|------------------|---------------------------------------------------------------------------|
15+
| `account_id` | `AccountId` | Required | The account ID (with the venue). |
16+
| `account_type` | `AccountType` | Required | The account type (`CASH`, `MARGIN`, or `BETTING`). |
17+
| `base_currency` | `Currency` or `None` | Required | The account base currency (`None` for multi‑currency accounts). |
18+
| `is_reported` | `bool` | Required | If the state is reported from the exchange (otherwise system‑calculated). |
19+
| `balances` | `list[AccountBalance]` | Required | The account balances (may be empty). |
20+
| `margins` | `list[MarginBalance]` | Required | The margin balances (may be empty). |
21+
| `info` | `dict[str, object]` | Required | Additional implementation‑specific account information. |
22+
| `event_id` | `UUID4` | Required | The event ID. |
23+
| `ts_event` | `int` | Required | UNIX timestamp (nanoseconds) when the event occurred. |
24+
| `ts_init` | `int` | Required | UNIX timestamp (nanoseconds) when the object was initialized. |
25+
26+
## Example
27+
28+
Account state is normally consumed through the `Portfolio` rather than a dedicated handler:
29+
30+
```python
31+
from nautilus_trader.model import Venue
32+
33+
# Account state is tracked by the portfolio; query it by venue
34+
account = self.portfolio.account(Venue("BINANCE"))
35+
self.log.info(f"Account state: {account}")
36+
```
37+
38+
## Related guides
39+
40+
- [Events](index.md) - Event categories and dispatch.
41+
- [Accounting](../accounting.md) - Account types, balances, and margin models.
42+
- [Portfolio](../portfolio.md) - How account state feeds exposure and balance tracking.
Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -41,30 +41,30 @@ omit the callback, the event is delivered to `on_event` instead.
4141
## Order events
4242

4343
Each order event corresponds to a state transition in the
44-
[order state machine](orders/index.md#order-state-flow). The `ExecutionEngine`
44+
[order state machine](../orders/index.md#order-state-flow). The `ExecutionEngine`
4545
applies the event to the order, updates the `Cache`, and publishes it on the
4646
`MessageBus`. The table below shows the primary transitions; partially filled
4747
and triggered orders support additional transitions documented in the full
48-
[order state flow](orders/index.md#order-state-flow).
49-
50-
| Event | Primary transition | Handler |
51-
|------------------------|-------------------------------------|----------------------------|
52-
| `OrderInitialized` | (created locally) | `on_order_initialized` |
53-
| `OrderDenied` | Initialized -> Denied | `on_order_denied` |
54-
| `OrderEmulated` | Initialized -> Emulated | `on_order_emulated` |
55-
| `OrderReleased` | Emulated -> Released | `on_order_released` |
56-
| `OrderSubmitted` | Initialized/Released -> Submitted | `on_order_submitted` |
57-
| `OrderAccepted` | Submitted -> Accepted | `on_order_accepted` |
58-
| `OrderRejected` | Submitted -> Rejected | `on_order_rejected` |
59-
| `OrderTriggered` | Accepted -> Triggered | `on_order_triggered` |
60-
| `OrderPendingUpdate` | Accepted -> PendingUpdate | `on_order_pending_update` |
61-
| `OrderPendingCancel` | Accepted -> PendingCancel | `on_order_pending_cancel` |
62-
| `OrderUpdated` | PendingUpdate -> Accepted | `on_order_updated` |
63-
| `OrderModifyRejected` | PendingUpdate -> Accepted | `on_order_modify_rejected` |
64-
| `OrderCancelRejected` | PendingCancel -> Accepted | `on_order_cancel_rejected` |
65-
| `OrderCanceled` | PendingCancel/Accepted -> Canceled | `on_order_canceled` |
66-
| `OrderExpired` | Accepted -> Expired | `on_order_expired` |
67-
| `OrderFilled` | Accepted -> Filled/PartiallyFilled | `on_order_filled` |
48+
[order state flow](../orders/index.md#order-state-flow).
49+
50+
| Event | Primary transition | Handler |
51+
|---------------------------------------------------|------------------------------------|----------------------------|
52+
| [`OrderInitialized`](order_initialized.md) | (created locally) | `on_order_initialized` |
53+
| [`OrderDenied`](order_denied.md) | Initialized -> Denied | `on_order_denied` |
54+
| [`OrderEmulated`](order_emulated.md) | Initialized -> Emulated | `on_order_emulated` |
55+
| [`OrderReleased`](order_released.md) | Emulated -> Released | `on_order_released` |
56+
| [`OrderSubmitted`](order_submitted.md) | Initialized/Released -> Submitted | `on_order_submitted` |
57+
| [`OrderAccepted`](order_accepted.md) | Submitted -> Accepted | `on_order_accepted` |
58+
| [`OrderRejected`](order_rejected.md) | Submitted -> Rejected | `on_order_rejected` |
59+
| [`OrderTriggered`](order_triggered.md) | Accepted -> Triggered | `on_order_triggered` |
60+
| [`OrderPendingUpdate`](order_pending_update.md) | Accepted -> PendingUpdate | `on_order_pending_update` |
61+
| [`OrderPendingCancel`](order_pending_cancel.md) | Accepted -> PendingCancel | `on_order_pending_cancel` |
62+
| [`OrderUpdated`](order_updated.md) | PendingUpdate -> previous status | `on_order_updated` |
63+
| [`OrderModifyRejected`](order_modify_rejected.md) | PendingUpdate -> previous status | `on_order_modify_rejected` |
64+
| [`OrderCancelRejected`](order_cancel_rejected.md) | PendingCancel -> previous status | `on_order_cancel_rejected` |
65+
| [`OrderCanceled`](order_canceled.md) | PendingCancel/Accepted -> Canceled | `on_order_canceled` |
66+
| [`OrderExpired`](order_expired.md) | Accepted -> Expired | `on_order_expired` |
67+
| [`OrderFilled`](order_filled.md) | Accepted -> Filled/PartiallyFilled | `on_order_filled` |
6868

6969
### Common order event fields
7070

@@ -83,13 +83,14 @@ All order events share these fields:
8383
| `ts_event` | Timestamp when the event occurred. |
8484
| `ts_init` | Timestamp when the event was created. |
8585

86-
Individual events add type-specific fields (e.g. `OrderFilled` adds
87-
`last_qty`, `last_px`, `trade_id`, `commission`). See the API reference
88-
for the full field list per event type.
86+
Each order event's page lists the type-specific fields it adds beyond this
87+
common set, plus which optional common fields are populated. For example,
88+
[`OrderFilled`](order_filled.md) adds `last_qty`, `last_px`, `trade_id`, and
89+
`commission`.
8990

9091
:::tip
9192
Override `on_order_event` to handle all order events in one place. The specific
92-
handlers fire first, so you can mix both approaches.
93+
handlers fire first, so you can combine both approaches.
9394
:::
9495

9596
## Position events
@@ -98,11 +99,11 @@ Position events are a direct consequence of fill events. The `ExecutionEngine`
9899
processes each `OrderFilled`, updates or creates a position, and emits the
99100
corresponding position event.
100101

101-
| Event | When it fires | Handler |
102-
|---------------------|-------------------------------------------|-----------------------|
103-
| `PositionOpened` | First fill creates a new position. | `on_position_opened` |
104-
| `PositionChanged` | Subsequent fill changes quantity or side. | `on_position_changed` |
105-
| `PositionClosed` | Fill reduces quantity to zero. | `on_position_closed` |
102+
| Event | When it fires | Handler |
103+
|------------------------------------------|-------------------------------------------|-----------------------|
104+
| [`PositionOpened`](position_opened.md) | First fill creates a new position. | `on_position_opened` |
105+
| [`PositionChanged`](position_changed.md) | Subsequent fill changes quantity or side. | `on_position_changed` |
106+
| [`PositionClosed`](position_closed.md) | Fill reduces quantity to zero. | `on_position_closed` |
106107

107108
### From fill to position: the causal chain
108109

@@ -157,6 +158,11 @@ sequenceDiagram
157158

158159
### Position event fields
159160

161+
Every position event exposes all of these fields (they are defined on the `PositionEvent`
162+
base). A check mark means the field carries a meaningful value for that event; a dash means
163+
it is left at its zero or default (for example `avg_px_close` and `duration_ns` before a
164+
position closes).
165+
160166
| Field | Opened | Changed | Closed | Description |
161167
|----------------------|--------|---------|--------|-----------------------------------|
162168
| `trader_id` |||| Trader instance identifier. |
@@ -170,17 +176,17 @@ sequenceDiagram
170176
| `side` |||| Current position side. |
171177
| `signed_qty` |||| Signed quantity (negative=short). |
172178
| `quantity` |||| Unsigned position quantity. |
173-
| `peak_qty` | - ||| Largest quantity held. |
179+
| `peak_qty` | ||| Largest quantity held. |
174180
| `last_qty` |||| Quantity of the last fill. |
175181
| `last_px` |||| Price of the last fill. |
176182
| `currency` |||| Settlement currency. |
177183
| `avg_px_open` |||| Average entry price. |
178184
| `avg_px_close` | - ||| Average exit price. |
179185
| `realized_return` | - ||| Realized return as a ratio. |
180-
| `realized_pnl` | - ||| Realized profit and loss. |
186+
| `realized_pnl` | ||| Realized profit and loss. |
181187
| `unrealized_pnl` | - ||| Unrealized profit and loss. |
182188
| `duration_ns` | - | - || Time held in nanoseconds. |
183-
| `ts_opened` | - ||| Timestamp when position opened. |
189+
| `ts_opened` | ||| Timestamp when position opened. |
184190
| `ts_closed` | - | - || Timestamp when position closed. |
185191
| `event_id` |||| Unique event identifier. |
186192
| `ts_event` |||| Timestamp of the triggering fill. |
@@ -211,7 +217,8 @@ opening_order_id = position.opening_order_id
211217

212218
Account state contains balances, margins, account type, and base currency.
213219
The `Portfolio` subscribes to these events internally to maintain exposure
214-
and balance tracking.
220+
and balance tracking. See [`AccountState`](account_state.md) for the full
221+
field list.
215222

216223
## Event subscriptions
217224

@@ -230,12 +237,12 @@ These are useful for monitoring actors that track execution quality or fill
230237
rates across strategies without participating in order management.
231238

232239
For details and examples, see
233-
[Order event subscriptions](actors.md#order-event-subscriptions).
240+
[Order event subscriptions](../actors.md#order-event-subscriptions).
234241

235242
## Related guides
236243

237-
- [Orders](orders/) - Order types and state machine.
238-
- [Positions](positions.md) - Position lifecycle and PnL.
239-
- [Execution](execution.md) - Execution flow and risk checks.
240-
- [Strategies](strategies.md) - Handler implementations in strategies.
241-
- [Architecture](architecture.md) - Data and execution flow patterns.
244+
- [Orders](../orders/) - Order types and state machine.
245+
- [Positions](../positions.md) - Position lifecycle and PnL.
246+
- [Execution](../execution.md) - Execution flow and risk checks.
247+
- [Strategies](../strategies.md) - Handler implementations in strategies.
248+
- [Architecture](../architecture.md) - Data and execution flow patterns.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# OrderAccepted
2+
3+
`OrderAccepted` represents an order having been accepted by the trading venue. The
4+
`ExecutionEngine` applies it to the order, updates the `Cache`, and publishes it on the
5+
`MessageBus`. It fires when the venue acknowledges the order as received and valid (often
6+
a FIX `NEW` OrdStatus).
7+
8+
Transition: `SUBMITTED` -> `ACCEPTED`. Handler: `on_order_accepted`.
9+
10+
## Fields
11+
12+
`OrderAccepted` carries only the [common order event fields](index.md#common-order-event-fields). On this event, `venue_order_id` and `account_id` are
13+
populated, and `reconciliation` carries a real value (default `False`).
14+
15+
## Example
16+
17+
Reading the event in a strategy handler:
18+
19+
```python
20+
def on_order_accepted(self, event: OrderAccepted) -> None:
21+
self.log.info(
22+
f"Order {event.client_order_id} accepted as {event.venue_order_id}",
23+
)
24+
```
25+
26+
## Related guides
27+
28+
- [Events](index.md) - Event categories, dispatch, and the common order event fields.
29+
- [Orders](../orders/) - Order types and the state machine.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# OrderCancelRejected
2+
3+
`OrderCancelRejected` represents a `CancelOrder` command having been rejected by the
4+
trading venue. The `ExecutionEngine` applies it to the order, updates the `Cache`, and
5+
publishes it on the `MessageBus`. It fires when the venue rejects a cancel request.
6+
7+
Transition: `PENDING_CANCEL` -> previous status (for example `ACCEPTED`). Handler:
8+
`on_order_cancel_rejected`.
9+
10+
## Fields
11+
12+
Beyond the [common order event fields](index.md#common-order-event-fields), `OrderCancelRejected` carries:
13+
14+
| Field | Python type | Required/default | Description |
15+
|----------|-------------|------------------|-----------------------------------|
16+
| `reason` | `str` | Required | The order cancel rejected reason. |
17+
18+
On this event, `venue_order_id` and `account_id` are usually populated but may be `None`,
19+
and `reconciliation` carries a real value.
20+
21+
## Example
22+
23+
Reading the event in a strategy handler:
24+
25+
```python
26+
def on_order_cancel_rejected(self, event: OrderCancelRejected) -> None:
27+
self.log.warning(
28+
f"Cancel rejected for {event.client_order_id}: {event.reason}",
29+
)
30+
```
31+
32+
## Related guides
33+
34+
- [Events](index.md) - Event categories, dispatch, and the common order event fields.
35+
- [Orders](../orders/) - Order types and the state machine.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# OrderCanceled
2+
3+
`OrderCanceled` represents an order having been canceled at the trading venue. The
4+
`ExecutionEngine` applies it to the order, updates the `Cache`, and publishes it on the
5+
`MessageBus`. It fires when the venue confirms cancellation of the order.
6+
7+
Transition: `PENDING_CANCEL` / `ACCEPTED` -> `CANCELED`. Handler: `on_order_canceled`.
8+
9+
## Fields
10+
11+
`OrderCanceled` carries only the [common order event fields](index.md#common-order-event-fields). On this event, `venue_order_id` and `account_id` are
12+
usually populated but may be `None`, and `reconciliation` carries a real value.
13+
14+
## Example
15+
16+
Reading the event in a strategy handler:
17+
18+
```python
19+
def on_order_canceled(self, event: OrderCanceled) -> None:
20+
self.log.info(f"Order {event.client_order_id} canceled")
21+
```
22+
23+
## Related guides
24+
25+
- [Events](index.md) - Event categories, dispatch, and the common order event fields.
26+
- [Orders](../orders/) - Order types and the state machine.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# OrderDenied
2+
3+
`OrderDenied` represents an order having been denied by the Nautilus system. The
4+
`ExecutionEngine` applies it to the order, updates the `Cache`, and publishes it on the
5+
`MessageBus`. It fires when an otherwise valid order cannot be submitted, for example due
6+
to a risk limit or an unsupported feature.
7+
8+
Transition: `INITIALIZED` -> `DENIED`. Handler: `on_order_denied`.
9+
10+
## Fields
11+
12+
Beyond the [common order event fields](index.md#common-order-event-fields), `OrderDenied` carries:
13+
14+
| Field | Python type | Required/default | Description |
15+
|----------|-------------|------------------|--------------------------|
16+
| `reason` | `str` | Required | The order denied reason. |
17+
18+
On this event, `venue_order_id` and `account_id` are both `None`, `reconciliation` is
19+
always `False`, and `ts_event` equals `ts_init`.
20+
21+
## Example
22+
23+
Reading the event in a strategy handler:
24+
25+
```python
26+
def on_order_denied(self, event: OrderDenied) -> None:
27+
self.log.warning(f"Order {event.client_order_id} denied: {event.reason}")
28+
```
29+
30+
## Related guides
31+
32+
- [Events](index.md) - Event categories, dispatch, and the common order event fields.
33+
- [Execution](../execution.md) - Risk checks and order denied reasons.
34+
- [Orders](../orders/) - Order types and the state machine.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# OrderEmulated
2+
3+
`OrderEmulated` represents an order having become emulated by the Nautilus system. The
4+
`ExecutionEngine` applies it to the order, updates the `Cache`, and publishes it on the
5+
`MessageBus`. It fires when the `OrderEmulator` takes an order under local emulation.
6+
7+
Transition: `INITIALIZED` -> `EMULATED`. Handler: `on_order_emulated`.
8+
9+
## Fields
10+
11+
`OrderEmulated` carries only the [common order event fields](index.md#common-order-event-fields). On this event, `venue_order_id` and `account_id` are
12+
both `None`, `reconciliation` is always `False`, and `ts_event` equals `ts_init`.
13+
14+
## Example
15+
16+
Reading the event in a strategy handler:
17+
18+
```python
19+
def on_order_emulated(self, event: OrderEmulated) -> None:
20+
self.log.info(f"Order {event.client_order_id} is now emulated locally")
21+
```
22+
23+
## Related guides
24+
25+
- [Events](index.md) - Event categories, dispatch, and the common order event fields.
26+
- [Emulated orders](../orders/emulated.md) - The local emulation lifecycle.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# OrderExpired
2+
3+
`OrderExpired` represents an order having expired at the trading venue. The
4+
`ExecutionEngine` applies it to the order, updates the `Cache`, and publishes it on the
5+
`MessageBus`. It fires when the order reaches its expiry (for example a GTD order) at the
6+
venue.
7+
8+
Transition: `ACCEPTED` -> `EXPIRED`. Handler: `on_order_expired`.
9+
10+
## Fields
11+
12+
`OrderExpired` carries only the [common order event fields](index.md#common-order-event-fields). On this event, `venue_order_id` and `account_id` are
13+
usually populated but may be `None`, and `reconciliation` carries a real value.
14+
15+
## Example
16+
17+
Reading the event in a strategy handler:
18+
19+
```python
20+
def on_order_expired(self, event: OrderExpired) -> None:
21+
self.log.info(f"Order {event.client_order_id} expired")
22+
```
23+
24+
## Related guides
25+
26+
- [Events](index.md) - Event categories, dispatch, and the common order event fields.
27+
- [Orders](../orders/) - Order types and the state machine.

0 commit comments

Comments
 (0)