OPEN SOURCE · UPSTREAM CONTRIBUTIONS

NautilusTrader

Correctness, reference validation, regression and performance work across Rust-native trading indicators in an open-source, production-grade multi-asset trading engine.

What NautilusTrader is

NautilusTrader is an open-source, production-grade, Rust-native engine for multi-asset and multi-venue trading systems. It combines research, deterministic simulation and live execution in one event-driven architecture, with Python serving as a control plane for strategy logic, configuration and orchestration.

Contribution trail

Seven authored upstream items across two indicator areas: three AroonOscillator contributions and four ArcherMovingAveragesTrends contributions.

7 items

AroonOscillator

Boundary correctness, merged regression coverage and a separate rolling-extrema performance RFC.

3 items
check_circle Issue · completed
#4995 · fixed by #5037

AroonOscillator accepts MAX_PERIOD but cannot retain its required period + 1 window

FindingAt the accepted maximum period, the oscillator needed 1,025 highs and lows but its wrapping deques could hold only 1,024. That made the public constructor contract disagree with the storage invariant used by the calculation.

The report reproduced the failure against published v2.0.0rc5 and demonstrated a real signal error, not just an internal mismatch: an oldest unique high was evicted too early, changing Aroon Up from the expected 0.0 to 100.0 and the oscillator from -100.0 to 0.0.

Bug reportBoundary invariantRuntime reproductionTrading signal correctness
lightbulb Open RFC
#4996 · performance proposal

Consider amortized O(1) rolling extrema for AroonOscillator

ProposalAfter initialization, every Aroon update rescans the complete high and low windows. The RFC proposes maintaining monotonic deques so each observation enters and leaves once, moving initialized updates from O(p) to amortized O(1) and stream work from O(Np) toward O(N).

The proposal deliberately preserves the existing newest-occurrence tie semantics for equal highs/lows and treats benchmark evidence as a prerequisite for accepting the extra state and complexity. It keeps the optimization separate from the correctness fix.

RFCAlgorithmsPerformanceMonotonic dequeO(1) amortized

ArcherMovingAveragesTrends (AMAT)

A reference investigation that was closed after maintainer review, plus a confirmed reversal-state defect with a merged Rust fix.

4 items
fact_check Issue · closed
#5122 · reference clarified

ArcherMovingAveragesTrends ignores slow moving-average direction when computing trend state

InvestigationThe Rust port appeared to classify from fast-MA direction alone, so I reported the slow-MA path as a possible parity defect. Maintainer review went back to the pandas-ta reference and confirmed that a fast-rising, slow-falling window is intentionally a potential-bottom long signal rather than evidence of a missing agreement check.

The issue was closed as not a bug after that reference check. The investigation remains part of the contribution history because it documented the behavior, surfaced the historical #3017 interpretation, and led to an explicit maintainer clarification of the intended AMAT definition.

Reference investigationRustIndicator parityClosed as not a bug
cancel PR · closed unmerged
#5124 · closed after reference review

Fix ArcherMovingAveragesTrends slow MA direction

Proposed changeThe patch required the fast and slow MA deltas to agree before asserting a run. After re-checking the reference, the maintainer concluded that this would narrow AMAT beyond its intended definition, so the PR was closed without merge.

The code and regression tests were technically validated, but the behavioral premise was rejected. That distinction is recorded explicitly here: #5124 is a reviewed hypothesis and correction to the contribution history, not a merged upstream fix.

RustReference validationClosed unmergedAMAT
check_circle Issue · completed
#5123 · fixed by #5125

ArcherMovingAveragesTrends can report both long_run and short_run after a trend reversal

FindingThe Rust assignments OR-ed each new trend result with the previous boolean state. Once a direction became true, it could not clear without a full indicator reset, so a sustained reversal could leave both opposing flags true.

The report demonstrates both reversal directions and explains why the behavior conflicts with the bounded rolling signal window. After revisiting the AMAT reference, the maintainer confirmed that removing this historical latch is the standalone Rust correction. The issue was closed as completed when #5125 merged on 29 Sep 2026.

Bug reportState transitionRolling windowFixed upstream

Historical AMAT context

Closed PR #3017 is relevant prior work but is not counted as one of my contributions. It proposed both a same-direction slow-MA requirement and direct current-window trend classification. During review of #5124, the maintainer revisited the AMAT reference and clarified that #3017 had misread the legacy two-line Cython expression: the first assignment captures the potential-bottom or potential-top case, while the second or combines the second case within the same update rather than intentionally requiring both moving averages to agree. The same-direction interpretation was therefore rejected; the useful surviving thread is removing historical state latching, which is the behavior addressed by merged PR #5125.

Contribution approach

The work separates observation, reference validation, implementation and performance concerns. Reproductions and regression tests are used to make hypotheses reviewable, but upstream reference evidence wins: the rejected slow-MA interpretation is preserved as a closed investigation rather than presented as a fix, while the confirmed reversal-state defect is paired with its merged implementation.