🚀 AI One-Click Generation of quantconnect Strategy Code

How to Plot Custom Charts and Indicators in a QuantConnect Backtest

quantconnect | Published on: 2025/12/10
The following content is generated by EasyQuant .

Problem Description

How do I plot a custom data series on a chart during a backtest?

Solution

To plot a custom data series in QuantConnect, you use the self.plot() method within your algorithm (usually inside on_data).

This method allows you to send values to the front-end charting interface. You can group these values into specific "Charts" and "Series".

Key Method: self.plot()

The syntax is:

self.plot("Chart Name", "Series Name", value)
  • Chart Name: The title of the chart panel. If it doesn't exist, LEAN creates a new one.
  • Series Name: The label for the specific line or data point.
  • Value: The numerical value to plot (int, float, or Decimal).

Complete Strategy Example

The following code demonstrates how to create a custom chart named "Indicators" and plot the closing price of SPY against a 20-day Simple Moving Average (SMA).

# region imports
from AlgorithmImports import *
# endregion

class CustomPlottingAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2023, 1, 1)
        self.set_end_date(2023, 12, 1)
        self.set_cash(100000)

        # Add an asset
        self.spy = self.add_equity("SPY", Resolution.DAILY).symbol

        # Create an indicator to plot
        self.sma = self.sma(self.spy, 20, Resolution.DAILY)

        # Optional: Pre-define chart properties (e.g., Scatter, Bar)
        # If you don't do this, it defaults to a Line chart.
        # chart = Chart("Trade Plot")
        # chart.add_series(Series("Buy", SeriesType.SCATTER, "$", Color.Green, ScatterMarkerSymbol.TRIANGLE))
        # chart.add_series(Series("Sell", SeriesType.SCATTER, "$", Color.Red, ScatterMarkerSymbol.TRIANGLE_DOWN))
        # self.add_chart(chart)

    def on_data(self, slice: Slice):
        # Ensure data exists
        if not self.sma.is_ready or self.spy not in slice.bars:
            return

        current_price = slice.bars[self.spy].close
        sma_value = self.sma.current.value

        # 1. Plotting on a Custom Chart named "Analysis"
        # This creates a new chart panel separate from the Strategy Equity
        self.plot("Analysis", "SPY Price", current_price)
        self.plot("Analysis", "SMA 20", sma_value)

        # 2. Plotting the difference on a separate chart named "Spread"
        diff = current_price - sma_value
        self.plot("Spread", "Price vs SMA", diff)

    def on_end_of_algorithm(self):
        self.log("Algorithm Finished")

Important Considerations

  1. Performance Limits: To prevent browser crashes, QuantConnect limits charts to approximately 4,000 data points per series. If you plot every minute in a multi-year backtest, the chart will downsample.
  2. Default Chart: If you use self.plot("Strategy Equity", ...) you will draw on the main performance chart. This is generally discouraged for indicators because the scale of the indicator (e.g., RSI at 0-100) might distort the view of your Equity (e.g., $100,000).
  3. Plotting Indicators Shortcut: If you have a registered indicator object, you can use the helper method:
    self.plot_indicator("Chart Name", self.sma)
    
    This automatically handles the series naming based on the indicator's internal name.

Q&A: Plotting in QuantConnect

Q: Can I change the color or style of the plot line?
A: Yes. To customize colors or use Scatter/Bar charts, you must instantiate a Chart and Series object in initialize using self.add_chart(). You can specify SeriesType.SCATTER, SeriesType.BAR, etc., and define specific Color objects.

Q: Why isn't my chart showing up in the results?
A: Ensure you are calling self.plot() inside a loop that actually executes (like on_data). Also, check that the values you are passing are not None. If the backtest produces no trades and runs very quickly, sometimes charts may not render if the data density is too low, though this is rare.

Q: Can I plot from OnEndOfDay?
A: Yes. Plotting inside on_end_of_day is actually recommended for high-resolution strategies (like Second or Minute resolution) if you only need to visualize daily trends. This saves data points and avoids the 4,000 point limit downsampling.

Q: How do I plot buy and sell markers?
A: While self.plot draws lines, you can create a specific series with SeriesType.SCATTER to draw markers. However, QuantConnect automatically plots Buy/Sell annotations on the main "Strategy Equity" chart whenever an order is filled, so manual plotting of trades is often unnecessary unless you need custom logic.