Projects

Debugging

Introduction

Debugging is the process of systematically using a tool to find and fix errors in software. Errors can cause unintended trades, unexpected algorithm crashes, and faulty risk management logic. We use a debugging tool because we slow the code down, step through it line-by-line, and inspect the variables to understand the internal state of the program. To debug, you can use the built-in debugger, produce logging statements, and create charts.

Coding Errors

Coding errors are errors that cause your projects to not build, throw exceptions, or behave unexpectedly. There are generally 3 types of coding errors: build, runtime, and logic errors. Each type of error occurs for different reasons.

Build Errors

Build errors occur when the interpreter's syntax check fails. An example code snippet that produces a build error is the following:

var a = 1;
if (a = 2) {}
a = 1
if a = 2:
    pass

If build errors occur in your project, you can not use the debugger, logging statements, or custom charts to debug the issue. You're notified of build errors in the following ways:

  • The line where the error occurs is underlined in red.
  • The Problems panel at the bottom of the IDE displays the errors.
  • The Explorer panel highlights the editors, files, and outlines in red where the error occurs.

Runtime Errors

Runtime Errors, also called exceptions, occur when the interpreter’s syntax checks pass but an error occurs during execution. An example code snippet that produces a runtime error is the following:

var a = new List<int>() {1};
var b = a[1];
a = [1]
a[1]

If runtime errors occur in your project, a stack trace of the error is added to the Cloud Terminal and the log file. For example, the snippet above produces the following error message:

Runtime Error: IndexError : list index out of range
  at OnData
    a[1]
===
   at Python.Runtime.PyObject.Invoke(PyTuple args in main.py: line 17
     (Open Stack Trace)
Runtime Error: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') in Main.cs:line 24 (Open Stack Trace)

The stack trace from the build error identifies the line of code where the error occurs. If the error doesn't reference your project files, it's an issue with Lean or another library. To view more information about the error, click (Open Stack Trace).

Logic Errors

Logic errors occur when your algorithm behaves in an unexpected or unintended manner. These types of errors don't halt the program execution, so they are difficult to diagnose. An example code snippet that produces a logic error is the following:

var average = x + y / 2.0; // instead of (x + y) / 2.0
average = x + y / 2 # instead of (x + y) / 2

To resolve logic errors, carefully trace your algorithm. You may use the Log and Debug methods or the built-in debugger.

Debugger

The debugger is a built-in tool to help you debug coding errors while backtesting. The debugger enables you to slow down the code execution, step through the program line-by-line, and inspect the variables to understand the internal state of the program. For more information about the backtesting debugger, see Debugging.

Logging Statements

Logging statements are statements you can add to your algorithm in order to add information to the log file, add information to the Cloud Terminal, or even stop the algorithm. Use these statements to debug your backtests and live algorithms. Consider adding them in the code block of an if statement to signify an error has been caught.

It's good practice to add logging statements to live algorithm so that you can understand its behavior and keep records to compare against backtest results. If you don't add logging statements to a live algorithm and the algorithm doesn't trade as you expect, it's difficult to evaluate the underlying problem.

Log

Log statements are added to the log file while your algorithm continues executing. Logging dataset information is not permitted. Use Log statements to debug your backtests and live trading algorithms.

If you execute algorithms in QC Cloud, log length is capped by organization tier. If your organization hits the daily limit, contact us. The log files of each cloud project can store up to 100,000 lines for up to one year. If you log more than 100,000 lines or some lines become older than one year, we remove the oldest lines in the files so your project stays within the quota.

If you log the same content multiple times, only the first instance is added to the log file. To bypass this rate-limiting, add a timestamp to your log messages.

To record the algorithm state when the algorithm stops executing, add log statements to the OnEndOfAlgorithm event handler.

Log("My log message");
self.Log("My log message")

Debug

Debug statements are the same as log statements, but Debug statements are orange in the Cloud Terminal. Use these statements when you want to give more attention to a message in the Cloud Terminal. Debug messages can be up to 200 characters in length. If you send multiple debug statements within 1 second, your messages are rate-limited to avoid crashing your browser.

Debug("My debug message");
self.Debug("My debug message")

Error

Error statements are the same as log statements, but Error statements are displayed in red text in the Cloud Terminal. Use these statements when you want to give the most attention to a message in the Cloud Terminal. Error statements are rate-limited like debug statements.

Error("My error message");
self.Error("My error message")

Quit

Quit statements cause your project to stop running and may log some data to the log file and Cloud Terminal. These statements are orange in the Cloud Terminal. When you call the Quit method, the program continues executing until the end of the method definition. If you want to quit execution immediately, return after you call Quit.

Quit("My quit message");
self.Quit("My quit message")

Charting

You can use the IDE charting capabilities to plot values over time when debugging. To add data points to a custom chart, call the Plot method with a chart name, series name, and value. For a full example, see Charting.

Plot(chart, series, value);
self.Plot(chart, series, value)

If you run your algorithm in QC Cloud, we limit the number of points a chart can have to 4,000 because intensive charting generates hundreds of megabytes (200MB) of data, which is too much to stream online or display in a web browser. If you exceed the limit, the following error message is thrown:

Exceeded maximum data points per series, chart update skipped.

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: