How to Use the QuantConnect LEAN Engine for Algorithmic Trading: A Complete Guide

The QuantConnect LEAN engine is an open-source, event-driven framework that enables systematic traders to backtest and deploy strategies by inheriting from the QCAlgorithm base class and implementing lifecycle methods like Initialize, OnData, and universe selection functions.

The LEAN engine powers both local backtesting and live trading on the QuantConnect platform. In the paperswithbacktest/awesome-systematic-trading repository, you will find production-ready implementations demonstrating how to structure algorithms for the QuantConnect LEAN engine for algorithmic trading.

Core Architecture of the LEAN Engine

At the heart of every LEAN strategy is the QCAlgorithm class. According to the source code in static/strategies/asset-growth-effect.py, your algorithm must inherit from this base class and override specific lifecycle methods to define trading logic.

The QCAlgorithm Base Class

All LEAN algorithms begin by importing the LEAN primitives and inheriting from QCAlgorithm:

from AlgorithmImports import *

class AssetGrowthEffect(QCAlgorithm):
    def Initialize(self):
        # Strategy configuration

        pass

The from AlgorithmImports import * statement provides access to all LEAN symbols, data types, and helper classes including Symbol, Resolution, and OrderFee.

Essential Lifecycle Methods

The LEAN engine calls specific methods during the backtest lifecycle:

  • Initialize: Called once at startup to set dates, cash, and subscriptions
  • CoarseSelectionFunction: Filters the initial universe of securities
  • FineSelectionFunction: Applies fundamental data filters to coarse results
  • OnData: Processes incoming market data and executes portfolio decisions

Implementing Universe Selection with Coarse and Fine Filters

Universe selection allows your algorithm to dynamically select securities based on market data and fundamentals. The repository demonstrates a two-stage filtering pipeline in static/strategies/asset-growth-effect.py.

CoarseSelectionFunction for Initial Screening

The coarse selection runs first on every data slice, filtering thousands of securities down to a manageable set based on price, volume, and basic criteria:

def CoarseSelectionFunction(self, coarse):
    return [c.Symbol for c in coarse if c.HasFundamentalData and c.Market == "usa"]

FineSelectionFunction for Fundamental Analysis

After coarse filtering, the fine selection receives fundamental data objects (like market capitalization, earnings, etc.) for deeper analysis:

def FineSelectionFunction(self, fine):
    # Select top 500 by market cap

    fine = sorted(fine, key=lambda x: x.MarketCap, reverse=True)[:500]
    return [f.Symbol for f in fine]

Scheduling Rebalancing and Executing Trades

Systematic strategies require deterministic rebalancing points. LEAN provides scheduling mechanisms to trigger portfolio updates at specific times.

Deterministic Rebalancing with Schedule.On

Instead of polling every tick, use Schedule.On to attach callbacks to calendar events. As shown in the Asset Growth example, you can schedule month-end rebalancing:

self.Schedule.On(self.DateRules.MonthEnd("SPY"), 
                 self.TimeRules.AfterMarketOpen("SPY"), 
                 self.Selection)

This guarantees your Selection method runs at the specified time, improving performance and ensuring consistent behavior.

Order Execution in OnData

The OnData method serves as the central execution point. It processes incoming bar data, liquidates positions that fall out of the target universe, and places new orders:

def OnData(self, data):
    # Liquidate symbols no longer in universe

    for symbol in self.Portfolio.Keys:
        if symbol not in self.selected_symbols:
            self.Liquidate(symbol)
    
    # Equal weight new positions

    weight = 1.0 / len(self.selected_symbols)
    for symbol in self.selected_symbols:
        self.SetHoldings(symbol, weight)

Configuring Custom Transaction Fees

Realistic backtesting requires accurate cost modeling. The repository includes a CustomFeeModel class in static/strategies/asset-growth-effect.py that extends the base FeeModel to apply per-share transaction costs:

