Skip to content

Reports

Reports provide insights into your portfolio — holdings, asset allocation, performance metrics, and a comprehensive summary dashboard.

Warning

The source for this page is AI-generated and may contain errors.

If you spot an error, please Open an issue on our GitHub repo.

niveshpy reports

Group for report-related commands.

Usage:

niveshpy reports [options] <command>

Options:

  -h, --help  Show this message and exit.

Subcommands

niveshpy reports allocation

Generate asset allocation report.

By default, generates a report of current asset allocation grouped by security type and category.

Optionally, provide text to filter securities, accounts, and dates.

Usage:

niveshpy reports allocation [options] [<queries>]

Options:

  --category              Group allocation by security category.
  --type                  Group allocation by security type.
  -o, --output-file FILE  Path to save the output file (when using
                          --csv/--json flag).
  --csv
  --json
  -h, --help              Show this message and exit.

niveshpy reports holdings

Generate holdings report.

By default, generates a report of current holdings across all accounts.

Optionally, provide text to filter securities, accounts, and dates.

Usage:

niveshpy reports holdings [options] [<queries>]

Options:

  --total / --no-total    Show overall total row in the report output.
  -o, --output-file FILE  Path to save the output file (when using
                          --csv/--json flag).
  --csv
  --json
  --offset INTEGER        Number of securities to skip before starting to
                          list. Use with --limit for pagination.  [default: 0]
  -l, --limit INTEGER     Maximum number of securities to list.  [default: 30]
  -h, --help              Show this message and exit.

niveshpy reports performance

Generate portfolio performance report.

Shows per-holding performance metrics including current value, invested, gains, and annualized returns (XIRR) for each (account, security) pair.

Optionally, provide text to filter securities and accounts.

Usage:

niveshpy reports performance [options] [<queries>]

Options:

  --total / --no-total    Show overall total row in the report output.
  -o, --output-file FILE  Path to save the output file (when using
                          --csv/--json flag).
  --csv
  --json
  --offset INTEGER        Number of securities to skip before starting to
                          list. Use with --limit for pagination.  [default: 0]
  -l, --limit INTEGER     Maximum number of securities to list.  [default: 30]
  -h, --help              Show this message and exit.

niveshpy reports summary

Generate portfolio summary report.

Shows overall summary metrics like total current value, invested, gains, and XIRR, along with top holdings and allocation breakdown.

Optionally, provide text to filter securities and accounts.

Usage:

niveshpy reports summary [options] [<queries>]

Options:

  -o, --output-file FILE  Path to save the output file (when using
                          --csv/--json flag).
  --json
  -h, --help              Show this message and exit.

Usage notes and examples

Holdings

Show current holdings across all accounts, including invested amount and current value.

Example

niveshpy reports holdings # (1)
niveshpy reports holdings UTI DSP # (2)
niveshpy reports holdings 'date:2025-01' --no-total # (3)
niveshpy reports holdings --format json # (4)
niveshpy reports holdings --limit 5 # (5)
  1. Show all current holdings with a total row.
  2. Filter holdings for securities matching "UTI" or "DSP".
  3. Show holdings for January 2025 without the total row.
  4. Output holdings as JSON.
  5. Show only the top 5 holdings.

Date filtering and invested amounts

When using date filters, the current value reflects the filtered date range, but the invested amount is calculated from the full transaction history. This may lead to unexpected results when filtering by date.

Allocation

Show asset allocation grouped by security type, category, or both.

Example

niveshpy reports allocation # (1)
niveshpy reports allocation --type # (2)
niveshpy reports allocation --category # (3)
niveshpy reports allocation --format json # (4)
  1. Show allocation grouped by both type and category (default).
  2. Group allocation by security type only (e.g., Mutual Fund, Stock).
  3. Group allocation by security category only (e.g., Equity, Debt, Hybrid).
  4. Output allocation as JSON.

Performance

Show per-holding performance metrics — current value, invested amount, absolute gains, gains percentage, and XIRR.

Example

niveshpy reports performance # (1)
niveshpy reports performance HDFC # (2)
niveshpy reports performance --no-total # (3)
niveshpy reports performance --format csv # (4)
niveshpy reports performance --limit 10 --offset 5 # (5)
  1. Show performance for all holdings with a total row.
  2. Filter performance for securities matching "HDFC".
  3. Hide the aggregated total row.
  4. Export performance data as CSV.
  5. Show 10 holdings starting from the 6th.

