book
Checkout our new book! Hands on AI Trading with Python, QuantConnect, and AWS Learn More arrow

Live Trading

Charting and Logging

Introduction

The live results page shows your algorithm's live trading performance. You can add custom charts and logs to the results page.

Charting

Charts are sampled every one and ten minutes. If you create 1-minute resolution custom charts, the IDE charting will downgrade the granularity and display the 10-minutes sampling after a certain amount of samples. There are not quotas in live trading.

Logging

Algorithms can record string messages ('log statements') to a file for analysis after a backtest is complete, or as a live algorithm is running. These records can assist in debugging logical flow errors in the project code. 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 algorithms so 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.

If you run algorithms on QuantConnect, you must stay within the log quota. To only log when your algorithm is live, use the live_mode property.

Select Language:
if self.live_mode:
    self.log("My log message")

Runtime Statistics

Runtime statistics show the performace of your algorithm at a single moment in time.

The following table describes the default runtime statistics:

StatisticDescription
EquityThe total portfolio value if all of the holdings were sold at current market rates.
FeesThe total quantity of fees paid for all the transactions.
HoldingsThe absolute sum of the items in the portfolio.
Net ProfitThe dollar-value return across the entire trading period.
PSRThe probability that the estimated Sharpe ratio of an algorithm is greater than a benchmark (1).
ReturnThe rate of return across the entire trading period.
UnrealizedThe amount of profit a portfolio would capture if it liquidated all open positions and paid the fees for transacting and crossing the spread.
VolumeThe total value of assets traded for all of an algorithm's transactions.

For more information about runtime statistics, see Runtime Statistics.

Examples

The following examples demonstrate some common practices for logging in live algorithm.

Example 1: On Events And Trading Logic

The following example trades a simple EMA cross trend-following strategy on SPY. We log or debug messages in event handlers and trading logic changes to get information on any event flow.

Select Language:
class LoggingAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 8, 12)
        self.set_end_date(2024, 9, 1)
        self.set_cash(1000000)

        # Request SPY data to trade.
        self.spy = self.add_equity("SPY").symbol
        # Create an EMA indicator to generate trade signals.
        self._ema = self.ema(self.spy, 20, Resolution.DAILY)

        # Warm up the algorithm for indicator readiness.
        self.set_warm_up(20, Resolution.DAILY)

    def on_warmup_finished(self) -> None:
        # Signals on warm-up finished.
        self.log("Warm up finished")

    def on_data(self, slice: Slice) -> None:
        bar = None if self.is_warming_up else slice.bars.get(self.spy)
        if bar:
            # Trend-following strategy using price and EMA.
            # If the price is above EMA, SPY is in an uptrend, and we buy it.
            if bar.close > self._ema.current.value and not self.portfolio[self.spy].is_long:
                self.debug("Trend changes to upwards")
                self.set_holdings(self.spy, 1)
            elif bar.close < self._ema.current.value and not self.portfolio[self.spy].is_short:
                self.debug("Trend changes to downwards")
                self.set_holdings(self.spy, -1)
    
    def on_order_event(self, order_event: OrderEvent) -> None:
        if order_event.status == OrderStatus.FILLED:
            # Log the order details if being filled.
            self.log(f"Order filled - Quantity: {order_event.quantity}")

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: