Live Trading

Reconciliation

Introduction

Algorithms usually perform differently between backtesting and live trading over the same time period. Backtests are simulations where we model reality as close as possible, but the modeling isn't always perfect. To measure the performance differences, we run an out-of-sample (OSS) backtest in parallel to all of your live trading deployments. The live results page displays the live equity curve and the OOS backtest equity curve of your algorithms.

The live and OSS backtest equity curves of an Alpha

If your algorithm is perfectly reconciled, it has an exact overlap between its live and OOS backtest equity curves. Deviations mean that the performance of your algorithm has differed between the two execution modes. Several factors can contribute to the deviations.

Differences From Data

The data that your algorithm uses can cause differences between backtesting and live trading performance.

Look-Ahead Bias

The Time Frontier minimizes the risk of look-ahead bias in backtests, but it does not completely eliminate the risk of look-ahead bias. For instance, if you use a custom dataset that contains look-ahead bias, your algorithm's live and backtest equity curves may deviate. To avoid look-ahead bias with custom datasets, set a Periodperiod on your custom data points so that your algorithm receives the data points after the Time + Periodtime + period.

Discrete Time Steps

In backtests, we inject data into your algorithm at predictable times, according to the data resolution. In live trading, we inject data into your algorithm when new data is available. Therefore, if your algorithm has a condition with a specific time (i.e. time is 9:30:15), the condition may work in backtests but it will always fail in live trading since live data has microsecond precision. To avoid issues, either use a time range in your condition (i.e. 9:30:10 < time < 9:30:20), use a rounded time, or use a Scheduled Event.

Custom Data Emission Times

Custom data is often timestamped to midnight, but the data point may not be available in reality until several days after that point. If your custom dataset is prone to this delay, your backtest may not fetch the same data at the same time or frequency that your live trading algorithm receives the data, leading to deviations between backtesting and live trading. To avoid issues, ensure the timestamps of your custom dataset are the times when the data points would be available in reality.

In backtesting, LEAN and custom data are perfectly synchonized. In live trading, daily and hourly data from a custom data source are not because of the frequency that LEAN checks the data source depends on the resolution argument. The following table shows the polling frequency of each resolution:

ResolutionUpdate Frequency
DailyEvery 30 minutes
HourEvery 30 minutes
MinuteEvery minute
SecondEvery second
TickConstantly checks for new data

Split Adjustment of Indicators

Backtests use adjusted price data by default. Therefore, if you don't change the data normalization mode, the indicators in your backtests are updated with adjusted price data. In contrast, if a split or dividend occurs in live trading, your indicators will temporarily contain price data from before the corporate event and price data from after the corporate event. If this occurs, your indicators will produce different signals in your backtests compared to your live trading deployment. To avoid issues, reset and warm up your indicators when your algorithm receives a corporate event.

Tick Slice Sizes

In backtesting, we collect ticks into slices that span 1 millisecond before injecting them into your algorithm. In live trading, we collect ticks into slices that span up to 70 milliseconds before injecting them into your algorithm. This difference in slice sizes can cause deviations between your algorithm's live and OOS backtest equity curves. To avoid issues, ensure your strategy logic is compatible with both slice sizes.

Differences From Modeling

The modeling that your algorithm uses can cause differences between backtesting and live trading performance.

Reality Modeling Error

We provide brokerage models to model fees, slippage, and order fills in backtests. However, these model predictions may not always match the fees that your live algorithm incurs, leading to deviations between backtesting and live trading. You can adjust the reality models that your algorithm uses to more accurately reflect the specific assets that you're trading. For more information about reality models, see Reality Modeling.

Market Impact

We don't currently model market impact. So, if you are trading large orders, your fill prices can be better during backtesting than live trading, causing deviations between backtesting and live trading. To avoid issues, implement a custom fill model in your backtests that incorporates market impact.

Fills

In backtests, orders fill immediately. In live trading, they are sent to your brokerage and take about half a second to execute. If you fill an order in a backtest with stale data, deviations between backtesting and live trading can occur because the order is filled at a price that is likely different from the real market price. Stale order fills commonly occur in backtests when you create a Scheduled Event with an incompatible data resolution. For instance, if you subscribe to hourly data, place a Scheduled Event for 11:15 AM, and fill an order during the Scheduled Event, the order will fill at a stale price because the data between 11:00 AM and 11:15 AM is missing. To avoid stale fills, only place orders when your algorithm receives price data.

In live trading, your brokerage provides the fill price of your orders. Since the backtesting brokerage models do not know the price at which live orders are filled, the fill price of backtest orders is based on the best price available in the current backtesting data. Similarly, limit orders can fill at different prices between backtesting and live trading. In backtesting, limit orders fill as soon as the limit price is hit. In live trading, your brokerage may fill the same limit order at a different price or fail to fill the order, depending on the position of your order in their order book.

Borrowing Costs

We do not currently simulate the cost of borrowing shorts in backtests. Therefore, if your algorithm takes short positions, deviations can occur between backtesting and live trading. We are working on adding the functionality to model borrowing fees. Subscribe to GitHub Issue #4563 to track the feature progress.

Differences From Brokerage

The brokerage that your algorithm uses can cause differences between backtesting and live trading performance.

Portfolio Allocations on Small Accounts

