Skip to content

Plugin Types

Every component in Meridian beyond the kernel, the message bus, and the sidecar is a plugin. Plugins are built by vendors and run within deployments. Each plugin connects exclusively to its local sidecar on localhost:9191 and communicates with the rest of the platform through pub/sub messages on the bus.

This page covers each plugin type: what it does, what it publishes, what it subscribes to, and how it interacts with the kernel.


DGM (Data Gateway Manager)

A DGM plugin normalizes external data sources into the kernel's canonical schema. Each DGM instance corresponds to one external data provider or venue (e.g., Bloomberg, Polygon, Databento, a CSV file).

Three-Stage Pipeline

Every DGM plugin implements a three-stage data fetch pipeline, orchestrated by the sidecar:

Stage Method Description
1 transform_query(subscription_request) Translates a kernel subscription request into a vendor-specific query. Maps kernel instrument identifiers to the provider's symbology.
2 extract_data(normalized_query, credentials) Fetches data from the external provider. All network egress passes through the sidecar's network proxy. Credentials are injected by the sidecar and must not be stored or logged.
3 transform_data(normalized_query, raw_response) Transforms the provider-specific response into kernel-canonical events. Every output event must carry both ts_event and ts_init.

The plugin does not call these stages directly in response to bus messages. The sidecar orchestrates the pipeline.

Streaming Hooks

DGM plugins that support real-time streaming implement three additional hooks:

Hook Description
on_subscribe(symbol, resolution) Initiates a streaming subscription at tick, 1s, 1m, 1h, or 1d resolution.
on_unsubscribe(symbol) Terminates a streaming subscription.
on_tick(raw_tick) Normalizes a single raw tick into a NormalizedTick with dual timestamps.

Subscription management is handled by the sidecar. The plugin does not maintain its own subscription registry.

Feed Status

DGM plugins publish feed status updates to platform.dgm.{id}.data.feed.status whenever connection state changes. Status values: CONNECTED, DISCONNECTED, DEGRADED, RECONNECTING.

Publishes

Topic Pattern Content
platform.dgm.{id}.data.price.eod End-of-day prices
platform.dgm.{id}.data.price.tick Real-time tick data
platform.dgm.{id}.data.reference.instrument Instrument reference data
platform.dgm.{id}.data.alt.{subtype} Alternative data
platform.dgm.{id}.data.feed.status Feed health status

Subscribes To

DGM plugins subscribe to kernel subscription requests. They do not subscribe to other plugin output.

Kernel API

DGM plugins do not use OMS, EMS, or BOR kernel APIs directly. They produce data that other plugins consume.


Signal Engine

A Signal Engine consumes market data and reference data to generate trading insights. Signal Engines operate in a read-only capacity with respect to order flow.

Primary Hook

Method Input Output
on_data(data_window) A DataWindow bundling bars, ticks, reference data, and corporate actions Zero or more Insight objects

Insight Schema

Insight {
  symbol         string     Instrument identifier (kernel canonical ID)
  direction      enum       Up, Down, or Flat
  magnitude      float64    Expected magnitude, normalized to [0.0, 1.0]
  confidence     float64    Confidence in prediction, [0.0, 1.0]
  source_model   string     Name of the generating model or strategy
  weight         float64    Relative weight (default: 1.0, optional)
  period         Duration   Expected time horizon
  generated_at   Timestamp  Plugin wall-clock time
  close_at       Timestamp  Expiration time (must equal generated_at + period)
}

Order Submission Prohibition

A Signal Engine must not submit, modify, or cancel orders. The sidecar enforces this: any attempt to publish to platform.oms.* or platform.ems.* is rejected with ACL_DENIED. Signal Engines are restricted to platform.signal.* topics.

Warmup Protocol

A Signal Engine may declare a warmup requirement (warmup_bars or warmup_period). During warmup, the sidecar replays historical data through on_data with is_warmup = true. Insights generated during warmup are discarded, not published to the bus. The plugin transitions to RUNNING only after warmup completes.

Publishes

Topic Pattern Content
platform.signal.{id}.signal.insight Individual insight objects

Subscribes To

Topic Pattern Content
platform.dgm.*.data.price.* Market data from DGM plugins
platform.dgm.*.data.reference.* Reference data

Kernel API

Signal Engines do not use kernel APIs. They produce insights consumed by Portfolio Optimizers.


Portfolio Optimizer

A Portfolio Optimizer converts aggregated signals into target portfolio weights. It bridges the gap between alpha research (Signal Engines) and order generation (OMS).

Publishes

Topic Pattern Content
platform.optimizer.{id}.target.weights Target portfolio weights per instrument

Subscribes To

Topic Pattern Content
platform.signal.*.signal.aggregated Aggregated insights from Signal Pool Manager

Kernel API

