Alpha Vantage 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.
Here's the complete (desired) list of features. Checked items are the ones already implemented.
- Base API with support for all of the Alpha Vantage API params but nothing else
- Dedicated module for Timeseries functions
- Dedicated module for Forex functions
- Dedicated module for the cryptocurrencies functions
- Dedicated module for the indicators functions
- 'Watch' option for stocks
First, add :vantagex to your deps list in your mix.exs
file
def deps do
[
{:vantagex, "~> 0.1"}
]
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
config :vantagex,
api_key: "YOUR_API_KEY"
Finally run $ mix deps.get
and you should be good to go.
You can call Alpha Vantage's Time Series functions with the Vantagex.TimeSeries
module:
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:
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"
},
...
}
}
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:
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.
You can call Alpha Vantage's forex functions using the Vantagex.Forex
module
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.
You can call Alpha Vantage's cryptocurrencies functions using the Vantagex.Cryptocurrencies
module
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.
You can call Alpha Vantage's techincal indicators functions using the Vantagex.TechnicalIndicators
module.
All of the functions under this module take all of the API parameters that are required, and an additional opts
keyword list which can be used to pass extra parameters available to the functions.
So, for instance, if you wanted to call the Bollinger bands API for the close values of the "GOOG"
stock, with :daily
intervals, and a window of 20
, with a standard deviation of 1
both up and down, you would do it like this:
Vantagex.TechnicalIndicators.bbands("GOOG", :daily, 20, :close, nbdevup: 1, nbdevdn: 1)
As you can see in Alpha Vantage's docs for this function, for this function symbol
, interval
, time_period
, and series_type
are required parameters, that's why you pass those four values in. And then you have nbdevup
, nbdevdn
, matype
, and datatype
as optional parameters, thus, you pass those in the opts
list. The function
name and the apikey
are also required, but those shouldn't be passed in, since they are already pulled from the config.
This would produce a response like this:
%{
"Meta Data" => %{
"1: Symbol" => "GOOG",
"2: Indicator" => "Bollinger Bands (BBANDS)",
"3: Last Refreshed" => "2019-10-25",
"4: Interval" => "daily",
"5: Time Period" => 20,
"6.1: Deviation multiplier for upper band" => 1,
"6.2: Deviation multiplier for lower band" => 1,
"6.3: MA Type" => 0,
"7: Series Type" => "close",
"8: Time Zone" => "US/Eastern Time"
},
"Technical Analysis: BBANDS" => %{
"2017-07-13" => %{
"Real Lower Band" => "915.9401",
"Real Middle Band" => "935.2200",
"Real Upper Band" => "954.4999"
},
"2010-12-07" => %{
"Real Lower Band" => "284.9546",
"Real Middle Band" => "293.6493",
"Real Upper Band" => "302.3441"
},
"2011-06-30" => %{
"Real Lower Band" => "242.0506",
"Real Middle Band" => "249.3182",
"Real Upper Band" => "256.5859"
},
"2012-08-03" => %{
"Real Lower Band" => "288.5434",
"Real Middle Band" => "300.6135",
"Real Upper Band" => "312.6835"
},
"2012-08-23" => %{
"Real Lower Band" => "316.3829",
"Real Middle Band" => "325.2354",
"Real Upper Band" => "334.0880"
},
"2012-01-17" => %{
"Real Lower Band" => "310.1277",
"Real Middle Band" => "317.1253",
"Real Upper Band" => "324.1230"
},
"2018-11-12" => %{
"Real Lower Band" => "1046.5269",
"Real Middle Band" => "1074.0660",
"Real Upper Band" => "1101.6051"
},
"2018-05-29" => %{
"Real Lower Band" => "1046.7046",
"Real Middle Band" => "1068.5640",
"Real Upper Band" => "1090.4234"
},
"2010-04-09" => %{
"Real Lower Band" => "278.2627",
"Real Middle Band" => "281.2169",
"Real Upper Band" => "284.1711"
},
"2008-09-22" => %{
"Real Lower Band" => "211.8627",
"Real Middle Band" => "222.1877",
"Real Upper Band" => "232.5126"
},
"2005-02-22" => %{
"Real Lower Band" => "93.2264",
"Real Middle Band" => "96.8609",
"Real Upper Band" => "100.4954"
},
"2018-02-20" => %{
"Real Lower Band" => "1051.9637",
"Real Middle Band" => "1107.7015",
"Real Upper Band" => "1163.4393"
},
"2010-10-18" => %{
"Real Lower Band" => "255.0257",
"Real Middle Band" => "267.7918",
"Real Upper Band" => "280.5578"
},
"2009-09-25" => %{
"Real Lower Band" => "229.3201",
"Real Middle Band" => "237.3000",
"Real Upper Band" => "245.2800"
},
"2011-01-18" => %{
"Real Lower Band" => "297.9082",
"Real Middle Band" => "303.2645",
"Real Upper Band" => "308.6209"
},
"2017-08-09" => %{
"Real Lower Band" => "927.5829",
"Real Middle Band" => "945.5385",
"Real Upper Band" => "963.4941"
},
"2006-07-12" => %{
"Real Lower Band" => "196.2076",
"Real Middle Band" => "202.9005",
"Real Upper Band" => "209.5933"
},
"2005-06-27" => %{
"Real Lower Band" => "138.7568",
"Real Middle Band" => "142.3265",
"Real Upper Band" => "145.8963"
},
"2008-11-17" => %{
"Real Lower Band" => "156.5398",
"Real Middle Band" => "168.0404",
"Real Upper Band" => "179.5410"
},
"2010-06-30" => %{
"Real Lower Band" => "233.5966",
"Real Middle Band" => "241.1621",
"Real Upper Band" => "248.7276"
},
"2004-12-08" => %{
"Real Lower Band" => "84.3380",
"Real Middle Band" => "87.3474",
"Real Upper Band" => "90.3567"
},
"2016-02-16" => %{
"Real Lower Band" => "683.8266",
"Real Middle Band" => "708.3675",
"Real Upper Band" => "732.9084"
},
"2012-09-26" => %{
"Real Lower Band" => "341.9084",
"Real Middle Band" => "353.4631",
"Real Upper Band" => "365.0179"
},
"2017-08-04" => %{
"Real Lower Band" => "929.6691",
"Real Middle Band" => "946.7220",
"Real Upper Band" => "963.7749"
},
"2014-10-30" => %{
"Real Lower Band" => "526.2241",
"Real Middle Band" => "544.2130",
"Real Upper Band" => "562.2019"
},
"2013-03-15" => %{
"Real Lower Band" => "396.6416",
"Real Middle Band" => "404.8498",
"Real Upper Band" => "413.0580"
},
"2014-07-29" => %{
"Real Lower Band" => "577.0440",
"Real Middle Band" => "584.4662",
"Real Upper Band" => "591.8885"
},
"2018-07-23" => %{
"Real Lower Band" => "1118.7867",
"Real Middle Band" => "1153.0455",
"Real Upper Band" => "1187.3043"
},
"2018-01-24" => %{
"Real Lower Band" => "1067.2546",
"Real Middle Band" => "1104.5705",
"Real Upper Band" => "1141.8864"
},
"2018-01-03" => %{
"Real Lower Band" => "1031.8574",
"Real Middle Band" => "1050.5845",
"Real Upper Band" => "1069.3116"
},
"2015-10-09" => %{
"Real Lower Band" => "611.4766",
"Real Middle Band" => "626.6645",
"Real Upper Band" => "641.8524"
},
"2013-01-10" => %{
"Real Lower Band" => "351.1339",
"Real Middle Band" => "357.8278",
"Real Upper Band" => "364.5216"
},
"2018-12-06" => %{
"Real Lower Band" => "1033.6873",
"Real Middle Band" => "1059.0850",
"Real Upper Band" => "1084.4827"
},
"2011-11-02" => %{
"Real Lower Band" => "272.3310",
"Real Middle Band" => "285.3788",
"Real Upper Band" => "298.4267"
},
"2012-12-05" => %{
"Real Lower Band" => "326.1733",
"Real Middle Band" => "333.9057",
"Real Upper Band" => "341.6381"
},
"2006-04-03" => %{
"Real Lower Band" => "168.2978",
"Real Middle Band" => "178.2354",
"Real Upper Band" => "188.1731"
},
"2018-10-09" => %{
"Real Lower Band" => "1157.2593",
"Real Middle Band" => "1174.5160",
"Real Upper Band" => "1191.7727"
},
"2015-02-25" => %{
"Real Lower Band" => "523.1272",
"Real Middle Band" => "533.1575",
"Real Upper Band" => "543.1878"
},
"2011-09-12" => %{
"Real Lower Band" => "254.9090",
"Real Middle Band" => "262.4308",
"Real Upper Band" => "269.9527"
},
"2015-11-18" => %{
"Real Lower Band" => "700.9240",
"Real Middle Band" => "719.1615",
"Real Upper Band" => "737.3990"
},
"2007-06-22" => %{
"Real Lower Band" => "247.7323",
"Real Middle Band" => "252.8249",
"Real Upper Band" => "257.9174"
},
"2005-03-15" => %{
"Real Lower Band" => "90.0222",
"Real Middle Band" => "93.3613",
"Real Upper Band" => "96.7005"
},
"2005-12-16" => %{
"Real Lower Band" => "201.9022",
"Real Middle Band" => "206.1637",
"Real Upper Band" => "210.4253"
},
"2011-12-05" => %{
"Real Lower Band" => "290.1793",
"Real Middle Band" => "298.5353",
"Real Upper Band" => "306.8912"
},
"2005-07-19" => %{
"Real Lower Band" => "144.7881",
"Real Middle Band" => "147.5178",
"Real Upper Band" => "150.2475"
},
"2011-02-24" => %{
"Real Lower Band" => "302.6647",
"Real Middle Band" => "306.7161",
...
},
"2006-07-06" => %{"Real Lower Band" => "192.7600", ...},
"2013-09-27" => %{...},
...
}
}
You can check the module's or the functions' docs for detailed information on the arguments and optional params of each 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:
# 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 because 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:
%{
"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:
iex> Vantagex.call_api("TIME_SERIES_QUARTERLY", %{symbol: "GOOG"})
{:error, "Unknown function: 'TIME_SERIES_QUARTERLY'"}
Some of the options that HTTPoison allows per request, are allowed to be configured for all requests, not per request.
The supported options are:
:timeout
- the timeout for establishing the connection, in milliseconds. Defaults to 8000:recv_timeout
- the timeout for receiving an HTTP response. Defaults to 5000:proxy
- from HTTPoison docs: "a proxy to be used for the request; it can be a regular url or a {Host, Port} tuple, or a {:socks5, ProxyHost, ProxyPort} tuple":proxy_auth
- from HTTPoison docs: "proxy authentication {User, Password} tuple"
All of these options are to be defined in the application configuration, under :vantagex
. Like:
config :vantagex,
api_key: "YOUR_API_KEY",
recv_timeout: 30_000 # Sets a 30 second timeout for the requests
You cand find more about these options in HTTPoison's docs
To clone and run this project by itself run:
$ git clone https://github.com/sbacarob/vantagex.git
$ cd vantagex
$ iex -S mix