Skip to content

fix: use log1p(pct_change()) in to_log_returns for NaN-safe computation#282

Merged
timkpaine merged 1 commit intopmorissette:masterfrom
Jo2234:fix/sortino-ratio-and-log-returns
Feb 28, 2026
Merged

fix: use log1p(pct_change()) in to_log_returns for NaN-safe computation#282
timkpaine merged 1 commit intopmorissette:masterfrom
Jo2234:fix/sortino-ratio-and-log-returns

Conversation

@Jo2234
Copy link

@Jo2234 Jo2234 commented Feb 28, 2026

Summary

Use np.log1p(prices.pct_change()) instead of np.log(prices / prices.shift(1)) in to_log_returns().

Problem

The previous implementation can produce RuntimeWarnings in certain numpy/pandas configurations because prices.shift(1) introduces a NaN for the first element, and np.log(NaN) may trigger a warning.

Fix

-    return np.log(prices / prices.shift(1))
+    return np.log1p(prices.pct_change())

The two expressions are mathematically equivalent:

ln(p1/p0) = ln(1 + (p1-p0)/p0) = log1p(pct_change)

Benefits:

  • NaN-safe: pct_change() handles NaN from shift gracefully
  • Numerically stable: log1p avoids floating-point precision loss for small returns
  • Uses pandas built-in pct_change() instead of manual division

Fixes #156

The previous implementation np.log(prices / prices.shift(1)) can
produce RuntimeWarnings when prices.shift(1) introduces NaN values,
since np.log(NaN) triggers a warning in some numpy configurations.

Using np.log1p(prices.pct_change()) is mathematically equivalent:
  ln(p1/p0) = ln(1 + (p1-p0)/p0) = log1p(pct_change)

This approach:
- Avoids potential RuntimeWarnings from np.log(NaN)
- Uses pandas' built-in pct_change() which handles NaN gracefully
- Is numerically more stable for small returns (log1p avoids
  floating-point precision loss near zero)

Fixes pmorissette#156
@timkpaine timkpaine merged commit d9202e3 into pmorissette:master Feb 28, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

np.log can't handle NaN value in to_log_returns()

2 participants