Understanding XIRR

XIRR (Extended Internal Rate of Return) is an annualized return metric that accounts for the timing of each transaction. It provides a more accurate picture of investment performance than simple gain/loss calculations.

Summary

Display a comprehensive portfolio dashboard combining key metrics, top holdings, and asset allocation in a single view.

Example

niveshpy reports summary # (1)
niveshpy reports summary --format json # (2)
niveshpy reports summary UTI DSP # (3)
  1. Show a full portfolio summary dashboard.
  2. Output the summary as JSON (CSV is not supported for summary).
  3. Show summary for securities matching "UTI" or "DSP".

Note

The summary command only supports TABLE and JSON output formats. CSV output is not available for this command due to its multi-section layout.

The summary dashboard includes:

  • Portfolio metrics — total current value, total invested, absolute gains with percentage, and XIRR.
  • Top holdings — your largest holdings by current value with their individual XIRR.
  • Asset allocation — category-wise allocation with a visual bar chart.

Model Reference

Reports related models.

Allocation dataclass

Allocation(
    date: date,
    amount: Decimal,
    allocation: Decimal,
    security_type: SecurityType | None,
    security_category: SecurityCategory | None,
)

Data class for allocation data.

__post_init__

__post_init__() -> None

Validate that at least one of security_type or security_category is provided.

Source code in niveshpy/models/report.py
78
79
80
81
82
83
def __post_init__(self) -> None:
    """Validate that at least one of security_type or security_category is provided."""
    if self.security_type is None and self.security_category is None:
        raise ValueError(
            "Either security_type or security_category must be provided."
        )

Holding dataclass

Holding(
    account: Account,
    security: Security,
    date: date,
    units: Decimal,
    invested: Decimal,
    amount: Decimal,
)

Data class for a single holding used in report computations.

HoldingUnitRow dataclass

HoldingUnitRow(
    security_key: str,
    account_id: int,
    total_units: Decimal,
    last_transaction_date: date,
)

Data class for a single row of holding units used in report computations.

PerformanceHolding dataclass

PerformanceHolding(
    account: Account,
    security: Security,
    date: date,
    current_value: Decimal,
    invested: Decimal | None,
    xirr: Decimal | None,
)

Data class for per-holding performance data used in reports.

__post_init__

__post_init__() -> None

Compute gains and gains percentage after initialization.

Source code in niveshpy/models/report.py
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def __post_init__(self) -> None:
    """Compute gains and gains percentage after initialization."""
    object.__setattr__(
        self,
        "gains",
        self.current_value - self.invested if self.invested is not None else None,
    )
    object.__setattr__(
        self,
        "gains_pct",
        (self.gains / self.invested).quantize(decimal.Decimal("0.0001"))
        if self.gains is not None
        and self.invested is not None
        and self.invested != 0
        else None,
    )

from_holding classmethod

from_holding(
    holding: Holding, xirr: Decimal | None
) -> PerformanceHolding

Create PerformanceHolding from Holding and XIRR value.

Source code in niveshpy/models/report.py
119
120
121
122
123
124
125
126
127
128
129
130
131
@classmethod
def from_holding(
    cls, holding: Holding, xirr: decimal.Decimal | None
) -> "PerformanceHolding":
    """Create PerformanceHolding from Holding and XIRR value."""
    return cls(
        account=holding.account,
        security=holding.security,
        date=holding.date,
        current_value=holding.amount,
        invested=holding.invested,
        xirr=xirr,
    )

PerformanceResult dataclass

PerformanceResult(
    holdings: Sequence[PerformanceHolding],
    totals: PortfolioTotals,
)

Result of portfolio performance computation.

PortfolioTotals dataclass

PortfolioTotals(
    total_current_value: Decimal,
    total_invested: Decimal | None,
    total_gains: Decimal | None,
    gains_percentage: Decimal | None,
    xirr: Decimal | None = None,
    last_updated: date | None = None,
)

Portfolio-level aggregate totals.

SummaryResult dataclass

SummaryResult(
    as_of: date | None,
    metrics: PortfolioTotals,
    top_holdings: Sequence[PerformanceHolding],
    allocation: Sequence[Allocation],
)

Portfolio summary combining metrics, top holdings, and allocation.