跳到主要内容

订单管理 (Orders)

创建和管理交易订单。所有订单操作都需要使用 EIP-712 签名进行验证。

创建订单

创建限价单或市价单。系统会自动验证余额、计算保证金,并提交到撮合引擎。

接口信息

  • Method: POST
  • Path: /api/v1/orders
  • Authentication: 需要 JWT Token(Bearer Token)
  • Content-Type: application/json

请求参数

参数类型必须描述
symbolstring交易对(如 BTCUSDTETHUSDT
sidestring方向:buysell
order_typestring类型:limit(限价单)或 market(市价单)
amountstring数量(Decimal 字符串,如 "0.1")
pricestring价格(Decimal 字符串,限价单必填,市价单填 "0")
leveragenumber杠杆倍数(1-50)
signaturestringEIP-712 签名(0x 开头)
timestampnumberUnix 时间戳(,需在 5 分钟内有效)

EIP-712 签名

订单需要使用 EIP-712 结构化签名。签名的 typed data 结构如下:

{
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"CreateOrder": [
{ "name": "wallet", "type": "address" },
{ "name": "symbol", "type": "string" },
{ "name": "side", "type": "string" },
{ "name": "orderType", "type": "string" },
{ "name": "price", "type": "string" },
{ "name": "amount", "type": "string" },
{ "name": "leverage", "type": "uint32" },
{ "name": "timestamp", "type": "uint256" }
]
},
"primaryType": "CreateOrder",
"domain": {
"name": "ZTDX",
"version": "1",
"chainId": 421614, // Arbitrum Sepolia
"verifyingContract": "<VaultContractAddress>"
},
"message": {
"wallet": "0x742d35cc6634c0532925a3b844bc9e7595f0beb",
"symbol": "BTCUSDT",
"side": "buy",
"orderType": "limit",
"price": "65000",
"amount": "0.1",
"leverage": 10,
"timestamp": "1704067200"
}
}
重要
  • sideorderType 必须是小写字符串("buy"/"sell""limit"/"market"
  • priceamount 必须是 Decimal 字符串(不是 number)
  • 市价单的 price"0"
  • timestamp秒级时间戳(不是毫秒)

前端签名示例(ethers.js v6)

import { BrowserProvider } from 'ethers';

async function createOrder(order) {
const wallet = await getConnectedWallet();
const timestamp = Math.floor(Date.now() / 1000);

// 构造 EIP-712 typed data
const domain = {
name: "ZTDX",
version: "1",
chainId: 421614,
verifyingContract: vaultAddress
};

const types = {
CreateOrder: [
{ name: "wallet", type: "address" },
{ name: "symbol", type: "string" },
{ name: "side", type: "string" },
{ name: "orderType", type: "string" },
{ name: "price", type: "string" },
{ name: "amount", type: "string" },
{ name: "leverage", type: "uint32" },
{ name: "timestamp", type: "uint256" }
]
};

const message = {
wallet: wallet.address.toLowerCase(),
symbol: order.symbol,
side: order.side, // "buy" or "sell"
orderType: order.order_type, // "limit" or "market"
price: order.price || "0",
amount: order.amount,
leverage: order.leverage,
timestamp: timestamp.toString()
};

// 签名
const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const signature = await signer.signTypedData(domain, types, message);

// 发送请求
const response = await fetch('/api/v1/orders', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
},
body: JSON.stringify({
symbol: order.symbol,
side: order.side,
order_type: order.order_type,
amount: order.amount,
price: order.price || undefined,
leverage: order.leverage,
signature,
timestamp
})
});

return response.json();
}

请求示例

限价单

{
"symbol": "BTCUSDT",
"side": "buy",
"order_type": "limit",
"amount": "0.1",
"price": "65000",
"leverage": 10,
"signature": "0xabcdef123456...",
"timestamp": 1704067200
}

市价单

