nautechsystems/nautilus_trader · error

`calculate_from_positions` {IMPL_ERR} `{}`

Error message

`calculate_from_positions` {IMPL_ERR} `{}`

What it means

The default `calculate_from_positions` on the statistic trait panics when a statistic that does not implement it is called with position data. It marks the statistic as unsupported for position-based calculation.

Source

Thrown at crates/analysis/src/statistic.rs:69

    /// Calculates the statistic from realized profit and loss values.
    ///
    /// # Panics
    ///
    /// Panics if this method is not implemented for the specific statistic.
    fn calculate_from_realized_pnls(&self, realized_pnls: &[f64]) -> Option<Self::Item> {
        panic!(
            "`calculate_from_realized_pnls` {IMPL_ERR} `{}`",
            self.name()
        );
    }

    /// Calculates the statistic from position data.
    ///
    /// # Panics
    ///
    /// Panics if this method is not implemented for the specific statistic.
    fn calculate_from_positions(&self, positions: &[Position]) -> Option<Self::Item> {
        panic!("`calculate_from_positions` {IMPL_ERR} `{}`", self.name());
    }

    /// Calculates the statistic from time-indexed strategy returns relative to a benchmark.
    ///
    /// Defaults to `None`; only benchmark-relative statistics (beta, alpha, information
    /// ratio, tracking error, Treynor ratio) override this method. The `None` default
    /// lets analyzer loops filter results by `Option` - non-benchmark statistics are
    /// simply skipped, as `get_performance_stats_general` already does with
    /// `calculate_from_positions` results - rather than panicking.
    fn calculate_from_returns_with_benchmark(
        &self,
        returns: &Returns,
        benchmark: &Returns,
    ) -> Option<Self::Item> {
        None
    }

    /// Aligns two returns series onto a common daily grid.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Implement `calculate_from_positions` on the statistic.
  2. Or compute the statistic from the input it supports.
  3. Or remove the statistic from position-based analysis registration.

Example fix

// before
impl PerformanceStatistic for SharpeRatio {
    fn calculate_from_returns(&self, r: &Returns) -> Option<f64> { Some(calc(r)) }
}
analyzer.calculate_from_positions(&positions); // panic
// after
impl PerformanceStatistic for SharpeRatio {
    fn calculate_from_returns(&self, r: &Returns) -> Option<f64> { Some(calc(r)) }
    fn calculate_from_positions(&self, _: &[Position]) -> Option<f64> { None }
}
Defensive patterns

Strategy: type-guard

Validate before calling

// only feed position-capable statistics
let stats = stats.into_iter().filter(|s| s.supports_positions()).collect::<Vec<_>>();

Prevention

When it happens

Trigger: Analyzer computing statistics from `&[Position]` for a statistic that only implements returns- or realized-PnL-based calculation.

Common situations: Returns-based statistics (Sharpe, Sortino) registered into position-based portfolio analysis; custom trait impls missing the positions method.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/ef8853d2f17a7aaa. Report an issue: GitHub.