订单管理
本节介绍如何下单、改单、撤单、查询订单等。
订单概览
系统支持两种下单方式,都是通过异步方式发送交易指令:
-
直接调用:在函数内部通过
self.trader.publish(cmd)发送交易指令 -
回调返回:在回调函数(
on_xxx的回调函数)结尾(非start和subscribe函数)通过return返回交易指令,该方式性能更好,更推荐使用具体格式如下:
return {
'cmds': [cmd1,cmd2],
'logs': ['log1','log2']
}
与订单相关的功能函数如下:
| 参数 | 说明 | 同步或异步 |
|---|---|---|
PlaceOrder | 下单 | 异步 |
BatchPlaceOrder | 批量下单 | 异步 |
AmendOrder | 改单 | 异步 |
CancelOrder | 撤单 | 异步 |
BatchCancelOrder | 批量撤单 | 异步 |
BatchCancelOrderById | 批量撤单(通过订单ID) | 异步 |
GetOrderById | 查询订单详情 | 同步 |
GetOrders | 查询历史订单 | 同步 |
GetOpenOrders | 查询当前交易对挂单 | 同步 |
GetAllOpenOrders | 查询当前所有挂单 | 同步 |
信息
异步命令的返回值仅表示命令已成功发送,实际执行结果将通过对应的回调函数返回。例如:异步下单结果在 on_order_submitted 中返回,修改订单、批量下单、批量撤单等操作均遵循此机制。
订单管理
下单 (PlaceOrder)
请求参数
| 参数 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
| cid | String | 否 | 客户端自定义订单ID |
| symbol | String | 是 | 交易对名称 |
| order_type | String | 是 | 订单类型: Limit/Market |
| side | String | 是 | 交易方向: Buy/Sell |
| pos_side | String | 是 | 持仓方向: Long/Short |
| price | Number | 限价单必须 | 委托价格 |
| amount | Number | 是 | 委托数量 |
| time_in_force | String | 否 | 有效期类型: GTC/IOC/FOK/PostOnly |
| -以下需要另起一个对象- | -- | -- | -- |
| is_dual_side | Boolean | 是 | 是否开启双向持仓 |
| leverage | Number | 否 | 杠杆倍数,仅huobi需要 |
| margin_mode | String | 否 | 保证金模式: Cross/Isolated,仅okx需要 |
| take_profit | Number | 否 | 止盈价格 |
| stop_loss | Number | 否 | 止损价格 |
| leverage_order_mode | String | 否 | 杠杆订单模式, Normal: 普通下单; AutoLoan: 自动借款下单, AutoRepay: 自动还款下单; AutoLoanAndRepay: 自动借款还款下单 |
| market_order_mode | String | 否 | 市价单模式, Safe:安全市价单,订单必须传价格,会变成ioc加滑点下单,默认值为Safe; Normal: 普通市价单,订单可以不传价格 |
| market_order_slippage | Number | 否 | 市价单滑点,仅market_order_mode为Safe时需要,默认0.2% |
请求示例
# 方法一:直接调用方式下单
def place_limit_order(self, symbol, context, side, price, amount):
order = {
"cid": self.trader.create_cid(self.cex_configs[0]['exchange']), # 客户端订单ID
"symbol": symbol,
"order_type": "Limit", # 限价单
"side": side,
"pos_side": None, # 单向持仓模式
"time_in_force": "GTC", # 一直有效直到取消
"price": price,
"amount": amount,
}
cmd = {
"account_id": 0,
"context": context,
"cmd": {
"Async": {
"PlaceOrder": [
order,
{
"is_dual_side": False, # 单向持仓
"margin_mode": "Cross", # 全仓模式(okx需要)
}
]
}
}
}
result = self.trader.publish(cmd)
if 'Ok' in result:
order_id = result['Ok']
self.trader.log(f"提交订单成功: {symbol} {side} 数量: {amount} 价格: {price} 订单ID: {order_id}",
level="INFO", color="green")
# 方法二:回调返回方式下单
def on_depth(self, exchange, context, depth):
# ...
# 其他逻辑
cmd = self.build_trade_cmd(symbol, context, side)
return {
'cmds': [cmd], # 按照该格式返回
}
def build_trade_cmd(self, symbol, context, side):
# 通过其他逻辑,计算出价格和数量
price = round(price, price_precision)
amount = round(amount, amount_precision)
# 准备下单参数
order = {
"cid": self.trader.create_cid(self.cex_configs[0]['exchange']), # 客户端订单ID
"symbol": symbol,
"order_type": "Limit", # 限价单
"side": side,
"pos_side": None, # 单向持仓模式
"time_in_force": "GTC", # 一直有效直到取消
"price": price,
"amount": amount,
}
# 提交限价订单
cmd = {
"account_id": 0,
"context": context,
"cmd": {
"Async": {
"PlaceOrder": [
order,
{
"is_dual_side": False, # 单向持仓
"margin_mode": "Cross", # 全仓模式(okx需要)
}
]
}
}
}
return cmd
响应字段
| 字段 | 类型 | 描述 |
|---|---|---|
| id | String | 订单ID |
示例
"Ok": "order_12345"
批量下单 (BatchPlaceOrder)
请求参数
| 参数 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
| BatchPlaceOrder | Array/Object | 是 | 订单数组,每个订单的参数同PlaceOrder |
| BatchPlaceOrder.params | Object | 是 | 订单共同参数,同PlaceOrder |
请求示例
def on_depth(self, exchange, context, depth):
# ...
# 其他逻辑
cmd = self.build_trade_cmd(symbol, context, side)
return {
'cmds': [cmd], # 按照该格式返回
}
def build_trade_cmd(self, symbol, context, side):
# 准备下单参数
order1 = {
"symbol": "BTC_USDT",
"order_type": "Limit",
"side": "Buy",
"pos_side": "Long",
"price": 50000.0,
"amount": 0.1
}
order2 = {
"symbol": "BTC_USDT",
"order_type": "Limit",
"side": "Sell",
"pos_side": "Short",
"price": 51000.0,
"amount": 0.1
}
cmd = {
"account_id": 0,
"context": context,
"cmd": {
"Async": {
"BatchPlaceOrder": [
[order1, order2],
{
"is_dual_side": False,
"leverage": 10
}
]
}
}
}
return cmd
响应字段
| 字段 | 类型 | 描述 |
|---|---|---|
| success_list | Array | 成功订单ID列表 |
| > id | String | 订单ID |
| > cid | String | 客户端订单ID |
| failure_list | Array | 失败订单列表 |
| > id | String | 订单ID |
| > cid | String | 客户端订单ID |
| > error_code | String | 错误码 |
| > error | String | 错误信息 |
信息
由于部分交易所不返回成功的订单信息,建议以失败订单列表为主
示例
"Ok": {
"success_list": [
{
"id": "order id",
"cid": null
},
{
"id": null,
"cid": "orde client id"
}
],
"failure_list": [
{
"id": "order id",
"cid": null,
"error_code": 0,
"error": "error"
},
{
"id": null,
"cid": "order client id",
"error_code": 0,
"error": "error"
}
]
}
改单 (AmendOrder)
请求参数
| 参数 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
| id | String | 否 | 订单ID, id和cid必须有一个 |
| cid | String | 否 | 客户端自定义订单ID |
| symbol | String | 是 | 交易对名称 |
| order_type | String | 是 | 订单类型: Limit/Market |
| side | String | 是 | 交易方向: Buy/Sell |
| pos_side | String | 是 | 持仓方向: Long/Short |
| price | Number | 限价单必须 | 委托价格 |
| amount | Number | 是 | 委托数量 |
| time_in_force | String | 否 | 有效期类型: GTC/IOC/FOK |
请求示例
def amend_order(self, symbol, context, side, price, amount):
cmd = {
"account_id": 0,
"context": context,
"cmd": {
"Async": {
"AmendOrder": {
"id": "order_id",
"cid": "order_client_id",
"symbol": symbol,
"order_type": "Limit",
"side": side,
"pos_side": "Long",
"price": price,
"amount": amount,
"time_in_force": "GTC"
}
}
}
}
self.trader.publish(cmd)
响应字段
| 字段 | 类型 | 描述 |
|---|---|---|
| Ok | String | 订单ID |
示例
"Ok": "order_12345"
撤单 (CancelOrder)
| 参数 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
| Id | String | 否 | 订单ID,Id和ClientOrderId必须有一个 |
| ClientOrderId | String | 否 | 客户自定义的订单ID |
| Symbol | String | 是 | 交易对名称 |
请求示例
def cancel_all_orders(self):
"""
取消所有未完成订单
遍历所有交易品种,取消所有挂起的订单
"""
for symbol in self.symbols:
orders = self.get_orders(symbol)
for order in orders:
self.trader.log(f"取消订单: {order}", level="INFO", color="blue")
cmd = {
"account_id": 0,
"cmd": {
"Async": {
"CancelOrder": [
{"Id": order['id']}, order['symbol']
]
}
}
}
res = self.trader.publish(cmd)
self.trader.log(f"取消订单结果: {res}", level="INFO", color="blue")
响应字段
成功返回 Ok:null
示例
"Ok": null
批量撤单 (BatchCancelOrder)
请求参数
| 参数 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
| BatchCancelOrder | String | 是 | 交易对名称 |
请求示例
def cancel_all_orders(self):
"""
取消所有未完成订单
遍历所有交易品种,取消所有挂起的订单
"""
cmd = {
"account_id": 0,
"cmd": {
"Async": {
"BatchCancelOrder": "BTC_USDT"
}
}
}
self.trader.publish(cmd)
响应字段
| 字段 | 类型 | 描述 |
|---|---|---|
| success_list | Array | 成功订单ID列表 |
| > id | String | 订单ID |
| > cid | String | 客户端订单ID |
| failure_list | Array | 失败订单列表 |
| > id | String | 订单ID |
| > cid | String | 客户端订单ID |
| > error_code | String | 错误码 |
| > error | String | 错误信息 |
示例
"Ok": {
"success_list": [
{
"id": "order id",
"cid": null
},
{
"id": null,
"cid": "orde client id"
}
],
"failure_list": [
{
"id": "order id",
"cid": null,
"error_code": 0,
"error": "error"
},
{
"id": null,
"cid": "order client id",
"error_code": 0,
"error": "error"
}
]
}
通过订单ID批量撤单 (BatchCancelOrderById)
请求参数
| 参数 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
| Symbol | String | 否 | 表示要取消的订单的交易对。部分交易所不需要传: KrakenSpot、KucoinSwap(通过order_id撤单时)、BitgetSwap(通过order_id撤单时) |
| Ids | Array[String] | 否 | 订单Id数组 |
| Cids | Array[String] | 否 | 客户自定义订单Id数组 |
Ids和Cids至少一个不为空
请求示例
def cancel_orders_by_id(self):
"""
根据订单Id批量撤单
"""
cmd = {
"account_id": 0,
"cmd": {
"Async": {
"BatchCancelOrderById": {
"BTC_USDT",
[
"order-id-1"
],
[
"order-client-id-1"
]
}
}
}
}
self.trader.publish(cmd)
响应字段
| 字段 | 类型 | 描述 |
|---|---|---|
| success_list | Array | 成功订单ID列表 |
| > id | String | 订单ID |
| > cid | String | 客户端订单ID |
| failure_list | Array | 失败订单列表 |
| > id | String | 订单ID |
| > cid | String | 客户端订单ID |
| > error_code | String | 错误码 |
| > error | String | 错误信息 |
示例
"Ok": {
"success_list": [
{
"id": "order id",
"cid": null
},
{
"id": null,
"cid": "orde client id"
}
],
"failure_list": [
{
"id": "order id",
"cid": null,
"error_code": 0,
"error": "error"
}
]
}
查询订单详情 (GetOrderById)
请求参数:
| 参数 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
| symbol | Symbol | 是 | 交易对名称,例如 "BTC_USDT" |
| Id | OrderId | 是 | 订单Id或者客户端自定义Id |
OrderId
| 参数 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
| Id | String | 是 | 订单Id |
| ClientOrderId | String | 是 | 客户端自定义Id |
请求示例
def get_order_by_id(self, symbol, order_id, client_order_id):
# 根据订单Id查询订单详情
cmd = {
"account_id": 0,
"cmd": {
"Sync": {
"GetOrderById": [
symbol,
{
"Id": order_id,
}
]
}
}
}
# 根据客户端自定义Id查询订单详情
cmd = {
"account_id": 0,
"cmd": {
"Sync": {
"GetOrderById": [
symbol,
{
"ClientOrderId": client_order_id
}
]
}
}
}
self.trader.publish(cmd)
响应字段
| 字段 | 类型 | 描述 |
|---|---|---|
| id | String | 订单ID |
| symbol | String | 交易对名称 |
| status | Sting | 订单状态 |
| order_type | String | 订单类型: Limit/Market |
| side | String | 交易方向: Buy/Sell |
| pos_side | String | 持仓方向: Long/Short |
| price | Number | 委托价格 |
| amount | Number | 委托数量 |
| filled | Number | 已成交数量 |
| filled_avg_price | Number | 成交均价 |
示例
"Ok": [
{
"id": "order123",
"symbol": "BTC_USDT",
"status": "Open",
"order_type": "Limit",
"side": "Buy",
"pos_side": "Long",
"price": 50000.0,
"amount": 0.1,
"filled": 0.0,
"filled_avg_price": 0.0
}
]
查询历史订单 (GetOrders)
请求参数
| 参数 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
| GetOrders | String | 是 | 交易对名称,例如 "BTC_USDT" |
| start_time | Number | 是 | 开始时间戳。毫秒 |
| end_time | Number | 是 | 结束时间戳, 毫秒 |
请求示例
def get_orders(self, symbol, start_time, end_time):
cmd = {
"account_id": 0,
"cmd": {
"Sync": {
"GetOrders": [
symbol,
start_time,
end_time
]
}
}
}
self.trader.publish(cmd)
响应字段
| 字段 | 类型 | 描述 |
|---|---|---|
| id | String | 订单ID |
| symbol | String | 交易对名称 |
| status | Sting | 订单状态 |
| order_type | String | 订单类型: Limit/Market |
| side | String | 交易方向: Buy/Sell |
| pos_side | String | 持仓方向: Long/Short |
| price | Number | 委托价格 |
| amount | Number | 委托数量 |
| filled | Number | 已成交数量 |
| filled_avg_price | Number | 成交均价 |
示例
"Ok": [
{
"id": "order123",
"symbol": "BTC_USDT",
"status": "Open",
"order_type": "Limit",
"side": "Buy",
"pos_side": "Long",
"price": 50000.0,
"amount": 0.1,
"filled": 0.0,
"filled_avg_price": 0.0
}
]
查询当前交易对挂单 (GetOpenOrders)
| 参数 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
| GetOpenOrders | String | 是 | 交易对名称 |
请求示例
def get_open_orders(self, symbol):
cmd = {
"account_id": 0,
"cmd": {
"Sync": {
"GetOpenOrders": symbol
}
}
}
self.trader.publish(cmd)
响应字段
示例
"Ok": [
{
"id": "order123",
"symbol": "BTC_USDT",
"status": "Open",
"order_type": "Limit",
"side": "Buy",
"pos_side": "Long",
"price": 50000.0,
"amount": 0.1,
"filled": 0.0,
"filled_avg_price": 0.0
}
]
查询当前所有挂单 (GetAllOpenOrders)
请求参数 无
请求示例
def get_all_open_orders(self):
cmd = {
"account_id": 0,
"cmd": {
"Sync": "GetAllOpenOrders"
}
}
self.trader.publish(cmd)
响应字段
示例
"Ok": [
{
"id": "order123",
"symbol": "BTC_USDT",
"status": "Open",
"order_type": "Limit",
"side": "Buy",
"pos_side": "Long",
"price": 50000.0,
"amount": 0.1,
"filled": 0.0,
"filled_avg_price": 0.0
},
]