Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Principle:Nautechsystems Nautilus trader Portfolio Analysis

From Leeroopedia


Field Value
sources https://github.com/nautechsystems/nautilus_trader , https://nautilustrader.io/docs/
domains performance analysis, portfolio management, risk assessment
last_updated 2026-02-10 12:00 GMT

Overview

Portfolio Analysis is the principle of computing post-trade performance metrics from account state and position history to evaluate the quality and risk characteristics of a trading strategy.

Description

After a backtest (or live trading session) completes, the raw results -- account balances, closed positions, realized PnL per trade, and per-period returns -- must be distilled into interpretable statistics. Portfolio analysis provides a structured framework for this distillation.

The principle addresses the following concerns:

  • Realized PnL aggregation -- Each closed position has a realized PnL in its settlement currency. The analyzer aggregates these into per-currency PnL series, enabling drill-down by currency for multi-currency portfolios.
  • Return series construction -- For each closed position, the realized return (percentage) is recorded at the position's close timestamp. The resulting time series supports return-based statistics such as Sharpe ratio, Sortino ratio, and maximum drawdown.
  • Total PnL computation -- The difference between ending and starting account balances, optionally including unrealized PnL, gives the total profit or loss. Percentage changes are computed relative to the starting balance.
  • Pluggable statistics -- The analyzer supports a registry of PortfolioStatistic plugins. Each statistic implements one or more of calculate_from_realized_pnls, calculate_from_returns, and calculate_from_positions. This design allows users to add custom metrics (e.g., Calmar ratio, win rate, profit factor) without modifying the analyzer itself.
  • Multi-currency support -- Portfolios may trade instruments denominated in different currencies. The analyzer tracks balances and PnLs per currency, requiring the caller to specify a currency when querying multi-currency results.
  • Formatted output -- Statistics can be returned as raw dictionaries (for programmatic use) or as formatted string lists (for human-readable log output), with automatic padding for aligned display.

Usage

Apply this principle whenever you need to:

  • Evaluate the profitability and risk profile of a completed backtest.
  • Compare multiple strategy runs on standardized metrics.
  • Generate performance reports for stakeholders.
  • Implement custom performance metrics via the statistic plugin interface.
  • Feed performance data into optimization or selection pipelines.

Theoretical Basis

Portfolio analysis rests on the decomposition of trading outcomes into PnL-based and return-based metrics, each supporting a different class of performance statistics.

Key theoretical elements:

  • PnL series -- A series indexed by position ID, where each value is the realized PnL in the settlement currency. From this series, statistics compute: total PnL, average win/loss, win rate, profit factor, expectancy, and maximum consecutive wins/losses.
  • Return series -- A time-indexed series of realized returns (as fractions). At each timestamp, multiple position closures are summed. This series supports: Sharpe ratio, Sortino ratio, maximum drawdown, Calmar ratio, annualized return, and volatility.
  • Position-based statistics -- Some metrics (e.g., average holding period, percentage of long vs. short positions) require access to the full Position objects rather than just PnL or return numbers.
  • Statistic plugin protocol -- Each PortfolioStatistic must implement at least one of three methods:
    • calculate_from_realized_pnls(pnls) -- receives PnL values (list or Series).
    • calculate_from_returns(returns) -- receives return values (dict or Series).
    • calculate_from_positions(positions) -- receives position objects.
  • Starting balance anchoring -- The total PnL percentage is computed as (ending_balance - starting_balance) / starting_balance * 100. The starting balance is captured at the beginning of the analysis, protecting against mid-run balance adjustments.

Pseudocode:

FUNCTION calculate_statistics(analyzer, account, positions):
    starting_balances = account.starting_balances()
    current_balances = account.balances_total()

    RESET internal PnL and return series

    FOR EACH position in positions:
        IF position.realized_pnl is not None:
            ADD trade(position.id, position.realized_pnl)

            IF position is closed:
                ADD return(position.close_time, position.realized_return)

    SORT return series by timestamp

    -- Statistics are computed lazily when queried:
    -- get_performance_stats_pnls() iterates registered statistics with PnL data
    -- get_performance_stats_returns() iterates registered statistics with return data
    -- get_performance_stats_general() iterates registered statistics with position data

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment