Pulling data from HTTP URLs is straightforward in R. HTTPS support is a slightly different story, but the RCurl package easily solves the problem, using the
getURL function. Querying the various endpoints becomes fairly straightforward:
url <- paste0("https://api.vircurex.com/api/", request_type, ".json", parameters) fromJSON(json_str=getURL(url))
Almost all API calls follow the same sequence; build a query string and send it. R provides some interesting reflection capabilities that make implementing this particularly easy. Firstly,
match.call() gives the call for the function (name and arguments). In addition, named arguments can be extracted using
formals(). Between those two functions, we can determine argument names and values dynamically. These will be the parameters used in the query.
query_trade <- function(base = "BTC", alt="USD") request(as.list(match.call())[-1], formals())
This defines a function,
query_trade that calls out to the Vircurex API (via
request). Since most of the API calls take the same arguments, we can reuse this function for most of the calls by abusing
sys.calls() which gives access to the call stack.
caller_details <- sys.calls()[[sys.nframe()-1]] request_type <- caller_details[]
Included in the call stack is the name of the calling functions. Using the right entry in the stack allows the following definitions to “just work”:
get_last_trade <- query_trade get_lowest_ask <- query_trade get_highest_bid <- query_trade get_highest_bid <- query_trade get_volume <- query_trade get_info_for_1_currency <- query_trade orderbook <- query_trade trades <- query_trade
Visualising MtGox’s impact on BTC prices
Of the various API calls supports, the
trades function gives all the transactions completed in the last 7 days for a given currency pair. The
fromJSON function returns a list of lists which need to be munged into a data frame. The easiest way to do this is to convert it to a matrix, then to a data frame.
trade_list <- trades() trade.df <- data.frame(matrix(unlist(trade_list), nrow=length(trade_list), byrow=T)) #Convert columns from factors to numerics: for(col in 1:ncol(trade.df)) trade.df[,col] <- as.numeric(levels(trade.df[,col]))[trade.df[,col]] #Give columns names: names(trade.df) <- c("time","id","amount","price") #Convert the time column: trade.df$time <- as.POSIXct(as.numeric(df$time), origin="1970-01-01")
Now the data is in a data frame with the correct types, it’s straightforward to visualise it using ggplot2:
ggplot(trade.df, aes(time, price, size=amount)) + geom_point() + geom_smooth(aes(weight=amount)) + theme_minimal()
This plots each trade as a dot, scaled by the amount (in Bitcoin). The line is fitted using LOESS regression, weighted by the transaction amount.
There’s an interesting dip that corresponds to Feb 25, about the time that MtGox went offline.
Code for this entry is available in this GitHub Gist.