exchange.IO("lp.decrease", ...)
按比例从仓位撤出流动性,同时领取全部手续费与farm奖励,仓位保留。
exchange.IO(k, positionId, ratio)
exchange.IO(k, positionId, ratio, options)示例
仓位出区间时撤出一半并卖回USDC。
javascript
function main() {
var list = exchange.IO("lp.positions", "SOL_USDC")
if (!list) {
Log("查询失败:", GetLastError())
return
}
list.forEach(function(p) {
if (p.inRange) {
return
}
var r = exchange.IO("lp.decrease", p.id, 0.5, {sell: true})
if (!r) {
Log(p.id, "减仓失败:", GetLastError())
return
}
var row = r.positions[0]
Log(p.id, "拿回", row.receivedBase, "SOL", row.receivedQuote, "USDC",
"其中手续费", row.feesBase, row.feesQuote, "卖出", JSON.stringify(r.sells))
})
}返回值
| 类型 | 描述 |
object / 空值 |
|
参数
| 名称 | 类型 | 必填 | 描述 |
k | string | 是 | 固定为 |
positionId | string | 是 | 仓位ID( |
ratio | number | 是 | 撤出的比例,(0, 1],换算成万分比;为1时撤空但不关仓(关仓用 |
options | object | 否 |
|
参考
Jupiter exchange.IO exchange.IO("lp.remove") exchange.IO("lp.collect") exchange.IO("lp.positions") exchange.IO("lp.increase")
备注
各协议的做法
- Meteora DLMM:从仓位每个有流动性的bin按比例撤出(
remove_liquidity_by_range2),并领取手续费与奖励;超过70个bin的仓位按70个bin一段分多笔交易。撤出没有最少到手量的保护:拿回的是每个bin里的份额,数量取决于撤出时各bin的构成。 - Raydium CLMM:一笔
decrease_liquidity_v2撤出这个比例的流动性并领取手续费与全部奖励,两种代币的最少到手量为按现价算的数量 × 0.99。 - Orca Whirlpools:一笔交易按比例减流动性(
decrease_liquidity_v2,两种代币各有最少到手量 = 按现价估算的数量减1%,价格变动越过这个保护时模拟失败、不发送)并领取手续费与奖励(collect_fees_v2、collect_reward_v2)。
返回的仓位行
| 字段 | 说明 |
|---|---|
receivedBase、receivedQuote | 实际拿回的两种代币(按交易前后余额计算) |
feesBase、feesQuote | 其中的手续费部分(按发送前链上可领的量拆出) |
principalBase、principalQuote | 其中的本金部分 = 拿回的 − 手续费 |
rewards | 领到的farm奖励[{mint, symbol, amount}](不含池子的两种代币) |
rentRefundSol | 关仓退回的租金(SOL) |
feeSol | 这些交易付的网络费(SOL) |
朝向(基础币、计价币)按稳定币(其次SOL)作计价币。sells每项为{symbol, qty, txHash},卖出失败时为{symbol, qty, error};卖出是Jupiter市价单,只等广播、不等确认,用exchange.IO("receipt")查结果。
交易的执行
每笔交易发送前都用节点模拟一遍,模拟失败不发送并报出原因(DLMM、Raydium CLMM、Orca Whirlpool的错误码附名字);计算单元上限按模拟用量加余量,优先费按最近写这些账户的交易的费率取第75百分位,不超过exchange.IO("priorityFee")的上限。交易确认后才返回,实际数量按交易前后的余额计算。120秒内既没确认也证明不了过期时报outcome is unknown并附交易签名:交易可能已经上链,先用exchange.IO("receipt")核对再决定是否重试。