Foreign exchange rates simplified.
Forex is a simple Elixir library that serves as a wrapper to the
foreign exchange reference rates provided by the European Central Bank, no API keys,
no authentication, no rate limits.
The reference rates are usually updated at around 16:00 CET every working day, except on TARGET closing days.
They are based on the daily concertation procedure between central banks across Europe, which normally takes place around 14:10 CET. The reference rates are published for information purposes only. Using the rates for transaction purposes is strongly discouraged.
Source: European Central Bank
Even though there are other libraries in the Elixir ecosystem that provide
similar functionality (example: ex_money), Forex was created with the intent
of providing access to currency exchange rates for projects that want to self-host
the data and not rely on third-party paid services in a simple and straightforward
manner. No API keys, no authentication, no rate limits, just a simple Elixir library
that fetches the data from the European Central Bank and caches it for later use.
If you need a more advanced library that provides additional features and allows you to fetch exchange rates from multiple sources, you should check out the excellent money.
By default, Forex starts with your application which in turn starts the Forex.Supervisor. If you
don't want to start the Forex supervision tree by default, you can pass the runtime: false option
to the forex dependency in your mix.exs file:
def deps do
[
{:forex, "~> 1.1.2", runtime: false}
]
endThe Forex supervision tree is responsible for fetching the exchange rates from the European Central Bank
and caching them for later use. If you want to start the Forex.Fetcher manually, you can do so by calling
the Forex.Fetcher.Supervisor.start_link/1 function in your application supervision tree.
By default, Forex uses the Req HTTP client in Forex.Feed.Req to fetch the exchange rates from
the European Central Bank. To use a different HTTP client, define your own implementation of
the Forex.Feed.API behaviour and pass it to the Forex module in your config.exs file:
config :forex, feed_api: MyApp.Forex.APIClientBy default the base currency is the Euro (EUR), the same as the European Central Bank,
but you can change the base currency by passing the base option (for other options see the
Options section) to the relevant functions.
To fetch the latest exchange rates, you can use the latest_rates/1 function:
iex> Forex.latest_rates()
{:ok,
%Forex{
base: :eur,
date: ~D[2025-03-12],
rates: %{
usd: Decimal.new("1.1234"),
jpy: Decimal.new("120.1234"),
...
zar: Decimal.new("24.1442")
}}
}To fetch the exchange rates for the last ninety days, you can use the last_ninety_days_rates/1 function:
iex> Forex.last_ninety_days_rates()
{:ok,
[
%Forex{date: ~D[2025-03-12], base: :eur, rates: %{usd: Decimal.new("1.1234"), ...}},
...
]}To fetch the historic exchange rates (for any working day since 4 January 1999),
you can use the historic_rates/1 function:
iex> Forex.historic_rates()
{:ok,
[
%Forex{date: ~D[2025-03-12], base: :eur, rates: %{usd: Decimal.new("1.1234"), ...}},
...
]}To fetch the exchange rates for a specific date, you can use the get_historic_rate/2 function:
iex> Forex.get_historic_rate(~D[2025-02-25])
{:ok,
[
%Forex{date: ~D[2025-03-12], base: :eur, rates: %{usd: Decimal.new("1.1234"), ...}},
...
]}To fetch the exchange rates between two dates, you can use the get_historic_rates_between/3 function:
iex> Forex.get_historic_rates_between(~D[2025-02-25], ~D[2025-02-28])
{:ok,
[
%Forex{date: ~D[2025-03-12], base: :eur, rates: %{usd: Decimal.new("1.1234"), ...}},
...
]}To convert an amount from one currency to another, you can use the exchange/4 function:
iex> Forex.exchange(100, "USD", "EUR")
{:ok, Decimal.new("91.86100")}
iex> Forex.exchange(420, :eur, :gbp)
{:ok, Decimal.new("353.12760")}To list all available currencies from the European Central Bank,
you can use the available_currencies/1 function:
iex> Forex.available_currencies()
[:try, :eur, :aud, :bgn, :brl, ...]Forex provides a mix task to fetch exchange rates from the European Central Bank and export them to
a json file. There are three mix tasks available:
mix forex.export.latest- fetches the latest exchange rates from the European Central Bank and exports them to ajsonfile.mix forex.export.ninety- fetches the last ninety days exchange rates from the European Central Bank and exports them to ajsonfile.mix forex.export.historic- fetches the historic exchange rates from the European Central Bank and exports them to ajsonfile.
Check the mix tasks documentation for more information on how to use them.
The mix tasks json encoder uses the Elixir 1.18 JSON module by default. If you are using an older version of Elixir,
you can use any other JSON library (for example Jason) as long as the library
implements the encode_to_iodata!/2 function. This can be configured by setting
the json_library option in the config.exs file of your project:
config :forex, json_library: JasonThe package can be installed by adding forex to your list of dependencies in mix.exs:
def deps do
[
{:forex, "~> 1.1.2"}
]
endThis project is licensed under the MIT License - see the LICENSE file for details.