KucoinOcoOrders: OCO Order Management
KucoinOcoOrders: OCO Order Management
Details
Provides methods for managing OCO (One-Cancels-Other) orders on KuCoin Spot. Inherits from KucoinBase.
Purpose and Scope
Order Placement: Place OCO orders combining a limit order with a stop-limit order, where triggering one automatically cancels the other.
Order Cancellation: Cancel OCO orders by order ID, client OID, or in batch.
Order Queries: Retrieve OCO order summaries, detailed sub-order breakdowns, and paginated order lists with filtering.
Usage
All methods require authentication (valid API key, secret, passphrase). OCO orders are useful for setting simultaneous take-profit and stop-loss levels on a position. When one side fills, the other is automatically cancelled.
oco <- KucoinOcoOrders$new()
# Place an OCO order: limit sell at 110k, stop-limit sell at 90k
order <- oco$add_order(
symbol = "BTC-USDT", side = "sell",
price = "110000", size = "0.0001",
stopPrice = "90000", limitPrice = "89500"
)
# List all OCO orders
orders <- oco$get_order_list()Endpoints Covered
| Method | Endpoint | HTTP |
| add_order | POST /api/v3/oco/order | POST |
| cancel_order_by_id | DELETE /api/v3/oco/order/{orderId} | DELETE |
| cancel_order_by_client_oid | DELETE /api/v3/oco/client-order/{clientOid} | DELETE |
| cancel_all | DELETE /api/v3/oco/orders | DELETE |
| get_order_by_id | GET /api/v3/oco/order/{orderId} | GET |
| get_order_by_client_oid | GET /api/v3/oco/client-order/{clientOid} | GET |
| get_order_detail_by_id | GET /api/v3/oco/order/details/{orderId} | GET |
| get_order_list | GET /api/v3/oco/orders | GET |
Super class
kucoin::KucoinBase -> KucoinOcoOrders
Methods
Inherited methods
Method add_order()
Place an OCO Order
Places a new OCO (One-Cancels-Other) order on KuCoin Spot. An OCO order combines a limit order with a stop-limit order. When one side triggers or fills, the other side is automatically cancelled.
Workflow
Validation: Verifies
symbolformat and matchessideagainst allowed values.Body Construction: Builds the request body with price, size, stop, and limit parameters.
Request: Authenticated POST to the OCO order endpoint.
Parsing: Returns
data.tablewith the assignedorder_id.
Automated Trading Usage
Take-Profit + Stop-Loss: Place a sell OCO with
priceas take-profit andstopPrice/limitPriceas stop-loss to protect positions automatically.Bracket Entry: Use a buy OCO to enter a position at a limit price while also setting a stop-entry above resistance.
Client OID Tracking: Set
clientOidto a unique strategy identifier for programmatic order tracking and reconciliation.
curl
curl --location --request POST 'https://api.kucoin.com/api/v3/oco/order' \
--header 'Content-Type: application/json' \
--header 'KC-API-KEY: your-api-key' \
--header 'KC-API-SIGN: your-signature' \
--header 'KC-API-TIMESTAMP: 1729176273859' \
--header 'KC-API-PASSPHRASE: your-passphrase' \
--header 'KC-API-KEY-VERSION: 2' \
--data-raw '{"symbol":"BTC-USDT","side":"sell","price":"110000","size":"0.0001","stopPrice":"90000","limitPrice":"89500","tradeType":"TRADE"}'Usage
KucoinOcoOrders$add_order(
symbol,
side,
price,
size,
stopPrice,
limitPrice,
clientOid = NULL,
remark = NULL,
tradeType = "TRADE"
)Arguments
symbolCharacter; trading pair (e.g.,
"BTC-USDT"). Must match theBASE-QUOTEformat validated byverify_symbol().sideCharacter; order side, one of
"buy"or"sell".priceCharacter; limit order price for the take-profit leg. Must align with the symbol's
priceIncrement.sizeCharacter; order quantity in base currency (e.g.,
"0.0001"BTC). Must align with the symbol'sbaseIncrement.stopPriceCharacter; trigger price for the stop-limit leg. When the market reaches this price, the stop-limit order is activated.
limitPriceCharacter; limit price for the stop-limit leg after the stop is triggered. This is the price at which the stop-limit order is placed.
clientOidCharacter or NULL; unique client-assigned order identifier (max 40 characters). Useful for idempotent order placement and tracking.
remarkCharacter or NULL; order remarks or notes (max 20 characters).
tradeTypeCharacter; trade type, defaults to
"TRADE"for spot trading.
Returns
data.table (or promise<data.table> if constructed with async = TRUE) with columns:
order_id(character): KuCoin-assigned OCO order identifier.
Examples
\dontrun{
oco <- KucoinOcoOrders$new()
# Sell OCO: take-profit at 110k, stop-loss at 90k
order <- oco$add_order(
symbol = "BTC-USDT", side = "sell",
price = "110000", size = "0.0001",
stopPrice = "90000", limitPrice = "89500"
)
print(order$order_id)
# Buy OCO with client OID for tracking
order <- oco$add_order(
symbol = "ETH-USDT", side = "buy",
price = "3000", size = "0.01",
stopPrice = "3500", limitPrice = "3550",
clientOid = "my-bot-oco-001"
)
}
Method cancel_order_by_id()
Cancel OCO Order by Order ID
Cancels an active OCO order using its KuCoin-assigned order ID. Both the limit and stop-limit legs of the OCO order are cancelled.
Workflow
Request: Authenticated DELETE to the order-specific endpoint.
Cancellation: KuCoin cancels both legs of the OCO order.
Parsing: Returns
data.tablewith the cancelled order IDs.
Automated Trading Usage
Position Exit: Cancel an OCO order when manually closing a position or switching strategies.
Order Replacement: Cancel the existing OCO and place a new one with updated price levels.
Error Recovery: Cancel orphaned OCO orders detected during periodic order audits.
curl
curl --location --request DELETE 'https://api.kucoin.com/api/v3/oco/order/674c40d38b4b2f00073deef3' \
--header 'KC-API-KEY: your-api-key' \
--header 'KC-API-SIGN: your-signature' \
--header 'KC-API-TIMESTAMP: 1729176273859' \
--header 'KC-API-PASSPHRASE: your-passphrase' \
--header 'KC-API-KEY-VERSION: 2'Arguments
orderIdCharacter; the KuCoin-assigned OCO order ID to cancel (e.g.,
"674c40d38b4b2f00073deef3").
Method cancel_order_by_client_oid()
Cancel OCO Order by Client OID
Cancels an active OCO order using the client-assigned order ID (clientOid).
Both the limit and stop-limit legs of the OCO order are cancelled.
Workflow
Request: Authenticated DELETE to the client-order endpoint.
Lookup: KuCoin resolves the
clientOidto the internal OCO order.Cancellation: Both legs of the OCO order are cancelled.
Parsing: Returns
data.tablewith cancelled order IDs.
Automated Trading Usage
Strategy-Based Cancellation: Cancel OCO orders by your own strategy IDs without needing to store KuCoin order IDs.
Idempotent Operations: Use deterministic
clientOidvalues so re-running cancellation logic is safe.Multi-Bot Coordination: Each bot uses a unique
clientOidprefix to manage its own OCO orders independently.
curl
curl --location --request DELETE 'https://api.kucoin.com/api/v3/oco/client-order/my-bot-oco-001' \
--header 'KC-API-KEY: your-api-key' \
--header 'KC-API-SIGN: your-signature' \
--header 'KC-API-TIMESTAMP: 1729176273859' \
--header 'KC-API-PASSPHRASE: your-passphrase' \
--header 'KC-API-KEY-VERSION: 2'Arguments
clientOidCharacter; the client-assigned order ID used when placing the OCO order (e.g.,
"my-bot-oco-001").
Method cancel_all()
Cancel All OCO Orders
Cancels all active OCO orders matching the given filters. Can filter by
symbol or specify individual orderIds. If no filters are provided,
all active OCO orders are cancelled.
Workflow
Filter Construction: Builds query parameters from the provided filter list.
Request: Authenticated DELETE to the batch cancellation endpoint.
Cancellation: KuCoin cancels all matching OCO orders.
Parsing: Returns
data.tablewith cancelled order IDs.
Automated Trading Usage
Emergency Kill Switch: Call with no filters to cancel all OCO orders during market anomalies or system errors.
Symbol Cleanup: Pass
symbolto cancel all OCO orders for a specific pair when exiting a position entirely.Selective Batch Cancel: Pass specific
orderIdsto cancel a subset of OCO orders during strategy rebalancing.
Usage
KucoinOcoOrders$cancel_all(query = list())Arguments
queryNamed list; filter parameters for batch cancellation:
symbol(character): Optional. Trading pair to filter by (e.g.,"BTC-USDT").orderIds(character): Optional. Comma-separated order IDs to cancel specifically. If empty, all active OCO orders are cancelled.
Method get_order_by_id()
Get OCO Order by Order ID
Retrieves summary information for a specific OCO order using its
KuCoin-assigned order ID. Returns the OCO order metadata without
detailed sub-order information (use get_order_detail_by_id() for that).
Workflow
Request: Authenticated GET to the order-specific endpoint.
Response: KuCoin returns the OCO order summary.
Parsing: Returns
data.tablewith order metadata.
Automated Trading Usage
Status Polling: Periodically check OCO order status to determine if either leg has triggered.
Audit Logging: Retrieve order metadata for trade journal and performance tracking.
Conditional Logic: Check the
statusfield to decide whether to place replacement orders.
curl
curl --location --request GET 'https://api.kucoin.com/api/v3/oco/order/674c40d38b4b2f00073deef3' \
--header 'KC-API-KEY: your-api-key' \
--header 'KC-API-SIGN: your-signature' \
--header 'KC-API-TIMESTAMP: 1729176273859' \
--header 'KC-API-PASSPHRASE: your-passphrase' \
--header 'KC-API-KEY-VERSION: 2'Returns
data.table (or promise<data.table> if constructed with async = TRUE) with columns:
order_id(character): OCO order identifier.symbol(character): Trading pair (e.g.,"BTC-USDT").client_oid(character): Client-assigned order identifier.datetime_order(POSIXct): Order creation datetime.status(character): Order status (e.g.,"NEW","DONE","TRIGGERED").
Method get_order_by_client_oid()
Get OCO Order by Client OID
Retrieves summary information for a specific OCO order using the
client-assigned order ID (clientOid). Useful when you track orders
by your own identifiers rather than KuCoin-assigned IDs.
Workflow
Request: Authenticated GET to the client-order endpoint.
Lookup: KuCoin resolves the
clientOidto the internal OCO order.Parsing: Returns
data.tablewith order metadata.
Automated Trading Usage
Strategy Reconciliation: Look up OCO orders using your strategy-generated IDs for post-trade analysis.
Duplicate Detection: Check if an OCO order with a given
clientOidalready exists before placing a new one.Bot State Recovery: On restart, recover OCO order state using stored
clientOidvalues.
curl
curl --location --request GET 'https://api.kucoin.com/api/v3/oco/client-order/my-bot-oco-001' \
--header 'KC-API-KEY: your-api-key' \
--header 'KC-API-SIGN: your-signature' \
--header 'KC-API-TIMESTAMP: 1729176273859' \
--header 'KC-API-PASSPHRASE: your-passphrase' \
--header 'KC-API-KEY-VERSION: 2'Arguments
clientOidCharacter; the client-assigned order ID used when placing the OCO order (e.g.,
"my-bot-oco-001").
Returns
data.table (or promise<data.table> if constructed with async = TRUE) with columns:
order_id(character): KuCoin-assigned OCO order identifier.symbol(character): Trading pair (e.g.,"BTC-USDT").client_oid(character): Client-assigned order identifier.datetime_order(POSIXct): Order creation datetime.status(character): Order status (e.g.,"NEW","DONE","TRIGGERED").
Method get_order_detail_by_id()
Get OCO Order Details by Order ID
Retrieves detailed information for a specific OCO order, including the
individual sub-orders (limit leg and stop-limit leg) and their respective
statuses. This provides more information than get_order_by_id().
Workflow
Request: Authenticated GET to the order details endpoint.
Response: KuCoin returns the OCO order with full sub-order breakdown.
Parsing: Returns
data.tablewith detailed order information.
Automated Trading Usage
Fill Analysis: Inspect sub-order details to determine which leg filled and at what price.
Partial Fill Detection: Check individual sub-order fill quantities for partial execution scenarios.
Trade Journaling: Extract complete execution details for performance attribution and reporting.
curl
curl --location --request GET 'https://api.kucoin.com/api/v3/oco/order/details/674c40d38b4b2f00073deef3' \
--header 'KC-API-KEY: your-api-key' \
--header 'KC-API-SIGN: your-signature' \
--header 'KC-API-TIMESTAMP: 1729176273859' \
--header 'KC-API-PASSPHRASE: your-passphrase' \
--header 'KC-API-KEY-VERSION: 2'JSON Response
{
"code": "200000",
"data": {
"orderId": "674c40d38b4b2f00073deef3",
"symbol": "BTC-USDT",
"clientOid": "my-bot-oco-001",
"orderTime": 1729176273859,
"status": "NEW",
"orders": [
{
"id": "674c40d38b4b2f00073deef4",
"symbol": "BTC-USDT",
"side": "sell",
"price": "110000",
"size": "0.0001",
"status": "NEW"
},
{
"id": "674c40d38b4b2f00073deef5",
"symbol": "BTC-USDT",
"side": "sell",
"price": "89500",
"stopPrice": "90000",
"size": "0.0001",
"status": "NEW"
}
]
}
}Returns
data.table (or promise<data.table> if constructed with async = TRUE) with columns:
order_id(character): OCO order identifier.symbol(character): Trading pair (e.g.,"BTC-USDT").client_oid(character): Client-assigned order identifier.datetime_order(POSIXct): Order creation datetime.status(character): Overall OCO order status.orders(list): List of sub-order details, each containingid,symbol,side,price,size,status, and optionallystop_price.
Method get_order_list()
Get OCO Order List
Retrieves a paginated list of OCO orders with optional filtering by symbol, time range, and pagination parameters. Returns all OCO orders matching the specified criteria.
Workflow
Filter Construction: Builds query parameters from the provided filter list.
Request: Authenticated GET to the order list endpoint.
Pagination: KuCoin returns a paginated response with
itemsarray.Parsing: Binds all items into a single
data.tableusingrbindlist().
Automated Trading Usage
Portfolio Overview: List all active OCO orders to display current take-profit/stop-loss levels across positions.
Stale Order Detection: Filter by
startAt/endAtto find OCO orders that have been open too long and may need adjustment.Pagination Loop: Use
currentPageandpageSizeto iterate through large result sets in batch processing.
curl
curl --location --request GET 'https://api.kucoin.com/api/v3/oco/orders?symbol=BTC-USDT&pageSize=20¤tPage=1' \
--header 'KC-API-KEY: your-api-key' \
--header 'KC-API-SIGN: your-signature' \
--header 'KC-API-TIMESTAMP: 1729176273859' \
--header 'KC-API-PASSPHRASE: your-passphrase' \
--header 'KC-API-KEY-VERSION: 2'JSON Response
{
"code": "200000",
"data": {
"currentPage": 1,
"pageSize": 20,
"totalNum": 2,
"totalPage": 1,
"items": [
{
"orderId": "674c40d38b4b2f00073deef3",
"symbol": "BTC-USDT",
"clientOid": "my-bot-oco-001",
"orderTime": 1729176273859,
"status": "NEW"
},
{
"orderId": "674c40d38b4b2f00073deef6",
"symbol": "ETH-USDT",
"clientOid": "my-bot-oco-002",
"orderTime": 1729176274000,
"status": "TRIGGERED"
}
]
}
}Usage
KucoinOcoOrders$get_order_list(query = list())Arguments
queryNamed list; filter and pagination parameters:
symbol(character): Optional. Trading pair to filter by (e.g.,"BTC-USDT").startAt(numeric): Optional. Start time in milliseconds (inclusive).endAt(numeric): Optional. End time in milliseconds (inclusive).pageSize(integer): Optional. Number of results per page (default 20, max 100).currentPage(integer): Optional. Page number to retrieve (default 1).
Returns
data.table (or promise<data.table> if constructed with async = TRUE) with columns (one row per OCO order):
order_id(character): OCO order identifier.symbol(character): Trading pair (e.g.,"BTC-USDT").client_oid(character): Client-assigned order identifier.datetime_order(POSIXct): Order creation datetime.status(character): Order status (e.g.,"NEW","DONE","TRIGGERED"). Returns an emptydata.tableif no orders match.
Examples
\dontrun{
oco <- KucoinOcoOrders$new()
# Get all OCO orders
orders <- oco$get_order_list()
print(orders)
# Filter by symbol with pagination
orders <- oco$get_order_list(query = list(
symbol = "BTC-USDT",
pageSize = 50,
currentPage = 1
))
print(orders)
# Filter by time range
orders <- oco$get_order_list(query = list(
startAt = as.numeric(lubridate::now() - 86400) * 1000,
endAt = as.numeric(lubridate::now()) * 1000
))
}
Examples
if (FALSE) { # \dontrun{
# Synchronous
oco <- KucoinOcoOrders$new()
orders <- oco$get_order_list()
print(orders)
# Asynchronous
oco_async <- KucoinOcoOrders$new(async = TRUE)
main <- coro::async(function() {
orders <- await(oco_async$get_order_list())
print(orders)
})
main()
while (!later::loop_empty()) later::run_now()
} # }
## ------------------------------------------------
## Method `KucoinOcoOrders$add_order`
## ------------------------------------------------
if (FALSE) { # \dontrun{
oco <- KucoinOcoOrders$new()
# Sell OCO: take-profit at 110k, stop-loss at 90k
order <- oco$add_order(
symbol = "BTC-USDT", side = "sell",
price = "110000", size = "0.0001",
stopPrice = "90000", limitPrice = "89500"
)
print(order$order_id)
# Buy OCO with client OID for tracking
order <- oco$add_order(
symbol = "ETH-USDT", side = "buy",
price = "3000", size = "0.01",
stopPrice = "3500", limitPrice = "3550",
clientOid = "my-bot-oco-001"
)
} # }
## ------------------------------------------------
## Method `KucoinOcoOrders$cancel_order_by_id`
## ------------------------------------------------
if (FALSE) { # \dontrun{
oco <- KucoinOcoOrders$new()
# Cancel a specific OCO order
result <- oco$cancel_order_by_id("674c40d38b4b2f00073deef3")
print(result$cancelled_order_ids)
} # }
## ------------------------------------------------
## Method `KucoinOcoOrders$cancel_order_by_client_oid`
## ------------------------------------------------
if (FALSE) { # \dontrun{
oco <- KucoinOcoOrders$new()
# Cancel by client-assigned ID
result <- oco$cancel_order_by_client_oid("my-bot-oco-001")
print(result$cancelled_order_ids)
} # }
## ------------------------------------------------
## Method `KucoinOcoOrders$cancel_all`
## ------------------------------------------------
if (FALSE) { # \dontrun{
oco <- KucoinOcoOrders$new()
# Cancel all OCO orders for BTC-USDT
result <- oco$cancel_all(query = list(symbol = "BTC-USDT"))
print(result$cancelled_order_ids)
# Cancel all OCO orders (no filter)
result <- oco$cancel_all()
} # }
## ------------------------------------------------
## Method `KucoinOcoOrders$get_order_by_id`
## ------------------------------------------------
if (FALSE) { # \dontrun{
oco <- KucoinOcoOrders$new()
# Get OCO order summary
order <- oco$get_order_by_id("674c40d38b4b2f00073deef3")
print(order$status)
print(order$symbol)
} # }
## ------------------------------------------------
## Method `KucoinOcoOrders$get_order_by_client_oid`
## ------------------------------------------------
if (FALSE) { # \dontrun{
oco <- KucoinOcoOrders$new()
# Retrieve by client OID
order <- oco$get_order_by_client_oid("my-bot-oco-001")
print(order$order_id)
print(order$status)
} # }
## ------------------------------------------------
## Method `KucoinOcoOrders$get_order_detail_by_id`
## ------------------------------------------------
if (FALSE) { # \dontrun{
oco <- KucoinOcoOrders$new()
# Get full OCO order details with sub-orders
details <- oco$get_order_detail_by_id("674c40d38b4b2f00073deef3")
print(details$status)
print(details$orders)
} # }
## ------------------------------------------------
## Method `KucoinOcoOrders$get_order_list`
## ------------------------------------------------
if (FALSE) { # \dontrun{
oco <- KucoinOcoOrders$new()
# Get all OCO orders
orders <- oco$get_order_list()
print(orders)
# Filter by symbol with pagination
orders <- oco$get_order_list(query = list(
symbol = "BTC-USDT",
pageSize = 50,
currentPage = 1
))
print(orders)
# Filter by time range
orders <- oco$get_order_list(query = list(
startAt = as.numeric(lubridate::now() - 86400) * 1000,
endAt = as.numeric(lubridate::now()) * 1000
))
} # }