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

> Learn to use the QuantConnect LEAN engine for algorithmic trading. This complete guide covers backtesting and deploying strategies with this powerful open-source framework. Get started today.

- Repository: [Papers With Backtest/awesome-systematic-trading](https://github.com/paperswithbacktest/awesome-systematic-trading)
- Tags: how-to-guide
- Published: 2026-08-01

---

**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`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/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`:

```python
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`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/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:

```python
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:

```python
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:

```python
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:

```python
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`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/static/strategies/asset-growth-effect.py) that extends the base `FeeModel` to apply per-share transaction costs:

```python
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`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/asset-growth-effect.py))
3. Execute the Docker run command:

```bash
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`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/static/strategies/short-term-reversal-in-stocks.py) and other repository examples:

```python
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`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/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`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/asset-growth-effect.py) for universe selection patterns and [`short-term-reversal-in-stocks.py`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/short-term-reversal-in-stocks.py) for momentum-reversal filters. Both demonstrate the complete workflow from initialization through execution.