class TeaLeaves::MovingAverage
A calculator for simple & weighted moving averages.
Attributes
span[R]
weights[R]
Public Class Methods
multiple(m,n)
click to toggle source
Returns a moving average of a moving average calculator.
For Example, for a 3x3 MA:
MovingAverage.multiple(3,3).weights #=> [1/9, 2/9, 1/3, 2/9, 1/9]
# File lib/tealeaves/moving_average.rb, line 41 def self.multiple(m,n) divisor = (m * n).to_f weights = (1..m).map {|i| i / divisor } num_of_center_weights = ((m + n) / 2) - m num_of_center_weights = 0 if num_of_center_weights < 0 num_of_center_weights.times { weights << weights.last } new(expand_weights(weights.reverse)) end
new(weights)
click to toggle source
Creates a new MovingAverage
given a list of weights.
See also the class methods simple and weighted.
# File lib/tealeaves/moving_average.rb, line 54 def initialize(weights) @weights = weights @span = @weights.length check_weights end
simple(n)
click to toggle source
Returns a Simple Moving Average calculator, given a span n.
Examples:
MovingAverage.simple(5).weights # => [0.2, 0.2, 0.2, 0.2, 0.2]
@param [Integer] n the span or order of the moving average,
i.e. the number of terms to include in each average.
# File lib/tealeaves/moving_average.rb, line 28 def self.simple(n) raise ArgumentError.new("Number of terms must be positive") if n < 1 weights = n.odd?() ? [1.0 / n] * n : expand_weights([1.0 / n] * (n / 2) + [1.0 / (2 * n)]) new weights end
weighted(weights)
click to toggle source
Returns a Weighted Moving Average calculator, given a list of weights.
The list of weights should be an odd length, and should sum to 1.
Examples:
MovingAverage.weighted([0.15, 0.7, 0.15]) # => [0.2, 0.7, 0.1]
# File lib/tealeaves/moving_average.rb, line 16 def self.weighted(weights) new(weights) end
Private Class Methods
expand_weights(weights)
click to toggle source
# File lib/tealeaves/moving_average.rb, line 83 def self.expand_weights(weights) left_side_weights = weights.reverse left_side_weights.pop left_side_weights + weights end
Public Instance Methods
calculate(array)
click to toggle source
Calculates the moving average for the given array of numbers.
Moving averages won't include values for terms at the beginning or end of the array, so there will be fewer numbers than in the original.
# File lib/tealeaves/moving_average.rb, line 64 def calculate(array) return [] if @span > array.length array.each_cons(@span).map do |window| window.zip(weights).map {|(a,b)| a * b }.inject(&:+) end end
Private Instance Methods
check_weights()
click to toggle source
Error checking for weights
# File lib/tealeaves/moving_average.rb, line 75 def check_weights raise ArgumentError.new("Weights should be an odd list") unless @span.odd? sum = weights.inject(&:+) if sum < 0.999999 || sum > 1.000001 raise ArgumentError.new("Weights must sum to 1") end end