订单、仓位与杠杆:下单 流程完整技术文档
版本: v1.0
日期: 2026-04-13
适用范围: ZTDX.io USDT 保证金永续合约
目录
1. 概述
ZTDX.io 永续合约的下单流程涉及三个核心实体的交互:
| 实体 | 说明 |
|---|---|
| 订单(Order) | 用户提交的交易指令,携带杠杆参数 |
| 仓位(Position) | 订单撮合成交后产生或更新的持仓记录 |
| 杠杆(Leverage) | 决定保证金需求和仓位规模的倍数因子 |
核心设计原则:
- 杠杆跟随订单:每笔订单独立指定杠杆,而非全局设置
- 最大杠杆按交易对配置:不同交易对有不同的最大杠杆上限
- 仓位按方向合并:同一用户、同一交易对、同一方向仅维持一个仓位
- 反方向自动对冲:新订单方向与已有仓位相反时,优先平仓
2. 核心概念
2.1 杠杆的作用
杠杆本质上是一个资金效率倍数器,它影响两个方面:
下单时 — 决定需要冻结多少保证金:
所需保证金 = 名义价值 / 杠杆
持仓时 — 决定仓位规模和强平距离:
仓位规模 = 保证金 × 杠杆
强平距离 ∝ 1 / 杠杆 (杠杆越高,强平价格越近)
2.2 杠杆范围
| 参数 | 值 | 说明 |
|---|---|---|
| 最小杠杆 | 1x | 所有交易对统一 |
| 默认最大杠杆 | 50x | 未单独配置的交易对 |
| 可配置最大杠杆 | 最高 100x | 按交易对在服务端独立配置 |
2.3 保证金体系
| 参数 | 值 | 说明 |
|---|---|---|
| 维持保证金率(MMR) | 0.5% | 低于此比例触发强制平仓 |
| 开仓费率 | 0.1% | 从保证金中扣除 |
| 保证金缓冲 | 0.5% | 下单时额外冻结,覆盖手续费和滑点 |
| 最小保证金 | $10 | 单笔订单最低保证金 |
| 最小仓位规模 | $100 | 低于此值不创建仓位 |
3. 下单请求
3.1 请求端点
POST /fapi/v1/order
3.2 请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
symbol | String | 是 | 交易对,如 BTCUSDT |
side | Enum | 是 | BUY 或 SELL |
order_type | Enum | 是 | LIMIT 或 MARKET |
price | Decimal | 限价必填 | 委托价格 |
amount | Decimal | 是 | 下单数量(代币数量) |
leverage | Integer | 是 | 杠杆倍数(1 ~ max_leverage) |
signature | String | JWT 必填 | EIP-712 签名 |
timestamp | Integer | JWT 必填 | Unix 时间戳(5 分钟有效窗口) |
3.3 EIP-712 签名内容
签名覆盖以下字段,确保杠杆参数不可篡改:
CreateOrder(
address wallet,
string symbol,
string side,
string orderType,
uint256 price,
uint256 amount,
uint32 leverage,
uint256 timestamp
)
注意: API Key 认证方式下,
signature和timestamp为可选参数。
4. 杠杆验证
订单提交后,系统按以下顺序验证杠杆:
4.1 验证流程
请求中的 leverage
│
▼
① 检查 leverage ≥ 1
│
▼
② 读取交易对配置,获取该交易对的最大杠杆
│
▼
③ 检查 leverage ≤ max_leverage
│
▼
④ 验证通过 → 继续下单流程
4.2 交易对杠杆配置
每个交易对的杠杆上限由服务端配置管理,可通过 Admin API 动态调整,无需重启服务。调整后对新订单立即生效。
4.3 验证失败响应
{
"code": -1128,
"msg": "Invalid leverage. Must be between 1 and 100 for BTCUSDT"
}
5. 保证金计算与余额冻结
杠杆验证通过后,系统计算本次订单所需的保证金并冻结用户余额。
5.1 标准保证金计算
当用户没有反方向仓位时,使用标准公式:
名义价值 = amount × price
基础保证金 = 名义价值 / leverage
缓冲金额 = 基础保证金 × 0.5%
所需保证金 = 基础保证金 + 缓冲金额
计算示例:
| 参数 | 值 |
|---|---|
| 交易对 | BTCUSDT |
| 方向 | BUY |
| 数量 | 1 BTC |
| 价格 | $60,000 |
| 杠杆 | 10x |
名义价值 = 1 × $60,000 = $60,000
基础保证金 = $60,000 / 10 = $6,000
缓冲金额 = $6,000 × 0.5% = $30
所需保证金 = $6,000 + $30 = $6,030
5.2 对冲保证金计算
当用户已有反方向仓位时,保证金需求会降低:
场景 A:订单完全平掉反向仓位
条件: 订单名义价值 ≤ 反向仓位规模
所需保证金 = 订单名义价值 × 0.5% (仅需手续费)
示例: 持有 $50,000 空仓,下买单 $30,000
所需保证金 = $30,000 × 0.5% = $150 (而非 $30,000/leverage)
场景 B:订单平掉反向仓位后还有剩余
条件: 订单名义价值 > 反向仓位规模
净增部分 = 订单名义价值 - 反向仓位规模
净增保证金 = 净增部分 / leverage
缓冲 = 净增保证金 × 0.5%
所需保证金 = 净增保证金 + 缓冲
示例: 持有 $50,000 空仓,下买单 $80,000,杠杆 10x
净增部分 = $80,000 - $50,000 = $30,000
净增保证金 = $30,000 / 10 = $3,000
缓冲 = $3,000 × 0.5% = $15
所需保证金 = $3,000 + $15 = $3,015
场景 C:无反方向仓位
使用 5.1 节的标准公式。
5.3 余额冻结
验证用户可用余额充足后,执行冻结:
- 将本次订单所需保证金从「可用余额」划入「冻结余额」
- 订单对象记录
frozen_margin(冻结金额),用于订单成交或取消时精确释放 - 冻结操作与订单落库在同一事务内完成,保证一致性
6. 撮合引擎处理
6.1 订单提交到撮合引擎
保证金冻结完成后,订单写入数据库(status = pending),随后提交到内存撮合引擎:
matching_engine.submit_order(
order_id,
symbol,
user_address,
side,
order_type,
amount,
price,
leverage ← 杠杆传入撮合引擎
)
6.2 撮合过程
撮合引擎按价格-时间优先算法匹配买卖订单。成交时产生 TradeEvent:
TradeEvent {
symbol: "BTCUSDT",
trade_id: UUID,
maker_order_id: UUID, // 挂单方
taker_order_id: UUID, // 吃单方
maker_address: "0x...",
taker_address: "0x...",
side: "buy", // 吃单方方向
price: 60000.0, // 成交价
amount: 1.0, // 成交数量
maker_fee: 12.0, // 0.02% of $60,000
taker_fee: 30.0, // 0.05% of $60,000
maker_leverage: 5, // 挂单方杠杆
taker_leverage: 10, // 吃单方杠杆
timestamp: ...
}
关键点: 成交事件中保留了双方各自的杠杆值(maker_leverage 和 taker_leverage),因为它们可能不同。