Brokerage gateways

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.

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,
}
Capabilities and sub-gateways agree. A capability flag is the contract; the sub-gateway is the implementation. If you advertise 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 + a BrokerRegistration and 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 Data and set HasOwnMarketData: false on the registration; charts route to the asset-class data fallback.
  • You only need account/position read-only access (phase one) — implement just Account, advertise only Positions / Balances, and add trading later. Unadvertised actions are greyed out, never errors.
Crypto venues are a separate seam. This gateway is the broker analogue of the crypto layer's 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