Machine-readable execution records for fragmented markets.
OETS protos define the core event structures for describing what happened during execution: orders, fills, balances, fees, funding, settlement, source observations, timestamps, and reported state differences.
The goal is not to create another trading system.
The goal is to make execution explainable.
Modern execution does not happen in one clean place.
An order may start in a wallet, bot, OMS, router, or frontend. It may pass through a protocol, venue, bridge, market maker, indexer, RPC provider, broker, or reporting layer. Each system may record the same event differently.
That is where the rot begins.
One system says the order was filled.
Another system says the balance never changed.
A dashboard says the position is flat.
The ledger says otherwise.
The risk engine is quietly sweating in the corner.
OETS exists so these records can be described using a shared event language.
Not a single source of truth.
A shared structure for comparing partial truths.
OETS protos are designed to preserve execution context, not just execution outputs.
They describe:
- what happened
- when it happened
- when it was observed
- who or what observed it
- what other events it relates to
- what assumptions were used to interpret it
- where reported state diverges from reconstructed state
A fill is not just price and quantity.
A fill may imply:
- an order state transition
- a fee
- a balance change
- a position update
- realized PnL
- settlement
- downstream reconciliation
- a future argument with your own logs
OETS keeps the chain visible.
The first proto set focuses on the execution core. Files live under common/ rather than an oets/v1/ prefix for now; relocating to the buf-canonical layout is a separate follow-up.
common/account.proto
common/event_envelope.proto
common/execution_venue.proto
common/instrument.proto
common/relationships.proto
common/source.proto
common/timestamps.proto
common/execution/fill_event.proto
common/execution/order_event.proto
common/reconciliation/balance_event.proto
common/reconciliation/cash_flow_event.proto
common/reconciliation/fee_event.proto
common/reconciliation/position_event.proto
common/reconciliation/settlement_event.proto
The following wire-breaking changes were introduced in v0.1. Consumers of any pre-v0.1 generated bindings must migrate.
| Area | Change |
|---|---|
| Enum sentinels | All UNKNOWN_* zero-values renamed to *_UNSPECIFIED (e.g. UNKNOWN_ACCOUNT_TYPE = 0 → ACCOUNT_TYPE_UNSPECIFIED = 0). Affects AccountType, VenueType, InstrumentType, ContractType, RelationshipType, SourceType, EventType, OrderType, OrderState, FeeType. |
OrderSide |
BUY = 0 / SELL = 1 shifted to BUY = 1 / SELL = 2; new ORDER_SIDE_UNSPECIFIED = 0 sentinel. |
OrderTimeInForce |
GOOD_TIL_CANCEL = 0, …_IOC = 1, …_FOK = 2 shifted by +1; new ORDER_TIF_UNSPECIFIED = 0 sentinel. |
OrderIntentionType |
RESTING = 0 … ONE_CANCELS_OTHER = 3 shifted by +1; new ORDER_INTENTION_TYPE_UNSPECIFIED = 0 sentinel. |
EventType |
EVENT_TYPE_CASH_FLOW_EVENT renamed to EVENT_TYPE_CASH_FLOW; EVENT_TYPE_SETTLEMENT = 4 added (former gap). |
Fee.amount |
Field type changed from string to int64 (scaled integer per docs/SCALING.md). |
Fee.fee_type |
Field type changed from string to FeeType enum. |
FillEvent |
int64 fee = 12 replaced by Fee fee = 12 (structured sub-message, different wire type); fields fee_asset (13), notional_fee (14), source (15), timestamps (19) removed and reserved. |
OrderEvent |
Fields source (13) and timestamps (14) removed and reserved. |
CashFlowEvent |
OetsEventEnvelope envelope = 1 added (was string event_id = 1); fee_amount (field 9) replaced by Fee fee = 9; routing fields (timestamp, source, related_events, metadata) reserved; event_id and fee_amount names reserved. |
SettlementEvent |
Was an empty stub; now carries a full schema with OetsEventEnvelope, settlement type/amount/asset/mark price, and related-ID fields. |
# Install runtime + dev deps (use a venv)
pip install -r requirements.txt -r requirements-test.txt
# Run tests
pytest tests/
# Regenerate Python bindings if you touched a .proto
make generate_python_protos
# buf (if installed)
buf generate
buf lintcommon/ # .proto source files
├─ account.proto
├─ event_envelope.proto
├─ execution_venue.proto
├─ instrument.proto
├─ relationships.proto
├─ source.proto
├─ timestamps.proto
├─ execution/
│ ├─ fill_event.proto
│ └─ order_event.proto
└─ reconciliation/
├─ balance_event.proto
├─ cash_flow_event.proto
├─ fee_event.proto
├─ position_event.proto
└─ settlement_event.proto
generated/python/ # compiled _pb2.py bindings
validation/ # Python validators (oets_version.py)
tests/ # pytest suite
docs/ # SCALING.md, ARCHITECTURE.md
OETS protos are released under the Apache License 2.0 — see LICENSE.
The Apache 2.0 license permits use, modification, and distribution with attribution. Patent grants are included, and changes must be marked. Full terms in the LICENSE file.
- CONTRIBUTING.md — how to file issues and propose changes
- CHANGELOG.md — version history and breaking changes
- docs/SCALING.md — int64 monetary scaling convention
- docs/ARCHITECTURE.md — envelope-bearing vs snapshot/delta message-type design
- validation/oets_version.py — SemVer 2.0.0 validator for
OetsEventEnvelope.oets_version - buf.yaml — lint config with documented
exceptrules - Makefile — proto regeneration targets