diff --git a/DESCRIPTION b/DESCRIPTION index 5c0de48..3d49f9d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: rRofex Type: Package Title: Interface to ROFEX APIs -Version: 0.0.1.0003 +Version: 1.4.0 Authors@R: c(person("Augusto", "Hassel", role = c("aut", "cre"), email = "ahassel@primary.com.ar")) Description: Provides a convenient wrapper for consuming data from ROFEX APIs: Trading API, Risk API and BackOffice API. License: MIT diff --git a/NAMESPACE b/NAMESPACE index 79926b5..dab1bfa 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -18,8 +18,11 @@ import(jsonlite) importFrom(glue,glue) importFrom(glue,glue_collapse) importFrom(magrittr,"%>%") +importFrom(purrr,modify_depth) importFrom(purrr,some) importFrom(rlang,is_null) +importFrom(tibble,as_tibble) importFrom(tibble,enframe) +importFrom(tidyr,pivot_wider) importFrom(tidyr,replace_na) importFrom(tidyr,separate) diff --git a/NEWS.md b/NEWS.md index 8c6027f..781a6f6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,68 +1,75 @@ -# rRofex 0.0.1.0003 +## rRofex 1.4.0 -## Changes +### Changes + +* Corrected package version according to standars from [R Packages](http://r-pkgs.had.co.nz/) +* `trading_md()` and `trading_mdh()` gain a new parameter: **tidy**. If `tidy = TRUE` the information will be arrange in a tidy format. + +## rRofex 1.3.0 + +### Changes * Improved metadata on `trading_instruments()` method. It has been added: Product Type, Ticker, Option Type, Strike Price, Underlying, Settlement. -# rRofex 0.0.1.0002 +## rRofex 1.2.0 -## Changes +### Changes * Added new parameters to `trading_instruments()`. Now you can search instruments by Segment, Type and CFI Code. * Added new method `trading_instruments_fronts()` to list only front month future contracts. Thanks @jfgomezok for the request and clarification on how to show the data. -# rRofex 0.0.1.0001 +## rRofex 1.1.0 -## Changes +### Changes * Added a `NEWS.md` file to track changes to the package. * Using `pkgdown` to build the documentation. -# rRofex 0.0.1.0000 +## rRofex 1.0.0 -## New Features +### New Features * *xOMS* support. Ask your broker for credentials. * Use of S4 objects to save connections. This means that you can have different connections on the same R session. -## Changes +### Changes * Close issue #12 now that the connection parameters can be access with `token()`, `base_url()` and `login_date_time()` -## Important +### Important **This version is not backwards compatible due to the way connections work now.** -# rRofex 0.0.0.9008 +## rRofex 0.0.0.9008 -## New Features +### New Features * New *time_in_force* available. Now supports GTD. * New Iceberg order. -## Changes +### Changes * Sovled issue #8 -## Acknowledgement +### Acknowledgement * Thanks @jfgomezok for your PR solving #8 -# rRofex 0.0.0.9007 +## rRofex 0.0.0.9007 -## New Features +### New Features * New *time_in_force* available. Now supports IOC and FOK. -## Changes +### Changes * #6 Corrected mistakes on the documentation. -## BUG FIXES +### Bug Fixes * #6 'Environment' variable for log-in was misspelled. -## Acknowledgement +### Acknowledgement * Thanks @kenarab for your PR solving #6 diff --git a/R/functions.R b/R/functions.R index 8e5ef64..3db12c5 100644 --- a/R/functions.R +++ b/R/functions.R @@ -90,11 +90,8 @@ trading_login <- function(username, password, base_url) { warn_for_status(query) NULL } else if (typeof(query) == "list" && status_code(query) == 200) { + message(glue("Succesfully connected with rRofex to {base_url}...")) - message_for_status(query) - message(glue(" - - Succesfully connected with rRofex to {base_url}...")) invisible(rRofex_connection(token = headers(query)$`x-auth-token`, base_url = base_url)) } else { @@ -207,9 +204,6 @@ trading_instruments <- function(connection, request, sec_detailed = FALSE, marke } else { - message_for_status(query) - message("\r") - data <- fromJSON(toJSON(content(query))) if (request == 'segments') { @@ -325,87 +319,111 @@ trading_instruments_fronts <- function(connection) { # Market Data --------------------------- -#' @title Primary API Market Data Real Time +#' @title Market Data Real Time #' -#' @description \code{trading_md} retrivies Market Data in Real Time. +#' @description This method brings Market Data in Real Time. #' -#' @param connection S4. \strong{Mandaroty} Formal rRofexConnection class object +#' @param connection S4. \strong{Mandaroty}. Formal rRofexConnection class object #' @param market_id String. Market to wich you are going to connect. #' \itemize{ -#' \item ROFX. Matba Rofex +#' \item \strong{ROFX} - Matba Rofex #' } -#' @param symbol String. Use \code{\link{trading_instruments}} to see which symbols are available. -#' @param entries Vector of Strings. It contains the information to be required: +#' @param symbol String. \strong{Mandaroty}. Use \code{\link{trading_instruments}} to see which symbols are available. +#' @param entries Vector of Strings. It contains the information to be queried: #' \itemize{ -#' \item BI. Bid. -#' \item OF. Offer. -#' \item LA. Last Available Price. -#' \item OP. Open Price. -#' \item CL. Close Price. -#' \item SE. Settlement Price. -#' \item OI. Open Interest. +#' \item \strong{BI} - Bid. +#' \item \strong{OF} - Offer. +#' \item \strong{LA} - Last Available Price. +#' \item \strong{OP} - Open Price. +#' \item \strong{CL} - Close Price. +#' \item \strong{SE} - Settlement Price. +#' \item \strong{OI} - Open Interest. #' } -#' @param depth Integer. Depth of the book to be retrivied. +#' @param depth Integer. Depth of the book. +#' @param tidy Logical. Data arranged on a tidy format. #' -#' @return If correct, it will load a data frame. +#' @return If correct, it will load a tibble data frame #' #' @family market data functions -trading_md <- function(connection, market_id='ROFX', symbol, entries=c('BI', 'OF', 'LA', 'OP', 'CL', 'SE', 'OI'), depth=1L) { +trading_md <- function(connection, market_id='ROFX', symbol, entries=c('BI', 'OF', 'LA', 'OP', 'CL', 'SE', 'OI'), depth = 1L, tidy = FALSE) { if (missing(connection)) stop("Connection cannot be empty.") if (!isS4(connection) || rev(class(connection)) != "rRofexConnection" || !validObject(connection)) stop("The 'connection' must be a valid 'rRofexConnection'.") if (as.Date(connection@login_date_time) != Sys.Date()) stop("The 'acyRsaConnection' is no longer valid. Please log-in again.") if (!market_id %in% c("ROFX")) stop("Invalid 'market_id' parameter.") - if (missing(symbol)) stop("You should pick a 'symbol' to move forward.") - if (!all(sapply(entries, function(x) x %in% c('BI', 'OF', 'LA', 'OP', 'CL', 'SE', 'OI')))) stop("Invalid 'entries' parameter") + if (missing(symbol)) stop("You should pick a 'symbol' to move forward.") - # Base URL - url <- paste0(connection@base_url, "/rest/marketdata/get") + if (some(entries, ~ !.x %in% c('BI', 'OF', 'LA', 'OP', 'CL', 'SE', 'OI'))) stop("'entries' parameter is invalid. See documentation.") # Query - query <- GET(url = url, + query <- GET(url = glue(connection@base_url, "/rest/marketdata/get"), query = list( - marketId=market_id, - symbol=symbol, - entries=paste0(entries, collapse = ","), - depth=depth), + marketId = market_id, + symbol = symbol, + entries = glue_collapse(entries, sep = ","), + depth = depth), add_headers(.headers = c("X-Auth-Token" = connection@token))) - if (query$status_code != 200 | content(query)$status != "OK") stop("The query returned an unexpected result.") + if (status_code(query) != 200) { + + warn_for_status(query) + message("\r") + data <- NULL - result <- enframe(unlist(content(x = query)$marketData)) + } else { - data <- suppressWarnings(result %>% - separate(col = name, into = c("entries", "type"), sep = '\\.') %>% - mutate(type = case_when( - is.na(type) ~ 'value', - TRUE ~ type - ))) + if (tidy == TRUE) { + + data <- fromJSON(toJSON(content(query), auto_unbox = T, null = "null")) + + data <- data$marketData %>% + enframe() %>% + mutate(value = map(.x = value, function(x) if(is_null(x)) {NA_real_} else {x})) %>% + pivot_wider() %>% + mutate_if(., .predicate = ~ class(.[[1]]) == 'list', .funs = ~ modify_depth(.x = ., .depth = 1, ~ replace_na(data = ., replace = NA_real_))) %>% + mutate_if(., .predicate = ~ length(unlist(.)) == 1, .funs = ~ unlist(x = ., recursive = F)) %>% + mutate_if(., .predicate = ~ class(.) == 'list', .funs = ~ modify_depth(.x = ., .depth = 1, ~ as_tibble(.))) %>% + mutate_if(., .predicate = ~ class(.) == 'list', .funs = ~ modify_depth(.x = ., .depth = 1, ~ mutate_at(.tbl = ., .vars = vars(matches("date")), .funs = ~ as.POSIXct(./1000, origin = "1970-01-01", tz = "America/Buenos_Aires")))) %>% + mutate_if(., .predicate = ~ class(.) == 'list', .funs = ~ modify_depth(.x = ., .depth = 1, ~ mutate_at(.tbl = ., .vars = vars(matches("price")), .funs = ~ as.double(.)))) %>% + mutate_if(., .predicate = ~ class(.) == 'list', .funs = ~ modify_depth(.x = ., .depth = 1, ~ mutate_at(.tbl = ., .vars = vars(matches("size")), .funs = ~ as.double(.)))) + + } else { + result <- enframe(unlist(content(x = query)$marketData)) + + data <- suppressWarnings(result %>% + separate(col = name, into = c("entries", "type"), sep = '\\.') %>% + mutate(type = case_when( + is.na(type) ~ 'value', + TRUE ~ type) + ) + ) + } + } return(data) } -#' @title Primary API Historical Market Data +#' @title Historical Market Data #' -#' @description \code{trading_mdh} retrivies Historical Trades for a given instrument. +#' @description Access Historical Trades for a given instrument. #' #' @param connection S4. \strong{Mandaroty} Formal rRofexConnection class object #' @param market_id String. Market to wich we are going to connect. #' \itemize{ -#' \item ROFX. Rofex: Rosario Futures Exchange. -#' \item MATBA. Matba: Mercado a Termino de Buenos Aires. +#' \item \strong{ROFX} - Matba Rofex. #' } #' @param symbol String. Use \code{\link{trading_instruments}} to see which symbols are available. #' @param date String. Date to be queried. With format '\%Y-\%m-\%d'. #' @param date_from String. Used together with 'date_to'. #' @param date_to String. Userd together with 'date_from'. +#' @param tidy Logical. Data arranged on a tidy format. #' #' @return If correct, it will load a data frame. #' #' @family market data functions -trading_mdh <- function(connection, market_id='ROFX', symbol, date, date_from, date_to) { +trading_mdh <- function(connection, market_id='ROFX', symbol, date, date_from, date_to, tidy = FALSE) { if (missing(connection)) stop("Connection cannot be empty.") if (!isS4(connection) || rev(class(connection)) != "rRofexConnection" || !validObject(connection)) stop("The 'connection' must be a valid 'rRofexConnection'.") @@ -422,36 +440,56 @@ trading_mdh <- function(connection, market_id='ROFX', symbol, date, date_from, d if (!missing(date_to) & !.validate_fecha(date = date_to)) stop("The correct format for 'date_to' is %Y-%m-%d") } - # Base URL - url <- paste0(connection@base_url, "/rest/data/getTrades") - # Query query <- if (!missing(date)) { - GET(url = url, + GET(url = glue(connection@base_url, "/rest/data/getTrades"), query = list( - marketId=market_id, - symbol=symbol, - date=date + marketId = market_id, + symbol = symbol, + date = date ), add_headers(.headers = c("X-Auth-Token" = connection@token))) } else if (!missing(date_from) & !missing(date_to)) { - GET(url = url, + GET(url = glue(connection@base_url, "/rest/data/getTrades"), query = list( - marketId=market_id, - symbol=symbol, - dateFrom=date_from, - dateTo=date_to + marketId = market_id, + symbol = symbol, + dateFrom = date_from, + dateTo = date_to ), add_headers(.headers = c("X-Auth-Token" = connection@token))) } - if (query$status_code != 200 | content(query)$status != "OK") stop("The query returned an unexpected result.") - if (!length(content(query)$trades)) stop("There is no data for the product / period selected.") + if (status_code(query) != 200) { - result <- fromJSON(content(x = query, as = "text")) + warn_for_status(query) + message("\r") + data <- NULL - # Return - data <- flatten(result$trades) + } else if (!length(content(query)$trades)) { + + message("There is no data for the product / period selected.") + data <- NULL + + } else { + + if (tidy == TRUE) { + + data <- fromJSON(toJSON(content(query), auto_unbox = T, null = "null")) + + data <- data$trades %>% + mutate_all(.funs = ~ map(.x = ., function(x) if(is_null(x)) {NA_real_} else {x})) %>% + mutate_at(., .vars = vars(matches("price|size")), .funs = ~ as.double(.)) %>% + mutate_at(., .vars = vars(matches("datetime")), .funs = ~ as.POSIXct(x = unlist(.), tz = "America/Buenos_Aires")) %>% + mutate_at(., .vars = vars(matches("servertime")), .funs = ~ as.POSIXct(x = unlist(.)/1000, origin = "1970-01-01", tz = "America/Buenos_Aires")) %>% + mutate_at(., .vars = vars(matches("symbol")), .funs = ~ as.character(.)) %>% + as_tibble() + + } else { + result <- fromJSON(content(x = query, as = "text")) + data <- flatten(result$trades) + } + } return(data) } diff --git a/R/rRofex.R b/R/rRofex.R index 2a90b2b..2a61944 100644 --- a/R/rRofex.R +++ b/R/rRofex.R @@ -1,10 +1,10 @@ #' @import dplyr #' @import httr #' @import jsonlite -#' @importFrom tibble enframe -#' @importFrom tidyr separate replace_na +#' @importFrom tibble enframe as_tibble +#' @importFrom tidyr separate replace_na pivot_wider #' @importFrom magrittr %>% #' @importFrom glue glue glue_collapse -#' @importFrom purrr some +#' @importFrom purrr some modify_depth #' @importFrom rlang is_null "_PACKAGE" diff --git a/docs/404.html b/docs/404.html index 29d9847..63cd7e3 100644 --- a/docs/404.html +++ b/docs/404.html @@ -71,7 +71,7 @@
diff --git a/docs/CODE_OF_CONDUCT.html b/docs/CODE_OF_CONDUCT.html index 9d154ac..ef360c0 100644 --- a/docs/CODE_OF_CONDUCT.html +++ b/docs/CODE_OF_CONDUCT.html @@ -71,7 +71,7 @@ diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index 0d27a8b..27f0ca1 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -71,7 +71,7 @@ diff --git a/docs/authors.html b/docs/authors.html index 232c1b0..1486cca 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -71,7 +71,7 @@ diff --git a/docs/index.html b/docs/index.html index b88dfb4..605a673 100644 --- a/docs/index.html +++ b/docs/index.html @@ -31,7 +31,7 @@ diff --git a/docs/news/index.html b/docs/news/index.html index 9104f3c..ac1a435 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -71,7 +71,7 @@ @@ -114,120 +114,134 @@NEWS.md
- trading_md()
and trading_mdh()
gain a new parameter: tidy. If tidy = TRUE
the information will be arrange in a tidy format.trading_instruments()
method. It has been added: Product Type, Ticker, Option Type, Strike Price, Underlying, Settlement.trading_instruments()
. Now you can search instruments by Segment, Type and CFI Code.trading_instruments_fronts()
to list only front month future contracts. Thanks @jfgomezok for the request and clarification on how to show the data.token()
, base_url()
and login_date_time()
Primary API Market Data Real Time
Market Data Real Time
Primary API Historical Market Data
Historical Market Data
trading_md
retrivies Market Data in Real Time.
This method brings Market Data in Real Time.
trading_md( @@ -125,7 +125,8 @@Primary API Market Data Real Time
market_id = "ROFX", symbol, entries = c("BI", "OF", "LA", "OP", "CL", "SE", "OI"), - depth = 1L + depth = 1L, + tidy = FALSE )
S4. Mandaroty Formal rRofexConnection class object
S4. Mandaroty. Formal rRofexConnection class object
String. Market to wich you are going to connect.
ROFX. Matba Rofex
ROFX - Matba Rofex
String. Use trading_instruments
to see which symbols are available.
String. Mandaroty. Use trading_instruments
to see which symbols are available.
Vector of Strings. It contains the information to be required:
BI. Bid.
OF. Offer.
LA. Last Available Price.
OP. Open Price.
CL. Close Price.
SE. Settlement Price.
OI. Open Interest.
Vector of Strings. It contains the information to be queried:
BI - Bid.
OF - Offer.
LA - Last Available Price.
OP - Open Price.
CL - Close Price.
SE - Settlement Price.
OI - Open Interest.
Integer. Depth of the book to be retrivied.
Integer. Depth of the book.
Logical. Data arranged on a tidy format.
If correct, it will load a data frame.
+If correct, it will load a tibble data frame
Other market data functions: diff --git a/docs/reference/trading_mdh.html b/docs/reference/trading_mdh.html index df7f5d2..0e22763 100644 --- a/docs/reference/trading_mdh.html +++ b/docs/reference/trading_mdh.html @@ -6,7 +6,7 @@ -
trading_mdh
retrivies Historical Trades for a given instrument.
Access Historical Trades for a given instrument.
trading_mdh(connection, market_id = "ROFX", symbol, date, date_from, date_to)+
trading_mdh( + connection, + market_id = "ROFX", + symbol, + date, + date_from, + date_to, + tidy = FALSE +)