If you trade a small portfolio, it's difficult to achieve accurate portfolio allocations because shares are usually sold in whole numbers. For instance, you likely can't allocate exactly 10% of your portfolio to a security. You can use fractional shares to achieve accurate portfolio allocations, but not all brokerages support fractional shares. To get the closest results when backtesting and live trading over the same period, ensure both algorithms have the same starting cash balance.

Different Backtest Parameters

If you don't start your backtest and live deployment on the same date with the same holdings, deviations can occur between backtesting and live trading. To avoid issues, ensure your backtest parameters are the same as your live deployment.

Non-deterministic State From Algorithm Restarts

If you stop and redeploy your live trading algorithm, it needs to restart in a stateful way or else deviations can occur between backtesting and live trading. To avoid issues, redeploy your algorithm in a stateful way using the SetWarmUpset_warm_up and Historyhistory methods. Furthermore, use the Object Store to save state information between your live trading deployments.

Existing Portfolio Securities

If you deploy your algorithm to live trading with a brokerage account that has existing holdings, your live trading equity curve reflects your existing positions, but the backtesting curve won't. Therefore, if you have existing positions in your brokerage account when you deploy your algorithm to live trading, deviations will occur between backtesting and live trading. To avoid issues, deploy your algorithm to live trading using a separate brokerage account or subaccount that does not have existing positions.

Brokerage Limitations

We provide brokerage models that support specific order types and model your buying power. In backtesting, we simulate your orders  with the brokerage model you select. In live trading, we send your orders to your brokerage for execution. If the brokerage model that you use in backtesting is not the same brokerage that you use in live trading, deviations may occur between backtesting and live trading. The deviations can occur if your live brokerage doesn't support the order types that you use or if the backtesting brokerage models your buying power with a different methodology than the real brokerage. To avoid brokerage model issues, set the brokerage model in your backtest to the same brokerage that you use in live trading.

Differences From Third-Party Indicators

The values of our indicators can sometimes produce different results than the indicators on other platforms. There can be several reasons for these discrepancies.

Price Differences

If you find differences in indicator values, compare the prices that are fed into the indicator on each platform. If the input data is slightly different, the indicator values will be different. To test if it's a difference in price data, feed in the data from the third-party platform into our indicators. We validate the indicators against third-party sources and when the values are the same, the indicator values are similar too.

Timestamp Differences

We timestamp our data to the time when the period ends. Many other platforms timestamp to the beginning of the candle.

Implementation Differences

Some indicators can have slightly different default arguments for their implementation. A common difference across platforms is to use a different MovingAverageType for the indicators. To view the default arguments for all our indicators, see Supported Indicators. To view the full implementation of our indicators, see the LEAN GitHub repository.

Warm Up Period Differences

Some platforms use all of the historical data to warm up their indicators while LEAN indicators have a fixed number of bars they need to warm up. As a result, indicators with long memory like the Exponential Moving Average can have slightly different values across platforms.

Risk Free Interest Rate Differences

Some indicators, like Sharpe ratios and Sortino ratios, are a function of the risk free interest rate. LEAN provides several different ways to define the interest rate, which can lead to different indicator values compared to other platforms.

Differences From Real-time Scheduled Events

In live trading, Scheduled Events execute in a parallel thread based on a real-time clock. If you set a Scheduled Event to fire at 10:00 AM, it executes at exactly 10:00 AM. In backtesting, Scheduled Events are part of the main algorithm manager loop, so they may not execute exactly when you set them. For example, if your algorithm subscribes to minute resolution US Equity data with regular trading hours and you set a Scheduled Event to occur at 2:00 AM, your Scheduled Event will execute at 9:31 AM when the next bar is fed into your algorithm.

The difference between live trading and backtesting is important to note because it can affect your algorithm's behavior. There are two common scenarios to consider.

Execution Timing and Backtest Timeouts

Take the following scenario:

  • You set Scheduled Events for 2:00 AM, 3:00 AM, and 4:00 AM each day.
  • Each Scheduled Event takes eight minutes to execute.
  • Your algorithm only subscribes to US Equity securities without extended market hours (9:30 AM - 4:00 PM).

In this scenario, the Scheduled Events each fire at the correct time and execute without error in live trading. In backtesting, all of the Scheduled Events execute at 9:31 AM when your algorithm receives the first bar of the trading day. Since all the Scheduled Events take eight minutes to execute, the algorithm tries to execute all the Scheduled Events but reaches the 10-minute timeout and the backtest stops execution.

Live Data Delays

In backtests, your algorithm receives data at perfect timing. If you request minute resolution data, your algorithm receives the bars at the top of each minute. In live trading, bars have a slight delay, so you may receive them milliseconds after the top of each minute. Take the following scenario:

  • You subscribe to minute resolution data
  • You set a Scheduled Event for 10:00 AM
  • The Scheduled Event checks the current asset price

In live trading, the Scheduled Event executes at exactly 10:00 AM but your algorithm may receive the 9:59-10:00 AM bar at 10:00:00.01 AM. Therefore, when you check the price in the Scheduled Event, the price from the 9:58-9:59 AM bar is the latest price. In backtesting, the Scheduled Event gets the price from the 9:59-10:00 AM bar since your algorithm receives the bar at perfect timing.

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: