OHLC (ohlc v1.2.4)

A library that can generate OHLC(open, high, low, close) candles from trade events.

It supports multiple timeframes including minute, hour, day and week and different configuration options opts/0.

installation

Installation

The package can be installed by adding ohlc to your list of dependencies in mix.exs:

def deps do
  [
    {:ohlc, "~> 1.2"}
  ]
end

example-usage

Example usage

iex>trades = [
...>  [price: 12.21, volume: 0.98, time: 1616439921],
...>  [price: 12.54, volume: 12.1, time: 1616439931],
...>  [price: 12.56, volume: 18.3, time: 1616439952],
...>  [price: 18.9, volume: 12, time: 1616440004],
...>  [price: 11, volume: 43.1, time: 1616440025],
...>  [price: 18.322, volume: 43.1, time: 1616440028]
...>]
...>
...>OHLC.create_candles(trades, :minute)
{
  :ok,
  %{
    candles: [
      %{
        close: 12.56,
        etime: 1616439959,
        high: 12.56,
        low: 12.21,
        open: 12.21,
        processed: true,
        stime: 1616439900,
        trades: 3,
        type: :bullish,
        volume: 31.38
      },
      %{
        close: 18.9,
        etime: 1616440019,
        high: 18.9,
        low: 18.9,
        open: 18.9,
        processed: true,
        stime: 1616439960,
        trades: 1,
        type: :bearish,
        volume: 12.0
      },
      %{
        close: 18.322,
        etime: 1616440079,
        high: 18.322,
        low: 11.0,
        open: 11.0,
        processed: true,
        stime: 1616440020,
        trades: 2,
        type: :bullish,
        volume: 86.2
      }
    ],
    pair: nil,
    timeframe: :minute
  }
}

Link to this section Summary

Types

Single candle generated.

A list of candles.

Available options for create_candles/3

Available timeframes for create_candles/3

Single trade.

A list of trades.

Functions

Coverts candles to new timeframe.

Function for generating candles from trades and timeframe provided.

Merges candle into another candle.

Link to this section Types

@type candle() :: %{
  :open => float(),
  :high => float(),
  :low => float(),
  :close => float(),
  :volume => float(),
  :trades => integer(),
  :stime => integer() | float(),
  :etime => integer() | float(),
  :type => :bullish | :bearish | nil,
  optional(:processed) => boolean()
}

Single candle generated.

@type candles() :: [candle()]

A list of candles.

@type opts() :: [
  forward_fill: boolean(),
  validate_trades: boolean(),
  previous_candle: candle(),
  pair: atom() | binary()
]

Available options for create_candles/3

  • :forward_fill - When set true copies the previous candles closing price to the next candle if no trades happened to be in between. Useful when you don't want to get empty time gap between the generated candles.
  • :validate_trades - When set true all trades are being validated before generating the candles to avoid errors and misinformation.
  • :previous_candle - Trades are appended to the previous candle if possible before generating the new candles. Useful if you want to update existing candle.
  • :pair - Adds the asset pair name to the returned outputs metadata.
@type timeframe() :: :minute | :hour | :day | :week

Available timeframes for create_candles/3

@type trade() :: [price: number(), volume: number(), time: number()]

Single trade.

@type trades() :: [trade()]

A list of trades.

Link to this section Functions

Link to this function

convert_timeframe(candles, timeframe)

@spec convert_timeframe(candles(), timeframe()) :: {:ok, candles()}

Coverts candles to new timeframe.

Parameters:

candles - A list of candles. timeframe- Must be higher then the existing candles timeframe. For example if candles were previously created using :hour timeframe then the provided timeframe cannot be :minute.

Returns a tuple containing the list of candles with converted timeframe.

example

Example

iex>trades = [
...>  [price: 0.12, volume: 542.98, time: 1668108995],
...>  [price: 0.14, volume: 212.1, time: 1668108998],
...>  [price: 0.17, volume: 532.77, time: 1668112595],
...>  [price: 0.21, volume: 123.8, time: 1668112623]
...>]
...>
...>{:ok, %{candles: candles}} = OHLC.create_candles(trades, :minute)
...>OHLC.convert_timeframe(candles, :day)
{
  :ok,
  [
    %{
      close: 0.21,
      etime: 1668124799,
      high: 0.21,
      low: 0.12,
      open: 0.12,
      processed: true,
      stime: 1668038400,
      trades: 4,
      type: :bullish,
      volume: 1411.65
    }
  ]
}
Link to this function

create_candles(trades, timeframe, opts \\ [])

@spec create_candles(trades(), timeframe(), opts() | nil) ::
  {:ok, %{pair: binary() | atom(), timeframe: timeframe(), candles: candles()}}
  | {:error, atom()}

Function for generating candles from trades and timeframe provided.

Parameters:

  • trades/0 - A list containing all the trades. Trades must be chronologically arranged(ASC) by the timestamp field.
  • timeframe/0 - Timeframe for the candles.
  • opts/0 - Option values for the data proccessing.

Returns a tuple containing the metadata for the candles and a list of generated candles.

example

Example

iex>trades = [
...>  [price: 0.12, volume: 542.98, time: 1668108995],
...>  [price: 0.14, volume: 212.1, time: 1668108998],
...>  [price: 0.17, volume: 532.77, time: 1668112595],
...>  [price: 0.21, volume: 123.8, time: 1668112623]
...>]
...>
...>OHLC.create_candles(trades, :hour, [pair: "BTC/EUR", validate_trades: true])
{
  :ok,
  %{
    candles: [
      %{
        close: 0.14, etime: 1668110399,
        high: 0.14, low: 0.12,
        open: 0.12,
        processed: true,
        stime: 1668106800,
        trades: 2,
        type: :bullish,
        volume: 755.08
      },
      %{
        close: 0.21,
        etime: 1668113999,
        high: 0.21,
        low: 0.17,
        open: 0.17,
        processed: true,
        stime: 1668110400,
        trades: 2,
        type: :bullish,
        volume: 656.57
      }
    ],
    pair: "BTC/EUR",
    timeframe: :hour
  }
}
Link to this function

merge_child(main_candle, child_candle)

@spec merge_child(candle(), candle()) :: {:ok, candle()} | {:error, atom()}

Merges candle into another candle.

If main candles :stime is 0 then fallback to the merge_child :stime.

Parameters:

  • main_candle - Candle which will be merged into.
  • child_candle - Candle which will be merged. It is important to have etime less than or equal to the main candle. Meaning both candles should stay in the same timeframe.

example

Example

iex>trades1 = [
...>  [price: 0.12, volume: 542.98, time: 1668108995],
...>  [price: 0.14, volume: 212.1, time: 1668108998]
...>]
...>trades2 = [
...>  [price: 0.17, volume: 532.77, time: 1668112595],
...>  [price: 0.21, volume: 123.8, time: 1668112623]
...>]
...>{:ok, %{candles: candles1}} = OHLC.create_candles(trades1, :week)
...>{:ok, %{candles: candles2}} = OHLC.create_candles(trades2, :week)
...>OHLC.merge_child(List.first(candles1), List.first(candles2))
{
  :ok,
  %{
    close: 0.21,
    etime: 1668383999,
    high: 0.21,
    low: 0.12,
    open: 0.12,
    processed: true,
    stime: 1667779200,
    trades: 4,
    type: :bullish,
    volume: 1411.65
  }
}