Brokerage gateways
Overview
A brokerage gateway is the single broker-facing port behind the generic trading and data providers: one venue assembly speaks a vendor SDK, exposes three venue-neutral sub-gateways (data, trading, account) plus a factory and a registration row, and the whole platform lights up for that broker with no generic-layer changes.
On this page
What a brokerage gateway is
The Trading providers chapter covers ITradingProvider — the
platform-facing execution seam every consumer (chart trader, strategies, risk rules) talks to. A
brokerage gateway sits one level below that: it is the broker-facing integration seam,
the one place where a vendor SDK (Alpaca, OANDA, IBKR, FXCM, Saxo, Tradier, cTrader, …) is wrapped.
The contract is IBrokerageGateway (namespace TradeStrike.Pipeline.Brokerage). It is
the single venue port for a forex/equities broker — the one seam between the generic TradeStrike
providers and a concrete broker SDK. The provider/connection layer depends only on this
interface (Dependency Inversion); your per-broker assembly supplies the one class that knows the vendor
SDK, and faking the whole broker in a unit test touches nothing else.
IBrokerageGateway.csusing TradeStrike.Pipeline.Brokerage;
using TradeStrike.Pipeline.Trading; // AccountMode
public interface IBrokerageGateway : IDisposable
{
string BrokerKey { get; } // stable lower-case venue key, e.g. "alpaca"
BrokerCapabilities Capabilities { get; } // what this gateway actually supports
IBrokerageDataGateway? Data { get; } // null = no own market data (use the fallback)
IBrokerageTradingGateway? Trading { get; } // null = data/account only
IBrokerageAccountGateway? Account { get; } // null = no account/position/balance feed
BrokerConnectionStatus Status { get; }
event Action<BrokerConnectionStatus>? ConnectionStatusChanged;
Task ConnectAsync(BrokerCredentials credentials, AccountMode mode, CancellationToken ct = default);
Task DisconnectAsync();
}
Gateway vs. trading provider
Both seams exist because they solve different problems. A trading provider is what the platform consumes;
a brokerage gateway is what a broker integration implements. The generic
BrokerTradingProvider / data provider / account stream are driven entirely from your gateway,
so you write the vendor adapter once and inherit every platform feature.
INTERFACE IBrokerageGateway
Broker-facing. You implement this in a per-broker assembly. Wraps a vendor SDK and speaks venue-neutral DTOs. Three nullable sub-gateways declare what the venue does.
INTERFACE ITradingProvider
Platform-facing. The host's generic provider implements this on top of your gateway. You normally do not implement it for a broker — the gateway is enough. See the trading provider page.
In short: implement IBrokerageGateway and the platform synthesises the
ITradingProvider, the data provider, and the account-state stream for you. The DTOs are
deliberately venue-neutral — no vendor-SDK type crosses the seam — so the same generic providers
serve every broker.
The three sub-gateways + factory
A broker has three concerns, and each is its own sub-gateway hanging off IBrokerageGateway.
The sub-gateways are nullable: a broker exposes only what it does. A null Data means
"no own market data" (the provider uses the asset-class data fallback — e.g. dxFeed for equities); a
null Trading or Account greys out those actions in the UI rather than throwing.
graph TD;
F[IBrokerageGatewayFactory.Create]-->G[IBrokerageGateway];
R[BrokerRegistration]-->F;
R-->C[BrokerCapabilities];
G-->D[IBrokerageDataGateway · nullable];
G-->T[IBrokerageTradingGateway · nullable];
G-->A[IBrokerageAccountGateway · nullable];
D-->DP[generic data provider];
T-->TP[generic trading provider];
A-->AS[account-state stream];
Data
IBrokerageDataGateway — historical BrokerBars, a live
BrokerTrade stream, and the tradable BrokerInstrument universe.
Trading
IBrokerageTradingGateway — place / cancel / modify / flatten, symbol rules, and the
live BrokerOrderUpdate stream.
Account
IBrokerageAccountGateway — accounts, positions, per-asset balances, plus push
events when any of them change.
The gateway itself is created by an IBrokerageGatewayFactory — a typed factory (not a
Func<IServiceProvider, …>), so the per-broker assembly states its real
dependencies in the factory's constructor rather than reaching for a service locator. The factory is held
on a BrokerRegistration row; the connection layer calls Create once per
connection to get a gateway it then drives through ConnectAsync. Registration and capability
negotiation are covered on the Registration & capabilities page.
Capabilities drive the UI
BrokerCapabilities is a [Flags] enum a gateway declares for itself (and a
registration mirrors). The generic data + trading + account providers translate these into the platform's
own capability bitmasks, so a broker that, say, can't modify orders simply never advertises
ModifyOrders downstream — the host greys out the action instead of throwing a
NotSupportedException at click time.
BrokerCapabilities.csusing TradeStrike.Pipeline.Brokerage;
[Flags]
public enum BrokerCapabilities
{
None = 0,
// Market data (drives the data provider)
HistoricalBars = 1 << 0, // IBrokerageDataGateway.GetBarsAsync
LiveTrades = 1 << 1, // IBrokerageDataGateway.SubscribeTrades
Instruments = 1 << 2, // IBrokerageDataGateway.GetInstrumentsAsync
// Trading (drives the trading provider)
PlaceOrders = 1 << 3,
CancelOrders = 1 << 4,
ModifyOrders = 1 << 5, // native amend (else the provider does cancel-replace)
FlattenPositions = 1 << 6,
Brackets = 1 << 7, // native protective stop-loss + take-profit
// Account (drives the account-state stream)
Positions = 1 << 8,
Balances = 1 << 9,
}
HistoricalBars your Data gateway must be
non-null and serve GetBarsAsync; if you advertise ModifyOrders your
Trading.ModifyOrderAsync must work natively (the provider calls it instead of
cancel-replace).
Connection status
Connection lifecycle is a single venue-neutral enum, mirroring the data layer's
ProviderConnectionStatus. The connection orchestrator bridges
ConnectionStatusChanged to the app's connection-state service (and so to the connection
sounds and UI badges).
BrokerConnectionStatus.csusing TradeStrike.Pipeline.Brokerage;
public enum BrokerConnectionStatus
{
Disconnected = 0, // initial / after a clean disconnect
Connecting = 1, // a connect attempt is in progress
Connected = 2, // fully online — data + trading + account calls ready
ConnectionLost = 3, // link dropped unexpectedly (the gateway may be reconnecting)
}
ConnectAsync brings the gateway online for an AccountMode (Live vs Paper picks
the venue's endpoint), authenticates with BrokerCredentials, and throws on a hard
connect failure (bad credentials, venue unreachable, a required local bridge such as IB Gateway not
running). DisconnectAsync takes the gateway offline cleanly and is idempotent.
When to implement one
- You are integrating a forex or equities broker that has a REST/streaming SDK — this is the
intended path. Implement
IBrokerageGateway+ a factory + aBrokerRegistrationand you are done; no per-broker provider code is needed. - Your broker serves its own market data and execution — wire all three sub-gateways.
- Your broker trades but has no usable market data feed — return a null
Dataand setHasOwnMarketData: falseon the registration; charts route to the asset-class data fallback. - You only need account/position read-only access (phase one) — implement just
Account, advertise onlyPositions/Balances, and add trading later. Unadvertised actions are greyed out, never errors.
ICryptoTradingGateway, generalised to data + trading + account behind one gateway. If you are
integrating a spot-crypto exchange, that uses the crypto registration path, not
BrokerRegistration.
Namespaces & where things live
| Concern | Namespace | Key types |
|---|---|---|
| Brokerage gateway | TradeStrike.Pipeline.Brokerage |
IBrokerageGateway, IBrokerageGatewayFactory, IBrokerageDataGateway, IBrokerageTradingGateway, IBrokerageAccountGateway
|
| Registration | TradeStrike.Pipeline.Brokerage |
BrokerRegistration, BrokerCapabilities, BrokerConnectionStatus, BrokerCredentials
|
| DTOs | TradeStrike.Pipeline.Brokerage |
BrokerAccount, BrokerPosition, BrokerInstrument, BrokerSymbolRules, BrokerOrderSpec, BrokerOrderAck, BrokerOrderUpdate, BrokerModifySpec, BrokerModifyAck, BrokerCancelAck, BrokerTrade, BrokerBar
|
| Reused trading types | TradeStrike.Pipeline.Trading |
AccountMode, OrderSide, OrderType, TimeInForce, BracketSpec, AccountBalance, AccountMetrics
|
| Reused vocabulary |
TradeStrike.Pipeline.Bars / TradeStrike.Pipeline.Providers
|
QuantityUnit, InstrumentCategory, ProviderCredentialField
|