class CustomFeeModel(FeeModel):
    def GetOrderFee(self, parameters):
        # Custom fee logic here

        pass

Running LEAN Locally and on QuantConnect

The LEAN engine supports both local Docker-based backtesting and cloud deployment.

Local Backtesting with Docker

To run strategies locally:

  1. Clone the official LEAN repository and build the Docker image
  2. Copy algorithm files from static/strategies/ (e.g., asset-growth-effect.py)
  3. Execute the Docker run command:
docker run -v $(pwd)/strategies:/Lean/Algorithm.Python/strategies \
  quantconnect/lean:latest ./run.sh AssetGrowthEffect

This mounts your local strategies directory and launches the backtest using the LEAN engine.

Deploying to QuantConnect Cloud

To deploy to production:

  1. Push your .py file to a QuantConnect project via the web IDE or CLI
  2. Click Backtest to validate results
  3. Configure brokerage credentials to enable live trading with the same code

Complete Minimal Strategy Template

Below is a skeleton strategy combining all essential components. This pattern matches the implementations in static/strategies/short-term-reversal-in-stocks.py and other repository examples:

from AlgorithmImports import *

class ExampleSkeleton(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2020, 1, 1)
        self.SetCash(100000)
        self.AddEquity("SPY", Resolution.Daily)
        self.universe = self.AddUniverse(self.CoarseSelectionFunction, 
                                        self.FineSelectionFunction)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday), 
                          self.TimeRules.AfterMarketOpen("SPY"), 
                          self.Rebalance)

    def CoarseSelectionFunction(self, coarse):
        return [c.Symbol for c in coarse if c.HasFundamentalData]

    def FineSelectionFunction(self, fine):
        fine = sorted(fine, key=lambda x: x.MarketCap, reverse=True)[:100]
        return [f.Symbol for f in fine]

    def Rebalance(self):
        weight = 1.0 / len(self.universe.Values)
        for symbol in self.universe.Values:
            self.SetHoldings(symbol, weight)

Summary

  • QCAlgorithm is the mandatory base class for all LEAN strategies, requiring imports from AlgorithmImports.
  • Two-stage universe selection uses CoarseSelectionFunction for initial screening and FineSelectionFunction for fundamental filtering.
  • Schedule.On enables deterministic rebalancing without tick-level polling.
  • OnData handles order execution, position liquidation, and portfolio construction.
  • Local testing requires Docker with the volume mount command shown above, while cloud deployment uses the QuantConnect web IDE.

Frequently Asked Questions

What is the difference between CoarseSelectionFunction and FineSelectionFunction in LEAN?

CoarseSelectionFunction receives coarse data objects containing price and volume information for the entire security universe, allowing you to filter thousands of symbols down to a subset with basic criteria. FineSelectionFunction then receives fundamental data objects (including metrics like MarketCap, P/E ratios, etc.) only for the symbols passing the coarse filter, enabling detailed quantitative analysis.

How do I set custom transaction fees in a QuantConnect LEAN algorithm?

Extend the FeeModel base class and override the GetOrderFee method to implement broker-specific pricing. In static/strategies/asset-growth-effect.py, the repository demonstrates a CustomFeeModel class that calculates per-share costs. Assign this model to your securities using self.SetFeeModel(CustomFeeModel()) in the Initialize method.

Can I run LEAN algorithms locally without using Docker?

While Docker is the recommended method for local backtesting as shown in the paperswithbacktest/awesome-systematic-trading documentation, you can also build the LEAN engine from source using Visual Studio or the .NET CLI. However, Docker provides the most consistent environment matching QuantConnect's cloud infrastructure.

Where can I find production-ready LEAN strategy examples?

The static/strategies/ directory in the paperswithbacktest/awesome-systematic-trading repository contains multiple working implementations. Key files include asset-growth-effect.py for universe selection patterns and short-term-reversal-in-stocks.py for momentum-reversal filters. Both demonstrate the complete workflow from initialization through execution.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →