Domain: trading
Curated entry point for the
tradingbounded context. Spans the user-facing trading surface insideapiand the long-running broker-stream pipeline that feeds it.
Owner
Founder + agents (Phase 1).
Mission
Owns everything that touches the broker integration surface: maintaining long-running connections to Rithmic and CQG; translating broker-emitted events into our canonical Kafka topics; the user-facing trading API (order routing for the TradingView broker REST integration); position queries against the broker-stream cache. Boundary: trading owns the broker-facing data plane; rule evaluation lives in risk-engine; the account state machine lives in accounts. We do not ingest raw market data; we consume broker account streams (per docs/PRD/06-rules-risk-engine.md "Data Sources" section).
Code paths
- Application code (user-facing API):
apps/api/src/modules/trading/ - Application code (broker-stream pipeline, separate deploy unit):
apps/broker-streams/ - Domain logic (pure):
packages/domain/trading/ - Contracts:
packages/contracts/api/trading.ts,packages/contracts/events/trading.ts,packages/contracts/integrations/rithmic.ts,packages/contracts/integrations/cqg.ts - External clients:
packages/clients/rithmic/,packages/clients/cqg/ - Database schemas owned:
trading(BrokerAccount, BrokerSession, OrderEvent, FillEvent, PositionState, BrokerHealthCheck)
PRD chapters that touch this domain
04-trader-dashboard.md- trader UI consumes the trading surface06-rules-risk-engine.md- "Data Sources" subsection: what we ingest from brokers and what we explicitly do not08-live-transition.md- broker-clearing relationship for Edge Live10-integrations.md- Rithmic + CQG + TradingView integration specs16-open-questions.md- Q-E13 (Phase 1 broker scope: Rithmic + CQG)
TDD chapters
(Empty - will populate as TDDs arrive.)
ADRs that affected this domain
- ADR-0001 (
broker-streamsis one of the four extracted long-runners)
Service interfaces this domain exposes
export interface TradingService {
// getBrokerAccount(accountId): Promise<BrokerAccount>
// getCurrentPositions(brokerAccountId): Promise<Position[]>
// routeTradingViewOrder(payload: TradingViewOrderRequest): Promise<OrderResult>
// recordBrokerSessionState(brokerAccountId, state): Promise<void>
// (full surface defined during trading TDD)
}
Events this domain produces / consumes
| Direction | Topic | Schema |
|---|---|---|
| produces | trading.broker.order_event | Order submitted / acknowledged / canceled / rejected |
| produces | trading.broker.fill_event | Fill from Rithmic or CQG |
| produces | trading.broker.position_state | Position-level marked PnL from broker |
| produces | trading.broker.account_state | Cash, equity, balance updates |
| produces | trading.broker.session_event | Connection up/down, halt, market session boundaries |
External integrations
- Rithmic - account event stream (orders, fills, position state, marked PnL, account balance, session events) per
docs/PRD/10-integrations.md - CQG - same as Rithmic, for Tradovate Prop and TradingView
- TradingView - server-side broker REST integration we expose (the inverse: TradingView calls us, we route to CQG)
Runbooks for this domain
(Empty - will populate when alerts are defined in Section 17.6. Expected high-priority: broker-stream disconnect, fill-event lag, position drift between broker and our cache.)
On-call
To be filled in Section 17.6. Trading is one of the most operationally sensitive domains - broker disconnects during market hours are Sev 1.
Cross-domain dependencies
- This domain calls:
identity(actor lookup),accounts(link broker account to our account record). - This domain emits events consumed by:
risk-engine(every fill / position update is evaluated),audit(every broker event is logged),notifications(fill notifications via Centrifugo channels),admin(broker-health dashboards).