合约交易系统设计
永续合约(USDT-M / COIN-M)系统的完整架构设计,涵盖保证金计算、仓位管理、资金费率、强平引擎、ADL 与保险基金。
1. 合约交易总览
永续合约
无到期日的合约产品。通过资金费率机制锚定标的现货价格。交易者可做多或做空。
USDT-M
以 USDT 作为保证金和结算货币。盈亏以 USDT 计算。如 BTCUSDT 永续合约。
COIN-M
以对应币种作为保证金。如 BTCUSD 合约用 BTC 做保证金,盈亏以 BTC 计算。
杠杆
1x-125x 可调。杠杆越高,所需保证金越少,但强平风险越大。
2. 保证金模型
保证金计算公式
// === 初始保证金 (开仓时需要) === initialMargin = notionalValue / leverage notionalValue = quantity * entryPrice // USDT-M notionalValue = quantity * contractSize / entryPrice // COIN-M // 例: BTC 价格 42000, 买入 1 BTC, 10x 杠杆 // initialMargin = (1 * 42000) / 10 = 4,200 USDT // === 维持保证金 (低于此值触发强平) === maintenanceMargin = notionalValue * maintenanceMarginRate // maintenanceMarginRate 按档位递增: // < 50,000 USDT: 0.4% // < 250,000 USDT: 0.5% // < 1,000,000 USDT: 1.0% // ... // === 保证金率 === marginRatio = (margin + unrealizedPnL) / maintenanceMargin // marginRatio < 100% → 触发强平 // === 开仓冻结 === frozenAmount = initialMargin + openFee + closeFeeReserve // 预留平仓手续费,确保有足够资金平仓 // === 逐仓 vs 全仓 === // 逐仓: margin 固定,只看单个仓位 // 全仓: margin = accountBalance - 其他仓位initialMargin + 所有unrealizedPnL
资金利用率高,多仓位盈亏互补。适合对冲交易。缺点是一个仓位大亏可能拖累所有仓位。
风险隔离,最大亏损可预知。适合高杠杆投机。缺点是需要为每个仓位分别配置保证金。
逐仓模式下,用户可手动追加保证金提高强平价格。全仓模式自动使用可用余额。
大仓位使用更高的维持保证金率(阶梯费率),防止大仓位强平冲击市场。
保证金计算器
调整杠杆、价格和数量,实时查看保证金需求和强平价格:
| 杠杆 | 初始保证金 | 强平价 | 距强平% | 盈亏 @43000 | ROE |
|---|---|---|---|---|---|
| 1x | 42000.00 | N/A | 100% | +1000.00 | +2.4% |
| 2x | 21000.00 | 21168.00 | 49.60% | +1000.00 | +4.8% |
| 5x | 8400.00 | 33768.00 | 19.60% | +1000.00 | +11.9% |
| 10x | 4200.00 | 37968.00 | 9.60% | +1000.00 | +23.8% |
| 20x | 2100.00 | 40068.00 | 4.60% | +1000.00 | +47.6% |
| 50x | 840.00 | 41328.00 | 1.60% | +1000.00 | +119.0% |
| 100x | 420.00 | 41748.00 | 0.60% | +1000.00 | +238.1% |
3. 仓位管理
仓位操作逻辑
// === 开仓 ===
function openPosition(userId, symbol, side, qty, price, leverage):
margin = (qty * price) / leverage
freeze(userId, margin + fees)
position = {
userId, symbol, side,
quantity: qty,
entryPrice: price,
margin,
leverage,
liquidationPrice: calcLiquidationPrice(side, price, leverage)
}
// === 加仓 (同方向) ===
function addToPosition(position, addQty, addPrice):
newQty = position.quantity + addQty
// 更新加权平均入场价
position.entryPrice = (position.quantity * position.entryPrice
+ addQty * addPrice) / newQty
position.quantity = newQty
position.margin += (addQty * addPrice) / position.leverage
position.liquidationPrice = recalcLiquidationPrice(position)
// === 减仓 / 平仓 ===
function reducePosition(position, closeQty, closePrice):
// 已实现盈亏
if position.side == 'LONG':
pnl = (closePrice - position.entryPrice) * closeQty
else:
pnl = (position.entryPrice - closePrice) * closeQty
// 释放保证金
releasedMargin = position.margin * (closeQty / position.quantity)
returnToUser(releasedMargin + pnl - closeFee)
position.quantity -= closeQty
position.margin -= releasedMargin
if position.quantity == 0:
deletePosition(position)
// === 强平价格计算 ===
// LONG: liqPrice = entryPrice * (1 - 1/leverage + mmr)
// SHORT: liqPrice = entryPrice * (1 + 1/leverage - mmr)
// mmr = maintenanceMarginRate (维持保证金率)4. 标记价格与指数价格
多个外部交易所现货价格的加权中位数。权重按交易量分配,异常价格自动剔除。
= IndexPrice * (1 + FundingBasis)。用于计算未实现盈亏和强平,避免单一价格操纵。
LastPrice 用于止损/止盈触发;MarkPrice 用于强平和 PnL 计算。两者分离防止插针强平。
如果 MarkPrice 与 LastPrice 偏差 > 5%,启用价格保护模式,暂停强平直到价格回归。
5. 资金费率
// === 资金费率计算 === premiumIndex = (contractPrice - indexPrice) / indexPrice interestRate = 0.01% // 固定利率(可配置) // clamp 限制在 [-0.05%, 0.05%] 范围内 fundingRate = premiumIndex + clamp(interestRate - premiumIndex, -0.0005, 0.0005) // 最终 fundingRate 限制在 [-0.75%, 0.75%] fundingRate = clamp(fundingRate, -0.0075, 0.0075) // === 结算 === // 例: 持仓 10 BTC, MarkPrice = 42000, fundingRate = 0.01% // payment = 10 * 42000 * 0.0001 = 42 USDT // 如果 fundingRate > 0: 多头支付 42 USDT, 空头收到 42 USDT // 如果 fundingRate < 0: 空头支付, 多头收到 // === 结算时机 === // 只对结算时刻有持仓的用户收/付 // 结算前 15 秒冻结开仓(防止套利) // 结算后立即解冻
资金费率计算器
调整合约价格与指数价格的差值,观察资金费率如何变化:
6. 强平引擎
强平流程详解
// === 强平检测(每次 markPrice 更新) ===
function checkLiquidation(position, markPrice):
notional = position.quantity * markPrice
unrealizedPnL = calcUnrealizedPnL(position, markPrice)
maintenanceMargin = notional * getMMRate(notional)
// 逐仓
if position.marginType == 'ISOLATED':
marginRatio = (position.margin + unrealizedPnL) / maintenanceMargin
if marginRatio < 1.0:
triggerLiquidation(position)
// 全仓
else:
accountEquity = getAccountBalance(position.userId)
+ getAllUnrealizedPnL(position.userId)
totalMM = getAllMaintenanceMargin(position.userId)
if accountEquity < totalMM:
triggerLiquidation(position) // 按亏损最大的仓位优先
// === 强平订单 ===
function triggerLiquidation(position):
liquidationOrder = {
userId: SYSTEM,
side: opposite(position.side),
quantity: position.quantity,
type: 'MARKET',
isLiquidation: true,
priority: MAX, // 最高优先级
bankruptcyPrice: calcBankruptcyPrice(position)
}
submitToMatchingEngine(liquidationOrder)
// === 破产价格 ===
// LONG: bankruptcyPrice = entryPrice * (1 - 1/leverage)
// SHORT: bankruptcyPrice = entryPrice * (1 + 1/leverage)
// 实际成交价优于破产价 → 余额归保险基金
// 实际成交价差于破产价 → 保险基金补差额7. 自动减仓 (ADL)
当保险基金不足以覆盖强平损失时,系统自动减仓(Auto-Deleveraging)盈利最多的对手方仓位。
ADL 排序 = PnL% * 有效杠杆。盈利比例最高且杠杆最高的用户排在最前面,最先被减仓。
前端显示 ADL 风险等级(5 格灯塔)。用户可以通过降低杠杆或减少仓位降低 ADL 排名。
ADL 按被强平者的破产价格成交,不是市价。被减仓方按此价格强制平仓。
ADL 是最后手段,正常市场极少触发。保险基金的充裕程度直接影响 ADL 频率。
8. 保险基金
来源
强平订单成交价优于破产价时,差额进入保险基金。例如强平价 41000,破产价 40500,差额 500 USDT 归保险基金。
用途
强平订单成交价差于破产价时,从保险基金补偿差额,避免触发 ADL 影响其他用户。
透明度
保险基金余额定期公开披露。支持按交易对查看保险基金历史变化趋势。
上限
设置保险基金上限。超过上限的部分可用于回购平台代币/分红,防止资金沉淀。
9. 风控系统
仓位越大,要求的维持保证金率越高。分 7-10 个档位,每个档位有独立的 MMR。防止大仓位强平时冲击市场。
限价单价格不能偏离 Mark Price 超过一定比例(如 5%)。防止刷单和价格操纵。市价单有最大滑点保护。
单用户单合约最大持仓量限制。防止单一用户集中度过高影响市场。大户需要申请提高限额。
短时间内价格波动超过阈值时,暂停撮合 1-5 分钟。冷却后恢复交易,防止连环强平。
10. 现货 vs 合约差异
┌──────────────┬────────────────────┬────────────────────────┐ │ 维度 │ 现货交易 │ 合约交易 │ ├──────────────┼────────────────────┼────────────────────────┤ │ 资产 │ 实际持有币种 │ 合约(虚拟资产) │ │ 方向 │ 只能买入/卖出 │ 做多/做空 │ │ 杠杆 │ 1x (无杠杆) │ 1x-125x │ │ 保证金 │ 全额支付 │ 按杠杆缴纳保证金 │ │ 到期日 │ N/A │ 永续无到期/交割有到期 │ │ 资金费率 │ 无 │ 每 8 小时结算 │ │ 强平 │ 无 │ 保证金率低于阈值触发 │ │ 盈亏 │ 卖出时结算 │ 实时未实现 + 已实现 │ │ 账户 │ 现货账户 │ 合约账户(独立) │ │ 手续费 │ Maker/Taker │ Maker/Taker + 资金费率 │ │ 冻结 │ 买冻USDT/卖冻BTC │ 冻保证金 + 预留费用 │ │ 结算 │ 即时交割 │ PnL + 保证金释放 │ │ 风控 │ 余额校验 │ 保证金率 + 强平 + ADL │ └──────────────┴────────────────────┴────────────────────────┘