Skip to content

Fix Rust RSI moving-average type and max-value regression#4382

Merged
cjdsellers merged 2 commits into
nautechsystems:developfrom
bebop23:bebop23/fix-issue-1
Jul 5, 2026
Merged

Fix Rust RSI moving-average type and max-value regression#4382
cjdsellers merged 2 commits into
nautechsystems:developfrom
bebop23:bebop23/fix-issue-1

Conversation

@bebop23

@bebop23 bebop23 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Pull Request

NautilusTrader prioritizes correctness and reliability, please follow existing patterns for validation and testing.

  • I have reviewed the CONTRIBUTING.md and followed the established practices

Summary

The Rust-core RelativeStrengthIndex (crates/indicators/src/momentum/rsi.rs) had two numerical defects that diverged from the Cython source of truth. First, the ma_type argument was ignored — both inner gain/loss averages were always built as Exponential, so Wilder/Simple/Exponential produced identical output. Second, last_value was never advanced on zero-loss bars (the assignment sat after the early return), pinning RSI at rsi_max (1.0) even after real down-moves — the same bug fixed for the Cython indicator in #2703.

Related Issues/PRs

Rust port of the Cython fix in #2703 (originally reported for Cython in #2673). The v2 Rust indicator regressed both behaviors relative to the Cython source of truth (#2507).

Type of change

  • Bug fix (non-breaking)
  • New feature (non-breaking)
  • Improvement (non-breaking)
  • Breaking change (impacts existing behavior)
  • Documentation update
  • Maintenance / chore

Breaking change details (if applicable)

N/A

Documentation

  • Documentation changes follow the style guide (docs/developer_guide/docs.md)

Release notes

  • I added a concise entry to RELEASES.md that follows the existing conventions (when applicable)

Testing

Ensure new or changed logic is covered by tests.

  • Affected code paths are already covered by the test suite
  • I added/updated tests to cover new or changed logic

Added three Rust unit tests in crates/indicators/src/momentum/rsi.rs:

  • test_ma_type_is_plumbed_into_inner_averagesWilder/Simple/Exponential now produce distinct output on a fixed 15-close series.
  • test_recovers_below_max_after_losses — a rise-then-fall series drops below rsi_max once losses arrive (guards the flat-1.0 regression).
  • test_wilder_golden_series — Wilder RSI matches published reference values (0.8935, 0.7269, 0.5586, 0.4192, 0.3489) after each down-move.

The existing tests only exercised the default (Exponential) path with monotonic/constant inputs, which is why both defects slipped the earlier parity pass. Full crate suite green (cargo test -p nautilus-indicators --lib momentum::rsi, 17 passed) and clippy clean.

bebop23 and others added 2 commits July 4, 2026 19:59
The Rust-core RSI ignored the `ma_type` argument (inner gain/loss averages
were always built as Exponential) and never advanced `last_value` on
zero-loss bars, pinning RSI at `rsi_max` (1.0) even after real down-moves.
Both defects diverged from the Cython source of truth; the second is the
same bug fixed for Cython in nautechsystems#2703.

- Resolve `ma_type` once and pass it into `MovingAverageFactory::create`
  for both averages.
- Advance `last_value` in the zero-loss branch before the early return.
- Add regression tests: ma_type distinctness, recovery below max after
  losses, and a Wilder golden series vs published reference values.

Closes #1

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Satisfy the repo's custom pre-commit hooks: replace ', got' phrasing with
', was' in two assert messages, and add the required blank line above the
`for` loop in the Wilder golden-series test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cjdsellers cjdsellers changed the title Fix v2 Rust RelativeStrengthIndex ma_type and flat-max regression Fix Rust RSI moving-average type and max-value regression Jul 5, 2026

@cjdsellers cjdsellers left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the fix @bebop23 🙏

@cjdsellers cjdsellers merged commit 49a6fcc into nautechsystems:develop Jul 5, 2026
25 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.

2 participants