永续合约:非交易时段杠杆
Sai Perp 支持设有交易时段的市场的非交易时段风险控制。休市期间无法像开市时一样进行普通交易、持续强平和获取最新退出价格,因此会降低跨越收盘时间持有的仓位的有效敞口。
本页反映非交易时段杠杆上线及后续修复后,合并到 sai-perps main 分支的行为。
AFTER_HOURS_MARKETS 中启用的市场,对跨越最近一次收盘时间持有的仓位,使用 AFTER_HOURS_LEVERAGE 保存的全局上限。
effective_leverage = min(Trade.leverage, AFTER_HOURS_LEVERAGE)仅适用于已成交的 TradeType::Trade 仓位。待成交的限价和止损入场单在触发前没有实际敞口,因此不受限制。
休市期间仍禁止普通开仓和主动平仓。非交易时段触发流程是维护操作,可强平或归一化风险,不会重新开放市场供自主退出。
相关存储:
| 状态 | 类型 | 用途 |
|---|---|---|
AFTER_HOURS_LEVERAGE | Item<Decimal> | 已配置非交易时段市场的全局有效杠杆上限 |
AFTER_HOURS_MARKETS | Map<MarketIndex, bool> | 适用非交易时段上限的市场 |
MarketInfo.block_last_closed | Option<u64> | 最近进入 Closed 的区块 |
MarketInfo.block_last_opened | Option<u64> | 最近重新进入 Open 的区块 |
MarketInfo.last_close_price | Option<Decimal> | 尽可能记录的收盘价格快照,作为市场元数据 |
last_close_price 不是非交易时段风险检查的结算价。强平和归一化使用普通价格查询返回的预言机价格。
除非以下条件全部成立,get_effective_leverage 返回已保存的 Trade.leverage。
- 仓位未平仓,且
trade_type == TradeType::Trade。 - 市场在
AFTER_HOURS_MARKETS中启用。 block_last_closed和block_last_opened已初始化。- 最近开市区块及之后未开仓或修改风险。
Trade.leverage高于AFTER_HOURS_LEVERAGE。
开市区块边界包含等号。TradeInfo.created_block >= MarketInfo.block_last_opened 的交易保留已保存的杠杆。
合约可将 TriggerTrade 路由到非交易时段风险处理:
- 从普通价格查询加载返回的预言机价格。
- 先按已保存杠杆对应的强平价检查强平。
- 需要强平时走强平流程。
- 无需强平时,将已保存杠杆降至有效上限。
- 对移除的仓位规模差值,以
after_hours_risk_trigger类型调用process_closing_fees。 - 更新未平仓量并发出
sai/perp/trigger_trade/after_hours。
归一化不支付 catalyst 奖励。调用方协助同步风险,并非执行交易者的 TP/SL 订单。
归一化费用耗尽剩余抵押资产时,合约在费用和风险更新后关闭交易。
预言机价格时效
Section titled “预言机价格时效”即使休市时间使普通时效窗口失效,非交易时段强平和归一化仍有意使用返回的预言机价格。此有限例外使休市时仍能降低高杠杆留仓敞口。
普通开仓、主动平仓及正常 TP/SL 触发仍使用普通市场状态和时效检查,不回退到 last_close_price。
合约查询保留存储状态,并公开派生风险状态:
get_trade返回存储的Trade,包括Trade.leverage。- 交易符合归一化条件时,
get_trade_data返回needs_after_hours_trigger: true。 get_trade_pnl使用有效杠杆评估留仓交易。GetAfterHoursLeverage、IsAfterHoursMarket、ListAfterHoursMarkets提供当前上限和启用市场。
客户端不应仅凭存储杠杆推断非交易时段状态。判断 Keeper 或界面刷新是否应提交 TriggerTrade 时,使用派生查询字段。
修改前的延迟清理
Section titled “修改前的延迟清理”留仓的存储杠杆高于有效上限时,用户后续修改会先落实非交易时段归一化,再对归一化后的交易执行请求。
该检查在更新杠杆、TP/SL 和增加仓位规模前执行。减少规模时,仍优先检查强平,再调整仓位。