diff --git a/NAMESPACE b/NAMESPACE index 0effde8..9610de3 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -61,6 +61,10 @@ export(usdm_v1_premium_index) export(usdm_v1_time) export(usdm_v2_account) export(usdm_v2_position_risks) +export(usdm_v1_trades) +export(usdm_um_trades) +export(usdm_um_new_order) +export(usdm_um_open_orders) importFrom(assertive,assert_is_numeric) importFrom(data.table,"%chin%") importFrom(data.table,":=") diff --git a/R/binance.R b/R/binance.R index b7c2a41..e7e3ff1 100644 --- a/R/binance.R +++ b/R/binance.R @@ -1,7 +1,7 @@ BINANCE <- list( BASE = list( SPOT = 'https://api.binance.com', - USDM = 'https://fapi.binance.com' + USDM = 'https://papi.binance.com' ), SPOT = list( TIMEINFORCE = c('GTC', 'IOC', 'FOK'), @@ -15,7 +15,7 @@ BINANCE <- list( "MAX_NUM_ORDERS", "MAX_NUM_ALGO_ORDERS", "MIN_NOTIONAL", "PERCENT_PRICE"), TIMEINFORCE = c('GTC', 'IOC', 'FOK', 'GTX'), - POSITION_SIDE = c('LONG', 'SHORT'), + POSITION_SIDE = c('BOTH', 'LONG', 'SHORT'), TYPE = c('LIMIT', 'MARKET', 'STOP', 'STOP_MARKET', 'TAKE_PROFIT', 'TAKE_PROFIT_MARKET', @@ -798,24 +798,24 @@ binance_new_order <- function(symbol, side, type, time_in_force, quantity, price quantity <= filters[filterType == 'LOT_SIZE', maxQty]) # work around the limitation of %% (e.g. 200.1 %% 0.1 = 0.1 !!) quot <- (quantity - filters[filterType == 'LOT_SIZE', minQty]) / filters[filterType == 'LOT_SIZE', stepSize] - stopifnot(abs(quot - round(quot)) < 1e-10) + stopifnot(abs(quot - round(quot)) < 1) if (type == 'MARKET') { stopifnot(quantity >= filters[filterType == 'MARKET_LOT_SIZE', minQty], quantity <= filters[filterType == 'MARKET_LOT_SIZE', maxQty]) # work around the limitation of %% (e.g. 200.1 %% 0.1 = 0.1 !!) quot <- (quantity - filters[filterType == 'MARKET_LOT_SIZE', minQty]) / filters[filterType == 'MARKET_LOT_SIZE', stepSize] - stopifnot(abs(quot - round(quot)) < 1e-10) + stopifnot(abs(quot - round(quot)) < 1) - if (isTRUE(filters[filterType == 'MIN_NOTIONAL', applyToMarket])) { - if (filters[filterType == 'MIN_NOTIONAL', avgPriceMins] == 0) { + if (isTRUE(filters[filterType == 'NOTIONAL', applyToMarket])) { + if (filters[filterType == 'NOTIONAL', avgPriceMins] == 0) { ref_price <- binance_ticker_price(symbol)$price } else { ref_price <- binance_avg_price(symbol) - stopifnot(ref_price$mins == filters[filterType == 'MIN_NOTIONAL', avgPriceMins]) + stopifnot(ref_price$mins == filters[filterType == 'NOTIONAL', avgPriceMins]) ref_price <- ref_price$price } - stopifnot(ref_price * quantity >= filters[filterType == 'MIN_NOTIONAL', minNotional]) + stopifnot(ref_price * quantity >= filters[filterType == 'NOTIONAL', minNotional]) } } @@ -830,19 +830,19 @@ binance_new_order <- function(symbol, side, type, time_in_force, quantity, price stopifnot(abs(quot - round(quot)) < 1e-10) } - if (filters[filterType == 'PERCENT_PRICE', avgPriceMins] == 0) { +if (filters[filterType == 'NOTIONAL', avgPriceMins] == 0) { ref_price <- binance_ticker_price(symbol)$price } else { ref_price <- binance_avg_price(symbol) - stopifnot(ref_price$mins == filters[filterType == 'PERCENT_PRICE', avgPriceMins]) +stopifnot(ref_price$mins == filters[filterType == 'NOTIONAL', avgPriceMins]) ref_price <- ref_price$price } stopifnot( - price >= ref_price * filters[filterType == 'PERCENT_PRICE', multiplierDown], - price <= ref_price * filters[filterType == 'PERCENT_PRICE', multiplierUp] + price >= ref_price * filters[filterType == 'PERCENT_PRICE_BY_SIDE', 'askMultiplierDown'], + price <= ref_price * filters[filterType == 'PERCENT_PRICE_BY_SIDE', 'askMultiplierUp'] ) - stopifnot(price * quantity >= filters[filterType == 'MIN_NOTIONAL', minNotional]) + stopifnot(price * quantity >= filters[filterType == 'NOTIONAL', minNotional]) params$price = price } diff --git a/R/usdm.R b/R/usdm.R index 3c9a217..1ee9631 100644 --- a/R/usdm.R +++ b/R/usdm.R @@ -10,7 +10,7 @@ usdm_query <- function(endpoint, ...) { #' @export #' @return "OK" string on success usdm_v1_ping <- function() { - res <- usdm_query("/fapi/v1/ping") + res <- usdm_query("/papi/v1/ping") if (is.list(res) & length(res) == 0) { res <- "OK" } @@ -21,7 +21,7 @@ usdm_v1_ping <- function() { #' @export #' @return \code{POSIXct} usdm_v1_time <- function() { - res <- usdm_query("/fapi/v1/time")$serverTime + res <- usdm_query("/dapi/v1/time")$serverTime res <- as_timestamp(res / 1e3) res } @@ -31,7 +31,7 @@ usdm_v1_time <- function() { #' @export #' @importFrom jsonlite fromJSON usdm_v1_exchange_info <- function() { - res <- usdm_query("/fapi/v1/exchangeInfo", content_as = "text") + res <- usdm_query("/papi/v1/exchangeInfo", content_as = "text") res <- fromJSON(res) res$serverTime <- as_timestamp(res$serverTime / 1e3) res$rateLimits <- as.data.table(res$rateLimits) @@ -76,7 +76,7 @@ usdm_v1_premium_index <- function(symbol) { params$symbol <- symbol } - res <- usdm_query("/fapi/v1/premiumIndex", params = params) + res <- usdm_query("/dapi/v1/premiumIndex", params = params) if (missing(symbol)) { res <- rbindlist(res) @@ -97,7 +97,7 @@ usdm_v1_premium_index <- function(symbol) { res[, time := as_timestamp(time)] } -#' Open new order on the Binance USDM account +#' Open new order on the Binance Coin-m account #' #' This function serves as a low level entry for order classes. #' Do not use it directly. @@ -122,8 +122,8 @@ usdm_v1_new_order <- function(symbol, ... ) - order <- usdm_query( - "/fapi/v1/order", + order <- usdm_query( + "/papi/v1/cm/order", method = "POST", params = params, sign = TRUE @@ -132,7 +132,42 @@ usdm_v1_new_order <- function(symbol, as.data.table(order) } -#' Get all open orders of a symbol on USDM. +#' Open new order on the Binance USDM account +#' +#' This function serves as a low level entry for order classes. +#' Do not use it directly. +#' +#' @param symbol string +#' @param side enum +#' @param position_side enum +#' @param type enum +#' @param ... list +#' @return data.table +#' @export +usdm_um_new_order <- function(symbol, + side = BINANCE$SIDE, + position_side = BINANCE$USDM$POSITION_SIDE, + type = BINANCE$USDM$TYPE, + ...) { + params <- list( + symbol = symbol, + side = match.arg(side), + positionSide = match.arg(position_side), + type = match.arg(type), + ... + ) + + order <- usdm_query( + "/papi/v1/um/order", + method = "POST", + params = params, + sign = TRUE + ) + + as.data.table(order) +} + +#' Get all open orders of a symbol on Coin-M. #' #' Get all open orders on a symbol. Careful when accessing this with no symbol. #' Weight: 1 for a single symbol; 40 when the symbol parameter is omitted. @@ -148,7 +183,31 @@ usdm_v1_open_orders <- function(symbol) { } order <- usdm_query( - "/fapi/v1/openOrders", + "/papi/v1/cm/openOrders", + params = params, + sign = TRUE + ) + + rbindlist(order) +} + +#' Get all open orders of a symbol on USDM. +#' +#' Get all open orders on a symbol. Careful when accessing this with no symbol. +#' Weight: 1 for a single symbol; 40 when the symbol parameter is omitted. +#' +#' @param symbol optional string +#' @return data.table +#' @export +usdm_um_open_orders <- function(symbol) { + params <- list() + + if (!missing(symbol)) { + params$symbol <- symbol + } + + order <- usdm_query( + "/papi/v1/um/openOrders", params = params, sign = TRUE ) @@ -156,6 +215,7 @@ usdm_v1_open_orders <- function(symbol) { rbindlist(order) } + #' Get positions of a symbol or all symbols on USDM. #' @param symbol optional string #' @return data.table @@ -169,13 +229,49 @@ usdm_v2_position_risks <- function(symbol) { rbindlist( usdm_query( - "/fapi/v2/positionRisk", + "/dapi/v2/positionRisk", params = params, sign = TRUE ) ) } +#' Trade list (sp) +#' @return data.table +#' @export +usdm_v1_trades <- function(symbol) { + params <- list() + + if (!missing(symbol)) { + params$symbol <- symbol + } + + rbindlist( + usdm_query( + "/papi/v1/cm/userTrades", + sign = TRUE + ) + ) +} + +#' Trade list USDM (sp) +#' @return data.table +#' @export +usdm_um_trades <- function(symbol) { + params <- list() + + if (!missing(symbol)) { + params$symbol <- symbol + } + + rbindlist( + usdm_query( + "/papi/v1/um/userTrades", + sign = TRUE + ) + ) +} + #' Convert columns of positions into numeric. #' @param positions data.table #' @return data.table @@ -198,7 +294,7 @@ convert_position_risks <- function(positions) { #' @return list #' @export usdm_v2_account <- function() { - account <- usdm_query("/fapi/v2/account", sign = TRUE) + account <- usdm_query("/dapi/v2/account", sign = TRUE) account$assets <- rbindlist(account$assets) account$positions <- rbindlist(account$positions) account @@ -216,7 +312,7 @@ usdm_v1_change_initial_leverage <- function(symbol, leverage) { ) usdm_query( - "/fapi/v1/leverage", + "/dapi/v1/leverage", method = "POST", params = params, sign = TRUE @@ -236,7 +332,7 @@ usdm_v1_change_margin_type <- function(symbol, ) usdm_query( - "/fapi/v1/marginType", + "/dapi/v1/marginType", method = "POST", params = params, sign = TRUE @@ -255,7 +351,7 @@ usdm_v1_cancel_order_by_id <- function(symbol, order_id) { ) order <- usdm_query( - "/fapi/v1/order", + "/dapi/v1/order", method = "DELETE", params = params, sign = TRUE @@ -276,7 +372,7 @@ usdm_v1_cancel_order_by_client_order_id <- function(symbol, client_order_id) { ) order <- usdm_query( - "/fapi/v1/order", + "/dapi/v1/order", method = "DELETE", params = params, sign = TRUE