{
"symbol": "ETHUSDT",
"side": "sell",
"order_type": "market",
"amount": "1.5",
"leverage": 5,
"signature": "0x123456abcdef...",
"timestamp": 1704067200
}
市价单说明
  • 市价单不需要提供 price 参数(或填 null
  • 市价单会以当前最优价格立即成交
  • 系统有自动做市商确保市价单始终有流动性

响应示例

{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "open",
"filled_amount": "0",
"remaining_amount": "0.1",
"average_price": "0",
"created_at": 1704067200000
}

响应字段说明

字段类型描述
order_idstring订单 UUID
statusstring订单状态(见下表)
filled_amountstring已成交数量(Decimal 字符串)
remaining_amountstring剩余未成交数量(Decimal 字符串)
average_pricestring平均成交价格(Decimal 字符串,未成交时为 "0"
created_atnumber创建时间(毫秒级时间戳)

订单状态说明

状态说明可取消
pending待处理(刚提交,尚未进入撮合)
open已挂单(活动中,等待成交)
partially_filled部分成交
filled完全成交
cancelled已取消
rejected已拒绝(参数错误或余额不足)

智能保证金计算

系统会根据订单类型智能计算所需保证金:

1. 开仓/加仓订单

基础保证金 = (数量 × 价格) ÷ 杠杆
手续费缓冲 = 基础保证金 × 0.5%
所需保证金 = 基础保证金 + 手续费缓冲

示例:买入 0.1 BTC @ 65000 USD,10x 杠杆

  • 名义价值 = 0.1 × 65000 = 6500 USD
  • 基础保证金 = 6500 ÷ 10 = 650 USD
  • 手续费缓冲 = 650 × 0.005 = 3.25 USD
  • 所需保证金 = 653.25 USD

2. 平仓订单(智能优化)

如果订单是平仓(买入平空仓,或卖出平多仓),系统会大幅减少保证金要求:

  • 完全平仓:只需手续费(约 0.5%)
  • 部分平仓:只需净开仓部分的保证金

示例:已有 0.2 BTC 多仓,现卖出 0.15 BTC

  • 平仓部分(0.15 BTC):只需手续费
  • 无需额外保证金!

示例:已有 0.1 BTC 多仓,现卖出 0.2 BTC

  • 平仓部分(0.1 BTC):只需手续费
  • 开仓部分(0.1 BTC):需要正常保证金
  • 所需保证金 = 0.1 BTC 的开仓保证金
资金利用率

这个智能保证金机制可以让您用更少的资金进行平仓操作,提高资金利用率!

错误响应

HTTP 状态码错误码描述
400INVALID_SYMBOL不支持的交易对
400TIMESTAMP_EXPIRED时间戳已过期(超过 5 分钟)
400INVALID_LEVERAGE杠杆倍数必须在 1-50 之间
400INVALID_AMOUNT订单数量必须大于 0
400PRICE_REQUIRED限价单必须指定价格
400INSUFFICIENT_BALANCE可用余额不足(需要 xxx USDT 作为保证金)
400INVALID_SIGNATURE_FORMAT签名格式无效
401SIGNATURE_INVALIDEIP-712 签名验证失败
500MATCHING_ERROR撮合引擎错误
500DB_ERROR数据库错误

查询订单

查询单个订单的详细信息。

接口信息

  • Method: GET
  • Path: /api/v1/orders/:order_id
  • Authentication: 需要 JWT Token

路径参数

参数类型必须描述
order_idstring订单 UUID

响应示例

{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"symbol": "BTCUSDT",
"side": "buy",
"order_type": "limit",
"price": "65000",
"amount": "0.1",
"filled_amount": "0.05",
"remaining_amount": "0.05",
"leverage": 10,
"status": "partially_filled",
"created_at": 1704067200000
}

响应字段说明

字段类型描述
order_idstring订单 UUID
symbolstring交易对
sidestring方向(buy/sell
order_typestring订单类型(limit/market
pricestring订单价格(Decimal 字符串)
amountstring订单数量(Decimal 字符串)
filled_amountstring已成交数量(Decimal 字符串)
remaining_amountstring剩余数量(Decimal 字符串)
leveragenumber杠杆倍数
statusstring订单状态(见上表)
created_atnumber创建时间(毫秒级时间戳)

取消订单

取消单个活动订单。只能取消状态为 openpendingpartially_filled 的订单。

接口信息

  • Method: DELETE
  • Path: /api/v1/orders/:order_id
  • Authentication: 需要 JWT Token
  • Content-Type: application/json

路径参数

参数类型必须描述
order_idstring订单 UUID

请求参数

参数类型必须描述
signaturestringEIP-712 取消订单签名(0x 开头)
timestampnumberUnix 时间戳(秒)

EIP-712 签名

取消订单的 typed data 结构:

{
"types": {
"CancelOrder": [
{ "name": "wallet", "type": "address" },
{ "name": "orderId", "type": "string" },
{ "name": "timestamp", "type": "uint256" }
]
},
"message": {
"wallet": "0x742d35cc6634c0532925a3b844bc9e7595f0beb",
"orderId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "1704067200"
}
}

前端签名示例

async function cancelOrder(orderId) {
const wallet = await getConnectedWallet();
const timestamp = Math.floor(Date.now() / 1000);

const domain = {
name: "ZTDX",
version: "1",
chainId: 421614,
verifyingContract: vaultAddress
};

const types = {
CancelOrder: [
{ name: "wallet", type: "address" },
{ name: "orderId", type: "string" },
{ name: "timestamp", type: "uint256" }
]
};

const message = {
wallet: wallet.address.toLowerCase(),
orderId: orderId,
timestamp: timestamp.toString()
};

const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const signature = await signer.signTypedData(domain, types, message);

const response = await fetch(`/api/v1/orders/${orderId}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
},
body: JSON.stringify({ signature, timestamp })
});

return response.json();
}

请求示例

{
"signature": "0xabcdef123456...",
"timestamp": 1704067200
}

响应示例

{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"symbol": "BTCUSDT",
"side": "buy",
"order_type": "limit",
"price": "65000",
"amount": "0.1",
"filled_amount": "0.05",
"remaining_amount": "0.05",
"leverage": 10,
"status": "cancelled",
"created_at": 1704067200000
}

保证金释放

取消订单后,系统会自动释放未使用的保证金:

  • 未成交部分的保证金 会立即返回到可用余额
  • 已成交部分的保证金 会继续锁定在仓位中

错误响应

HTTP 状态码错误码描述
400ORDER_NOT_CANCELLABLE订单状态不允许取消(已成交或已取消)
400TIMESTAMP_EXPIRED时间戳已过期
400INVALID_SIGNATURE_FORMAT签名格式无效
401SIGNATURE_INVALIDEIP-712 签名验证失败
403ORDER_NOT_OWNED无权取消此订单(不属于您)
404ORDER_NOT_FOUND订单不存在

批量取消订单

一次性取消多个订单。适用于需要快速清空所有挂单的场景。

接口信息

  • Method: POST
  • Path: /api/v1/orders/batch
  • Authentication: 需要 JWT Token
  • Content-Type: application/json

请求参数

参数类型必须描述
order_idsarray订单 UUID 列表(数组)
signaturestringEIP-712 批量取消签名
timestampnumberUnix 时间戳(秒)

EIP-712 签名

批量取消的 typed data 结构:

{
"types": {
"BatchCancelOrders": [
{ "name": "wallet", "type": "address" },
{ "name": "orderIds", "type": "string" },
{ "name": "timestamp", "type": "uint256" }
]
},
"message": {
"wallet": "0x742d35cc6634c0532925a3b844bc9e7595f0beb",
"orderIds": "uuid1,uuid2,uuid3", // 逗号分隔
"timestamp": "1704067200"
}
}
注意

orderIds 是一个逗号分隔的字符串,不是数组!

前端签名示例

async function batchCancelOrders(orderIds) {
const wallet = await getConnectedWallet();
const timestamp = Math.floor(Date.now() / 1000);

// 将 UUID 数组转为逗号分隔的字符串
const orderIdsString = orderIds.join(',');

const domain = {
name: "ZTDX",
version: "1",
chainId: 421614,
verifyingContract: vaultAddress
};

const types = {
BatchCancelOrders: [
{ name: "wallet", type: "address" },
{ name: "orderIds", type: "string" },
{ name: "timestamp", type: "uint256" }
]
};

const message = {
wallet: wallet.address.toLowerCase(),
orderIds: orderIdsString,
timestamp: timestamp.toString()
};

const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const signature = await signer.signTypedData(domain, types, message);

const response = await fetch('/api/v1/orders/batch', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
},
body: JSON.stringify({
order_ids: orderIds, // 发送数组
signature,
timestamp
})
});

return response.json();
}

请求示例

{
"order_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"550e8400-e29b-41d4-a716-446655440001",
"550e8400-e29b-41d4-a716-446655440002"
],
"signature": "0xabcdef123456...",
"timestamp": 1704067200
}

响应示例

{
"cancelled": [
"550e8400-e29b-41d4-a716-446655440000",
"550e8400-e29b-41d4-a716-446655440002"
],
"failed": [
"550e8400-e29b-41d4-a716-446655440001"
]
}

响应字段说明

字段类型描述
cancelledarray成功取消的订单 ID 列表
failedarray取消失败的订单 ID 列表
部分成功

即使某些订单取消失败,已成功取消的订单仍然有效。请检查 failed 数组中的订单。

失败原因

订单可能取消失败的原因:

  • 订单不存在
  • 订单不属于您
  • 订单已经成交
  • 订单已经被取消

最佳实践

1. 使用限价单控制风险

// ✅ 推荐:使用限价单
await createOrder({
symbol: "BTCUSDT",
side: "buy",
order_type: "limit",
amount: "0.1",
price: "65000", // 明确价格
leverage: 10
});

2. 市价单适合快速成交

// 适用场景:需要立即平仓
await createOrder({
symbol: "BTCUSDT",
side: "sell",
order_type: "market",
amount: "0.1",
leverage: 10
});

3. 批量取消优化

// ✅ 推荐:一次性取消所有订单
const openOrders = await getOpenOrders();
const orderIds = openOrders.map(o => o.order_id);
await batchCancelOrders(orderIds);

// ❌ 不推荐:逐个取消
for (const order of openOrders) {
await cancelOrder(order.order_id); // 太慢!
}

4. 错误处理

try {
const result = await createOrder(order);
console.log('订单创建成功:', result.order_id);
} catch (error) {
if (error.code === 'INSUFFICIENT_BALANCE') {
alert('余额不足,请充值');
} else if (error.code === 'SIGNATURE_INVALID') {
alert('签名验证失败,请重新签名');
} else {
alert('订单创建失败: ' + error.message);
}
}

相关文档