Problem Description
Solution
To log messages for debugging your trading algorithm in QuantConnect, you primarily use the self.debug() and self.log() methods provided by the QCAlgorithm class.
Here is a breakdown of the methods and a code example demonstrating their usage.
Primary Logging Methods
-
self.debug(message)- Purpose: Used for immediate feedback during development.
- Behavior: Sends the message directly to the IDE console (the "Debug" tab) in real-time.
- Limitation: It is rate-limited to prevent flooding the browser. If you send too many debug messages quickly, some may be dropped.
-
self.log(message)- Purpose: Used for permanent records and post-trade analysis.
- Behavior: Appends the message to a text file stored in the "Logs" tab of your backtest or live deployment.
- Usage: Ideal for recording order fills, specific indicator values, or logic branches taken.
-
self.error(message)- Purpose: Used to highlight critical issues.
- Behavior: Sends a message that is highlighted (usually in red) to draw attention to runtime errors or invalid states.
Implementation Example
Below is a complete algorithm demonstrating how to implement these logging methods in different event handlers (Initialization, Data Processing, and Order Events).
from AlgorithmImports import *
class LoggingAndDebuggingAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2023, 1, 1)
self.set_end_date(2023, 1, 5)
self.set_cash(100000)
self.symbol = self.add_equity("SPY", Resolution.MINUTE).symbol
# 1. Debug: Useful for confirming the algorithm started correctly
self.debug("Initialize: Algorithm started successfully.")
# 2. Log: Useful for keeping a permanent record of settings
self.log(f"Initialize: Equity added {self.symbol}, Cash set to 100k")
def on_data(self, slice: Slice):
# Check if data exists for our symbol
if self.symbol in slice.bars:
bar = slice.bars[self.symbol]
# Example: Log price only at specific times to avoid flooding logs
if self.time.hour == 10 and self.time.minute == 0:
# f-strings are highly recommended for readable logs
self.debug(f"10:00 AM Check - Current Price: {bar.close}")
# Simple logic to trigger an order
if not self.portfolio.invested:
self.set_holdings(self.symbol, 1)
self.debug(f"Buy Signal Triggered at {self.time}")
def on_order_event(self, order_event: OrderEvent):
# 3. Log: Best place to record transaction details permanently
if order_event.status == OrderStatus.FILLED:
order = self.transactions.get_order_by_id(order_event.order_id)
message = (f"ORDER FILLED: {order_event.symbol} "
f"| Price: {order_event.fill_price} "
f"| Quantity: {order_event.fill_quantity} "
f"| Fees: {order.order_fee}")
self.log(message)
def on_end_of_algorithm(self):
self.debug("Algorithm execution finished.")
Best Practices
- Avoid
print(): While standard Pythonprint()statements work, they are not as integrated into the LEAN report system asself.debugorself.log. - Use f-strings: Python f-strings (e.g.,
f"Price: {price}") are the most efficient way to format strings for logging. - Watch Rate Limits: Do not put
self.debug()inside a loop that runs every tick (likeon_data) without a conditional check (e.g., checking the time), otherwise, your backtest may be slowed down or messages will be suppressed.
Q&A: Debugging in QuantConnect
Q: What is the difference between Debug and Log in QuantConnect?
A: Debug is intended for real-time feedback in the console during development and is rate-limited. Log writes to a permanent text file which is better for analyzing the full history of an algorithm's execution after a backtest completes.
Q: Can I log messages in Live Trading?
A: Yes. In live trading, self.log() messages are stored in the result files, and self.debug() messages appear in the live console. However, be mindful of logging sensitive information.
Q: Why are my debug messages not showing up?
A: If you generate too many messages in a short period (e.g., logging every second in on_data), the system will suppress them to maintain performance. Use conditional logic to log less frequently.
Q: How do I view the output of self.log()?
A: After a backtest finishes, click on the "Logs" tab in the results panel. You can read the logs there or download the text file for offline analysis.