Event-Driven Workflow

⚠️ This page may evolve as the architecture is refined.

TheoryCraft is built around an event-driven architecture.
Market data, execution updates, and strategy logic communicate exclusively through structured events.

This design ensures that the same trading logic behaves consistently across backtesting, paper trading, and live trading environments.

Core Components

A TheoryCraft system is composed of three conceptual components:

  • MarketSource - produces market data events
  • Broker - produces execution and account events, and receives orders
  • Engines - consume events and perform specific tasks

Each component operates independently and communicates only through events.

Event Streams

Two primary event streams exist in the system:

MarketEvents

MarketEvents are emitted by the MarketSource when new market data becomes available.

They may represent:

  • Price updates (ticks or bars)
  • Timeframe resampling
  • Computed indicators
  • Instrument or session metadata

MarketEvents flow sequentially and represent the passage of market time.

BrokerEvents

BrokerEvents are emitted by the Broker when execution state changes.

They may represent:

  • Order lifecycle updates (submitted, filled, cancelled)
  • Position changes
  • Account balance updates

BrokerEvents reflect the consequences of prior trading decisions.

Engines as Event Consumers

Engines consume one or both event streams depending on their responsibility.

An Engine:

  • Subscribes to MarketEvents and/or BrokerEvents
  • Reacts to events according to its role
  • May emit new artifacts such as orders, metrics, or alerts

Engines do not communicate directly with each other. Coordination emerges through shared event streams.

Event Broadcasting Model

MarketSource and Broker broadcast events to all Engines.

┌──────────────┐     MarketEvent     ┌──────────┐
│ MarketSource │ ──────────────────► │          │
└──────────────┘                     │  Engine  │
                                     │          │
┌──────────────┐     BrokerEvent     │          │
│    Broker    │ ──────────────────► │          │
└──────────────┘ ◄────────────────── └──────────┘
                   Orders / Queries


MarketSource ──(MarketEvents)──► Engines
Broker ────(BrokerEvents)──────► Engines
Engines ──────(Orders)─────────► Broker

Each Engine operates independently and can be added or removed without affecting the rest of the system.

Causal and Reproducible Execution

Each event represents a discrete decision point.

Engines react only to information available at the time of the event. No future data is accessible, eliminating look-ahead bias by construction.

Because events are processed sequentially, a historical replay of events produces the same behavior as live execution.

Same Logic, Different Environments

The event-driven model allows the same Engine logic to run unchanged in different environments:

Backtesting

  • MarketSource replays historical data
  • Broker simulates execution
  • Time advances as fast as events are processed

Paper Trading

  • MarketSource streams live market data
  • Broker simulates execution
  • Time advances in real time

Live Trading

  • MarketSource streams live market data
  • Broker executes orders on real venues
  • Time advances in real time

Only the data source and broker configuration change. Engine logic remains identical.

Why Event-Driven?

Event-driven systems are a natural fit for trading:

  • Accuracy - events mirror how markets evolve over time
  • Consistency - identical logic across environments
  • Composability - Engines can be combined flexibly
  • Fault tolerance - components are isolated
  • Scalability - parallel processing of independent workloads

This architecture favors correctness and reproducibility over raw throughput.

Next Steps