Flirt With Julia

Learn the Julia programming language through real-world examples.

Get Data From An Api And Plot

23 Dec 2018 »

In this post we’ll learn how to make an HTTP get request to an API (Oanda) to retrieve exchange rate data, and then plot the results on a graph. You’ll need an API key from Oanda if you want to execute the code, so head over to www.oanda.com to create a practice account and obtain an API key.

Install Dependencies


using Pkg
Pkg.add(["JSON", "Dates", "HTTP", "Plots"])

using JSON, Dates, HTTP, Plots

plotly() # set Plots backend


  • JSON will allow us to easily parse the JSON response object that is returned from the API
  • Dates makes working with dates convenient and easy
  • HTTP is the package that we will use to make the request to the API
  • Plots will be used to visualize the data that we receive

Define a function to call the API and return the results


function getData(url, from_date, to_date, granularity)
    try
        response = HTTP.get(
            url,
            ["Authorization" => "Bearer [YOUR-API-KEY]"],
            query = [
                "price" => "M",
                "from" => string(from_date),
                "to" => string(to_date),
                "granularity" => string(granularity)
            ]
        )
        return JSON.parse(String(response.body)) # parse the response object
    catch e
        return "Error occurred: $e"
    end
end


Our function includes four parameters: the API’s URL, the from date, the to date, and the granularity. The URL and dates are self explantory and the granularity parameter allows us to define the period that each data point should cover (daily prices, hourly prices, 5-minute prices, etc.).

Inside of our function we define a variable response and assign to it the return value from our HTTP request. Note that we are using the try/catch statement in our function so that we can gracefully handle any errors that might occur when calling the API without crashing our program. When making an HTTP request, a number of things could go wrong so you want to be sure to handle any errors. Here we are simply returning a string that states that an error occurred, followed by the actual error.

Our HTTP request is made by calling the get method and passing in three arguments: a URL, an authorization header, and a query. The URL is the same one passed to the getData() function and both the auth header and query arguments are arrays of Pairs. In the case of the query array, we are utilizing our date arguments as well as our granularity argument to define our query parameters. Note: In a future post, we’ll make another kind of HTTP request where we will include a body in the request.

Finally, we parse the body of the response object returned from Oanda with JSON.parse and return it.

Define arguments to pass to getData() and assign the return value of getData() to the variable candlesticks


url = "https://api-fxtrade.oanda.com/v3/instruments/EUR_USD/candles"
from_date = Dates.now() - Dates.Month(3)
to_date = Dates.now()
granularity = "D"
candlesticks = getData(url, from_date, to_date, granularity)["candles"]
JSON.print(candlesticks, 4) # pretty prints the JSON object


Here we are just grabbing the “candles” on the response object, as this contains the data we are interested in plotting (remove [“candles”] from the end of the line above to view the whole response object). Then, we pretty print our candlesticks using JSON.print and specify indentation of 4 so that we can view our JSON object in a nice format.

In a future post, we’ll plot an actual candlestick chart that makes use of all of the information returned, rather than just plotting the closing price (“c”).

The last line of this block results in the following output (showing what candlesticks looks like):

[
    {
        "volume": 125476,
        "time": "2018-09-23T21:00:00.000000000Z",
        "complete": true,
        "mid": {
            "c": "1.17464",
            "o": "1.17451",
            "l": "1.17240",
            "h": "1.18154"
        }
    },
    {
        "volume": 137517,
        "time": "2018-09-24T21:00:00.000000000Z",
        "complete": true,
        "mid": {
            "c": "1.17661",
            "o": "1.17498",
            "l": "1.17310",
            "h": "1.17926"
        }
    },

    ...

    {
        "volume": 102340,
        "time": "2018-12-23T22:00:00.000000000Z",
        "complete": false,
        "mid": {
            "c": "1.14128",
            "o": "1.13720",
            "l": "1.13607",
            "h": "1.14384"
        }
    }
]

Create empty arrays, loop through candlesticks, push data to their respective arrays, then plot


dates = []
prices = []

for candle in candlesticks
    push!(dates, DateTime(chop(candle["time"], tail = 8)))
    push!(prices, parse(Float64, candle["mid"]["c"]))
end

plot(dates, prices, label="EUR/USD", title = "EUR/USD Exchange Rates")
xlabel!("Date")
ylabel!("Rate")


In order to convert our dates in candlesticks to Julia DateTime types, I had to chop off the last eight digits from the string (if you know a workaround for this, please post in the comments!). We also need to parse our prices to the Float64 type since they are strings.

Finally, we plot our data, include labels and a title, and voila!

plot

Until next time, I hope you’ve enjoyed flirting with Julia! 💘