README.md

# Vantagex

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

#### Elixir wrapper for Alpha Vantage API

[Alpha Vantage](https://alphavantage.co) offers free financial APIs in JSON and CSV formats, providing access to realtime and historical stock data. As well as forex and cryptocurrency feeds, and 50+ technical indicators.

## Roadmap

Here's the complete (desired) list of features. Checked items are the ones already implemented.

- [x] Base API with support for all of the Alpha Vantage API params but nothing else
- [x] Dedicated module for Timeseries functions
- [x] Dedicated module for Forex functions
- [x] Dedicated module for the cryptocurrencies functions
- [ ] Dedicated module for the indicators functions
- [ ] 'Watch' option for stocks

## Installation

First, add :vantagex to your deps list in your `mix.exs` file

```elixir
def deps do
  [
    {:vantagex, git: "https://github.com/sbacarob/vantagex.git"}
  ]
end
```

Then, make sure to add your Alpha Vantage API key to your config files `config.exs` or environment specific, like `dev.exs`

> If you don't have an Alpha Vantage API key, you can get one for free [here](https://www.alphavantage.co/support/#api-key)

```elixir
config :vantagex,
  api_key: "YOUR_API_KEY"
```

Finally run `$ mix deps.get` and you should be good to go.

## Time Series functions

You can call Alpha Vantage's Time Series functions with the `Vantagex.TimeSeries` module:

```elixir
iex> Vantagex.TimeSeries.daily_adjusted("GOOG")
%{
  "Meta Data" => %{
    "1. Information" => "Daily Time Series with Splits and Dividend Events",
    "2. Symbol" => "GOOG",
    "3. Last Refreshed" => "2019-02-08 16:00:01",
    "4. Output Size" => "Compact",
    "5. Time Zone" => "US/Eastern"
  },
  "Time Series (Daily)" => %{
    "2018-11-12" => %{
      "1. open" => "1061.3900",
      "2. high" => "1062.1200",
      "3. low" => "1031.0000",
      "4. close" => "1038.6300",
      "5. adjusted close" => "1038.6300",
      "6. volume" => "1471758",
      "7. dividend amount" => "0.0000",
      "8. split coefficient" => "1.0000"
    },
    "2018-12-06" => %{
      "1. open" => "1034.2600",
      "2. high" => "1071.2000",
      "3. low" => "1030.7700",
      "4. close" => "1068.7300",
      "5. adjusted close" => "1068.7300",
      "6. volume" => "2769225",
      "7. dividend amount" => "0.0000",
      "8. split coefficient" => "1.0000"
    },
    ...
  }
}
```

These functions take the ticker symbol and accept an optional opts object, allowed options are `:outputsize` and `:datatype`. The only function that requires an extra argument is `intraday/3`, which expects the interval as an integer value:

```elixir
iex> Vantagex.TimeSeries.intraday("GOOG", 5) # 5 minute interval
%{
  "Meta Data" => %{
    "1. Information" => "Intraday (5min) open, high, low, close prices and volume",
    "2. Symbol" => "GOOG",
    "3. Last Refreshed" => "2019-02-08 16:00:00",
    "4. Interval" => "5min",
    "5. Output Size" => "Compact",
    "6. Time Zone" => "US/Eastern"
  },
  "Time Series (5min)" => %{
    "2019-02-07 15:50:00" => %{
      "1. open" => "1096.2900",
      "2. high" => "1096.6400",
      "3. low" => "1095.5500",
      "4. close" => "1095.9720",
      "5. volume" => "22465"
    },
    "2019-02-07 14:40:00" => %{
      "1. open" => "1093.5500",
      "2. high" => "1093.9301",
      "3. low" => "1092.7000",
      "4. close" => "1093.0000",
      "5. volume" => "11702"
    },
    ...
  }
}
```

### Output format

As you may notice, these functions return an Elixir Map. This is the default option. However, you can get plaintext JSON or CSV responses, by specifying the `:datatype` option:

```elixir
iex> Vantagex.TimeSeries.intraday("GOOG", 5, datatype: :csv)
"timestamp,open,high,low,close,volume\r\n2019-02-04 16:00:00,1130.7800,1132.4301,1130.5000,1132.4301,122109\r\n2019-02-04 15:55:00,1129.9800,1130.7900,1129.3140,1130.4685,52596\r\n2019-02-04 15:50:00,1129.2600,1130.2520,1128.8500,1129.8600,50110\r\n2019-02-04 15:45:00,1126.7550,1129.4750,1126.7550,1129.4100,33314\r\n2019-02-04 15:40:00,1127.7600,1127.7600,1125.3700,1126.4900,42554\r\n2019-02-04 15:35:00,1130.2900,1130.2900,1127.7006,1127.7006,36706\r\n2019-02-04 15:30:00,1131.1500,1131.5450,1130.3400,1130.6600,17684\r\n2019-02-04 15:25:00,1131.5900,1132.0100,1130.6899,1130.9900,20110\r\n2019-02-04 15:20:00,1130.7800,1131.7999,1130.7130,1131.3280,19301\r\n2019-02-04 15:15:00,1129.8400,1131.5500,1129.8400,1130.5072,36392\r\n2019-02-04 15:10:00,1129.0200,1130.1187,1128.0400,1130.1187,25009\r\n2019-02-04 15:05:00,1129.9000,1129.9998,1128.9301,1129.1600,15658\r\n2019-02-04 15:00:00,1130.0000,1130.4399,1129.7700,1130.0699,21459\r\n2019-02-04 14:55:00,1128.5500,1129.9000,1128.5500,1129.9000,41086\r\n2019-02-04 14:50:00,1128.8400,1128.9718,1127.8025,1128.3900,14609\r\n2019-02-04 14:45:00,1127.6191,1129.0000,1127.6191,1128.5900,12154\r\n..."
```

For more information, see the module's documentation.

## Forex functions.

You can call Alpha Vantage's forex functions using the `Vantagex.Forex` module

```elixir
iex> Vantagex.Forex.intraday("USD", "COP", 5)
%{
  "Meta Data" => %{
    "1. Information" => "FX Intraday (5min) Time Series",
    "2. From Symbol" => "USD",
    "3. To Symbol" => "COP",
    "4. Last Refreshed" => "2019-02-17 22:40:00",
    "5. Interval" => "5min",
    "6. Output Size" => "Compact",
    "7. Time Zone" => "UTC"
  },
  "Time Series FX (5min)" => %{
    "2019-02-17 17:45:00" => %{
      "1. open" => "3130.0000",
      "2. high" => "3130.0000",
      "3. low" => "3130.0000",
      "4. close" => "3130.0000"
    },
    ...
  }
}
```

These functions take two currencies (their ISO 4217 code. e.g. "USD"), as well as options to set
datatype and outputsize, just like TimeSeries.

The only function from `Vantagex.Forex` that requires an extra argument is `intraday/4`, which expects
an integer that determines the interval in minutes, as shown in the example above.

Output format works the same as TimeSeries.

For more information, see the module's documentation.

## Cryptocurrencies functions.

You can call Alpha Vantage's cryptocurrencies functions using the `Vantagex.Cryptocurrencies` module

```elixir
iex> Vantagex.Cryptocurrencies.daily("BTC", "USD")
%{
  "Meta Data" => %{
    "1. Information" => "Daily Prices and Volumes for Digital Currency",
    "2. Digital Currency Code" => "BTC",
    "3. Digital Currency Name" => "Bitcoin",
    "4. Market Code" => "USD",
    "5. Market Name" => "United States Dollar",
    "6. Last Refreshed" => "2019-03-09 (end of day)",
    "7. Time Zone" => "UTC"
  },
  "Time Series (Digital Currency Daily)" => %{
    "2017-07-13" => %{
      "1a. open (USD)" => "2397.70831714",
      "1b. open (USD)" => "2397.70831714",
      "2a. high (USD)" => "2429.55116636",
      "2b. high (USD)" => "2429.55116636",
      "3a. low (USD)" => "2329.24694466",
      "3b. low (USD)" => "2329.24694466",
      "4a. close (USD)" => "2353.72968273",
      "4b. close (USD)" => "2353.72968273",
      "5. volume" => "73837.90295505",
      "6. market cap (USD)" => "173794463.89599040"
    },
    "2018-11-12" => %{
      "1a. open (USD)" => "6404.47988049",
      "1b. open (USD)" => "6404.47988049",
      "2a. high (USD)" => "6435.95061677",
      "2b. high (USD)" => "6435.95061677",
      "3a. low (USD)" => "6359.81993277",
      "3b. low (USD)" => "6359.81993277",
      "4a. close (USD)" => "6375.86047086",
      "4b. close (USD)" => "6375.86047086",
      "5. volume" => "57756.07950395",
      "6. market cap (USD)" => "368244704.26095134"
    },
  ...
  }
}
```

These functions take the digital or crypto currency and the market, as well as options to set
datatype and outputsize, just like TimeSeries.

## Calling the general API function

You can call the base API function, which should support all of the existing APIs provided by Alpha Vantage using `Vantagex.call_api`, like so:

```elixir
# Use the TIME_SERIES_DAILY function
iex> params = %{symbol: "GOOG", outputsize: "full"}
%{outputsize: "full", symbol: "GOOG"}
iex> Vantagex.call_api("TIME_SERIES_DAILY", params)
%{
  "Meta Data" => %{
    "1. Information" => "Daily Prices (open, high, low, close) and Volumes",
    "2. Symbol" => "GOOG",
    "3. Last Refreshed" => "2019-01-04",
    "4. Output Size" => "Full size",
    "5. Time Zone" => "US/Eastern"
  },
  "Time Series (Daily)" => %{
    "2017-07-13" => %{
      "1. open" => "946.2900",
      "2. high" => "954.4500",
      "3. low" => "943.0100",
      "4. close" => "947.1600",
      "5. volume" => "1291782"
    },
    "2018-11-12" => %{
      "1. open" => "1061.3900",
      "2. high" => "1062.1200",
      "3. low" => "1031.0000",
      "4. close" => "1038.6300",
      "5. volume" => "1471758"
    },
    "2018-05-29" => %{
      "1. open" => "1064.8900",
      "2. high" => "1073.3700",
      "3. low" => "1055.2200",
      "4. close" => "1060.3200",
      "5. volume" => "1865139"
    },
    ...
  }
}
```
> Notice that the result has no particular order. This is of the way maps work in Elixir.

You can pass any of the options allowed by Alpha Vantage to the `params` map. However, if you fail to include one of the required params (Except for `apikey` and `function` which should not be passed in `params`), you'll get an error like this:

```elixir
%{
  "Error Message" => "Invalid API call. Please retry or visit the documentation (https://www.alphavantage.co/documentation/) for TIME_SERIES_DAILY."
}
```

Or, in case you attempt to call an unknown function, you'll get a different error message:

```elixir
iex> Vantagex.call_api("TIME_SERIES_QUARTERLY", %{symbol: "GOOG"})
{:error, "Unknown function: 'TIME_SERIES_QUARTERLY'"}
```

## Running the project by itself

To clone and run this project by itself run:

```bash
$ git clone https://github.com/sbacarob/vantagex.git
$ cd vantagex
$ iex -S mix
```