Portfolio Optimizers may read current positions via the BOR API (GetPositions) to compute the delta between current and target weights. They do not write to the kernel directly. Order creation is handled downstream by the OMS.


OMS (Order Management System)

An OMS plugin manages order creation, compliance checks, allocation, and the pre-trade/post-trade lifecycle. It is the entry point for all order flow into the kernel.

Key Responsibilities

  • Create, modify, and cancel orders
  • Trigger pre-trade and post-trade compliance checks
  • Allocate block fills to individual accounts
  • Hand off orders to the trading desk (SendToTrader) and to operations (SendToOperations)
  • Create remainder orders for partial fills via the CloseOrder / CreateRemainderOrder pattern
  • Merge and split orders

Publishes

Topic Pattern Content
platform.oms.{id}.order.created New order events
platform.oms.{id}.order.compliance.* Compliance check results
platform.oms.{id}.order.allocated Allocation results
platform.oms.{id}.order.cancelled Cancellation events

Subscribes To

Topic Pattern Content
platform.optimizer.*.target.weights Target weights from Portfolio Optimizer
platform.oms.*.order.compliance.* Compliance results (from compliance plugins)

Kernel API

OMS plugins use the OMS API surface extensively: CreateOrder, UpdateOrder, CancelOrder, CloseOrder, CreateRemainderOrder, CreateAllocation, SendToTrader, SendToOperations.


EMS (Execution Management System)

An EMS plugin handles smart order routing, algorithm selection, RFQ workflows, and fill aggregation. It takes orders approved by the OMS and creates placements at venues via CCM plugins.

Key Responsibilities

  • Split orders into placements across brokers and venues
  • Select execution strategies via the algo wheel (SelectStrategy)
  • Manage RFQ (Request for Quote) workflows for quote-driven markets
  • Aggregate responses from child placements back to the parent order
  • Close orders and compute executed/unfilled quantities

Strategy Wheel

The EMS supports pluggable execution algorithms as named strategies. SelectStrategy evaluates the order and market context, returning a broker, algorithm, parameters, and confidence score. The result is a recommendation; the caller may override it.

RFQ Workflow

RFQ is a first-class execution paradigm, not a special case. It is the primary pattern for fixed income and certain FX instruments. The workflow:

  1. RequestQuotes creates one placement per dealer with strategy RFQ
  2. Dealers respond with quotes (responses in QUOTED state)
  3. SelectQuote accepts one quote (transitions to FILLED) and cancels the others

Publishes

Topic Pattern Content
platform.ems.{id}.placement.created New placement events
platform.ems.{id}.order.closed Order close events with executed/unfilled quantities

Subscribes To

Topic Pattern Content
platform.oms.*.order.* Order events from OMS
platform.ccm.*.fill.recorded Fill events from CCM plugins
platform.ccm.*.execution.rfq.* RFQ quotes from CCM plugins

Kernel API

EMS plugins use the EMS API surface: CreatePlacement, CancelPlacement, CloseOrder, CreateResponse, SelectStrategy, RequestQuotes, SelectQuote.


CCM (Capital and Connectivity Manager)

A CCM plugin manages connectivity to a single execution venue or broker. Each CCM instance corresponds to one broker session or venue connection.

Required Methods

Method Description
connect(credentials) Establishes connection to the venue. Credentials are injected by the sidecar and must not be stored or logged.
disconnect() Gracefully disconnects. Must cancel or acknowledge all in-flight orders first.
submit_order(order) Submits a child order to the venue. Translates to venue's native protocol (e.g., FIX NewOrderSingle).
cancel_order(order_id) Requests cancellation at the venue. The acknowledgment does not guarantee cancellation.
modify_order(order_id, changes) Requests modification (price, quantity, time-in-force). Translates to the venue's cancel/replace protocol.

FIX Adapter Pattern

CCM plugins typically implement a FIX adapter. The plugin translates between the kernel's order model and FIX messages (NewOrderSingle, OrderCancelRequest, OrderCancelReplaceRequest, ExecutionReport). The kernel model is a superset of FIX, so translation is always possible.

Fill Requirements

  • Every fill event must include a trade_id field with the venue-assigned trade identifier. This field is required and must not be empty or synthetic.
  • Fill deduplication is handled by the sidecar using the composite key (trade_id, side, price, quantity, venue). The plugin must not implement its own deduplication.
  • Fills must carry dual timestamps: ts_event (venue execution time) and ts_init (CCM receive time).

Session Management

CCM plugins publish session status to platform.ccm.{id}.session.status with values: CONNECTED, DISCONNECTED, LOGON_PENDING, RECONNECTING. They must implement automatic reconnection with exponential backoff. During reconnection, the plugin enters DEGRADED state and rejects new order submissions. Pending orders must be reconciled on reconnection.

Publishes

