35 lines
941 B
Crystal
35 lines
941 B
Crystal
module Math::MACD
|
|
# Computes the MACD (sliding mean) over N values.
|
|
# It will return another list of *size - n + 1* elements, because it is not
|
|
# possible to computes the n/2 first and lasts means.
|
|
# NOTE for now it is impossible to computes a MACD with a pair window (n should be odd)
|
|
#
|
|
# TODO: maybe computing a reduced MACD is good solution against reduced returns ?
|
|
def macd(n : Int)
|
|
((n.odd?) ? macd_odd(n) : macd_pair(n)).compact
|
|
end
|
|
|
|
# :nodoc:
|
|
#
|
|
# MACD computation if n is odd
|
|
private def macd_odd(n)
|
|
map_with_index do |_, i|
|
|
next if i < n / 2
|
|
next if i + n / 2 >= size
|
|
range = (i - n / 2)..(i + n / 2)
|
|
self[range].mean
|
|
end
|
|
end
|
|
|
|
# :nodoc:
|
|
#
|
|
# MACD computation if n is pair
|
|
private def macd_pair(n)
|
|
raise ArgumentError.new "The MACD should be computed for an odd window (you should retry with #{n + 1})"
|
|
end
|
|
end
|
|
|
|
module Enumerable(T)
|
|
include Math::MACD
|
|
end
|