DheerajAgarwal / rgdax

Wrapper for Coinbase pro (erstwhile GDAX) Cryptocurrency exchange
Other
33 stars 16 forks source link

/fills suggestion. #1

Closed kwartler closed 6 years ago

kwartler commented 6 years ago

When I perform a GET /fills I get an uneven nested list. Your code grabs specific list elements to overcome this. What about something like below which is what I used before seeing your package (I have my own private). This way you get the complete response. Just my $0.02 though. If you need a contributor I would be happy to spend some time on your package if you need it. :)

#' @title GET Account Fills Info
#'
#' @description Requires authentication, will retreive account information including profile-id, currency balances, currency availability (differs from balances if there are any holds), and hold amounts.
#'
#' @param apiKey Your API key from the gdax account page
#' @param secret Your API secret from the gdax account page
#' @param passphrase your API passphrase from the gdax account page
#' @param product_id optional market product id.  String must be one of "LTC-EUR", "LTC-BTC", "LTC-USD", "ETH-USD", "ETH-EUR", "ETH-BTC", "BTC-USD", "BTC-EUR", or "BTC-GBP".
#' @export
#' @seealso \url{https://docs.gdax.com/}
#' @return response a data frame of account information including available balances.
#' @examples  \dontrun{
#' api.key <- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
#' secret <- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
#' passphrase <- "xxxxxxxxxxx"
#' actInfo<-gdaxFills(api.key,secret,passphrase)
#' }
gdaxFills<-function(apiKey,secret,passphrase,product_id){
  if(missing(product_id)){product_id<-'*'}

  # Libs
  require(httr)
  require(RCurl)

  # Endpoint
  apiURL <- "https://api.gdax.com"
  reqURL <- "/fills"
  meth <- "GET"

  # Official timestamp
  timestamp<-as.character(getTime()[1,2])

  # Encode Info
  key <- base64Decode(secret, mode="raw")
  what <- paste0(timestamp, toupper(meth), reqURL)

  signa <- base64Encode(hmac(key, what, algo="sha256", raw=TRUE))

  # https://stackoverflow.com/questions/27153979/converting-nested-list-unequal-length-to-data-frame
  res <- GET(paste0(apiURL,reqURL), 
             add_headers('CB-ACCESS-KEY'=apiKey,
                         'CB-ACCESS-SIGN'=signa,
                         'CB-ACCESS-TIMESTAMP'=timestamp,
                         'CB-ACCESS-PASSPHRASE'=passphrase,
                         'Content-Type'='application/json'))
  print(http_status(res)$message)
  lst<-content(res)
  indx <- sapply(lst, length)
  res <- as.data.frame(do.call(rbind,lapply(lst, `length<-`,
                                            max(indx))))

  colnames(res) <- names(lst[[which.max(indx)]])
  res<-res[grepl(product_id,sapply(res$product_id,'[')),]
  return(res)

}

The interesting bit is arranging the info into a df filled w/ NULL if needed and then using grepl to perform a subset based on product. Again, just my $0.02 and trying to help!

DheerajAgarwal commented 6 years ago

Hi @kwartler! This is a nice suggestion. Thank you for the suggestion as well as for interest in contributing. Now that the package has been officially released on CRAN, I do not feel the same pressure to get the basic functionality to work. I can start focussing on making the functions more robust. I also notice from your code that you were able to use httr to pass headers which for some reason I struggled after encapsulating the logic in auth().

Anyways, I will appreciate if you can actively contribute towards it and send me a pull request. Also if possible, please spread the word. Hopefully there are many folks who may find it easier to use this than to start from scratch.

DheerajAgarwal commented 6 years ago

I have looked at this and believe, the difference lies in using jsonlite. The content of the response is returned as a json and converting it to a data frame using fromJSON() addresses the issue by default and gives it a normalized form. At this time, no implementation changes will be done. When the enhancement to replace RCurl is undertaken, this issue can be revisited.