Backtests

Reading Results

Introduction

This page explains how to read results of backtests in the research environment.

Prerequisites

Working knowledge of C#.

Working knowledge of Python of working with pandas DataFrames and Series. If you are not familiar with pandas, refer to the pandas documentation.

You'll need to understand how to do Project Management and Backtest Management through the QuantConnect Api.

Read Backtest Instance

Follow the below instruction to read a backtest instance by using the QuantConnect Api.

  1. Load the required assembly files and data types.
  2. #load "../Initialize.csx"
    #load "../QuantConnect.csx"
    
    using QuantConnect;
    using QuantConnect.Api;
  3. Call ReadBacktest with the project ID and backtest ID.
  4. var backtest = api.ReadBacktest(<yourProjectId>, <yourBacktestId>);
    backtest = api.ReadBacktest(<your_project_id>, <your_backtest_id>)

Note that this would be a snapshot of the backtest at this instance. If the backtest is not finished, you'll need to re-read it to update the information after its completion.

Metadata

You need to understand how to Read Backtest Instance to read the metadata.

Follow the below exmaple to display the metadata of the backtest.

Console.WriteLine($@"Backtest ID: {backtest.BacktestId}
Name: {backtest.Name}
Created Time: {backtest.Created}
Success?: {backtest.Success}
Completed?: {backtest.Completed}
Progress [0,1]: {backtest.Progress}
Note: {backtest.Note}")
print(f"""Backtest ID: {backtest.BacktestId}
Name: {backtest.Name}
Created Time: {backtest.Created.strftime("%Y/%m/%d %H:%M:%S")}
Success?: {backtest.Success}
Completed?: {backtest.Completed}
Progress [0,1]: {backtest.Progress}
Note: {backtest.Note}\n""")

Errors

You need to understand how to Read Backtest Instance to read the errors.

Call Error and StackTrace to obtain the error messages of the backtest.

Console.WriteLine($@"Error: {backtest.Error}
Stacktrace: {backtest.StackTrace}")
print(f"""Error: {backtest.Error}
Stacktrace: {backtest.StackTrace}""")

Statistics

You need to understand how to Read Backtest Instance to read the statistics.

Follow these steps to get the statistics of the backtest. Note that these metrics will only be available when the backtest is completed.

  1. Call Statistics attribute of the backtest, then display it.
  2. var statistics = backtest.Statistics;
    foreach(var kvp in statistics)
    {
        Console.WriteLine($"{kvp.Key}: {kvp.Value}");
    }
    statistics = backtest.Statistics
    for kvp in statistics:
        print(f"{kvp.Key}: {kvp.Value}")
  3. Call RuntimeStatistics attribute of the backtest, then display it.
  4. var runtimeStatistics = backtest.RuntimeStatistics;
    foreach(var kvp in runtimeStatistics)
    {
        Console.WriteLine($"{kvp.Key}: {kvp.Value}");
    }
    runtime_statistics = backtest.RuntimeStatistics
    for kvp in runtime_statistics:
        print(f"{kvp.Key}: {kvp.Value}")
  5. Call AlphaRuntimeStatistics attribute of the backtest, then display it.
  6. var alphaStatistics = backtest.AlphaRuntimeStatistics.ToDictionary();
    foreach(var kvp in alphaStatistics)
    {
        Console.WriteLine($"{kvp.Key}: {kvp.Value}");
    }
    alpha_statistics = backtest.AlphaRuntimeStatistics.ToDictionary()
    for kvp in alpha_statistics:
        print(f"{kvp.Key}: {kvp.Value}")

Charts

You need to understand how to Read Backtest Instance to read the charts.

Follow these steps to read chart data of a backtest.

Follow these steps to read and plot chart data of a backtest.

  1. Call Charts attribute of the backtest.
  2. var charts = backtest.Charts;
    charts = backtest.Charts
  3. Hash the chart's name to obtain a particular chart's data.
  4. var equityChart = charts["Strategy Equity"];
    var drawdownChart = charts["Drawdown"];
    var exposureChart = charts["Exposure"];
    equity_chart = charts["Strategy Equity"]
    drawdown_chart = charts["Drawdown"]
    exposure_chart = charts["Exposure"]
  5. Call Series attribute of the charts, then hash with the name of the desired series to obtain particular series's data.
  6. var equitySeries = equityChart.Series["Equity"].Values;
    var drawdownSeries = drawdownChart.Series["Equity Drawdown"].Values;
    equity_series = equity_chart.Series["Equity"].Values
    drawdown_series = drawdown_chart.Series["Equity Drawdown"].Values
  7. Iterate each data point of each series, store them in (nested) Dictionary.
  8. var equityData = equitySeries
                     .Where(kvp => kvp != null)
                     .ToDictionary(kvp => kvp.x, kvp => kvp.y);
    var drawdownData = drawdownSeries
                       .Where(kvp => kvp != null)
                       .ToDictionary(kvp => kvp.x, kvp => kvp.y);
    var exposureData = new Dictionary<string, Dictionary<long, decimal>>();
    foreach(var col in exposureChart.Series.Keys)
    {
        exposureData[col] = new Dictionary<long, decimal>();
        foreach(var kvp in exposureChart.Series[col].Values)
        {
            if (kvp != null)
            {
                exposureData[col].Add(kvp.x, kvp.y);
            }
        }
    }
    equity_data = {kvp.x: kvp.y for kvp in equity_series if kvp}
    drawdown_data = {kvp.x: kvp.y for kvp in drawdown_series if kvp}
    exposure_data = {}
    for col in exposure_chart.Series.Keys:
        series = {}
        for kvp in exposure_chart.Series[col].Values:
            if not kvp: continue
            series[kvp.x] = kvp.y
        exposure_data[col] = series
  9. Display the data.
  10. Console.WriteLine("Equity Curve:");
    foreach(var kvp in equityData.Take(5))
    {
        var time = DateTimeOffset.FromUnixTimeSeconds(kvp.Key).DateTime;
        Console.WriteLine($"{time} : {kvp.Value}");
    }
    Console.WriteLine("Drawdown %:");
    foreach(var kvp in drawdownData.Take(5))
    {
        var time = DateTimeOffset.FromUnixTimeSeconds(kvp.Key).DateTime;
        Console.WriteLine($"{time} : {kvp.Value}");
    }
    foreach(var kvpExposure in exposureData)
    {
        Console.WriteLine($"{kvpExposure.Key} Exposure:");
        foreach(var kvp in kvpExposure.Value.Take(5))
        {
            var time = DateTimeOffset.FromUnixTimeSeconds(kvp.Key).DateTime;
            Console.WriteLine($"{time} : {kvp.Value}");
        }
    }
  11. Convert the dictionaries into pandas.Series/DataFrame.
  12. equity_data = pd.Series(equity_data)
    drawdown_data = pd.Series(drawdown_data)
    exposure_data = pd.DataFrame(exposure_data)
  13. Call plot to plot the data.
  14. equity_data.plot(figsize=(10, 6), title="Equity Curve")
    plt.show()
    drawdown_data.plot(figsize=(10, 6), title="Underwater Plot")
    plt.show()
    exposure_data.plot(figsize=(10, 6), title="Exposure")
    plt.show()

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: