Skip to content

Commit

Permalink
version 1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
augustohassel committed Apr 28, 2020
1 parent 6738fad commit fb01f48
Show file tree
Hide file tree
Showing 26 changed files with 295 additions and 205 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -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 = "[email protected]"))
Description: Provides a convenient wrapper for consuming data from ROFEX APIs: Trading API, Risk API and BackOffice API.
License: MIT
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -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)
45 changes: 26 additions & 19 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -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

162 changes: 100 additions & 62 deletions R/functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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') {
Expand Down Expand Up @@ -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'.")
Expand All @@ -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)
}
Expand Down
6 changes: 3 additions & 3 deletions R/rRofex.R
Original file line number Diff line number Diff line change
@@ -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"
2 changes: 1 addition & 1 deletion docs/404.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/CODE_OF_CONDUCT.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit fb01f48

Please sign in to comment.