Broker venues
Broker venues: overview
A broker is a venue whose session also routes orders. One plugin DLL, the same seam every data venue uses, and a trading port implemented directly over your own vendor client.
On this page
A broker is a venue
A broker is a venue plugin like any other (same
IVenuePlugin export, same manifest, same session, same settings form) whose session
publishes a Trading port alongside (or instead of) Data. One seam covers
market data and order routing alike.
Everything in the Venue plugins chapter applies unchanged. This chapter is only about what is specific to routing orders: implementing the trading port directly, the venue-neutral components that carry the order-lifecycle invariants, and the behavioural promises every trading port must keep.
graph LR PL["IVenuePlugin"] --> D["IVenueDescriptor
VenueManifest"] D -->|CreateSession| S["IVenueSession"] S -->|Data| DP["IDataProvider
(optional for a broker)"] S -->|Trading| TP["ITradingProvider"] S -->|AsPort| PO["Chains · Trade history · Cash activity"]
What a broker plugin contains
One DLL per broker, referencing only the SDK contract packages plus its vendor client. The vendor API mapping is the real venue knowledge; the SDK supplies the interface layer around it.
| Piece | What it does |
|---|---|
IVenuePlugin + IVenueDescriptor
|
A stable TypeId, a credential schema that matches the saved profile shape, capabilities declared honestly. |
IVenueSession |
The vendor login / stream bring-up, and the composition root for both ports. |
ITradingProvider |
Your own implementation over your own vendor client: accounts, orders, positions, fills. |
IDataProvider |
Present when the broker also serves market data (most do). Same shape as any data venue. |
| Session ports | Option chains, trade-history backfill, cash activity: whichever the broker has. |
| Tests | Plugin checks, the trading-port promises, and your own venue tests. See Contract tests & capabilities. |
The ports a broker publishes
MyBrokerVenueSession.cs (abridged)internal sealed class MyBrokerVenueSession(VenueSessionContext context)
: IVenueSession, IVenueTradeHistorySource, IVenueCashActivitySource
{
private MyBrokerDataProvider? _data;
private MyBrokerTradingProvider? _trading;
private IOptionChainSource? _chains; // built in ConnectAsync
public IDataProvider? Data => _data;
public ITradingProvider? Trading => _trading;
// Option chains are a separately-owned object built in ConnectAsync, so it is
// exposed only while connected. Trade history + cash activity are implemented
// on the session itself and resolve through the default GetPort probe.
public T? GetPort<T>() where T : class
=> (this as T) ?? (Volatile.Read(ref _chains) as T);
}
Declare the matching manifest flags so the host's registrars know to look:
Trading, TradeHistoryBackfill, CashActivity,
OptionChains.
Shared components
The order-lifecycle invariants that are genuinely venue-neutral live as small, single-purpose
components in SabrTrader.Pipeline.Venues.Trading, and any venue (broker, crypto
exchange, futures gateway) composes the ones it needs. Each takes primitives and delegates rather
than vendor types, so every venue inherits the same tested behaviour.
They are covered on The trading port. The short version: cancel-replace revision tracking, ambiguous-placement resolution, the missed-fill probe, position-snapshot retirement, the order-update fold, and quantity/price snapping.
What to test
A trading venue has two sets of checks. The plugin checks cover the seam shape: loader compatibility, manifest validity, stable TypeIds, contracts-only references, offline lifecycle safety. The trading-port promises cover the behaviour of your trading port: cancel semantics, the OCO leg-gateway contract, realized-PnL nullability, commission honesty, and the seven promises the ATM decides on. Both lists are on Contract tests & capabilities.
Keeping saved profiles working
TypeId is the key
every saved profile of that broker is stored under, and the settings schema decides the exact JSON
those profiles are written as. Keep the id stable, point every field's StorageName at
the property the profile already uses (dotted paths such as PlainValues.Environment and
GatewaySecretsBase64.refresh_token nest into the existing objects), and pin the result
byte-identical against a captured real profile before shipping.
A tour of the chapter
| Page | Covers |
|---|---|
| The trading port | Implementing ITradingProvider directly, the core operations, OCO and multi-leg, the
event stream, and the venue-neutral components. |
| Contract tests & capabilities | Declaring capabilities across both layers, session ports, credential rotation, and the trading-port promises. |
| Trading providers | The full trading contract surface: orders, positions, accounts, events, risk, commissions. |