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

Donchian Channels [Wikipedia](https://en.wikipedia.org/wiki/Donchian_channel).

* upper = Highest High over the window
* lower = Lowest Low over the window
* middle = (upper + lower) / 2

Bars are maps with at least `:high` and `:low`. See `TAlib` for the
remaining conventions: chronological order, oldest first, series aligned
with the input, `nil` when there is not enough data.

# `donchian`

```elixir
@spec donchian([map()], pos_integer()) ::
  %{upper: number(), middle: float(), lower: number()} | nil
```

Calculate the latest Donchian Channels as a map.

## Parameters

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

## Examples

    iex> bars = [
    ...>   %{high: 12, low: 8, close: 10},
    ...>   %{high: 11, low: 9, close: 10},
    ...>   %{high: 13, low: 9, close: 12}
    ...> ]
    iex> TAlib.Indicators.Donchian.donchian(bars, 3)
    %{lower: 8, middle: 10.5, upper: 13}

# `donchian_list`

```elixir
@spec donchian_list([map()], pos_integer()) :: [map() | nil]
```

Calculate the full Donchian Channels series.

Returns a list aligned with `bars`: the first `period - 1` entries are
`nil`, and every later entry is a map with `:upper`, `:middle` and
`:lower`.

## Parameters

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

## Examples

    iex> bars = [
    ...>   %{high: 12, low: 8, close: 10},
    ...>   %{high: 11, low: 9, close: 10},
    ...>   %{high: 13, low: 9, close: 12}
    ...> ]
    iex> TAlib.Indicators.Donchian.donchian_list(bars, 2)
    [nil, %{lower: 8, middle: 10.0, upper: 12}, %{lower: 9, middle: 11.0, upper: 13}]

# `init`

```elixir
@spec init([map()], pos_integer()) ::
  {TAlib.Indicators.Donchian.State.t(), [map() | nil]}
```

Warm up streaming Donchian Channels state from `history`.

Returns `{state, values}` with `values` the full channel series of
`history` (identical to `donchian_list/2`), and `state` ready to
continue it one bar at a time in O(1) via `next/2`. History needs at
least `period` bars.

## Examples

    iex> bars = [
    ...>   %{high: 12, low: 8, close: 10},
    ...>   %{high: 11, low: 9, close: 10},
    ...>   %{high: 13, low: 9, close: 12}
    ...> ]
    iex> {state, values} = TAlib.Indicators.Donchian.init(bars, 2)
    iex> values
    [nil, %{lower: 8, middle: 10.0, upper: 12}, %{lower: 9, middle: 11.0, upper: 13}]
    iex> {_state, %{lower: 7, middle: 10.5, upper: 14}} = TAlib.Indicators.Donchian.next(state, %{high: 14, low: 7})

# `midprice`

```elixir
@spec midprice([map()], pos_integer()) :: float() | nil
```

The Midprice of the `period` newest bars: `(highest high + lowest
low) / 2` — the middle Donchian channel line on its own.

    iex> bars = [
    ...>   %{high: 12, low: 8, close: 10},
    ...>   %{high: 11, low: 9, close: 10},
    ...>   %{high: 13, low: 9, close: 12}
    ...> ]
    iex> TAlib.Indicators.Donchian.midprice(bars, 3)
    10.5

# `next`

```elixir
@spec next(TAlib.Indicators.Donchian.State.t(), map()) ::
  {TAlib.Indicators.Donchian.State.t(), map() | nil}
```

Advance streaming Donchian Channels state by one bar (a map with at
least `:high` and `:low`), in O(1): `{state, %{upper: , middle: ,
lower: }}`.

    iex> {state, _} = TAlib.Indicators.Donchian.init([%{high: 12, low: 8}, %{high: 11, low: 9}, %{high: 13, low: 9}], 2)
    iex> {_state, channel} = TAlib.Indicators.Donchian.next(state, %{high: 14, low: 7})
    iex> channel
    %{lower: 7, middle: 10.5, upper: 14}

---

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