From 9c6f545885c31bcdb0b965c3e7e2bb1ff1192d38 Mon Sep 17 00:00:00 2001 From: Dereck Mezquita Date: Fri, 21 Feb 2025 08:24:07 -0600 Subject: [PATCH] Cleanup. --- R/merged_R_files.txt | 1528 ------------------------------------------ 1 file changed, 1528 deletions(-) delete mode 100755 R/merged_R_files.txt diff --git a/R/merged_R_files.txt b/R/merged_R_files.txt deleted file mode 100755 index 7a97adc8..00000000 --- a/R/merged_R_files.txt +++ /dev/null @@ -1,1528 +0,0 @@ -# ./impl_spottrading_orders_get_order_by.R - -# File: ./R/impl_spottrading_orders_get_order_by.R - -# box::use( -# ./helpers_api[process_kucoin_response, build_headers], -# ./utils[build_query, get_base_url, verify_symbol, get_api_keys], -# ./utils_time_convert_kucoin[time_convert_from_kucoin], -# coro[async, await], -# data.table[rbindlist, data.table], -# httr[GET, timeout], -# rlang[abort] -# ) - -#' Get Order By OrderId (Implementation) -#' -#' Retrieves detailed information for a single spot order using its order ID from the KuCoin Spot trading system asynchronously. -#' This function returns a `data.table` with comprehensive order details, including additional UTC datetime columns derived from timestamps. -#' -#' ## Description -#' This endpoint fetches data for a specific spot order identified by its `orderId`. The order can be in an active or done state: -#' - **Active Orders**: Orders currently in the order book (check `inOrderBook` to confirm). -#' - **Done Orders**: Orders that are canceled or fully filled (data available only within 3 * 24 hours from the current time). -#' -#' If the order is not active and exceeds the 3 * 24-hour window, the API defaults to querying within that timeframe, potentially returning no data if outside the range. -#' -#' ## Workflow -#' 1. **Parameter Validation**: Ensures `orderId` and `symbol` are non-empty strings, with `symbol` validated as a trading pair. -#' 2. **Request Construction**: Builds the endpoint URL with `orderId` in the path and `symbol` as a query parameter. -#' 3. **Authentication**: Generates private API headers using `build_headers()` with the GET method and endpoint. -#' 4. **API Request**: Sends a GET request to the KuCoin API with a 3-second timeout. -#' 5. **Response Processing**: Parses the response, converts the `data` object to a `data.table`, and adds `createdAtDatetime` and `lastUpdatedAtDatetime` columns. -#' -#' ## API Details -#' - **Endpoint**: `GET https://api.kucoin.com/api/v1/hf/orders/{orderId}?symbol={symbol}` -#' - **Domain**: Spot -#' - **API Channel**: Private -#' - **API Permission**: General -#' - **Rate Limit Pool**: Spot -#' - **Rate Limit Weight**: 2 -#' - **SDK Service**: Spot -#' - **SDK Sub-Service**: Order -#' - **SDK Method Name**: getOrderByOrderId -#' - **Official Documentation**: [KuCoin Get Order By OrderId](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-order-by-orderld) -#' -#' ## Request -#' ### Path Parameters -#' - `orderId`: String (required) - The unique order ID generated by the trading system (e.g., "6717422bd51c29000775ea03"). -#' -#' ### Query Parameters -#' - `symbol`: String (required) - The trading pair symbol (e.g., "BTC-USDT"). -#' -#' ### Example Request -#' ```bash -#' curl --location --request GET 'https://api.kucoin.com/api/v1/hf/orders/6717422bd51c29000775ea03?symbol=BTC-USDT' -#' ``` -#' -#' ## Response -#' ### HTTP Code: 200 -#' - **Content Type**: `application/json` -#' -#' ### Data Schema -#' - `code`: String (required) - Response code ("200000" indicates success). -#' - `data`: Object (required) - Order details with the following fields: -#' - `id`: String (required) - Unique order ID. -#' - `clientOid`: String (required) - Client-assigned order ID. -#' - `symbol`: String (required) - Trading pair (e.g., "BTC-USDT"). -#' - `opType`: String (required) - Operation type. -#' - `type`: Enum (required) - Order type: "limit" or "market". -#' - `side`: Enum (required) - Order side: "buy" or "sell". -#' - `price`: String (required) - Order price. -#' - `size`: String (required) - Order size. -#' - `funds`: String (required) - Order funds. -#' - `dealSize`: String (required) - Filled quantity. -#' - `dealFunds`: String (required) - Filled funds. -#' - `cancelledSize`: String (required) - Canceled quantity. -#' - `cancelledFunds`: String (required) - Canceled funds. -#' - `remainSize`: String (required) - Remaining quantity. -#' - `remainFunds`: String (required) - Remaining funds. -#' - `fee`: String (required) - Handling fees. -#' - `feeCurrency`: String (required) - Fee currency. -#' - `stp`: Enum (optional) - Self Trade Prevention: "DC", "CO", "CN", "CB". -#' - `timeInForce`: Enum (required) - Time in force: "GTC", "GTT", "IOC", "FOK". -#' - `postOnly`: Boolean (required) - Post-only flag. -#' - `hidden`: Boolean (required) - Hidden order flag. -#' - `iceberg`: Boolean (required) - Iceberg order flag. -#' - `visibleSize`: String (required) - Visible size for iceberg orders. -#' - `cancelAfter`: Integer (required) - Seconds until cancellation for GTT. -#' - `channel`: String (required) - Order channel. -#' - `remark`: String (optional) - Order remarks. -#' - `tags`: String (optional) - Order tags. -#' - `cancelExist`: Boolean (required) - Indicates a cancellation record. -#' - `tradeType`: String (required) - Trade type (redundant parameter). -#' - `inOrderBook`: Boolean (required) - Whether the order is in the order book. -#' - `active`: Boolean (required) - Order status (true = active, false = done). -#' - `tax`: String (required) - Tax information (for certain regions). -#' - `createdAt`: Integer (required) - Creation timestamp in milliseconds. -#' - `lastUpdatedAt`: Integer (required) - Last update timestamp in milliseconds. -#' -#' ### JSON Response Example -#' ```json -#' { -#' "code": "200000", -#' "data": { -#' "id": "6717422bd51c29000775ea03", -#' "clientOid": "5c52e11203aa677f33e493fb", -#' "symbol": "BTC-USDT", -#' "opType": "DEAL", -#' "type": "limit", -#' "side": "buy", -#' "price": "70000", -#' "size": "0.00001", -#' "funds": "0.7", -#' "dealSize": "0.00001", -#' "dealFunds": "0.677176", -#' "remainSize": "0", -#' "remainFunds": "0.022824", -#' "cancelledSize": "0", -#' "cancelledFunds": "0", -#' "fee": "0.000677176", -#' "feeCurrency": "USDT", -#' "stp": null, -#' "timeInForce": "GTC", -#' "postOnly": false, -#' "hidden": false, -#' "iceberg": false, -#' "visibleSize": "0", -#' "cancelAfter": 0, -#' "channel": "API", -#' "remark": "order remarks", -#' "tags": null, -#' "cancelExist": false, -#' "tradeType": "TRADE", -#' "inOrderBook": false, -#' "active": false, -#' "tax": "0", -#' "createdAt": 1729577515444, -#' "lastUpdatedAt": 1729577515481 -#' } -#' } -#' ``` -#' -#' @param keys List; API configuration parameters from `get_api_keys()`. Defaults to `get_api_keys()`. -#' @param base_url Character string; base URL for the KuCoin API. Defaults to `get_base_url()`. -#' @param orderId Character string; the unique order ID to retrieve (e.g., "6717422bd51c29000775ea03"). Required. -#' @param symbol Character string; the trading pair symbol (e.g., "BTC-USDT"). Required. -#' @return Promise resolving to a `data.table` with one row containing order details, including: -#' - `id` (character): Unique order ID. -#' - `clientOid` (character): Client-assigned order ID. -#' - `symbol` (character): Trading pair. -#' - `opType` (character): Operation type. -#' - `type` (character): Order type ("limit" or "market"). -#' - `side` (character): Order side ("buy" or "sell"). -#' - `price` (character): Order price. -#' - `size` (character): Order size. -#' - `funds` (character): Order funds. -#' - `dealSize` (character): Filled quantity. -#' - `dealFunds` (character): Filled funds. -#' - `cancelledSize` (character): Canceled quantity. -#' - `cancelledFunds` (character): Canceled funds. -#' - `remainSize` (character): Remaining quantity. -#' - `remainFunds` (character): Remaining funds. -#' - `fee` (character): Handling fees. -#' - `feeCurrency` (character): Fee currency. -#' - `stp` (character or NA): Self Trade Prevention strategy. -#' - `timeInForce` (character): Time in force. -#' - `postOnly` (logical): Post-only flag. -#' - `hidden` (logical): Hidden order flag. -#' - `iceberg` (logical): Iceberg order flag. -#' - `visibleSize` (character): Visible size for iceberg orders. -#' - `cancelAfter` (integer): Seconds until cancellation for GTT. -#' - `channel` (character): Order channel. -#' - `remark` (character or NA): Order remarks. -#' - `tags` (character or NA): Order tags. -#' - `cancelExist` (logical): Indicates a cancellation record. -#' - `tradeType` (character): Trade type. -#' - `inOrderBook` (logical): Whether in the order book. -#' - `active` (logical): Order status (true = active, false = done). -#' - `tax` (character): Tax information. -#' - `createdAt` (integer): Creation timestamp (milliseconds). -#' - `lastUpdatedAt` (integer): Last update timestamp (milliseconds). -#' - `createdAtDatetime` (POSIXct): Creation time in UTC. -#' - `lastUpdatedAtDatetime` (POSIXct): Last update time in UTC. -#' @examples -#' \dontrun{ -#' library(coro) -#' library(data.table) -#' -#' main_async <- coro::async(function() { -#' # Retrieve order details -#' order_details <- await(get_order_by_order_id_impl( -#' orderId = "6717422bd51c29000775ea03", -#' symbol = "BTC-USDT" -#' )) -#' print(order_details) -#' }) -#' -#' # Run the async function -#' main_async() -#' while (!later::loop_empty()) later::run_now() -#' } -#' -#' # Expected Output (simplified): -#' # id clientOid symbol opType type side price size ... createdAtDatetime lastUpdatedAtDatetime -#' # 1: 6717422bd51c29000775ea03 5c52e11203aa677f33e493fb BTC-USDT DEAL limit buy 70000 0.00001 ... 2023-10-22 03:31:55 2023-10-22 03:31:55 -#' @importFrom coro async await -#' @importFrom data.table rbindlist data.table -#' @importFrom httr GET timeout -#' @importFrom rlang abort -#' @export -get_order_by_order_id_impl <- coro::async(function( - keys = get_api_keys(), - base_url = get_base_url(), - orderId, - symbol -) { - tryCatch({ - # Validate parameters - if (is.null(orderId) || !is.character(orderId) || nchar(orderId) == 0) { - rlang::abort("Parameter 'orderId' must be a non-empty string.") - } - if (is.null(symbol) || !verify_symbol(symbol)) { - rlang::abort("Parameter 'symbol' must be a valid ticker (e.g., 'BTC-USDT').") - } - - # Construct endpoint and query string - endpoint <- paste0("/api/v1/hf/orders/", orderId) - query_params <- list(symbol = symbol) - query_string <- build_query(query_params) - endpoint_with_query <- paste0(endpoint, query_string) - full_url <- paste0(base_url, endpoint_with_query) - - # Generate authentication headers - headers <- await(build_headers("GET", endpoint_with_query, NULL, keys)) - - # Send GET request - response <- httr::GET( - url = full_url, - headers, - httr::timeout(3) - ) - - # Process response - parsed_response <- process_kucoin_response(response, full_url) - if (parsed_response$code != "200000") { - rlang::abort(sprintf("API error: %s - %s", parsed_response$code, parsed_response$msg)) - } - - # Convert response data to data.table - order_details <- data.table::rbindlist(list(parsed_response$data), fill = TRUE) - - # Add datetime columns from millisecond timestamps - order_details[, createdAtDatetime := time_convert_from_kucoin(createdAt, unit = "ms")] - order_details[, lastUpdatedAtDatetime := time_convert_from_kucoin(lastUpdatedAt, unit = "ms")] - - return(order_details) - }, error = function(e) { - rlang::abort(sprintf("Error in get_order_by_order_id_impl: %s", conditionMessage(e))) - }) -}) - -#' Get Order By ClientOid (Implementation) -#' -#' Retrieves detailed information for a single spot order using its client order ID (clientOid) from the KuCoin Spot trading system asynchronously. -#' This function returns a `data.table` with comprehensive order details, including additional UTC datetime columns derived from timestamps. -#' -#' ## Description -#' This endpoint fetches data for a specific spot order identified by its `clientOid`, a unique identifier assigned by the user when placing the order. -#' The order can be in an active or done state: -#' - **Active Orders**: Orders currently in the order book (check `inOrderBook` to confirm). -#' - **Done Orders**: Orders that are canceled or fully filled (data available only within 3 * 24 hours from the current time). -#' -#' If the order is not active and exceeds the 3 * 24-hour window, the API defaults to querying within that timeframe, potentially returning no data if outside the range. -#' -#' ## Differences from Get Order By OrderId -#' - **Get Order By OrderId**: Uses the KuCoin-generated `orderId` to retrieve order details, suitable when tracking orders via system-assigned IDs. -#' - **Get Order By ClientOid**: Uses the user-assigned `clientOid`, ideal when managing orders with custom identifiers without needing to map to KuCoin’s IDs. -#' -#' Choose this method if you track orders using your own identifiers. -#' -#' ## Workflow -#' 1. **Parameter Validation**: Ensures `clientOid` and `symbol` are non-empty strings, with `symbol` validated as a trading pair. -#' 2. **Request Construction**: Builds the endpoint URL with `clientOid` in the path and `symbol` as a query parameter. -#' 3. **Authentication**: Generates private API headers using `build_headers()` with the GET method and endpoint. -#' 4. **API Request**: Sends a GET request to the KuCoin API with a 3-second timeout. -#' 5. **Response Processing**: Parses the response, converts the `data` object to a `data.table`, and adds `createdAtDatetime` and `lastUpdatedAtDatetime` columns. -#' -#' ## API Details -#' - **Endpoint**: `GET https://api.kucoin.com/api/v1/hf/orders/client-order/{clientOid}?symbol={symbol}` -#' - **Domain**: Spot -#' - **API Channel**: Private -#' - **API Permission**: General -#' - **Rate Limit Pool**: Spot -#' - **Rate Limit Weight**: 2 -#' - **SDK Service**: Spot -#' - **SDK Sub-Service**: Order -#' - **SDK Method Name**: getOrderByClientOid -#' - **Official Documentation**: [KuCoin Get Order By ClientOid](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-order-by-clientoid) -#' -#' ## Request -#' ### Path Parameters -#' - `clientOid`: String (required) - The unique client order ID created by the user (e.g., "5c52e11203aa677f33e493fb"). -#' -#' ### Query Parameters -#' - `symbol`: String (required) - The trading pair symbol (e.g., "BTC-USDT"). -#' -#' ### Example Request -#' ```bash -#' curl --location --request GET 'https://api.kucoin.com/api/v1/hf/orders/client-order/5c52e11203aa677f33e493fb?symbol=BTC-USDT' -#' ``` -#' -#' ## Response -#' ### HTTP Code: 200 -#' - **Content Type**: `application/json` -#' -#' ### Data Schema -#' - `code`: String (required) - Response code ("200000" indicates success). -#' - `data`: Object (required) - Order details with the following fields: -#' - `id`: String (required) - Unique order ID generated by the trading system. -#' - `clientOid`: String (required) - Client-assigned order ID. -#' - `symbol`: String (required) - Trading pair (e.g., "BTC-USDT"). -#' - `opType`: String (required) - Operation type. -#' - `type`: Enum (required) - Order type: "limit" or "market". -#' - `side`: Enum (required) - Order side: "buy" or "sell". -#' - `price`: String (required) - Order price. -#' - `size`: String (required) - Order size. -#' - `funds`: String (required) - Order funds. -#' - `dealSize`: String (required) - Filled quantity. -#' - `dealFunds`: String (required) - Filled funds. -#' - `cancelledSize`: String (required) - Canceled quantity. -#' - `cancelledFunds`: String (required) - Canceled funds. -#' - `remainSize`: String (required) - Remaining quantity. -#' - `remainFunds`: String (required) - Remaining funds. -#' - `fee`: String (required) - Handling fees. -#' - `feeCurrency`: String (required) - Fee currency. -#' - `stp`: Enum (optional) - Self Trade Prevention: "DC", "CO", "CN", "CB". -#' - `timeInForce`: Enum (required) - Time in force: "GTC", "GTT", "IOC", "FOK". -#' - `postOnly`: Boolean (required) - Post-only flag. -#' - `hidden`: Boolean (required) - Hidden order flag. -#' - `iceberg`: Boolean (required) - Iceberg order flag. -#' - `visibleSize`: String (required) - Visible size for iceberg orders. -#' - `cancelAfter`: Integer (required) - Seconds until cancellation for GTT. -#' - `channel`: String (required) - Order channel. -#' - `remark`: String (optional) - Order remarks. -#' - `tags`: String (optional) - Order tags. -#' - `cancelExist`: Boolean (required) - Indicates a cancellation record. -#' - `tradeType`: String (required) - Trade type (redundant parameter). -#' - `inOrderBook`: Boolean (required) - Whether the order is in the order book. -#' - `active`: Boolean (required) - Order status (true = active, false = done). -#' - `tax`: String (required) - Tax information (for certain regions). -#' - `createdAt`: Integer (required) - Creation timestamp in milliseconds. -#' - `lastUpdatedAt`: Integer (required) - Last update timestamp in milliseconds. -#' -#' ### JSON Response Example -#' ```json -#' { -#' "code": "200000", -#' "data": { -#' "id": "6717422bd51c29000775ea03", -#' "clientOid": "5c52e11203aa677f33e493fb", -#' "symbol": "BTC-USDT", -#' "opType": "DEAL", -#' "type": "limit", -#' "side": "buy", -#' "price": "70000", -#' "size": "0.00001", -#' "funds": "0.7", -#' "dealSize": "0.00001", -#' "dealFunds": "0.677176", -#' "remainSize": "0", -#' "remainFunds": "0.022824", -#' "cancelledSize": "0", -#' "cancelledFunds": "0", -#' "fee": "0.000677176", -#' "feeCurrency": "USDT", -#' "stp": null, -#' "timeInForce": "GTC", -#' "postOnly": false, -#' "hidden": false, -#' "iceberg": false, -#' "visibleSize": "0", -#' "cancelAfter": 0, -#' "channel": "API", -#' "remark": "order remarks", -#' "tags": null, -#' "cancelExist": false, -#' "tradeType": "TRADE", -#' "inOrderBook": false, -#' "active": false, -#' "tax": "0", -#' "createdAt": 1729577515444, -#' "lastUpdatedAt": 1729577515481 -#' } -#' } -#' ``` -#' -#' @param keys List; API configuration parameters from `get_api_keys()`. Defaults to `get_api_keys()`. -#' @param base_url Character string; base URL for the KuCoin API. Defaults to `get_base_url()`. -#' @param clientOid Character string; the unique client order ID to retrieve (e.g., "5c52e11203aa677f33e493fb"). Required. -#' @param symbol Character string; the trading pair symbol (e.g., "BTC-USDT"). Required. -#' @return Promise resolving to a `data.table` with one row containing order details, including: -#' - `id` (character): Unique order ID. -#' - `clientOid` (character): Client-assigned order ID. -#' - `symbol` (character): Trading pair. -#' - `opType` (character): Operation type. -#' - `type` (character): Order type ("limit" or "market"). -#' - `side` (character): Order side ("buy" or "sell"). -#' - `price` (character): Order price. -#' - `size` (character): Order size. -#' - `funds` (character): Order funds. -#' - `dealSize` (character): Filled quantity. -#' - `dealFunds` (character): Filled funds. -#' - `cancelledSize` (character): Canceled quantity. -#' - `cancelledFunds` (character): Canceled funds. -#' - `remainSize` (character): Remaining quantity. -#' - `remainFunds` (character): Remaining funds. -#' - `fee` (character): Handling fees. -#' - `feeCurrency` (character): Fee currency. -#' - `stp` (character or NA): Self Trade Prevention strategy. -#' - `timeInForce` (character): Time in force. -#' - `postOnly` (logical): Post-only flag. -#' - `hidden` (logical): Hidden order flag. -#' - `iceberg` (logical): Iceberg order flag. -#' - `visibleSize` (character): Visible size for iceberg orders. -#' - `cancelAfter` (integer): Seconds until cancellation for GTT. -#' - `channel` (character): Order channel. -#' - `remark` (character or NA): Order remarks. -#' - `tags` (character or NA): Order tags. -#' - `cancelExist` (logical): Indicates a cancellation record. -#' - `tradeType` (character): Trade type. -#' - `inOrderBook` (logical): Whether in the order book. -#' - `active` (logical): Order status (true = active, false = done). -#' - `tax` (character): Tax information. -#' - `createdAt` (integer): Creation timestamp (milliseconds). -#' - `lastUpdatedAt` (integer): Last update timestamp (milliseconds). -#' - `createdAtDatetime` (POSIXct): Creation time in UTC. -#' - `lastUpdatedAtDatetime` (POSIXct): Last update time in UTC. -#' @examples -#' \dontrun{ -#' library(coro) -#' library(data.table) -#' -#' main_async <- coro::async(function() { -#' # Retrieve order details by clientOid -#' order_details <- await(get_order_by_client_oid_impl( -#' clientOid = "5c52e11203aa677f33e493fb", -#' symbol = "BTC-USDT" -#' )) -#' print(order_details) -#' }) -#' -#' # Run the async function -#' main_async() -#' while (!later::loop_empty()) later::run_now() -#' } -#' -#' # Expected Output (simplified): -#' # id clientOid symbol opType type side price size ... createdAtDatetime lastUpdatedAtDatetime -#' # 1: 6717422bd51c29000775ea03 5c52e11203aa677f33e493fb BTC-USDT DEAL limit buy 70000 0.00001 ... 2023-10-22 03:31:55 2023-10-22 03:31:55 -#' @importFrom coro async await -#' @importFrom data.table rbindlist data.table -#' @importFrom httr GET timeout -#' @importFrom rlang abort -#' @export -get_order_by_client_oid_impl <- coro::async(function( - keys = get_api_keys(), - base_url = get_base_url(), - clientOid, - symbol -) { - tryCatch({ - # Validate parameters - if (is.null(clientOid) || !is.character(clientOid) || nchar(clientOid) == 0) { - rlang::abort("Parameter 'clientOid' must be a non-empty string.") - } - if (is.null(symbol) || !verify_symbol(symbol)) { - rlang::abort("Parameter 'symbol' must be a valid ticker (e.g., 'BTC-USDT').") - } - - # Construct endpoint and query string - endpoint <- paste0("/api/v1/hf/orders/client-order/", clientOid) - query_params <- list(symbol = symbol) - query_string <- build_query(query_params) - endpoint_with_query <- paste0(endpoint, query_string) - full_url <- paste0(base_url, endpoint_with_query) - - # Generate authentication headers - headers <- await(build_headers("GET", endpoint_with_query, NULL, keys)) - - # Send GET request - response <- httr::GET( - url = full_url, - headers, - httr::timeout(3) - ) - - # Process response - parsed_response <- process_kucoin_response(response, full_url) - if (parsed_response$code != "200000") { - rlang::abort(sprintf("API error: %s - %s", parsed_response$code, parsed_response$msg)) - } - - # Convert response data to data.table - order_details <- data.table::rbindlist(list(parsed_response$data), fill = TRUE) - - # Add datetime columns from millisecond timestamps - order_details[, createdAtDatetime := time_convert_from_kucoin(createdAt, unit = "ms")] - order_details[, lastUpdatedAtDatetime := time_convert_from_kucoin(lastUpdatedAt, unit = "ms")] - - return(order_details) - }, error = function(e) { - rlang::abort(sprintf("Error in get_order_by_client_oid_impl: %s", conditionMessage(e))) - }) -}) - -# ./impl_spottrading_orders_get_trade_history.R - -# File: ./R/impl_spottrading_orders_get_trade_history.R - -# box::use( -# ./helpers_api[process_kucoin_response, build_headers], -# ./utils[build_query, get_base_url, verify_symbol, get_api_keys], -# ./utils_time_convert_kucoin[time_convert_from_kucoin], -# coro[async, await], -# data.table[rbindlist, data.table], -# httr[GET, timeout], -# rlang[abort], -# purrr[map_dfr] -# ) - -#' Get Trade History (Implementation) -#' -#' Retrieves a list of the latest spot transaction details (fills) for a specified symbol or orderId from the KuCoin Spot trading system asynchronously. -#' This function returns a `data.table` with detailed information about each fill, sorted by the latest update time in descending order. -#' -#' ## Description -#' This endpoint fetches the latest transaction details (fills) for a given trading pair or specific order. The data is sorted in descending order based on the update time of the order. -#' If `orderId` is provided, it overrides other query parameters except for `lastId`, `limit`, `startAt`, and `endAt`. -#' -#' ## Workflow -#' 1. **Parameter Validation**: Ensures `symbol` is a valid trading pair if `orderId` is not provided. Validates optional parameters. -#' 2. **Request Construction**: Builds the endpoint URL with query parameters. -#' 3. **Authentication**: Generates private API headers using `build_headers()` with the GET method and endpoint. -#' 4. **API Request**: Sends a GET request to the KuCoin API with a 3-second timeout. -#' 5. **Response Processing**: Parses the response, converts the `items` array to a `data.table`, and adds a `createdAtDatetime` column. -#' -#' ## API Details -#' - **Endpoint**: `GET https://api.kucoin.com/api/v1/hf/fills` -#' - **Domain**: Spot -#' - **API Channel**: Private -#' - **API Permission**: General -#' - **Rate Limit Pool**: Spot -#' - **Rate Limit Weight**: 2 -#' - **SDK Service**: Spot -#' - **SDK Sub-Service**: Order -#' - **SDK Method Name**: getTradeHistory -#' - **Official Documentation**: [KuCoin Get Trade History](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-trade-history) -#' -#' ## Request -#' ### Query Parameters -#' - `symbol`: String (required if `orderId` is not provided) - The trading pair symbol (e.g., "BTC-USDT"). -#' - `orderId`: String (optional) - The unique order ID. If provided, other parameters (except `lastId`, `limit`, `startAt`, `endAt`) are ignored. -#' - `side`: Enum (optional) - Order side: "buy" or "sell". -#' - `type`: Enum (optional) - Order type: "limit" or "market". -#' - `lastId`: Integer (optional) - The ID of the last fill from the previous batch for pagination. -#' - `limit`: Integer (optional) - Number of fills per page (1 to 100, default 20). -#' - `startAt`: Integer (optional) - Start time in milliseconds. -#' - `endAt`: Integer (optional) - End time in milliseconds. -#' -#' ### Example Request -#' ```bash -#' curl --location --request GET 'https://api.kucoin.com/api/v1/hf/fills?symbol=BTC-USDT&limit=100&startAt=1728663338000&endAt=1728692138000' -#' ``` -#' -#' ## Response -#' ### HTTP Code: 200 -#' - **Content Type**: `application/json` -#' -#' ### Data Schema -#' - `code`: String (required) - Response code ("200000" indicates success). -#' - `data`: Object (required) - Contains: -#' - `lastId`: Integer (required) - The ID of the last fill in the current batch. -#' - `items`: Array of objects (required) - List of fill details, each with: -#' - `id`: Integer - Fill ID. -#' - `orderId`: String - Order ID. -#' - `counterOrderId`: String - Counterparty order ID. -#' - `tradeId`: Integer - Trade ID. -#' - `symbol`: String - Trading pair. -#' - `side`: Enum - "buy" or "sell". -#' - `liquidity`: Enum - "taker" or "maker". -#' - `type`: Enum - "limit" or "market". -#' - `forceTaker`: Boolean - Whether the order was forced to take liquidity. -#' - `price`: String - Fill price. -#' - `size`: String - Fill size. -#' - `funds`: String - Funds involved in the fill. -#' - `fee`: String - Handling fees. -#' - `feeRate`: String - Fee rate. -#' - `feeCurrency`: String - Fee currency. -#' - `stop`: String - Stop type (currently empty for HFT). -#' - `tradeType`: String - Trade type. -#' - `taxRate`: String - Tax rate. -#' - `tax`: String - Tax amount. -#' - `createdAt`: Integer - Fill timestamp in milliseconds. -#' -#' ### JSON Response Example -#' ```json -#' { -#' "code": "200000", -#' "data": { -#' "items": [ -#' { -#' "id": 19814995255305, -#' "orderId": "6717422bd51c29000775ea03", -#' "counterOrderId": "67174228135f9e000709da8c", -#' "tradeId": 11029373945659392, -#' "symbol": "BTC-USDT", -#' "side": "buy", -#' "liquidity": "taker", -#' "type": "limit", -#' "forceTaker": false, -#' "price": "67717.6", -#' "size": "0.00001", -#' "funds": "0.677176", -#' "fee": "0.000677176", -#' "feeRate": "0.001", -#' "feeCurrency": "USDT", -#' "stop": "", -#' "tradeType": "TRADE", -#' "taxRate": "0", -#' "tax": "0", -#' "createdAt": 1729577515473 -#' } -#' ], -#' "lastId": 19814995255305 -#' } -#' } -#' ``` -#' -#' @param keys List; API configuration parameters from `get_api_keys()`. Defaults to `get_api_keys()`. -#' @param base_url Character string; base URL for the KuCoin API. Defaults to `get_base_url()`. -#' @param symbol Character string; the trading pair symbol (e.g., "BTC-USDT"). Required if `orderId` is not provided. -#' @param orderId Character string; the unique order ID. If provided, other parameters are ignored except for pagination and time filters. -#' @param side Character string; optional filter for order side: "buy" or "sell". -#' @param type Character string; optional filter for order type: "limit" or "market". -#' @param lastId Integer; optional ID of the last fill for pagination. -#' @param limit Integer; number of fills to return per request (1–100, default 20). -#' @param startAt Integer; optional start time in milliseconds. -#' @param endAt Integer; optional end time in milliseconds. -#' @return Promise resolving to a `data.table` with columns corresponding to the fill fields, including: -#' - `id` (integer): Fill ID. -#' - `orderId` (character): Order ID. -#' - `counterOrderId` (character): Counterparty order ID. -#' - `tradeId` (integer): Trade ID. -#' - `symbol` (character): Trading pair. -#' - `side` (character): "buy" or "sell". -#' - `liquidity` (character): "taker" or "maker". -#' - `type` (character): "limit" or "market". -#' - `forceTaker` (logical): Whether forced to take liquidity. -#' - `price` (character): Fill price. -#' - `size` (character): Fill size. -#' - `funds` (character): Funds involved. -#' - `fee` (character): Handling fees. -#' - `feeRate` (character): Fee rate. -#' - `feeCurrency` (character): Fee currency. -#' - `stop` (character): Stop type. -#' - `tradeType` (character): Trade type. -#' - `taxRate` (character): Tax rate. -#' - `tax` (character): Tax amount. -#' - `createdAt` (integer): Fill timestamp (milliseconds). -#' - `createdAtDatetime` (POSIXct): Fill time in UTC. -#' @examples -#' \dontrun{ -#' library(coro) -#' library(data.table) -#' -#' main_async <- coro::async(function() { -#' # Retrieve trade history for BTC-USDT -#' trade_history <- await(get_trade_history_impl( -#' symbol = "BTC-USDT", -#' limit = 50 -#' )) -#' print(trade_history) -#' }) -#' -#' # Run the async function -#' main_async() -#' while (!later::loop_empty()) later::run_now() -#' } -#' @importFrom coro async await -#' @importFrom data.table rbindlist data.table -#' @importFrom httr GET timeout -#' @importFrom rlang abort -#' @export -get_trade_history_impl <- coro::async(function( - keys = get_api_keys(), - base_url = get_base_url(), - symbol = NULL, - orderId = NULL, - side = NULL, - type = NULL, - lastId = NULL, - limit = 20, - startAt = NULL, - endAt = NULL -) { - tryCatch({ - # Validate parameters - if (is.null(orderId)) { - if (is.null(symbol) || !verify_symbol(symbol)) { - rlang::abort("Parameter 'symbol' must be a valid ticker (e.g., 'BTC-USDT') when 'orderId' is not provided.") - } - } - if (!is.null(limit) && (!is.integer(limit) || limit < 1 || limit > 100)) { - rlang::abort("Parameter 'limit' must be an integer between 1 and 100.") - } - - # Construct query parameters - query_params <- list() - if (!is.null(orderId)) { - query_params$orderId <- orderId - } else { - query_params$symbol <- symbol - if (!is.null(side)) query_params$side <- side - if (!is.null(type)) query_params$type <- type - } - if (!is.null(lastId)) query_params$lastId <- lastId - if (!is.null(limit)) query_params$limit <- limit - if (!is.null(startAt)) query_params$startAt <- startAt - if (!is.null(endAt)) query_params$endAt <- endAt - - # Build query string - query_string <- build_query(query_params) - endpoint <- "/api/v1/hf/fills" - full_url <- paste0(base_url, endpoint, query_string) - - # Generate authentication headers - headers <- await(build_headers("GET", endpoint, query_string, keys)) - - # Send GET request - response <- httr::GET( - url = full_url, - headers, - httr::timeout(3) - ) - - # Process response - parsed_response <- process_kucoin_response(response, full_url) - if (parsed_response$code != "200000") { - rlang::abort(sprintf("API error: %s - %s", parsed_response$code, parsed_response$msg)) - } - - # Convert response data to data.table - if (length(parsed_response$data$items) == 0) { - fills_dt <- data.table::data.table( - id = integer(), - orderId = character(), - counterOrderId = character(), - tradeId = integer(), - symbol = character(), - side = character(), - liquidity = character(), - type = character(), - forceTaker = logical(), - price = character(), - size = character(), - funds = character(), - fee = character(), - feeRate = character(), - feeCurrency = character(), - stop = character(), - tradeType = character(), - taxRate = character(), - tax = character(), - createdAt = integer(), - createdAtDatetime = as.POSIXct(character()) - ) - } else { - fills_dt <- data.table::rbindlist(parsed_response$data$items, fill = TRUE) - fills_dt[, createdAtDatetime := time_convert_from_kucoin(createdAt, unit = "ms")] - } - - return(fills_dt) - }, error = function(e) { - rlang::abort(sprintf("Error in get_trade_history_impl: %s", conditionMessage(e))) - }) -}) - -# ./impl_spottrading_orders_get_x.R - -# File: ./R/impl_spottrading_orders_get_x.R - -# box::use( -# ./helpers_api[process_kucoin_response, build_headers], -# ./utils[get_base_url, verify_symbol, get_api_keys], -# coro[async, await], -# data.table[rbindlist, data.table], -# httr[GET, timeout], -# rlang[abort] -# ) - -#' Get Symbols With Open Order (Implementation) -#' -#' Retrieves a list of spot trading symbols with active orders from the KuCoin Spot trading system asynchronously. -#' This function returns a `data.table` containing the symbols that currently have open orders. -#' -#' ## Description -#' This endpoint queries all trading pair symbols (e.g., "BTC-USDT", "ETH-USDT") that have active orders for the authenticated account. -#' An active order is one that is currently in the order book and has not been fully filled or canceled. -#' This is useful for monitoring which markets have ongoing trading activity for the user. -#' -#' ## Workflow -#' 1. **Request Construction**: Builds the endpoint URL with no additional parameters since none are required. -#' 2. **Authentication**: Generates private API headers using `build_headers()` with the GET method and endpoint. -#' 3. **API Request**: Sends a GET request to the KuCoin API with a 3-second timeout. -#' 4. **Response Processing**: Parses the response and converts the `symbols` array within the `data` object to a `data.table`. -#' -#' ## API Details -#' - **Endpoint**: `GET https://api.kucoin.com/api/v1/hf/orders/active/symbols` -#' - **Domain**: Spot -#' - **API Channel**: Private -#' - **API Permission**: Spot -#' - **Rate Limit Pool**: Spot -#' - **Rate Limit Weight**: 2 -#' - **SDK Service**: Spot -#' - **SDK Sub-Service**: Order -#' - **SDK Method Name**: getSymbolsWithOpenOrder -#' - **Official Documentation**: [KuCoin Get Symbols With Open Order](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-symbols-with-open-order) -#' -#' ## Request -#' ### Path Parameters -#' - None -#' -#' ### Query Parameters -#' - None -#' -#' ### Example Request -#' ```bash -#' curl --location --request GET 'https://api.kucoin.com/api/v1/hf/orders/active/symbols' -#' ``` -#' -#' ## Response -#' ### HTTP Code: 200 -#' - **Content Type**: `application/json` -#' -#' ### Data Schema -#' - `code`: String (required) - Response code ("200000" indicates success). -#' - `data`: Object (required) - Contains the following field: -#' - `symbols`: Array[String] (required) - List of trading pair symbols with active orders (e.g., "ETH-USDT", "BTC-USDT"). -#' -#' ### JSON Response Example -#' ```json -#' { -#' "code": "200000", -#' "data": { -#' "symbols": [ -#' "ETH-USDT", -#' "BTC-USDT" -#' ] -#' } -#' } -#' ``` -#' -#' @param keys List; API configuration parameters from `get_api_keys()`. Defaults to `get_api_keys()`. -#' @param base_url Character string; base URL for the KuCoin API. Defaults to `get_base_url()`. -#' @return Promise resolving to a `data.table` with one column: -#' - `symbols` (character): Vector of trading pair symbols with active orders. -#' @examples -#' \dontrun{ -#' library(coro) -#' library(data.table) -#' -#' main_async <- coro::async(function() { -#' # Retrieve symbols with open orders -#' active_symbols <- await(get_symbols_with_open_order_impl()) -#' print(active_symbols) -#' }) -#' -#' # Run the async function -#' main_async() -#' while (!later::loop_empty()) later::run_now() -#' } -#' -#' # Expected Output (example): -#' # symbols -#' # 1: ETH-USDT -#' # 2: BTC-USDT -#' @importFrom coro async await -#' @importFrom data.table data.table -#' @importFrom httr GET timeout -#' @importFrom rlang abort -#' @export -get_symbols_with_open_order_impl <- coro::async(function( - keys = get_api_keys(), - base_url = get_base_url() -) { - tryCatch({ - # Construct endpoint - endpoint <- "/api/v1/hf/orders/active/symbols" - full_url <- paste0(base_url, endpoint) - - # Generate authentication headers - headers <- await(build_headers("GET", endpoint, NULL, keys)) - - # Send GET request - response <- httr::GET( - url = full_url, - headers, - httr::timeout(3) - ) - - # Process response - parsed_response <- process_kucoin_response(response, full_url) - if (parsed_response$code != "200000") { - rlang::abort(sprintf("API error: %s - %s", parsed_response$code, parsed_response$msg)) - } - - # Convert response data to data.table - # If no symbols, return an empty data.table with the correct column - if (length(parsed_response$data$symbols) == 0) { - result_dt <- data.table::data.table(symbols = character()) - } else { - result_dt <- data.table::data.table(symbols = parsed_response$data$symbols) - } - - return(result_dt) - }, error = function(e) { - rlang::abort(sprintf("Error in get_symbols_with_open_order_impl: %s", conditionMessage(e))) - }) -}) - -#' Get Open Orders (Implementation) -#' -#' Retrieves all active spot orders for a specified symbol from the KuCoin Spot trading system asynchronously. -#' This function returns a `data.table` with detailed information about each active order, sorted by the latest update time in descending order. -#' -#' ## Description -#' This endpoint fetches all active orders for a given trading pair (e.g., "BTC-USDT"). Active orders are those currently in the order book and not fully filled or canceled. -#' The orders are returned in descending order based on their last update time. -#' -#' ## Workflow -#' 1. **Parameter Validation**: Ensures `symbol` is a non-empty string and a valid trading pair. -#' 2. **Request Construction**: Builds the endpoint URL with `symbol` as a query parameter. -#' 3. **Authentication**: Generates private API headers using `build_headers()` with the GET method and endpoint. -#' 4. **API Request**: Sends a GET request to the KuCoin API with a 3-second timeout. -#' 5. **Response Processing**: Parses the response, converts the array of orders to a `data.table`, and adds `createdAtDatetime` and `lastUpdatedAtDatetime` columns. -#' -#' ## API Details -#' - **Endpoint**: `GET https://api.kucoin.com/api/v1/hf/orders/active?symbol={symbol}` -#' - **Domain**: Spot -#' - **API Channel**: Private -#' - **API Permission**: General -#' - **Rate Limit Pool**: Spot -#' - **Rate Limit Weight**: 2 -#' - **SDK Service**: Spot -#' - **SDK Sub-Service**: Order -#' - **SDK Method Name**: getOpenOrders -#' - **Official Documentation**: [KuCoin Get Open Orders](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-open-orders) -#' -#' ## Request -#' ### Query Parameters -#' - `symbol`: String (required) - The trading pair symbol (e.g., "BTC-USDT"). -#' -#' ### Example Request -#' ```bash -#' curl --location --request GET 'https://api.kucoin.com/api/v1/hf/orders/active?symbol=BTC-USDT' -#' ``` -#' -#' ## Response -#' ### HTTP Code: 200 -#' - **Content Type**: `application/json` -#' -#' ### Data Schema -#' - `code`: String (required) - Response code ("200000" indicates success). -#' - `data`: Array of objects (required) - List of active orders, each with fields such as: -#' - `id`: String - Unique order ID. -#' - `clientOid`: String - Client-assigned order ID. -#' - `symbol`: String - Trading pair. -#' - `opType`: String - Operation type. -#' - `type`: Enum - Order type: "limit" or "market". -#' - `side`: Enum - Order side: "buy" or "sell". -#' - `price`: String - Order price. -#' - `size`: String - Order size. -#' - `funds`: String - Order funds. -#' - `dealSize`: String - Filled quantity. -#' - `dealFunds`: String - Filled funds. -#' - `cancelledSize`: String - Canceled quantity. -#' - `cancelledFunds`: String - Canceled funds. -#' - `remainSize`: String - Remaining quantity. -#' - `remainFunds`: String - Remaining funds. -#' - `fee`: String - Handling fees. -#' - `feeCurrency`: String - Fee currency. -#' - `stp`: Enum - Self Trade Prevention: "DC", "CO", "CN", "CB" or null. -#' - `timeInForce`: Enum - Time in force: "GTC", "GTT", "IOC", "FOK". -#' - `postOnly`: Boolean - Post-only flag. -#' - `hidden`: Boolean - Hidden order flag. -#' - `iceberg`: Boolean - Iceberg order flag. -#' - `visibleSize`: String - Visible size for iceberg orders. -#' - `cancelAfter`: Integer - Seconds until cancellation for GTT. -#' - `channel`: String - Order channel. -#' - `remark`: String or null - Order remarks. -#' - `tags`: String or null - Order tags. -#' - `cancelExist`: Boolean - Indicates a cancellation record. -#' - `tradeType`: String - Trade type. -#' - `inOrderBook`: Boolean - Whether in the order book. -#' - `tax`: String - Tax information. -#' - `active`: Boolean - Order status (true = active). -#' - `createdAt`: Integer - Creation timestamp in milliseconds. -#' - `lastUpdatedAt`: Integer - Last update timestamp in milliseconds. -#' -#' ### JSON Response Example -#' ```json -#' { -#' "code": "200000", -#' "data": [ -#' { -#' "id": "67120bbef094e200070976f6", -#' "clientOid": "5c52e11203aa677f33e493fb", -#' "symbol": "BTC-USDT", -#' "opType": "DEAL", -#' "type": "limit", -#' "side": "buy", -#' "price": "50000", -#' "size": "0.00001", -#' "funds": "0.5", -#' "dealSize": "0", -#' "dealFunds": "0", -#' "fee": "0", -#' "feeCurrency": "USDT", -#' "stp": null, -#' "timeInForce": "GTC", -#' "postOnly": false, -#' "hidden": false, -#' "iceberg": false, -#' "visibleSize": "0", -#' "cancelAfter": 0, -#' "channel": "API", -#' "remark": "order remarks", -#' "tags": "order tags", -#' "cancelExist": false, -#' "tradeType": "TRADE", -#' "inOrderBook": true, -#' "cancelledSize": "0", -#' "cancelledFunds": "0", -#' "remainSize": "0.00001", -#' "remainFunds": "0.5", -#' "tax": "0", -#' "active": true, -#' "createdAt": 1729235902748, -#' "lastUpdatedAt": 1729235909862 -#' } -#' ] -#' } -#' ``` -#' -#' @param keys List; API configuration parameters from `get_api_keys()`. Defaults to `get_api_keys()`. -#' @param base_url Character string; base URL for the KuCoin API. Defaults to `get_base_url()`. -#' @param symbol Character string; the trading pair symbol (e.g., "BTC-USDT"). Required. -#' @return Promise resolving to a `data.table` with columns corresponding to the order fields, including: -#' - `id` (character): Unique order ID. -#' - `clientOid` (character): Client-assigned order ID. -#' - `symbol` (character): Trading pair. -#' - `opType` (character): Operation type. -#' - `type` (character): Order type ("limit" or "market"). -#' - `side` (character): Order side ("buy" or "sell"). -#' - `price` (character): Order price. -#' - `size` (character): Order size. -#' - `funds` (character): Order funds. -#' - `dealSize` (character): Filled quantity. -#' - `dealFunds` (character): Filled funds. -#' - `cancelledSize` (character): Canceled quantity. -#' - `cancelledFunds` (character): Canceled funds. -#' - `remainSize` (character): Remaining quantity. -#' - `remainFunds` (character): Remaining funds. -#' - `fee` (character): Handling fees. -#' - `feeCurrency` (character): Fee currency. -#' - `stp` (character or NA): Self Trade Prevention strategy. -#' - `timeInForce` (character): Time in force. -#' - `postOnly` (logical): Post-only flag. -#' - `hidden` (logical): Hidden order flag. -#' - `iceberg` (logical): Iceberg order flag. -#' - `visibleSize` (character): Visible size for iceberg orders. -#' - `cancelAfter` (integer): Seconds until cancellation for GTT. -#' - `channel` (character): Order channel. -#' - `remark` (character or NA): Order remarks. -#' - `tags` (character or NA): Order tags. -#' - `cancelExist` (logical): Indicates a cancellation record. -#' - `tradeType` (character): Trade type. -#' - `inOrderBook` (logical): Whether in the order book. -#' - `tax` (character): Tax information. -#' - `active` (logical): Order status (true = active). -#' - `createdAt` (integer): Creation timestamp (milliseconds). -#' - `lastUpdatedAt` (integer): Last update timestamp (milliseconds). -#' - `createdAtDatetime` (POSIXct): Creation time in UTC. -#' - `lastUpdatedAtDatetime` (POSIXct): Last update time in UTC. -#' @examples -#' \dontrun{ -#' library(coro) -#' library(data.table) -#' -#' main_async <- coro::async(function() { -#' # Retrieve open orders for BTC-USDT -#' open_orders <- await(get_open_orders_impl(symbol = "BTC-USDT")) -#' print(open_orders) -#' }) -#' -#' # Run the async function -#' main_async() -#' while (!later::loop_empty()) later::run_now() -#' } -#' @importFrom coro async await -#' @importFrom data.table data.table rbindlist -#' @importFrom httr GET timeout -#' @importFrom rlang abort -#' @export -get_open_orders_impl <- coro::async(function( - keys = get_api_keys(), - base_url = get_base_url(), - symbol -) { - tryCatch({ - # Validate parameters - if (is.null(symbol) || !is.character(symbol) || nchar(symbol) == 0) { - rlang::abort("Parameter 'symbol' must be a non-empty string (e.g., 'BTC-USDT').") - } - if (!verify_symbol(symbol)) { - rlang::abort("Parameter 'symbol' must be a valid trading pair (e.g., 'BTC-USDT').") - } - - # Construct endpoint and query string - endpoint <- "/api/v1/hf/orders/active" - query_params <- list(symbol = symbol) - query_string <- build_query(query_params) - endpoint_with_query <- paste0(endpoint, query_string) - full_url <- paste0(base_url, endpoint_with_query) - - # Generate authentication headers - headers <- await(build_headers("GET", endpoint_with_query, NULL, keys)) - - # Send GET request - response <- httr::GET( - url = full_url, - headers, - httr::timeout(3) - ) - - # Process response - parsed_response <- process_kucoin_response(response, full_url) - if (parsed_response$code != "200000") { - rlang::abort(sprintf("API error: %s - %s", parsed_response$code, parsed_response$msg)) - } - - # Convert response data to data.table - if (length(parsed_response$data) == 0) { - # Define empty data.table with expected columns - order_details <- data.table::data.table( - id = character(), - clientOid = character(), - symbol = character(), - opType = character(), - type = character(), - side = character(), - price = character(), - size = character(), - funds = character(), - dealSize = character(), - dealFunds = character(), - cancelledSize = character(), - cancelledFunds = character(), - remainSize = character(), - remainFunds = character(), - fee = character(), - feeCurrency = character(), - stp = character(), - timeInForce = character(), - postOnly = logical(), - hidden = logical(), - iceberg = logical(), - visibleSize = character(), - cancelAfter = integer(), - channel = character(), - remark = character(), - tags = character(), - cancelExist = logical(), - tradeType = character(), - inOrderBook = logical(), - tax = character(), - active = logical(), - createdAt = integer(), - lastUpdatedAt = integer(), - createdAtDatetime = as.POSIXct(character()), - lastUpdatedAtDatetime = as.POSIXct(character()) - ) - } else { - order_details <- data.table::rbindlist(parsed_response$data, fill = TRUE) - # Add datetime columns - order_details[, createdAtDatetime := time_convert_from_kucoin(createdAt, unit = "ms")] - order_details[, lastUpdatedAtDatetime := time_convert_from_kucoin(lastUpdatedAt, unit = "ms")] - } - - return(order_details) - }, error = function(e) { - rlang::abort(sprintf("Error in get_open_orders_impl: %s", conditionMessage(e))) - }) -}) - -#' Get Closed Orders (Implementation) -#' -#' Retrieves all closed spot orders for a specified symbol from the KuCoin Spot trading system asynchronously. -#' This function supports pagination and returns a `data.table` with detailed information about each closed order, -#' sorted by the latest update time in descending order. -#' -#' ## Description -#' This endpoint fetches all closed orders (canceled or fully filled) for a given trading pair (e.g., "BTC-USDT"). -#' The orders are returned in descending order based on their last update time. The function handles pagination -#' using the `lastId` parameter to fetch multiple pages of results, with data availability limited to the last -#' 72 hours by default if no time range is specified beyond that period. -#' -#' ## Workflow -#' 1. **Parameter Validation**: Ensures `symbol` is a valid trading pair and `limit` is an integer between 1 and 100. -#' 2. **Request Construction**: Builds the API endpoint with query parameters including `symbol`, `side`, `type`, `startAt`, `endAt`, and `limit`. -#' 3. **Authentication**: Generates private API headers using `build_headers()` with the GET method and endpoint. -#' 4. **API Request**: Sends asynchronous GET requests to fetch pages of closed orders until no more orders are returned or `max_pages` is reached. -#' 5. **Response Processing**: Combines the fetched orders into a single `data.table` and adds `createdAtDatetime` and `lastUpdatedAtDatetime` columns using `time_convert_from_kucoin()`. -#' -#' ## API Details -#' - **Endpoint**: `GET https://api.kucoin.com/api/v1/hf/orders/done` -#' - **Domain**: Spot -#' - **API Channel**: Private -#' - **API Permission**: General -#' - **Rate Limit Pool**: Spot -#' - **Rate Limit Weight**: 2 -#' - **SDK Service**: Spot -#' - **SDK Sub-Service**: Order -#' - **SDK Method Name**: getClosedOrders -#' - **Official Documentation**: [KuCoin Get Closed Orders](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-closed-orders) -#' -#' ## Request -#' ### Query Parameters -#' - `symbol`: String (required) - The trading pair symbol (e.g., "BTC-USDT"). -#' - `side`: Enum (optional) - Order side: "buy" or "sell". -#' - `type`: Enum (optional) - Order type: "limit" or "market". -#' - `lastId`: Integer (optional) - The ID of the last order from the previous batch for pagination. -#' - `limit`: Integer (optional) - Number of orders per page (default 20, max 100). -#' - `startAt`: Integer (optional) - Start time in milliseconds. -#' - `endAt`: Integer (optional) - End time in milliseconds. -#' -#' ### Example Request -#' ```bash -#' curl --location --request GET 'https://api.kucoin.com/api/v1/hf/orders/done?symbol=BTC-USDT&side=buy&type=limit&lastId=254062248624417&limit=20&startAt=1728663338000&endAt=1728692138000' -#' ``` -#' -#' ## Response -#' ### HTTP Code: 200 -#' - **Content Type**: `application/json` -#' -#' ### Data Schema -#' - `code`: String (required) - Response code ("200000" indicates success). -#' - `data`: Object (required) - Contains: -#' - `lastId`: Integer (required) - The ID for the next page of data. -#' - `items`: Array of objects (required) - List of closed orders, each with fields: -#' - `id`: String - Unique order ID. -#' - `clientOid`: String - Client-assigned order ID. -#' - `symbol`: String - Trading pair. -#' - `opType`: String - Operation type. -#' - `type`: Enum - Order type: "limit" or "market". -#' - `side`: Enum - Order side: "buy" or "sell". -#' - `price`: String - Order price. -#' - `size`: String - Order size. -#' - `funds`: String - Order funds. -#' - `dealSize`: String - Filled quantity. -#' - `dealFunds`: String - Filled funds. -#' - `remainSize`: String - Remaining quantity. -#' - `remainFunds`: String - Remaining funds. -#' - `cancelledSize`: String - Canceled quantity. -#' - `cancelledFunds`: String - Canceled funds. -#' - `fee`: String - Handling fees. -#' - `feeCurrency`: String - Fee currency. -#' - `stp`: Enum - Self Trade Prevention: "DC", "CO", "CN", "CB" or NA. -#' - `timeInForce`: Enum - Time in force: "GTC", "GTT", "IOC", "FOK". -#' - `postOnly`: Boolean - Post-only flag. -#' - `hidden`: Boolean - Hidden order flag. -#' - `iceberg`: Boolean - Iceberg order flag. -#' - `visibleSize`: String - Visible size for iceberg orders. -#' - `cancelAfter`: Integer - Seconds until cancellation for GTT. -#' - `channel`: String - Order channel. -#' - `remark`: String or NA - Order remarks. -#' - `tags`: String or NA - Order tags. -#' - `cancelExist`: Boolean - Indicates a cancellation record. -#' - `tradeType`: String - Trade type. -#' - `inOrderBook`: Boolean - Whether in the order book. -#' - `tax`: String - Tax information. -#' - `active`: Boolean - Order status (false for closed orders). -#' - `createdAt`: Integer - Creation timestamp in milliseconds. -#' - `lastUpdatedAt`: Integer - Last update timestamp in milliseconds. -#' -#' ### JSON Response Example -#' ```json -#' { -#' "code": "200000", -#' "data": { -#' "lastId": 19814995255305, -#' "items": [ -#' { -#' "id": "6717422bd51c29000775ea03", -#' "clientOid": "5c52e11203aa677f33e493fb", -#' "symbol": "BTC-USDT", -#' "opType": "DEAL", -#' "type": "limit", -#' "side": "buy", -#' "price": "70000", -#' "size": "0.00001", -#' "funds": "0.7", -#' "dealSize": "0.00001", -#' "dealFunds": "0.677176", -#' "remainSize": "0", -#' "remainFunds": "0.022824", -#' "cancelledSize": "0", -#' "cancelledFunds": "0", -#' "fee": "0.000677176", -#' "feeCurrency": "USDT", -#' "stp": null, -#' "timeInForce": "GTC", -#' "postOnly": false, -#' "hidden": false, -#' "iceberg": false, -#' "visibleSize": "0", -#' "cancelAfter": 0, -#' "channel": "API", -#' "remark": "order remarks", -#' "tags": null, -#' "cancelExist": false, -#' "tradeType": "TRADE", -#' "inOrderBook": false, -#' "active": false, -#' "tax": "0", -#' "createdAt": 1729577515444, -#' "lastUpdatedAt": 1729577515481 -#' } -#' ] -#' } -#' } -#' ``` -#' -#' @param keys List; API configuration parameters from `get_api_keys()`. Defaults to `get_api_keys()`. -#' @param base_url Character string; base URL for the KuCoin API. Defaults to `get_base_url()`. -#' @param symbol Character string; the trading pair symbol (e.g., "BTC-USDT"). Required. -#' @param side Character string; optional filter for order side: "buy" or "sell". -#' @param type Character string; optional filter for order type: "limit" or "market". -#' @param startAt Numeric; optional start time in milliseconds. -#' @param endAt Numeric; optional end time in milliseconds. -#' @param limit Integer; number of orders per page (1 to 100, default 20). -#' @param max_pages Numeric; maximum number of pages to fetch (default `Inf`). -#' @return Promise resolving to a `data.table` with columns: -#' - `id` (character): Unique order ID. -#' - `clientOid` (character): Client-assigned order ID. -#' - `symbol` (character): Trading pair. -#' - `opType` (character): Operation type. -#' - `type` (character): Order type ("limit" or "market"). -#' - `side` (character): Order side ("buy" or "sell"). -#' - `price` (character): Order price. -#' - `size` (character): Order size. -#' - `funds` (character): Order funds. -#' - `dealSize` (character): Filled quantity. -#' - `dealFunds` (character): Filled funds. -#' - `remainSize` (character): Remaining quantity. -#' - `remainFunds` (character): Remaining funds. -#' - `cancelledSize` (character): Canceled quantity. -#' - `cancelledFunds` (character): Canceled funds. -#' - `fee` (character): Handling fees. -#' - `feeCurrency` (character): Fee currency. -#' - `stp` (character or NA): Self Trade Prevention strategy. -#' - `timeInForce` (character): Time in force. -#' - `postOnly` (logical): Post-only flag. -#' - `hidden` (logical): Hidden order flag. -#' - `iceberg` (logical): Iceberg order flag. -#' - `visibleSize` (character): Visible size for iceberg orders. -#' - `cancelAfter` (integer): Seconds until cancellation for GTT. -#' - `channel` (character): Order channel. -#' - `remark` (character or NA): Order remarks. -#' - `tags` (character or NA): Order tags. -#' - `cancelExist` (logical): Indicates a cancellation record. -#' - `tradeType` (character): Trade type. -#' - `inOrderBook` (logical): Whether in the order book. -#' - `tax` (character): Tax information. -#' - `active` (logical): Order status (false for closed orders). -#' - `createdAt` (numeric): Creation timestamp (milliseconds). -#' - `lastUpdatedAt` (numeric): Last update timestamp (milliseconds). -#' - `createdAtDatetime` (POSIXct): Creation time in UTC. -#' - `lastUpdatedAtDatetime` (POSIXct): Last update time in UTC. -#' @examples -#' \dontrun{ -#' library(coro) -#' library(data.table) -#' -#' main_async <- coro::async(function() { -#' # Retrieve closed orders for BTC-USDT -#' closed_orders <- await(get_closed_orders_impl( -#' symbol = "BTC-USDT", -#' side = "buy", -#' type = "limit", -#' startAt = 1728663338000, -#' endAt = 1728692138000, -#' limit = 50, -#' max_pages = 2 -#' )) -#' print(closed_orders) -#' }) -#' -#' # Run the async function -#' main_async() -#' while (!later::loop_empty()) later::run_now() -#' } -#' @importFrom coro async await -#' @importFrom data.table data.table rbindlist -#' @importFrom httr GET timeout -#' @importFrom rlang abort -#' @export -get_closed_orders_impl <- coro::async(function( - keys = get_api_keys(), - base_url = get_base_url(), - symbol, - side = NULL, - type = NULL, - startAt = NULL, - endAt = NULL, - limit = 20, - max_pages = Inf -) { - tryCatch({ - # Validate parameters - if (is.null(symbol) || !is.character(symbol) || nchar(symbol) == 0) { - rlang::abort("Parameter 'symbol' must be a non-empty string (e.g., 'BTC-USDT').") - } - if (!verify_symbol(symbol)) { - rlang::abort("Parameter 'symbol' must be a valid trading pair (e.g., 'BTC-USDT').") - } - if (!is.numeric(limit) || limit < 1 || limit > 100 || limit %% 1 != 0) { - rlang::abort("Parameter 'limit' must be an integer between 1 and 100.") - } - - # Construct base query - query <- list(symbol = symbol, limit = as.integer(limit)) - if (!is.null(side)) query$side <- side - if (!is.null(type)) query$type <- type - if (!is.null(startAt)) query$startAt <- as.numeric(startAt) - if (!is.null(endAt)) query$endAt <- as.numeric(endAt) - - # Inner function to fetch a single page - fetch_page <- coro::async(function(lastId = NULL) { - if (!is.null(lastId)) query$lastId <- lastId - query_string <- build_query(query) - endpoint <- "/api/v1/hf/orders/done" - full_url <- paste0(base_url, endpoint, query_string) - headers <- await(build_headers("GET", paste0(endpoint, query_string), NULL, keys)) - response <- httr::GET(full_url, headers, httr::timeout(3)) - parsed <- process_kucoin_response(response, full_url) - if (parsed$code != "200000") { - rlang::abort(sprintf("API error: %s - %s", parsed$code, parsed$msg)) - } - return(parsed$data) - }) - - # Collect pages - orders_list <- list() - page <- 1 - lastId <- NULL - while (TRUE) { - data <- await(fetch_page(lastId)) - if (length(data$items) == 0 || page >= max_pages) { - break - } - orders_list[[page]] <- data$items - lastId <- data$lastId - page <- page + 1 - } - - # Combine results and add datetime columns - if (length(orders_list) == 0) { - orders_dt <- data.table::data.table( - id = character(), - clientOid = character(), - symbol = character(), - opType = character(), - type = character(), - side = character(), - price = character(), - size = character(), - funds = character(), - dealSize = character(), - dealFunds = character(), - remainSize = character(), - remainFunds = character(), - cancelledSize = character(), - cancelledFunds = character(), - fee = character(), - feeCurrency = character(), - stp = character(), - timeInForce = character(), - postOnly = logical(), - hidden = logical(), - iceberg = logical(), - visibleSize = character(), - cancelAfter = integer(), - channel = character(), - remark = character(), - tags = character(), - cancelExist = logical(), - tradeType = character(), - inOrderBook = logical(), - tax = character(), - active = logical(), - createdAt = numeric(), - lastUpdatedAt = numeric(), - createdAtDatetime = as.POSIXct(character()), - lastUpdatedAtDatetime = as.POSIXct(character()) - ) - } else { - orders_dt <- data.table::rbindlist(orders_list, fill = TRUE) - orders_dt[, createdAtDatetime := time_convert_from_kucoin(createdAt, unit = "ms")] - orders_dt[, lastUpdatedAtDatetime := time_convert_from_kucoin(lastUpdatedAt, unit = "ms")] - } - - return(orders_dt) - }, error = function(e) { - rlang::abort(sprintf("Error in get_closed_orders_impl: %s", conditionMessage(e))) - }) -}) -