# `TAlib.Indicators.MA`
[🔗](https://github.com/benyblack/talib/blob/main/lib/indicators/ma.ex#L1)

Moving average indicator [Wikipedia](https://en.wikipedia.org/wiki/Moving_average).

Calculates SMA, WMA, EMA and CMA, plus streaming `*_init`/`*_next`
state for maintaining a moving average in O(1) as new prices arrive
(and the older incremental `update_*` helpers).

See `TAlib` for the input conventions: prices are always given in
chronological order, oldest first. Series functions return results aligned
with the input, the first `period - 1` entries being `nil`. All functions
return `nil` when there is not enough data.

# `cma`

```elixir
@spec cma([number()]) :: float() | nil
```

Calculate the Cumulative (unweighted) Moving Average: the arithmetic mean
of **all** given prices. Unlike the other functions it takes no window;
use `update_cma/3` to maintain it incrementally.

## Parameters

  - prices: list of prices (the mean is order-independent).

## Examples

    iex> TAlib.Indicators.MA.cma([0, 1, 2, 3])
    1.5

# `cma_list`

```elixir
@spec cma_list([number()]) :: [float()]
```

Calculate the full CMA series: the running mean over all prices seen so
far at every point.

## Parameters

  - prices: list of prices, oldest first.

## Examples

    iex> TAlib.Indicators.MA.cma_list([1, 2, 3])
    [1.0, 1.5, 2.0]

# `dema`

```elixir
@spec dema([number()], pos_integer()) :: float() | nil
```

Calculate the Double Exponential Moving Average: `2 * EMA - EMA(EMA)`.

## Parameters

  - prices: list of prices, oldest first.
  - period: lookback window, a positive integer (default 30).

## Examples

    iex> TAlib.Indicators.MA.dema([1, 2, 3, 4, 5, 6, 7, 8], 2)
    8.0

# `dema_list`

```elixir
@spec dema_list([number()], pos_integer()) :: [float() | nil]
```

Calculate the full DEMA series (`2 * EMA - EMA(EMA)`).

    iex> TAlib.Indicators.MA.dema_list([1, 2, 3, 4, 5, 6, 7, 8], 2)
    [nil, nil, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]

# `ema`

```elixir
@spec ema([number()], pos_integer()) :: float() | nil
```

Calculate the Exponential Moving Average.

The series is seeded with the SMA of the oldest `period` prices, then
walked forward with `multiplier = 2 / (period + 1)`.

## Parameters

  - prices: list of prices, oldest first.
  - period: lookback window, a positive integer.

## Examples

    iex> TAlib.Indicators.MA.ema([1, 2, 3, 4], 2)
    3.5

# `ema_init`

```elixir
@spec ema_init([number()], pos_integer()) ::
  {TAlib.Indicators.MA.EMAState.t(), [float() | nil]}
```

Warm up streaming EMA state from `history`: returns `{state, values}`
(identical to `ema_list/2`) and continues in O(1) via `ema_next/2`.
History needs at least `period` prices.

    iex> {state, values} = TAlib.Indicators.MA.ema_init([1, 2, 3, 4, 5], 2)
    iex> values
    [nil, 1.5, 2.5, 3.5, 4.5]
    iex> {_state, 5.5} = TAlib.Indicators.MA.ema_next(state, 6)

# `ema_list`

```elixir
@spec ema_list([number()], pos_integer()) :: [float() | nil]
```

Calculate the full EMA series in a single forward pass, seeded at the SMA
of the oldest `period` prices.

Returns a list aligned with `prices`: the first `period - 1` entries are
`nil`, and every later entry is the EMA as of that point.

## Parameters

  - prices: list of prices, oldest first.
  - period: lookback window, a positive integer.

## Examples

    iex> TAlib.Indicators.MA.ema_list([1, 2, 3, 4, 5], 2)
    [nil, 1.5, 2.5, 3.5, 4.5]

# `ema_next`

```elixir
@spec ema_next(TAlib.Indicators.MA.EMAState.t(), number()) ::
  {TAlib.Indicators.MA.EMAState.t(), float() | nil}
```

Advance streaming EMA state by one price, in O(1).

    iex> {state, _} = TAlib.Indicators.MA.ema_init([1, 2, 3, 4, 5], 2)
    iex> {_state, value} = TAlib.Indicators.MA.ema_next(state, 6)
    iex> value
    5.5

# `kama`

```elixir
@spec kama([number()], pos_integer()) :: float() | nil
```

Calculate Kaufman's Adaptive Moving Average: an exponential average
whose smoothing constant adapts to the efficiency ratio
(net change over path length) of the last `period` prices.

The smoothing constants are fixed like TA-Lib's (fastest 2/3,
slowest 2/31) regardless of the period, and at `period` 1 the series
is the input itself.

    iex> TAlib.Indicators.MA.kama([1, 2, 3, 4, 5, 6, 7, 8], 2) |> Float.round(4)
    6.7868

# `kama_list`

```elixir
@spec kama_list([number()], pos_integer()) :: [number() | nil]
```

Calculate the full KAMA series.

    iex> TAlib.Indicators.MA.kama_list([1, 2, 3, 4, 5, 6, 7, 8], 2) |> Enum.map(fn
    ...>   nil -> nil
    ...>   x -> Float.round(x * 1.0, 4)
    ...> end)
    [nil, nil, 2.4444, 3.1358, 3.9643, 4.8691, 5.8162, 6.7868]

# `ma`

```elixir
@spec ma([number()], pos_integer(), atom()) :: float() | nil
```

The generic moving average dispatcher (TA-Lib MA): computes the moving
average of the given `type` — one of `:sma`, `:ema`, `:wma`, `:dema`,
`:tema`, `:trima`, `:kama` or `:t3`.

    iex> TAlib.Indicators.MA.ma([1, 2, 3, 4, 5, 6, 7, 8], 4, :ema) |> Float.round(4)
    6.5

# `mavp`

```elixir
@spec mavp([number()], [number()], pos_integer(), pos_integer(), atom()) :: [
  float() | nil
]
```

The variable-period moving average (TA-Lib MAVP): the value at each
point uses the period given for that point, clamped to
`[min_period, max_period]` (both defaulting to 2 and 30). Only
`:sma` and `:ema` types are supported.

    iex> TAlib.Indicators.MA.mavp([1, 2, 3, 4, 5, 6], [2, 2, 2, 2, 2, 2]) |> List.last()
    5.5

# `midpoint`

```elixir
@spec midpoint([number()], pos_integer()) :: float() | nil
```

Calculate the Midpoint of the `period` newest prices:
`(highest + lowest) / 2`.

    iex> TAlib.Indicators.MA.midpoint([5, 3, 8, 2, 6], 3)
    5.0

# `midpoint_list`

```elixir
@spec midpoint_list([number()], pos_integer()) :: [float() | nil]
```

Calculate the full Midpoint series.

    iex> TAlib.Indicators.MA.midpoint_list([5, 3, 8, 2, 6], 3)
    [nil, nil, 5.5, 5.0, 5.0]

# `rma`

```elixir
@spec rma([number()], pos_integer()) :: float() | nil
```

Calculate Wilder's smoothed Moving Average (RMA), used by ATR, ADX and
friends: seeded with the SMA of the oldest `period` prices, then
`rma = (prev * (period - 1) + price) / period`.

## Parameters

  - prices: list of prices, oldest first.
  - period: lookback window, a positive integer.

## Examples

    iex> TAlib.Indicators.MA.rma([1, 2, 3, 4, 5], 3) |> Float.round(4)
    3.4444

# `rma_init`

```elixir
@spec rma_init([number()], pos_integer()) ::
  {TAlib.Indicators.MA.RMAState.t(), [float() | nil]}
```

Warm up streaming RMA (Wilder) state from `history`: returns
`{state, values}` (identical to `rma_list/2`) and continues in O(1)
via `rma_next/2`. History needs at least `period` prices.

    iex> {state, values} = TAlib.Indicators.MA.rma_init([1, 2, 3, 4, 5], 3)
    iex> values
    [nil, nil, 2.0, 2.6666666666666665, 3.444444444444444]
    iex> {_state, value} = TAlib.Indicators.MA.rma_next(state, 6)
    iex> Float.round(value, 4)
    4.2963

# `rma_list`

```elixir
@spec rma_list([number()], pos_integer()) :: [float() | nil]
```

Calculate the full RMA series in a single forward pass.

Returns a list aligned with `prices`: the first `period - 1` entries are
`nil`, and every later entry is the Wilder-smoothed average as of that
point.

## Parameters

  - prices: list of prices, oldest first.
  - period: lookback window, a positive integer.

## Examples

    iex> TAlib.Indicators.MA.rma_list([1, 2, 3, 4, 5], 3)
    [nil, nil, 2.0, 2.6666666666666665, 3.444444444444444]

# `rma_next`

```elixir
@spec rma_next(TAlib.Indicators.MA.RMAState.t(), number()) ::
  {TAlib.Indicators.MA.RMAState.t(), float() | nil}
```

Advance streaming RMA (Wilder) state by one price, in O(1).

    iex> {state, _} = TAlib.Indicators.MA.rma_init([1, 2, 3, 4, 5], 3)
    iex> {_state, value} = TAlib.Indicators.MA.rma_next(state, 6)
    iex> Float.round(value, 4)
    4.2963

# `sma`

```elixir
@spec sma([number()], pos_integer()) :: float() | nil
```

Calculate the Simple Moving Average of the `period` newest prices.

## Parameters

  - prices: list of prices, oldest first.
  - period: lookback window, a positive integer.

## Examples

    iex> TAlib.Indicators.MA.sma([1, 2, 3, 4], 3)
    3.0

# `sma_init`

```elixir
@spec sma_init([number()], pos_integer()) ::
  {TAlib.Indicators.Roll.Sum.t(), [float() | nil]}
```

Warm up streaming SMA state from `history`.

Returns `{state, values}` with `values` the full SMA series of
`history` (identical to `sma_list/2`), and `state` ready to continue
that series one price at a time in O(1) via `sma_next/2`. History
needs at least `period` prices.

## Examples

    iex> {state, values} = TAlib.Indicators.MA.sma_init([1, 2, 3, 4, 5], 3)
    iex> values
    [nil, nil, 2.0, 3.0, 4.0]
    iex> {_state, 5.0} = TAlib.Indicators.MA.sma_next(state, 6)

# `sma_list`

```elixir
@spec sma_list([number()], pos_integer()) :: [float() | nil]
```

Calculate the full SMA series in a single pass (sliding window sum).

Returns a list aligned with `prices`: the first `period - 1` entries are
`nil`, and every later entry is the simple moving average of the window
ending at that point.

## Parameters

  - prices: list of prices, oldest first.
  - period: lookback window, a positive integer.

## Examples

    iex> TAlib.Indicators.MA.sma_list([1, 2, 3, 4, 5], 3)
    [nil, nil, 2.0, 3.0, 4.0]

# `sma_next`

```elixir
@spec sma_next(TAlib.Indicators.Roll.Sum.t(), number()) ::
  {TAlib.Indicators.Roll.Sum.t(), float() | nil}
```

Advance streaming SMA state by one price, in O(1).

    iex> {state, _} = TAlib.Indicators.MA.sma_init([1, 2, 3, 4, 5], 3)
    iex> {_state, value} = TAlib.Indicators.MA.sma_next(state, 6)
    iex> value
    5.0

# `t3`

```elixir
@spec t3([number()], pos_integer(), number()) :: float() | nil
```

Calculate Tim Tillson's T3 moving average: six chained EMAs combined
with the given volume factor.

    iex> TAlib.Indicators.MA.t3(Enum.to_list(1..14), 2) |> Float.round(4)
    13.55

# `t3_list`

```elixir
@spec t3_list([number()], pos_integer(), number()) :: [float() | nil]
```

Calculate the full T3 series.

    iex> TAlib.Indicators.MA.t3_list(Enum.to_list(1..14), 2) |> Enum.count(&is_nil/1)
    6

# `tema`

```elixir
@spec tema([number()], pos_integer()) :: float() | nil
```

Calculate the Triple Exponential Moving Average:
`3 * EMA - 3 * EMA(EMA) + EMA(EMA(EMA))`.

    iex> TAlib.Indicators.MA.tema([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2) |> Float.round(4)
    10.0

# `tema_list`

```elixir
@spec tema_list([number()], pos_integer()) :: [float() | nil]
```

Calculate the full TEMA series.

    iex> TAlib.Indicators.MA.tema_list([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2)
    [nil, nil, nil, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]

# `trima`

```elixir
@spec trima([number()], pos_integer()) :: float() | nil
```

Calculate the Triangular Moving Average: an SMA applied twice, over the
half (odd period) or half/half-plus-one (even period) windows.

    iex> TAlib.Indicators.MA.trima([1, 2, 3, 4, 5, 6, 7], 5)
    5.0

# `trima_list`

```elixir
@spec trima_list([number()], pos_integer()) :: [float() | nil]
```

Calculate the full TRIMA series.

    iex> TAlib.Indicators.MA.trima_list([1, 2, 3, 4, 5, 6, 7], 5)
    [nil, nil, nil, nil, 3.0, 4.0, 5.0]

# `update_cma`

```elixir
@spec update_cma(number(), number(), pos_integer()) :: float()
```

Update a Cumulative Moving Average when a new price arrives.

`period` is the number of prices already averaged into `current_cma`.

## Parameters

  - current_cma: the previously calculated CMA.
  - new_value: the new price.
  - period: how many prices `current_cma` covers, a positive integer.

## Examples

    iex> TAlib.Indicators.MA.update_cma(44.45, 44.0, 4)
    44.36

# `update_ema`

```elixir
@spec update_ema(number(), number(), pos_integer()) :: float()
```

Update an Exponential Moving Average when a new price arrives.

## Parameters

  - current_ema: the previously calculated EMA.
  - new_value: the new price.
  - period: EMA period, a positive integer.

## Examples

    iex> TAlib.Indicators.MA.update_ema(1306.72, 1300, 50) |> Float.round(4)
    1306.4565

# `update_sma`

```elixir
@spec update_sma([number()], number(), number(), pos_integer()) :: float() | nil
```

Update a Simple Moving Average when a new price arrives.

`prices` (oldest first) must **not** include `new_value`; the current
window is the `period` newest prices, and the value leaving it is
`Enum.at(prices, length(prices) - period)`.

## Parameters

  - prices: list of prices, oldest first, without `new_value`.
  - current_sma: the previously calculated SMA.
  - new_value: the new price.
  - period: lookback window, a positive integer.

## Examples

    iex> TAlib.Indicators.MA.update_sma([1, 2, 3, 4, 5], 4.5, 3, 2)
    4.0

# `wma`

```elixir
@spec wma([number()], pos_integer()) :: float() | nil
```

Calculate the Linear Weighted Moving Average of the `period` newest
prices. The newest price gets the weight `period`, the oldest price in
the window gets 1.

## Parameters

  - prices: list of prices, oldest first.
  - period: lookback window, a positive integer.

## Examples

    iex> TAlib.Indicators.MA.wma([1, 2, 3, 4], 3)
    3.3333333333333335

# `wma_init`

```elixir
@spec wma_init([number()], pos_integer()) ::
  {TAlib.Indicators.MA.WMAState.t(), [float() | nil]}
```

Warm up streaming WMA state from `history`: returns `{state, values}`
(identical to `wma_list/2`) and continues in O(1) via `wma_next/2`.
History needs at least `period` prices.

    iex> {state, values} = TAlib.Indicators.MA.wma_init([1, 2, 3, 4, 5], 3)
    iex> values
    [nil, nil, 2.3333333333333335, 3.3333333333333335, 4.333333333333333]
    iex> {_state, value} = TAlib.Indicators.MA.wma_next(state, 6)
    iex> Float.round(value, 4)
    5.3333

# `wma_list`

```elixir
@spec wma_list([number()], pos_integer()) :: [float() | nil]
```

Calculate the full WMA series in a single pass (sliding weighted and
plain window sums).

Returns a list aligned with `prices`: the first `period - 1` entries are
`nil`, and every later entry is the weighted moving average of the window
ending at that point.

## Parameters

  - prices: list of prices, oldest first.
  - period: lookback window, a positive integer.

## Examples

    iex> TAlib.Indicators.MA.wma_list([1, 2, 3, 4, 5], 3)
    [nil, nil, 2.3333333333333335, 3.3333333333333335, 4.333333333333333]

# `wma_next`

```elixir
@spec wma_next(TAlib.Indicators.MA.WMAState.t(), number()) ::
  {TAlib.Indicators.MA.WMAState.t(), float() | nil}
```

Advance streaming WMA state by one price, in O(1).

    iex> {state, _} = TAlib.Indicators.MA.wma_init([1, 2, 3, 4, 5], 3)
    iex> {_state, value} = TAlib.Indicators.MA.wma_next(state, 6)
    iex> Float.round(value, 4)
    5.3333

---

*Consult [api-reference.md](api-reference.md) for complete listing*
