OGT Owl Group Trading by Dr. Ken Long
Home About Learn The Loop Code Courses Essays Store Partners FAQ
Python · Indicator Code

The Mean (30-period SMA) in Python

The 30-period simple moving average. In Owl Group Trading this is the Mean (Z0, the BBmean) - the centerline that anchors the River, Flood Plain, and Dragon.

Concept: what MEAN means →

Verified. Python and JavaScript implementations agree to 0.00e+00 on a 60-bar reference price series (Python vs JavaScript, comparable positions).

Python

import math


def sma(values, n=30):
    """Simple Moving Average over a trailing window of n values.

    Faithful port of edge-canvas calcSMA (incremental running-sum):
      - returns a list the same length as `values`
      - the first n-1 positions are None (warmup: not enough history yet)
      - a position emits only when the trailing window of n entries is
        fully populated with finite numbers; the value is then sum / n
      - n <= 0, or fewer than n inputs, yields an all-None result
    None / NaN inputs are skipped from the running sum and count.
    """
    vals = list(values)
    length = len(vals)
    result = [None] * length
    if n <= 0 or length < n:
        return result

    running_sum = 0.0
    count = 0
    for i in range(length):
        v = vals[i]
        if v is not None and not (isinstance(v, float) and math.isnan(v)):
            running_sum += v
            count += 1
        # drop the element that just left the trailing window
        if i >= n:
            old = vals[i - n]
            if old is not None and not (isinstance(old, float) and math.isnan(old)):
                running_sum -= old
                count -= 1
        # emit only once a full window of finite values is present
        if i >= n - 1 and count == n:
            result[i] = running_sum / n
    return result