Contributing Brokerages

Creating the Brokerage

IBrokerage
Primary RoleBrokerage connection, orders, and fill events.
InterfaceIBrokerage.cs
ExampleBitfinexBrokerage.cs
Target LocationLean.Brokerages.<brokerageName> / QuantConnect.<brokerageName>Brokerage /

Introduction

The IBrokerage holds the bulk of the core logic responsible for running the brokerage implementation. Many smaller models described later internally use the brokerage implementation, so its best to now start implementating the IBrokerage. Brokerage classes can get quite large, so use a partial class modifier to break up the files in appropriate categories.

Prerequisites

You need to lay the foundation before you can create a new brokerage.

Brokerage Roles

The brokerage has many the following important roles vital for the stability of a running algorithm:

  1. Maintain Connection - Connect and maintain connection while algorithm running.
  2. Setup State - Initialize the algorithm portfolio, open orders and cashbook.
  3. Order Operations - Create, update and cancel orders.
  4. Order Events - Receive order fills and apply them to portfolio.
  5. Account Events - Track non-order events (cash deposits/removals).
  6. Brokerage Events - Interpret brokerage messages and act when required.
  7. Serve History Requests - Provide historical data on request.

Brokerages often have their own ticker styles, order class names, and event names. Many of the methods in the brokerage implementation may simply be converting from the brokerage object format into LEAN format. You should plan accordingly to write neat code.

The brokerage must implement the following interfaces:

class MyBrokerage : Brokerage, IDataQueueHandler, IDataQueueUniverseProvider { ... }

Implementation Style

This guide focuses on implementing the brokerage step-by-step in LEAN because it's a more natural workflow for most people. You can also follow a more test-driven development process by following the test harness. To do this, create a new test class that extends from the base class in Lean / Tests / Brokerages / BrokerageTests.cs. This test-framework tests all the methods for an IBrokerage implementation.

Connection Requirements

LEAN is best used with streaming or socket-based brokerage connections. Streaming brokerage implementations allow for the easiest translation of broker events into LEAN events. Without streaming order events, you will need to poll for to check for fills. In our experience, this is fraught with additional risks and challenges.

SDK Libraries

Most brokerages provide a wrapper for their API. If it has a permissive license and it's compatible with .NET 6, you should utilize it. Although it is technically possible to embed an external github repository, we've elected to not do this to make LEAN easier to install (submodules can be tricky for beginners). Instead, copy the library into its own subfolder of the brokerage implementation. For example, Lean.Brokerages.<brokerageName> / QuantConnect.<brokerageName>Brokerage / BrokerLib / *. After you add a library, build the project again to make sure the library successfully compiles.

LEAN Open-Source. If you copy and paste code from an external source, leave the comments and headers intact. If they don't have a comment header, add one to each file, referencing the source. Let's keep the attributions in place.

Define the Brokerage Class

The following sections describe components of the brokerage implementation in the Lean.Brokerages.<brokerageName> / QuantConnect.<brokerageName>Brokerage / <brokerageName>Brokerage.cs file.

Base Class

Using a base class is optional but allows you to reuse event methods we have provided. The Brokerage object implements these event handlers and marks the remaining items as abstract.

LEAN provides an optional base class BaseWebsocketsBrokerage which seeks to connect and maintain a socket connection and pass messages to an event handler. As each socket connection is different, carefully consider before using this class. It might be easier and more maintainable to simply maintain your own socket connection.

Brush up on the partial class keyword. It will help you break-up your class later.

Class Constructor

Once the scaffolding brokerage methods are in place (overrides of the abstract base classes), you can focus on the class constructor. If you are using a brokerage SDK, create a new instance of their library and store it to a class variable for later use. You should define the constructor so that it accepts all the arguments you pass it during the CreateBrokerage method you implemented in the Lean.Brokerages.<brokerageName> / QuantConnect.<brokerageName>Brokerage / <brokerageName>BrokerageFactory.cs file.

