R/public-api-requests.R

Defines functions parse_raw_order_book format_gdax_market_datum get_order_book get_gdax_market_datum

Documented in format_gdax_market_datum get_gdax_market_datum get_order_book parse_raw_order_book

# Contains functions for making public GDAX API requests
#' @include load-configurations.R

#' @title Get the last trade on GDAX
#'
#' @description Uses the \code{GDAX} API to get the most recent trade recorded
#' on GDAX's exchange.
#'
#' @param ticker The ticker to grab data for (e.g. \code{"btc_usd"}, \code{"eth_usd"})
#' @param exchange Since this function pulls from the GDAX exchange, this is set to \code{"gdax"}
#' @param ticker_lookup_table The ticker lookup table as a \code{data.frame}, if
#' \code{NULL} then this function will attempt to read the table from the database
#' @param exchange_lookup_table The exchange lookup table as a \code{data.frame}, if
#' \code{NULL} then this function will attempt to read the table from the database
#' 
#' @details Column descriptions:
#' \itemize{
#'   \item{\strong{\code{trade_id:}}}{ A unique ID generated by GDAX for each trade}
#'   \item{\strong{\code{bid:}}}{ The bid price on that trade}
#'   \item{\strong{\code{ask:}}}{ The ask price on that trade}
#'   \item{\strong{\code{size:}}}{ The size of that trade}
#'   \item{\strong{\code{time_requested:}}}{ The time that data was requested from GDAX}
#'   \item{\strong{\code{time_returned:}}}{ The time returned by GDAX}
#'   \item{\strong{\code{ticker_lookup_id:}}}{ The ticker lookup id}
#'   \item{\strong{\code{exchange_lookup_id:}}}{ The exchange lookup id}
#' }
#' 
#' @return A \code{data.frame} with a single row containing the columns described above
#' 
#' @export
#' 
get_gdax_market_datum <- function (ticker = "btc_usd", exchange = "gdax", 
                                   ticker_lookup_table = NULL,
                                   exchange_lookup_table = NULL) {
  
  # Attempt to load in the lookup tables if they were not provided
  if (is.null(ticker_lookup_table)) {
    ticker_lookup_table <- get_table(ticker_lookup)
  }
  if (is.null(exchange_lookup_table)) {
    exchange_lookup_table <- get_table(exchange_lookup)
  }
  
  # Send the GET request
  api_url        <- build_api_url(gdax_config, ticker = ticker)
  request_time   <- as.numeric(Sys.time())
  request_output <- httr::GET(api_url)
  
  # Interpret the output and return as data.frame
  market_datum <- as.data.frame(httr::content(request_output), stringsAsFactors = FALSE)
  
  # If output is an error return the error
  if(is.character(market_datum[[1]])) {
    return(message("Error returned by API: ", market_datum[[1]]))
  }
  
  # Add the lookup IDs
  ticker_ind   <- which(ticker_lookup_table$ticker_name == ticker)
  exchange_ind <-  which(exchange_lookup_table$exchange_name == exchange)
  market_datum$ticker_lookup_id <- ticker_lookup_table$ticker_lookup_id[ticker_ind]
  market_datum$exchange_lookup_id <- exchange_lookup_table$exchange_lookup_id[exchange_ind]
  
  # Build the data.frame to return
  formatted_data <- format_gdax_market_datum(market_datum, request_time)
  return (formatted_data)
}

#' @title Get order book data
#' 
#' @description Uses the \code{cryptowat.ch} API to grab the current ask 
#' and bid orders on the order book for a given exchange and ticker
#' 
#' @param exchange Exchange to grab data from recognized by \code{cryptowat.ch} API
#' @param ticker Ticker symbol recognized by \code{cryptowat.ch} API
#' 
get_order_book <- function (exchange = "gdax", ticker = "btc_usd") {
  
  # Build the url
  api_url <- build_api_url(cryptowatch_config, exchange = exchange, ticker = ticker)
  
  # Pull the data
  raw_order_book <- httr::content(httr::GET(api_url))
  
  # Parse the data and return it
  order_book <- parse_raw_order_book(raw_order_book)
  return (order_book)
  
}

#' @title Format raw GDAX data
#'
#' @description Formats data returned from a GDAX API ticker GET request.
#'
#' @param output_data Raw data output by \code{get_gdax_market_datum}
#' @param request_time The time that data was requested
#'
#' @details Column descriptions:
#' \itemize{
#'   \item{\strong{\code{trade_id:}}}{ A unique ID generated by GDAX for each trade}
#'   \item{\strong{\code{bid:}}}{ The bid price on that trade}
#'   \item{\strong{\code{ask:}}}{ The ask price on that trade}
#'   \item{\strong{\code{size:}}}{ The size of that trade}
#'   \item{\strong{\code{time_requested:}}}{ The time that data was requested from GDAX}
#'   \item{\strong{\code{time_returned:}}}{ The time returned by GDAX}
#'   \item{\strong{\code{ticker_lookup_id:}}}{ The ticker lookup id: 1 = BTC/USD}
#'   \item{\strong{\code{exchange_lookup_id:}}}{ The exchange lookup id: 1 = GDAX}
#' }
#' 
#' Currently only supports BTC/USD ticker from GDAX
#' 
#' @return A \code{data.frame} with a single row containing the columns described above
#' 
format_gdax_market_datum <- function (output_data, request_time) {
  
  # Convert returned time to epoch and add request time
  time_returned <- as.numeric(as.POSIXct(output_data$time,
                                                     format = "%Y-%m-%dT%H:%M:%S",
                                                     tz = "GMT"))
  time_requested <- request_time
  trade_id <- as.numeric(output_data$trade_id)
  size     <- as.numeric(output_data$size)
  bid      <- as.numeric(output_data$bid)
  ask      <- as.numeric(output_data$ask)
  ticker_lookup_id   <- as.numeric(output_data$ticker_lookup_id)
  exchange_lookup_id <- as.numeric(output_data$exchange_lookup_id)
  
  # Build gdax_market_datum_class
  output_data <- new("gdax_market_datum", 
                      trade_id = trade_id,
                      size     = size,
                      bid      = bid,
                      ask      = ask,
                      time_returned  = time_returned,
                      time_requested = time_requested,
                      ticker_lookup_id   = ticker_lookup_id,
                      exchange_lookup_id = exchange_lookup_id)
  
  return (output_data)
}

#' @title Parse raw order book data from \code{cryptowat.ch} API
#' 
#' @description Splits up the data into ask and bid orders and returns the
#' data as a \code{list} of two \code{data.frame}s.
#' 
#' @param raw_order_book Raw order book data from a \code{cryptowat.ch} API pull
#' 
#' @return A \code{list} with \code{names} \code{"ask_orders"} and
#' \code{"bid_orders"} corresponding to all open ask and bid orders on
#' the order book
parse_raw_order_book <- function (raw_order_book) {
  
  # Split up the data into ask and bid data.frames
  ask_df <- data.frame(do.call(rbind, raw_order_book$result$asks))
  bid_df <- data.frame(do.call(rbind, raw_order_book$result$bids))
  
  # Name the columns and return the data as a list
  colnames(ask_df) <- c("ask_price", "ask_size")
  colnames(bid_df) <- c("bid_price", "bid_size")
  return (list(ask = ask_df,
               bid = bid_df))
} 
kyleengel/btclearn documentation built on June 7, 2018, 12:26 a.m.