Quantconnect Lean Engine Python
Quantconnect Lean Engine Python
QuantConnect
and Explore
Features
LEAN ENGINE
Radically open-source
algorithmic trading
engine
Multi-asset with full portfolio modeling,
LEAN is data agnostic, empowering you
to explore faster than ever before.
Table of Content
1 Getting Started
2 Contributions
2.1 Datasets
2.1.1 Key Concepts
2.1.2 Defining Data Models
2.1.3 Rendering Data
[Link] Rendering Data with Python
[Link] Rendering Data with CSharp
Getting Started
Introduction
Lean Engine is an open-source algorithmic trading engine built for easy strategy research, backtesting and live
trading. We integrate with common data providers and brokerages so you can quickly deploy algorithmic trading
strategies.
The core of the LEAN Engine is written in C#; but it operates seamlessly on Linux, Mac and Windows operating
systems. It supports algorithms written in Python 3.11 or C#. Lean drives the web-based algorithmic trading
platform QuantConnect .
System Overview
The Engine is broken into many modular pieces which can be extended without touching other files. The modules
are configured in [Link] as set "environments". Through these environments, you can control LEAN to
operate in the mode required.
Result Processing
An IResultHandler that handle all messages from the algorithmic trading engine. Decide what should be sent, and
where the messages should go. The result processing system can send messages to a local GUI, or the web
interface.
Datafeed Sourcing
An IDataFeed that connect and download the data required for the algorithmic trading engine. For backtesting this
sources files from the disk, for live trading, it connects to a stream and generates the data objects.
Transaction Processing
An ITransactionHandler that process new order requests; either using the fill models provided by the algorithm or
with an actual brokerage. Send the processed orders back to the algorithm's portfolio to be filled.
An IRealtimeHandler that generate real-time events - such as the end of day events. Trigger callbacks to real-
time event handlers. For backtesting, this is mocked-up to work on simulated time.
An ISetupHandler that configure the algorithm cash, portfolio and data requested. Initialize all state parameters
required.
These are all configurable from the [Link] file in the Launcher Project.
QuantConnect recommends using Lean CLI for local algorithm development. This is because it is a great tool for
working with your algorithms locally while still being able to deploy to the cloud and have access to Lean data. It is
also able to run algorithms on your local machine with your data through our official docker images.
Installation Instructions
This section will cover how to install lean locally for you to use in your own environment.
Refer to the following readme files for a detailed guide regarding using your local IDE with Lean:
VS Code
VS
To install locally, download the zip file with the latest master and unzip it to your favorite location. Alternatively,
install Git and clone the repo:
Mac OS
Visual Studio for Mac has been discontinued , use Visual Studio Code instead.
1. Install dotnet 6
3. Run Lean
$ cd Launcher/bin/Debug
$ dotnet [Link]
To set up Interactive Brokers integration, make sure you fix the ib-tws-dir and ib-controller-dir fields in the
[Link] file with the actual paths to the TWS and the IBController folders respectively. If after all you still
receive connection refuse error, try changing the ib-port field in the [Link] file from 4002 to 4001 to match
Windows
Python Support
A full explanation of the Python installation process can be found in the [Link] project.
Seamlessly develop locally in your favorite development environment, with full autocomplete and debugging
support to quickly and easily identify problems with your strategy. For more information please see the CLI
documentation .
Roadmap
Our Roadmap shows the feature requests and bugs that receive the most attention from community members. The
core QuantConnect team gives priority to the feature requests and bugs that have the most votes. If you want to
shape the future of QuantConnect and LEAN, vote today. To add a new item to the roadmap, create a new GitHub
Issue on the LEAN repository and then react to it with a thumbs up emoji.
Sponsorships
Sponsor QuantConnect to support our developers as we improve a revolutionary quantitative trading platform
LEAN, in an open, collaborative way. We will continue to level the playing field with industry-grade tools and data
accessibility. We use sponsorship funds to achieve the following goals:
To connect more individuals with financial institutions so individuals can gain income for their ideas at scale
Contributions
Contributions
Datasets
Datasets
Key Concepts
Introduction
Listing Process
Datasets contributed to LEAN can be quickly listed in the QuantConnect Dataset Marketplace, and distributed for
sale to more than 250,000 users in the QuantConnect community. To list a dataset, reach out to the QuantConnect
Team for a quick review, then proceed with the data creation and process steps in the following pages.
Datasets must be well defined, with realistic timestamps for when the data was available ("point in time"). Ideally
datasets need at least a 2 year track record and to be maintained by a reputable company. They should be
accompanied with full documentation and code examples so the community can harness the data.
Data Sources
The get_source method of your dataset class instructs LEAN where to find the data. This method must return a
SubscriptionDataSource object, which contains the data location and format. We host your data, so the
TimeZones
The DataTimeZone method of your data source class declares the time zone of your dataset. This method returns a
NodaTime .DateTimeZone object. If your dataset provides trading data and universe data, the DataTimeZone
methods in your [Link].<vendorNameDatasetName> / <vendorNameDatasetName>.cs and
Linked Datasets
AAPL).
Examples of unlinked datasets would be the weather of New York City, where data is not relevant to a specific
security.
When a dataset is linked, it needs to be mapped to underlying assets through time. The RequiresMapping boolean
instructs LEAN to handle the security and ticker mapping issues.
Contributions > Datasets > Defining Data Models
Datasets
Defining Data Models
Introduction
This page explains how to set up the data source SDK and use it to create data models.
1. Open the [Link] repository and click Use this template > Create a new repository .
Start with the SDK repository instead of existing data source implementations because we periodically update
2. On the Create a new repository from [Link] page, set the repository name to
If your dataset contains multiple series, use <vendorName> instead of <vendorNameDatasetName> . For
instance, the Federal Reserve Economic Data (FRED) dataset repository has the name [Link]
because it has many different series .
$ [Link]
The input to your model should be one or many CSV files that are in chronological order.
1997-01-01,905.2,941.4,905.2,939.55,38948210,978.21
1997-01-02,941.95,944,925.05,927.05,49118380,1150.42
1997-01-03,924.3,932.6,919.55,931.65,35263845,866.74
...
2014-07-24,7796.25,7835.65,7771.65,7830.6,117608370,6271.45
2014-07-25,7828.2,7840.95,7748.6,7790.45,153936037,7827.61
2014-07-28,7792.9,7799.9,7722.65,7748.7,116534670,6107.78
If you don't already have these CSV files, you'll create them later during the Rendering Data part of this tutorial
series. For this part of the contribution process, consider using a "toy example" file to establish the format and
requirements.
1. Duplicate lines 32-36 for as many properties as there are in your dataset.
2. Rename the SomeCustomProperty properties to the names of your dataset properties (for example,
Destination ).
3. If your dataset is a streaming dataset like the Benzinga News Feed , change the argument that is passed
to the ProtoMember members so that they start at 10 and increment by one for each additional property
in your dataset.
4. If your dataset isn't a streaming dataset, delete the ProtoMember property decorators.
5. Replace the “Some custom data propertyˮ comments with a description of each property in your
dataset.
3. If your dataset contains multiple series, like the FRED dataset , create a helper class file in [Link].
<vendorNameDatasetName> directory to map the series name to the series code. For a full example, see the
[Link] file in the [Link] repository. The helper class makes it easier for members to
subscribe to the series in your dataset because they don't need to know the series code. For instance, you
can subscribe to the 1-Week London Interbank Offered Rate (LIBOR) based on U.S. Dollars with the following
code snippet:
PY
self.add_data(Fred, [Link].one_week_based_on_usd)
# Instead of
# self.add_data(Fred, "USD1WKD156N")
4. Define the GetSource method to point to the path of your dataset file(s).
If your dataset is organized across multiple CSV files, use the [Link] string to build the file
path. [Link] is the string value of the argument you pass to the AddData method when you
subscribe to the dataset. An example output file path is / output / alternative / xyzairline / ticketsales / [Link]
Set Symbol = [Link] and set end_time to the time that the datapoint first became available for
consumption.
Your data class inherits from the BaseData class, which has Value and time properties. Set the Value
property to one of the factors in your dataset. If you don't set the time property, its default value is the value
of end_time . For more information about the time and end_time properties, see Periods .
If you import using QuantConnect , the TimeZones class provides helper attributes to create DateTimeZone
objects. For example, you can use [Link] or [Link] . For more information about time
DefaultResolution .
If your dataset is not tick resolution and your dataset is missing data for at least one sample, it's sparse. If
<vendorNameDatasetName>UniverseSelectionAlgorithm.* files.
3. In the [Link].<vendorNameDatasetName> / tests / [Link] file, delete the code on line 8 that
The input to your model should be many CSV files where the first column is the security identifier and the second
A R735QTJ8XC9X,A,17.19,109700,1885743,False,0.9904858,1
AA R735QTJ8XC9X,AA,71.25,513400,36579750,False,0.3992678,0.750075
AAB R735QTJ8XC9X,AAB,16.38,5000,81900,False,0.9902758,1
...
ZSEV R735QTJ8XC9X,ZSEV,10.5,800,8400,False,0.8981684,1
ZTR R735QTJ8XC9X,ZTR,9.56,102300,977988,False,0.0803037,3.97015016
ZVX R735QTJ8XC9X,ZVX,10,15600,156000,False,1,0.666667
1. Duplicate lines 33-36 or 38-41 (depending on the data type) for as many properties as there are in your
dataset.
3. Replace the “Some custom data propertyˮ comments with a description of each property in your
dataset.
3. Define the GetSource method to point to the path of your dataset file(s).
Use the date parameter as the file name to get the DateTime of data being requested. Example output file
paths are / output / alternative / xyzairline / ticketsales / universe / [Link] for daily data and / output /
The date in your data file must be the date that the data point is available for consumption. With this
If you import using QuantConnect , the TimeZones class provides helper attributes to create DateTimeZone
objects. For example, you can use [Link] or [Link] . For more information about time
zones, see Time Zones .
If a member doesn't specify a resolution when they subscribe to your dataset, Lean uses the
DefaultResolution .
Datasets
Rendering Data
Contributions > Datasets > Rendering Data > Rendering Data with Python
Rendering Data
Rendering Data with Python
Introduction
This page explains how to create a script to download and process your dataset with Python for QuantConnect
distribution.
During this part of the contribution process, you need to edit the [Link].<vendorNameDatasetName> /
DataProcessing / [Link] file so it transforms and moves your raw data into the format and location the
GetSource methods expect. The script should save all the data history to the output directory in your machine's
root directory (for example, C: / output ) and it should save a sample of the data history to the [Link].
Follow these steps to set up the downloading and processing script for your dataset:
path structure you defined in the get_source methods (for example, output / alternative / xyzairline /
ticketsales ).
worth of data.
You need this information for when you provide the dataset documentation . We need to know how long it
takes to process your dataset so we can schedule its processing job.
3. In the processing file, load the raw data from your source.
Source Considerations
Local Files It can help to first copy the data into location.
Stay within the rate limits. You can use the rate
Remote API
gate class.
You should load and process the data period by period. Use the date range provided to the script to process
4. If your dataset is for universe selection data and it's at a higher frequency than hour resolution, resample your
5. If any of the following statements are true, skip the rest of the steps in this tutorial:
Your dataset is not linked to Equities.
Your dataset is related to Equities and already includes the point-in-time tickers.
If your dataset is related to Equities and your dataset doesn't account for ticker changes, the rest of the steps
help you to adjust the tickers over the historical data so they are point-in-time.
CLRImports library.
PY
PY
map_file_provider = LocalZipMapFileProvider()
map_file_provider.initialize(DefaultDataProvider())
PY
sid = SecurityIdentifier.generate_equity(point_in_time_ticker,
[Link], True, map_file_provider, csv_date)
12. Copy the [Link] script to the DataProcessing / bin / debug / net9.0 directory.
You need to place the script under the bin directory so that LEAN's packages dlls are correctly loaded for the
CLRImports .
$ cp [Link] DataProcessing/bin/Debug/net9.0
13. Run the DataProcessing / bin / debug / net9.0 / [Link] script to populate the [Link].
<vendorNameDatasetName> / output directory and the output directory in your machine's root directory.
$ cd DataProcessing/bin/debug/net9.0/
$ python [Link]
Note: The pull request you make at the end must contain sample data so we can review it and run the
demonstration algorithms.
[Link]
[Link]
[Link]
[Link]
[Link]
Contributions > Datasets > Rendering Data > Rendering Data with CSharp
Rendering Data
Rendering Data with CSharp
Introduction
This page explains how to create a script to download and process your dataset with C# for QuantConnect
distribution.
During this part of the contribution process, you need to edit the [Link].<vendorNameDatasetName> /
DataProcessing / [Link] file so it transforms and moves your raw data into the format and location the
GetSource methods expect. The program should save all the data history to the output directory in your machine's
root directory (for example, C: / output ) and it should save a sample of the data history to the [Link].
Follow these steps to set up the downloading and processing script for your dataset:
path structure you defined in the get_source methods (for example, output / alternative / xyzairline /
ticketsales ).
time how long it takes to process the entire dataset and how long it takes to update the dataset with one day's
worth of data.
You need this information for when you provide the dataset documentation . We need to know how long it
takes to process your dataset so we can schedule its processing job.
3. In the processing file, load the raw data from your source.
Source Considerations
Local Files It can help to first copy the data into location.
Stay within the rate limits. You can use the rate
Remote API
gate class.
You should load and process the data period by period. Use the date range provided to the script to process
4. If your dataset is for universe selection data and it's at a higher frequency than hour resolution, resample your
data to hourly or daily resolution.
5. If any of the following statements are true, skip the rest of the steps in this tutorial:
Your dataset is not related to Equities.
Your dataset is related to Equities and already includes the point-in-time tickers.
If your dataset is related to Equities and your dataset doesn't account for ticker changes, the rest of the steps
help you to adjust the tickers over the historical data so they are point-in-time.
9. In a terminal, compile the data processing project to generate the [Link] executable file.
After you finish compiling the [Link] file, run the [Link] file to populate the [Link].
<vendorNameDatasetName> / output directory and the output directory in your machine's root directory.
Note: The pull request you make at the end must contain sample data so we can review it and run the
demonstration algorithms.
[Link]
[Link]
[Link]
[Link]
[Link]
Contributions > Datasets > Rendering Data > Rendering Data with Notebooks
Rendering Data
Rendering Data with Notebooks
Introduction
This page explains how to create a script to download and process your dataset with Jupyter Notebooks for
QuantConnect distribution.
During this part of the contribution process, you need to edit the [Link].<vendorNameDatasetName> /
DataProcessing / [Link] file so it transforms and moves your raw data into the format and location the
GetSource methods expect. The notebook should save all the data history to the output directory in your machine's
root directory (for example, C: / output ) and it should save a sample of the data history to the [Link].
Follow these steps to set up the downloading and processing script for your dataset:
path structure you defined in the get_source methods (for example, output / alternative / xyzairline /
ticketsales ).
time how long it takes to process the entire dataset and how long it takes to update the dataset with one day's
worth of data.
You need this information for when you provide the dataset documentation . We need to know how long it
takes to process your dataset so we can schedule its processing job.
3. In the processing file, load the raw data from your source.
Source Considerations
Local Files It can help to first copy the data into location.
Stay within the rate limits. You can use the rate
Remote API
gate class.
You should load and process the data period by period. Use the date range provided to the script to process
4. If your dataset is for universe selection data and it's at a higher frequency than hour resolution, resample your
Your dataset is related to Equities and already includes the point-in-time tickers.
If your dataset is related to Equities and your dataset doesn't account for ticker changes, the rest of the steps
help you to adjust the tickers over the historical data so they are point-in-time.
CLRImports library.
PY
PY
map_file_provider = LocalZipMapFileProvider()
map_file_provider.initialize(DefaultDataProvider())
PY
sid = SecurityIdentifier.generate_equity(point_in_time_ticker,
[Link], True, map_file_provider, csv_date)
After you finish editing the [Link] script, run its cells to populate the [Link].
<vendorNameDatasetName> / output directory and the output directory in your machine's root directory.
Note: The pull request you make at the end must contain sample data so we can review it and run the
demonstration algorithms.
The following examples are rendering datasets with Jupyter Notebook processing:
[Link]
[Link]
Contributions > Datasets > Testing Data Models
Datasets
Testing Data Models
Introduction
The implementation of your Data Source must be thoroughly tested to be listed on the Dataset Market .
Follow these steps to test if your demonstration algorithm will run in production with the processed data:
Studio.
2. In the top menu bar of Visual Studio, click Build > Build Solution .
5. If you don't have a local copy of LEAN, fork the LEAN repository and then clone it .
6. Copy the contents of the [Link].<vendorNameDatasetName> / output directory and paste them
8. In the Solution Explorer panel of Visual Studio, right-click [Link] and then click Add
10. In the Solution Explorer panel, right-click [Link] and then click Add > Project
Reference... .
12. In the Select the files to reference… window, click the [Link].<vendorNameDatasetName> / bin /
13. Click OK .
14. In the Lean / [Link] / <vendorNameDatasetName>[Link] file, write an algorithm that uses
"algorithm-type-name": "<vendorNameDatasetName>Algorithm",
"algorithm-language": "CSharp",
"algorithm-location": "[Link]",
19. In the Lean / [Link] / <vendorNameDatasetName>[Link] file, write an algorithm that uses
"algorithm-type-name": "<vendorNameDatasetName>Algorithm",
"algorithm-language": "Python",
"algorithm-location": "../../../[Link]/<vendorNameDatasetName>[Link]",
Important: Your backtests must run without error. If your backtests produce errors, correct them and then run
the backtest again.
<vendorNameDatasetName> / <vendorNameDatasetName>[Link] .
<vendorNameDatasetName> / <vendorNameDatasetName>[Link] .
You must run your demonstration algorithms without error before you set up unit tests.
CreateNewInstance method to return an instance of your DataSource class and then execute the following
Datasets
Data Documentation
Introduction
This page explains how to provide documentation for your dataset so QuantConnect members can use it in their
trading algorithms.
You need to process the entire dataset to collect the following information:
Property Description
Data process time Time and days of the week to process the data.
Provide Documentation
content.
Next Steps
After we review and accept your dataset contribution, we will create a page in our Dataset Market . At that point,
you will be able to write algorithms in QuantConnect Cloud using your dataset and you can contribute an example
algorithm for the dataset listing. After your dataset listing is complete, we'll include your new dataset in our
Contributions
Brokerages
Creating a fully supported brokerage is a challenging endeavor. LEAN requires a number of individual pieces which
work together to form a complete brokerage implementation. This guide aims to describe in as much detail as
possible what you need to do for each module.
The end goal is to submit a pull request that passes all tests. Partially-completed brokerage implementations are
acceptable if they are merged to a branch. It's easy to fall behind master, so be sure to keep your branch updated
with the master branch. Before you start, read LEAN's coding style guidelines to comply with the code commenting
The root of the brokerage system is the algorithm job packets, which hold configuration information about how to
run LEAN. The program logic is a little convoluted. It moves from [Link] > create job packet > create
brokerage factory matching name > set job packet brokerage data > factory creates brokerage instance . As a
result, we'll start creating a brokerage at the root, the configuration and brokerage factory.
( IBrokerage ) Instal key brokerage application logic, where possible using a brokerage SDK.
( ISymbolMapper ) Translate brokerage specific tickers to LEAN format for a uniform algorithm design experience.
( IHistoryProvider ) Tap into the brokerage historical data API to serve history for live algorithms.
Downloading Data
See Also
Dataset Market
Purchasing Datasets
Contributions > Brokerages > Setting Up Your Environment
Brokerages
Setting Up Your Environment
Introduction
This page explains how to set up your coding environment to create, develop, and test your brokerage before you
contribute it to LEAN.
Prerequisites
Set Up Environment
1. Fork Lean and then clone your forked repository to your local machine.
3. On the Create a new repository from [Link] page, set the repository name to
$ chmod +x ./renameBrokerage
$ [Link]
The bash script replaces some placeholder text in the [Link].<brokerageName> directory and
Brokerages
Laying the Foundation
IBrokerageFactory
Interface [Link]
Example [Link]
[Link].<brokerageName> /
Target Location
QuantConnect.<brokerageName>Brokerage /
Introduction
The IBrokerageFactory creates brokerage instances and configures LEAN with a Job Packet . To create the right
BrokerageFactory type, LEAN uses the brokerage name in the job packet. To set the brokerage name, LEAN uses
Prerequisites
You need to set up your environment before you can lay the foundation for a new brokerage.
Follow these steps to stub out the implementation and initialize a brokerage instance:
1. In the Lean / Launcher / [Link] file, add a few key-value pairs with your brokerage configuration
information.
For example, oanda-access-token and oanda-account-id keys. These key-value pairs will be used for most
local debugging and testing as the default. LEAN automatically copies these pairs to the BrokerageData
<brokerageName>[Link] file, update the BrokerageData member so it uses the Config class to load all
the required configuration settings from the Lean / Launcher / [Link] file.
configuration file. For a full example, see the BrokerageData member in the BitfinexBrokerageFactory .
. The Composer is a system in LEAN for dynamically loading types. In this case, it's adding an instance of the
DataQueueHandler for the brokerage to the composer. You can think of the Composer as a library and adding
3. In the Lean / Common / Brokerages folder, create a <brokerageName>[Link] file with a stub
Brokerage models tell LEAN what order types a brokerage supports, whether we're allowed to update an
order, and what reality models to use. Use the following stub implementation for now:
where BrokerageName is the name of your brokerage. For example, if the brokerage name is XYZ, then
brokerage model.
BaseWebsocketsBrokerage .
<brokerageName>[Link] file, update the constructor to save required authentication data to private
variables.
7. In the [Link].<brokerageName> / QuantConnect.<brokerageName>Brokerage /
The Brokerage Factory uses a job packet to create an initialized brokerage instance in the CreateBrokerage
method. Assume the job argument has the best source of data, not the BrokerageData property. The
BrokerageData property in the factory are the starting default values from the configuration file, which can be
These live-<brokerageName> keys group configuration flags together and override the root configuration
"live-mode-brokerage": "BrokerageName",
"setup-handler": "[Link]",
"result-handler": "[Link]",
"data-feed-handler": "[Link]",
"data-queue-handler": [ "[Link]" ],
"real-time-handler": "[Link]",
"transaction-handler":
"[Link]"
},
where brokerage-name and "BrokerageName" are placeholders for your brokerage name.
9. In the Lean / Launcher / [Link] file, set the environment value to the your new brokerage environment.
Running the solution won't work, but the stub implementation should still build.
Contributions > Brokerages > Creating the Brokerage
Brokerages
Creating the Brokerage
IBrokerage
Interface [Link]
Example [Link]
[Link].<brokerageName> /
Target Location
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
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:
2. Setup State - Initialize the algorithm portfolio, open orders and cashbook.
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
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 / [Link] .
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
<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.
The following sections describe components of the brokerage implementation in the [Link].
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
Brokerage Description
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:
Brokerage Description
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
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.
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
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.
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:
Brokerage Description
List<Holding> GetAccountHoldings()
List<Cash> GetCashBalance()
bool AccountInstantlyUpdated
bool AccountInstantlyUpdated
Contributions > Brokerages > Translating Symbol Conventions
Brokerages
Translating Symbol Conventions
Introduction
Brokerages
Describing Brokerage Limitations
Introduction
Brokerages
Enabling Live Data Streaming
Introduction
Brokerages
Enabling Historical Data
Introduction
Brokerages
Downloading Data
Introduction
Brokerages
Modeling Fee Structures
Introduction
Brokerages
Updating the Algorithm API
Introduction
Contributions
Indicators
Introduction
LEAN currently supports over 100 indicators . This page explains how to contribute a new indicator to the open-
source project by making a pull request to Lean. Before you get started, familiarize yourself with our contributing
guidelines , and review previous contributions to understand our standards. If you don't already have a new
indicator in mind that you want to contribute, see the GitHub Issues in the Lean repository for a list of indicators
that community members have requested. Before you begin, create a GitHub Issue with a description of your
As a quantitative algorithmic trading engine, accuracy and reliability are very important to LEAN. When you submit
a new indicator to the LEAN, you must include third-party source values are required as reference points in your
pull request to contrast the values output by your indicator implementation. This requirement validates that your
indicator implementation is correct. The following sections explain some examples of acceptable third-party
sources.
Developed and maintained by expert teams, these sources undergo rigorous testing and optimization, ensuring
accurate calculations. The transparent nature of open-source projects allows for community scrutiny, resulting in
bug fixes and continuous improvements. Open-source projects provide thorough information on how the indicator
values are calculated, which provides excellent reproducibility. Thus, we accept values from these projects with
Similar reasons apply to these websites as well. The site should be either the original source or a very popular
trading data provider, such that we have confidence in their accuracy and reliability. These sources might provide
structured data samples, like a JSON response, CSV /Excel file, or scripts for calculating the indicator values.
To add a new indicator to Lean, add a class file to the Lean / Indicators directory. Indicators are classified as either
a data point, bar, or TradeBar indicator. Their classification depends on the class they inherit and the type of data
they receive. The following sections explain how to implement each type. Regardless of the indicator type, the
The class must also define a ComputeNextValue method, which accepts some data and returns the indicator value.
As shown in the following sections, the data/arguments that this method receives depends on the indicator type.
On rare occassions, some indicators can produce invalid values. For example, a moving average can produce
unexpected values due to extreme quotes. In cases like these, override the ValidateAndComputeNextValue
method to return an IndicatorResult with an IndicatorStatus enumeration. If the IndicatorStatus states the
value is invalid, it won't be passed to the main algorithm. The IndicatorStatus enumeration has the following
members:
To enable the algorithm to warm up the indicator with the WarmUpIndicator method, inherit the
IIndicatorWarmUpPeriodProvider interface.
If your indicator requires a moving average, see the Extra Steps for Moving Averages Types as you complete the
following tutorial.
Data point indicators use IndicatorDataPoint objects to compute their value. These types of indicators can inherit
WindowIndicator<IndicatorDataPoint> class has several members to help you compute indicator values over
multiple periods.
To view some example data point indicators that inherit the IndicatorBase<IndicatorDataPoint> class, see the
SharpeRatio
DetrendedPriceOscillator
HullMovingAverage
To view some example data point indicators that inherit the WindowIndicator<IndicatorDataPoint> class, see the
SimpleMovingAverage
Momentum
Maximum
Bar Indicators
Bar indicators use QuoteBar or TradeBar objects to compute their value. Since Forex and CFD securities don't have
TradeBar data, they use bar indicators. Candlestick patterns are examples of bar indicators.
To view some example bar indicators, see the implementation of the following indicators in the LEAN repository:
WilliamsPercentR
AverageTrueRange
Stochastics
TradeBar Indicators
TradeBar indicators use TradeBar objects to compute their value. Some TradeBar indicators use the volume
To view some example TradeBar indicators, see the implementation of the following indicators in the LEAN
repository:
Beta
AdvanceDeclineIndicator
MassIndex
The preceding indicator class is sufficient to instatiate a manual version of the indicator. To enable users to create
an automatic version of the indicator, add a new method to the Lean / Algorithm / [Link] file.
Name the method a short abbreviation of the indicator's full name. In the method definition, call the
InitializeIndicator method to create a consolidator and register the indicator for automatic updates with the
consolidated data.
Unit tests ensure your indicator functions correctly and produces accurate values. Follow these steps to add unit
1. Save the third-party values in the Lean / Tests / TestData directory as a CSV file.
2. In the Lean / Tests / [Link] file, reference the new data file.
3. Create a Lean / Tests / Indicators / <IndicatorName>[Link] file with the following content:
4. Set the values of the TestFileName and TestColumnName attributes to the CSV file name and the column name
Test if the constructor, IsReady flag, and Reset method work. If there are other custom calculation methods
1. In the Documentation / Resources / indicators / [Link] file, add the indicator to one of
indicators if the indicator only involves one symbol and doesn't depend on other indicators
option_indicators if the indicator is an Option-related indicator (for example, Option greeks indicators)
The following code block explains the format of the key-value pairs of the dictionaries:
PY
'<hyphenated-title-case-of-the-indicator>': IndicatorInfo(
<PythonConstructor>(<python-constructor-arguments>),
'<CSharpHelperMethod>(<csharp-helper-method-arguments>)',
'self.<python_helper_method>(<python-helper-method-arguments>)'
),
The fourth argument to the IndicatorInfo constructor defines which of the indicator's properties to plot on
each subplot in the Visualization section of the documentation. By default, its value is [['current']] , which
plots the current property on a single subplot. In this argument, each element in the list you pass defines
which properties to plot on each subplot. Group properties that are on the same scale together so they show
[['fast', 'slow'], ['current', 'histogram', 'signal']] to plot the fast and slow properties on the
first subplot and plot the current , histogram , and signal properties on the second subplot.
This script generates the indicator reference page. For an example, see Simple Moving Average .
A moving average is a special type of indicator that smoothes out the fluctuations in a security's price or market
data. It calculates the average value of a security's price over a specified period with a special smoothing function,
helping traders to identify trends and reduce noise. Moving averages can also be used in conjunction with other
technical indicators to make more informed trading decisions and identify potential support or resistance levels in
the market. LEAN has extra abstraction interface for indicators to implement a specific type of moving average.
If you are contributing an indicator that requires a new moving average type, follow these additional steps:
1. In the Lean / Indicators / [Link] file, define a new MovingAverageType enumeration member.
2. In the Lean / Indicators / [Link] file, add a new case of your custom moving
average indicator in each AsIndicator method.
3. In the Lean / Tests/ Indicators / [Link] file, add a new test case of your
custom moving average indicator that asserts the indicator is correctly instantiated through the abstraction
methods.
Data Format
Data Format
Data Format
Key Concepts
Introduction
From the beginning, LEAN has strived to use an open, human-readable data format - independent of any specific
database or file format. From this core philosophy, we built LEAN to read its financial data from flat files on disk.
Data compression is done in zip format, and all individual files are CSV or JSON.
The prices are expressed in the asset quote currency . For example, the value 0.06920 for ETHBTC is the amount
When there is no activity for a security, the price is omitted from the file. Only new ticks and price changes are
recorded.
Folder Structure
The marketName value is used to separate different tradable assets with the same ticker. E.g. BTCUSDT is traded
Price Representation
The prices are expressed in the asset quote currency . For example, the value 0.06920 for ETHBTC is the amount
When there is no activity for a security, the price is omitted from the file. Only new ticks and price changes are
recorded.
Data Format > Core Data Types
Data Format
Core Data Types
Introduction
This page shows the file schema of the core data types represented in supported asset classes .
Trade Tick
Tick of TickType. Quote represents an individual record of trades for an asset. Tick data does not have a period.
Column Description
Quote Tick
Tick of TickType. QUOTE represents an individual record of quote updates for an asset. Tick data does not have a
period.
Column Description
Trade Bar
Quote Bar
QuoteBar represents top of book quote data consolidated over a period of time (bid and ask bar).
Column Description
Column Description
Statistics
Statistics
Capacity
Introduction
Capacity is a measure of how much capital a strategy can trade before the performance of the strategy degrades
from market impact. The capacity calculation is done on a rolling basis with one snapshot taken at the end of each
week. This page outlines how LEAN performs the entire calculation.
Security Capacity
The first step to determine the capacity of the strategy is to compute the capacity of each security the strategy
trades.
Following each order fill, LEAN monitors and records the dollar-volume for a series of bars. To get an estimate of
the available capacity, we combine many second and minute trade bars together. For hourly or daily data
Crypto Volume
Crypto trade volume is light, but there is significant capacity even at the very top of the order book. The estimated
volume of Crypto is based on the average size on the bid and ask.
Forex and CFD assets do not have a trade volume or quote size information so they were approximated as deeply
The number of bars we use to calculate the market volume estimate depends on the asset liquidity. The following
table shows the formulas LEAN uses to determine how long of a period the market capacity dollar volume is
accumulated for after each order fill, as a function of the security resolution. The AvgDollarVolume in the table
represents the average dollar volume per minute for the security you're trading. Notice that for the edge case
where the average dollar volume is zero, the calculations use 10 minutes of data.
Resolution Timeout Period
{
100 , 000
AvgDollarVolume
Second k= , if AvgDollarVolume ≠ 0
10, otherwise
min
Hour 1 hour
Daily 1 day
Only a fraction of the market capacity dollar volume is available to be taken by a strategyʼs orders because there
are other market participants. The data resolution of the security determines how much of the market capacity
dollar volume is available for the strategy to consume. The following table shows what percentage of the market
Daily 2
Hour 5
Minute 20
Second 50
Tick 50
down the market capacity dollar volume of the security proportional to the number of trades that it places per day
for the security. The more frequently the strategy trades a security, the lower the capacity of the security goes
since it becomes harder to get into a larger position without incurring significant market impact. The formula that
LEAN uses to discount the capacity of the securities that the algorithm trades intraday is
d_i = \left\{ \begin{array}{ c l } 1,& \text{if } i = 1\\ \min(1, \max(0.2, d_{i-1} * \frac{m}{390})), & \text{if } i > 1
\end{array} \right.
where d_i\in{[0.2, 1]} is the fast trading volume discount factor after order i and m is the number of minutes since
order i-1 was filled. We divide m by 390 because there are 390 = 6.5 * 60 minutes of trading in a regular Equity
trading day.
Sale Volume
In addition to the market capacity dollar volume, for each security the strategy trades, LEAN also accumulates the
weekly sale volume of the order fills. The sale volume scales down the weekly snapshot capacity.
Portfolio Capacity
Now that we have the values to calculate the capacity of each security, we can compute the capacity of the
portfolio.
Snapshot Capacity
To calculate the strategy capactiy, weekly snapshots are taken. When itʼs time to take a snapshot, the capacity of
the strategy for the current snapshot is calculated by first selecting the security with the least market capacity
dollar volume available. The fraction of trading volume that was available for this security is scaled down by the
number of orders that were filled for the security during the week. The result is scaled down further by the largest
value between the weight of the securityʼs sale volume in the portfolio sale volume and the weight of the securityʼs
holding value in the total portfolio value. The result of this final scaling is the strategyʼs capacity in the current
snapshot.
When any of the denominators are 0 in the preceding formula, the quotient that the denominator is part of defaults
to a value of 0. After the snapshot is taken, the sale volume and market capacity dollar volume of each security is
reset to 0.
Strategy Capacity
Instead of using the strategyʼs capacity at the current snapshot as the final strategy capacity value, the strategy
capacity is smoothed across the weekly snapshots. First, the capacity estimate of the current snapshot is
calculated, then the final strategy capacity value is set using the following exponentially-weighted model:
Strategy \ Capacity = \left\{ \begin{array}{ c l } S_{i},& \text{if } i = 1\\ 0.66 * S_{i-1} + 0.33 * S_{i}, & \text{if } i > 1
\end{array} \right.
Summary
Strategies that have a larger capacity are able to trade more capital without suffering from significant market
impact. In general, a strategy that trades a large weight of the portfolio in liquid securities with high volume will
have a large capacity. To avoid reducing the strategy capacity too much, only trade a small portion of your
Class Reference
The QuantConnect API Reference is a comprehensive technical document that details every class, method,
property, and event available in the LEAN algorithmic trading framework. It serves as the definitive source for
understanding how to interact with LEAN, helping you quickly look up syntax and explore available features. The
LEAN engine is written in C#, but you can create algorithms with either C# or Python since LEAN uses [Link]
to bridge between your Python code and the underlying C# engine. For your convenience, we provide an API
Python
C#