1from __future__ import division 2 3 4class SimpleMovingAverage(object): 5 """ 6 Simple Moving Average implementation. 7 """ 8 9 __slots__ = ( 10 "size", 11 "index", 12 "counts", 13 "totals", 14 "sum_count", 15 "sum_total", 16 ) 17 18 def __init__(self, size): 19 # type: (int) -> None 20 """ 21 Constructor for SimpleMovingAverage. 22 23 :param size: The size of the window to calculate the moving average. 24 :type size: :obj:`int` 25 """ 26 if size < 1: 27 raise ValueError 28 29 self.index = 0 30 self.size = size 31 32 self.sum_count = 0 33 self.sum_total = 0 34 35 self.counts = [0] * self.size 36 self.totals = [0] * self.size 37 38 def get(self): 39 # type: () -> float 40 """ 41 Get the current SMA value. 42 """ 43 if self.sum_total == 0: 44 return 0.0 45 46 return float(self.sum_count) / self.sum_total 47 48 def set(self, count, total): 49 # type: (int, int) -> None 50 """ 51 Set the value of the next bucket and update the SMA value. 52 53 :param count: The valid quantity of the next bucket. 54 :type count: :obj:`int` 55 :param total: The total quantity of the next bucket. 56 :type total: :obj:`int` 57 """ 58 if count > total: 59 raise ValueError 60 61 self.sum_count += count - self.counts[self.index] 62 self.sum_total += total - self.totals[self.index] 63 64 self.counts[self.index] = count 65 self.totals[self.index] = total 66 67 self.index = (self.index + 1) % self.size 68