Saturday, September 11, 2010

Running Sum

We've covered Running SMAs and EMAs...let's dig into Running Sums or often called Running Totals. Formula as follows:
$$Sum_{today} = Sum_{yesterday} + (price_{today} - price_{today - period})$$

Where $$price_{today - period}$$ represents the price that is dropping off the slice you are summing. For example:

Take a list of numbers = 20, 40, 60, 80, 100, 120.
The formula for the 3-bar running sum would be:
bar 1: 20
bar 2: 20 + 40 = 60
bar 3: 20 + 40 + 60 = 120
bar 4: 40 + 60 + 80 = 180

Or we can apply our formula from above as $$Sum_{today} = 120 + (80 - 20)$$
bar 5: 60 + 80 + 100 = 240

Or use formula of $$Sum_{today} = 180 + (100 - 40)$$
bar 6: 80 + 100 + 120 = 300

Or use formula of $$Sum_{today} = 240 + (120 - 60)$$

Coding in Python we get:
def running_sum(bar, series, period, pval=None):
"""
Returns the running sum of values in a list of tuple - avoids summing
entire series on each call.

Keyword arguments:
bar     --  current index or location of the value in the series
series  --  list or tuple of data to sum
period  -- number of values to include in sum
pval    --  previous sum (n - 1) of the series.
"""
if period < 1:
raise ValueError("period must be 1 or greater")

if bar <= 0:
return series[0]

if bar < period:
return pval + series[bar]

return pval + (series[bar] - series[bar - period])

Example call and results:
list_of_values = [20, 40, 60, 80, 100, 120]
prevsum = list_of_values[0]   #first sum is the first value in the series.

for bar, price in enumerate(list_of_values):
newsum = running_sum(bar, list_of_values, 3, pval=prevsum)
print "bar %i: %i" % (bar, newsum)
prevsum = newsum

----------------------------------------------------------
bar 0: 20
bar 1: 60
bar 2: 120
bar 3: 180
bar 4: 240
bar 5: 300