Improve Weighted Moving Average (WMA) indicator parity with Cython #2662
Merged
Conversation
Member
Author
|
needs some attention from you @cjdsellers 👇
|
cjdsellers
reviewed
May 23, 2025
cjdsellers
left a comment
Member
There was a problem hiding this comment.
Great stuff, and thanks for all the tests!
Removing has_inputs is a nice refinement.
On the suggestions, I don't think we need to support optional weights at this stage?
| } | ||
| if self.inputs.len() == self.period { | ||
| self.inputs.remove(0); | ||
| self.inputs.pop_front(); |
Member
There was a problem hiding this comment.
If we're using a VecDeque with a fixed capacity then this might not be necessary?
Member
Author
There was a problem hiding this comment.
VecDeque::with_capacity(n) only pre-allocates space; it doesn’t enforce a hard cap.
If you keep pushing after len == n, the deque re-allocates and grows, so you must still pop_front() (or otherwise drop the oldest element) to keep the window at exactly period items.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Restores feature-parity and behavioural equivalence between the Rust
WeightedMovingAverageimplementation and the canonical Python/Cython reference.1 · Why this matters — Context & Motivation
has_inputsflag and double-initialisation logic.2 · What changed
new_checked:period > 0,weights.len() == period,∑wᵢ > εhas_inputsboolean tracked manuallyhas_inputs()now derives from!inputs.is_empty()reverse_weightsveczip(self.inputs.iter().rev(), self.weights.iter().rev())(zero alloc)initialized = count() ≥ period"period must equal weights.len()")///comments on invariants & panics3 · Implementation notes
EPS = f64::EPSILONensures weight-sum check does not break on FP rounding.weighted_average()is safe becauseself.weights.len() == self.periodis proven by construction.reset()— matches Python behaviour.WeightedMovingAverageis still!Send + !Sync; wrap inArc<Mutex<…>>when sharing between threads.4 · Tests added / updated
new_panics_on_zero_period/new_checked_err_on_zero_periodperiod > 0new_panics_on_zero_weight_sum/weight_sum_below_epsilonvariants∑wᵢ > εinitialized_flag_transitionsperiodsamplescount_matches_inputs_and_has_inputsweighted_average_with_non_uniform_weightsnegative_weights_positive_sumnan_input_propagatessingle_period_returns_latest_inputperiod == 1degenerates to last pricevalue_with_sparse_weightsRelated #2507