The following table provides some example implementations of the brokerage class constructor:

BrokerageDescription
Interactive BrokersLaunches an external process to create the brokerage.
OANDACreates an SDK instance and assigns internal event handlers.
CoinbaseOffloads constructor work to BrokerageFactory and uses the BaseWebsocketBrokerage base class.

string Name

The Name property is a human-readable brokerage name for debugging and logging. For US Equity-regulated brokerages, convention states this name generally ends in the word "Brokerage".

void Connect()

The Connect method triggers logic for establishing a link to your brokerage. Normally, we don't do this in the constructor because it makes algorithms and brokerages die in the BrokerageFactory process. For most brokerages, to establish a connection with the brokerage, call the connect method on your SDK library.

The following table provides some example implementations of the Connect method:

BrokerageDescription
Interactive BrokersConnects to an external process with the brokerage SDK.
OANDASimple example that calls the brokerage SDK.
CoinbaseEstablishes the WebSocket connection and monitoring in a thread.

If a soft failure occurs like a lost internet connection or a server 502 error, create a new BrokerageMessageEvent so you allow the algorithm to handle the brokerage messages. For example, Interactive Brokers resets socket connections at different times globally, so users in other parts of the world can get disconnected at strange times of the day. Knowing this, they may elect to have their algorithm ignore specific disconnection attempts.

If a hard failure occurs like an incorrect password or an unsupported API method, throw a real exception with details of the error.

void Disconnect()

The Disconnect method is called at the end of the algorithm before LEAN shuts down.

bool IsConnected

The IsConnected property is a boolean that indicates the state of the brokerage connection. Depending on your connection style, this may be automatically handled for you and simply require passing back the value from your SDK. Alternatively, you may need to maintain your own connection state flag in your brokerage class.

bool PlaceOrder(Order order)

The PlaceOrder method should send a new LEAN order to the brokerage and report back the success or failure. The PlaceOrder method accepts a generic Order object, which is the base class for all order types. The first step of placing an order is often to convert it from LEAN format into the format that the brokerage SDK requires. Your brokerage implementation should aim to support as many LEAN order types as possible. There may be other order types in the brokerage, but implementing them is considered out of scope of a rev-0 brokerage implementation.

Converting order types is an error-prone process and you should carefully review each order after you've ported it. Some brokerages have many properties on their orders, so check each required property for each order. To simplify the process, define an internal BrokerOrder ConvertOrder(Order order) method to convert orders between LEAN format and your brokerage format. Part of the order conversion might be converting the brokerage ticker (for example, LEAN name "EURUSD" vs OANDA name "EUR/USD"). This is done with a BrokerageSymbolMapper class. You can add this functionality later. For now, pass a request for the brokerage ticker to the stub implementation.

Once the order type is converted, use the IsConnected property to check if you're connected before placing the order. If you're not connected, throw an exception to halt the algorithm. Otherwise, send the order to your brokerage submit API. Oftentimes, you receive an immediate reply indicating the order was successfully placed. The PlaceOrder method should return true when the order is accepted by the brokerage. If the order is invalid, immediately rejected, or there is an internet outage, the method should return false.

bool UpdateOrder(Order order)

The UpdateOrder method transmits an update request to the API and returns true if it was successfully processed. Updating an order is one of the most tricky parts of brokerage implementations. You can easily run into synchronization issues.

The following table provides some example implementations of the UpdateOrder method:

BrokerageDescription
Interactive BrokersUpdates multiple asset classes with an external application.
OANDASimple example that calls the brokerage SDK.
CoinbaseThrows an exception because order updates are not supported.

bool CancelOrder(Order order)

bool UpdateOrder(Order order)

List<Order> GetOpenOrders()

List<Holding> GetAccountHoldings()

List<Cash> GetCashBalance()

bool AccountInstantlyUpdated

IEnumerable<BaseData> GetHistory(HistoryRequest request)

bool AccountInstantlyUpdated

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: