Class: TeaLeaves::MovingAverage

Inherits:
Object
  • Object
show all
Defined in:
lib/tealeaves/moving_average.rb

Overview

A calculator for simple & weighted moving averages.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(weights) ⇒ MovingAverage

Creates a new MovingAverage given a list of weights.

See also the class methods simple and weighted.



54
55
56
57
58
# File 'lib/tealeaves/moving_average.rb', line 54

def initialize(weights)
  @weights = weights
  @span = @weights.length
  check_weights
end

Instance Attribute Details

#spanObject (readonly)

Returns the value of attribute span.



4
5
6
# File 'lib/tealeaves/moving_average.rb', line 4

def span
  @span
end

#weightsObject (readonly)

Returns the value of attribute weights.



4
5
6
# File 'lib/tealeaves/moving_average.rb', line 4

def weights
  @weights
end

Class Method Details

.multiple(m, n) ⇒ Object

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]


41
42
43
44
45
46
47
48
49
# 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

.simple(n) ⇒ Object

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]

Parameters:

  • n (Integer)

    the span or order of the moving average, i.e. the number of terms to include in each average.

Raises:

  • (ArgumentError)


28
29
30
31
32
# 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) ⇒ Object

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]


16
17
18
# File 'lib/tealeaves/moving_average.rb', line 16

def self.weighted(weights)
  new(weights)
end

Instance Method Details

#calculate(array) ⇒ Object

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.



64
65
66
67
68
69
70
# 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