Topic Pattern Content
platform.ccm.{id}.fill.recorded Fill events
platform.ccm.{id}.execution.rfq.quote.received RFQ quotes
platform.ccm.{id}.order.child.routed Child order routed confirmations
platform.ccm.{id}.session.connected Session connected
platform.ccm.{id}.session.disconnected Session disconnected

Subscribes To

Topic Pattern Content
platform.ems.*.placement.created Placement events from EMS

Kernel API

CCM plugins use the EMS API to report responses: CreateResponse, UpdateResponseStatus, AmendResponse, CancelResponse.


BOR (Book of Record)

The BOR API surface provides position queries, cash management, settlement, reconciliation, journal accounting, and multi-currency translation. The order-book kernel handles the order-to-fill lifecycle; BOR focuses on the post-trade balance sheet.

Key Responsibilities

  • Query positions by portfolio, instrument, status, or date
  • Query and project cash balances and cash movements
  • Manage the settlement lifecycle: confirm, settle, reconcile
  • Run reconciliations (any-versus-any matching pattern)
  • Ingest external statements (MT535, MT536, CSV, API JSON)
  • Maintain a double-entry journal with chart of accounts
  • Multi-currency translation and FX P&L

What BOR Does Not Do

BOR records transactions and maintains balances. It explicitly does not:

  • Value positions (valuation plugin)
  • Select lots to sell (OMS decides, advised by tax plugin)
  • Compute P&L (reporting plugin over transactions)
  • Translate currencies autonomously (FX plugin provides rates)
  • Calculate NAV (aggregation plugin over valuation + fees + cash)
  • Compute accruals (accruals plugin reads holdings + instrument data)

Publishes

BOR publishes settlement status updates, reconciliation break events, and position change events.

Subscribes To

BOR subscribes to fill events, corporate action events, and settlement confirmations from custodians.

Kernel API

BOR uses the BOR API surface: GetPositions, GetCashBalances, SettleOrder, ReconcileOrder, CreateReconciliation, RunReconciliation, PostJournalEntry, TranslatePortfolio.


Valuation (Vendor Plugin)

A Valuation plugin reads BOR positions and market data, then computes mark-to-market values and P&L. Valuation is a vendor plugin, not part of the kernel. The kernel stores quantities and costs; the valuation plugin computes values.

Publishes

Topic Pattern Content
platform.valuation.{id}.mark.* Mark-to-market prices and portfolio values

Subscribes To

Topic Pattern Content
platform.dgm.*.data.price.* Market data
BOR position events Current positions

Kernel API

Reads positions via BOR API (GetPositions). Does not write to the kernel.


Compliance (Vendor Plugin)

A Compliance plugin evaluates rules at the pre-trade and post-trade checkpoints in the order lifecycle. Compliance is a vendor plugin, not part of the kernel. The kernel provides the compliance checkpoint state transitions; the compliance plugin evaluates the rules.

Publishes

Topic Pattern Content
platform.compliance.{id}.result.* Compliance check results (pass, fail, with violations)

Subscribes To

Topic Pattern Content
platform.oms.*.order.compliance.* Compliance check requests from OMS
BOR position and cash data For rule evaluation (concentration limits, etc.)

Kernel API

Reads orders and positions via OMS and BOR APIs. Publishes compliance results back to the OMS.


Plugin Lifecycle

All plugins, regardless of type, follow the same lifecycle state machine:

INITIALIZING -> READY -> RUNNING -> STOPPING -> STOPPED
                           |                       |
                           v                       v
                        DEGRADED              DISPOSED
                           |
                           v
                        FAULTED -> DISPOSED
State Meaning
INITIALIZING Sidecar is completing its 8-step startup sequence
READY Sidecar startup complete, waiting for on_start()
RUNNING Plugin is active and processing messages
DEGRADED Plugin is impaired but operational (e.g., lost upstream connection)
FAULTED Terminal failure after 3 consecutive health check failures
STOPPING Graceful shutdown in progress
STOPPED Clean shutdown complete
DISPOSED All resources released

Required Hooks

Hook When Called
on_start() After sidecar completes startup. Must complete within 30 seconds.
on_stop() When graceful shutdown is requested. Must complete within 30 seconds.
on_degrade(reason) When the plugin detects an impairment (e.g., lost data feed).
on_resume() When the plugin recovers from degraded state.

Summary Table

Plugin Type Produces Consumes Uses Kernel API
DGM Market data, reference data, feed status Subscription requests No
Signal Engine Insights Market data No
Portfolio Optimizer Target weights Aggregated signals BOR read (positions)
OMS Orders, compliance events, allocations Target weights, compliance results OMS API
EMS Placements, order close events Orders, fills, RFQ quotes EMS API
CCM Fills, RFQ quotes, session status Placements EMS API (responses)
BOR Settlement status, break events Fills, corporate actions, settlements BOR API
Valuation Mark-to-market values Market data, positions BOR read
Compliance Compliance results Compliance requests, positions OMS/BOR read

Next Steps