CL LP Auto-Rebalancer v1
Cron 驱动的 Uniswap V3 集中流动性自动调仓机器人,运行在 EVM L2 链上,通过 onchainos CLI 执行 DeFi 操作。核心思路:波动率决定范围宽度 — 低波动率时收紧范围提高资本效率,高波动率时放宽范围减少调仓频率和无常损失。
每个 tick:获取价格 → 波动率分析 → 范围计算 → 调仓决策 → 执行调仓 → 报告。
Architecture
CODEBLOCK0
OKX Skill Dependencies (via onchainos CLI — 处理认证、链解析、错误重试):
- - Price: INLINECODE2
- K-line: INLINECODE3
- Quote: INLINECODE4
- Swap: INLINECODE5
- Approve: INLINECODE6
- Pool Search: INLINECODE7
- Pool Detail: INLINECODE8
- Calculate Entry: INLINECODE9
- Deposit: INLINECODE10
- Redeem: INLINECODE11
- Claim Fees: INLINECODE12
- Positions: INLINECODE13
- Position Detail: INLINECODE14
Step 0: Pool Selection (First-Time Setup)
When user has no config.json or asks to set up a new pool, trigger this step.
核心原则:AI 应从用户的自然语言中提取意图,自动推断尽可能多的参数,只在信息不足时才追问。
0.1 Intent Recognition
从用户输入中提取:
| 信息 | 示例用户输入 | 提取结果 |
|---|
| 链 | "在 Base 上做 LP" | chain = base |
| 代币对 |
"ETH/USDC 的流动性" | token0 = ETH, token1 = USDC |
| 风险偏好 | "稳定一点的" | pool_type = stablecoin |
| Fee tier | "0.3% 的池子" | fee_tier = 0.3% |
缺失信息的默认推断:
- - 未指定链 → 推荐 Base(L2 gas 低,适合频繁调仓)
- 未指定代币对 → 必须追问(核心参数,无法推断)
- 未指定 fee tier → 根据代币对自动选 TVL 最大的池子
- 未指定风险偏好 → 从代币对自动分类
0.2 Pool Type Classification
根据代币对自动分类,不需要问用户:
| 类型 | 判断规则 | 默认参数集 |
|---|
| 稳定币对 | 两个都是稳定币(USDC/USDT/DAI/FRAX) | 窄范围、低止损 |
| Native/稳定币 |
一个是 ETH/WETH/WBTC,另一个是稳定币 | 标准参数 |
|
非稳定币对 | 两个都不是稳定币,但都是主流币 | 宽范围、高止损 |
|
含 Meme 币 | 代币不在主流币列表中(市值低、无 Coingecko 排名) | 极宽范围 + 强制风险确认 |
主流币白名单:ETH, WETH, WBTC, USDC, USDT, DAI, FRAX, ARB, OP, MATIC, BNB, AVAX, SOL
0.3 Meme Coin Risk Gate
仅当检测到 meme/低市值代币时触发。MUST display warning before proceeding:
CODEBLOCK1
Must get explicit user confirmation before proceeding.
0.4 Search, Rank & Auto-Select
CODEBLOCK2
自动选择逻辑(用户无需手动选):
- 1. 按 TVL 降序排列
- 如果用户指定了 fee tier → 直接匹配
- 如果未指定 → 选 TVL 最大的池子(通常是最佳流动性)
- 展示选择结果供用户确认:池名、fee tier、TVL、预估池 APY(
rate 字段)
Fee tier 参考(仅在用户问及或多池需选择时展示):
- - 0.01%: 稳定币对 · 0.05%: 高相关性对 · 0.3%: 主流对(推荐)· 1%: 高波动对
0.5 Generate config.json
自动 fetch detail (onchainos defi detail) 并生成 config,无需用户手动填写。
字段映射:
- -
investment_id ← search INLINECODE19 - INLINECODE20 ← search INLINECODE21
- INLINECODE22 ← detail
analysisPlatformId(注意不是 platformId) - INLINECODE25 ← search INLINECODE26
- INLINECODE27 ← 根据 fee tier 推导:0.01%→1, 0.05%→10, 0.3%→60, 1%→200
- INLINECODE28 ← detail
underlyingToken。如果 token 是 native ETH(0xeee...),LP 合约用 WETH,需映射(Base: 0x4200000000000000000000000000000000000006) - INLINECODE32 ← 始终
0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee(用于 swap 和余额查询) - 其余参数 ← 根据 pool type 自动填入下表默认值
CODEBLOCK3
Pool-type-specific defaults(自动应用,无需用户选择):
| Parameter | 稳定币对 | Native/稳定币 | 非稳定币 | Meme 池 |
|---|
| INLINECODE34 | 0.5 | 2 | 3 | 5 |
| INLINECODE35 |
2 | 5 | 8 | 15 |
|
range_mult.low | 0.5 | 1.0 | 1.2 | 1.5 |
|
range_mult.extreme | 1.0 | 2.0 | 2.5 | 3.0 |
|
stop_loss_pct | 0.05 | 0.15 | 0.20 | 0.30 |
|
trailing_stop_pct | 0.03 | 0.10 | 0.15 | 0.20 |
|
max_il_tolerance_pct | 1.0 | 5.0 | 8.0 | 15.0 |
|
gas_reserve_eth | 0.005 | 0.02 | 0.02 | 0.02 |
0.6 Gate
- - [ ]
config.json written with valid investment_id, token0, INLINECODE45 - [ ]
.env configured (copy from .env.example, fill in API credentials + WALLET_ADDR) - [ ]
onchainos wallet balance returns valid balances for the target chain - [ ] If meme pool: user has explicitly confirmed risk warning
Pipeline: Runtime Steps
CRITICAL RULE: Steps MUST execute in order. Do NOT skip steps or proceed past a gate that has not been satisfied.
Step 1: Data Acquisition
Actions:
- 1. Fetch current price via
onchainos market price or INLINECODE51 - Fetch current position detail via
onchainos defi position-detail (if position exists) - Update
price_history (append, cap at 288 = 24h @ 5min) - Fetch on-chain balances via INLINECODE54
Gate (ALL must pass):
- - [ ] Price is non-null and > 0
- [ ] Circuit breaker not active (
consecutive_errors < 5) - [ ] Stop not triggered (
stop_triggered == null)
Step 2: Volatility & Trend Analysis
Actions:
- 1. Fetch K-line data (1H candles, 24 bars) → compute ATR-based volatility (hourly cache)
- Classify volatility: low (<1.5%), medium (1.5-3%), high (3-5%), extreme (>5%)
- Compute multi-timeframe trend analysis (复用 grid-trading MTF):
- Short EMA (25min), Medium EMA (1h), Long EMA (4h)
- EMA alignment → trend direction (bullish/bearish/neutral) + strength (0-1)
- 8h structure detection (uptrend/downtrend/ranging)
- 4. Compute 1h and 4h momentum
Output: atr_pct float, vol_class string, mtf dict
Gate:
- - [ ]
atr_pct is non-null and > 0 - [ ]
vol_class is one of: low, medium, high, extreme - [ ]
mtf dict has trend and strength fields (graceful fallback to neutral)
Step 3: Range Calculation
Actions:
- 1. Compute range width based on volatility class:
- Low (<1.5%):
2 × ATR each side → tight range, max capital efficiency
- Medium (1.5-3%):
3 × ATR each side → balanced
- High (3-5%):
5 × ATR each side → wide range, fewer rebalances
- Extreme (>5%):
8 × ATR each side → safety first
- 2. Apply trend asymmetry (if trend strength > 0.3):
- Bullish: upper side wider, lower side tighter (跟随上涨空间)
- Bearish: lower side wider, upper side tighter (防御下跌空间)
- 3. Convert price range to tick range (aligned to pool's
tick_spacing) - Compute capital efficiency estimate: INLINECODE70
Output: tick_lower, tick_upper, range_width_pct, INLINECODE74
Gate:
- - [ ] INLINECODE75
- [ ] Range width >= minimum (2 × tick_spacing)
- [ ] tick values aligned to pool's INLINECODE76
Step 4: Rebalance Decision
Actions:
- 1. If no existing position → always deploy (first run)
- Check rebalance triggers:
-
Out of range: price < lower or price > upper → MUST rebalance
- 3. Anti-churn checks:
- Position age >=
MIN_POSITION_AGE (2h)
- Rebalance count <
MAX_REBALANCES_24H (6/day)
- Gas cost <
GAS_TO_FEE_RATIO × expected fees (50%)
- New range differs >5% from current range
- 4. Check stop conditions: stop-loss, trailing stop, IL tolerance
Gate:
- - [ ] Rebalance trigger identified, OR no rebalance needed (skip to Step 5)
- [ ] All anti-churn checks passed (if rebalancing)
- [ ] No stop condition triggered
Step 5: Execution & Notification
Actions (if rebalancing):
- 1. Claim accumulated fees: INLINECODE80
- Remove liquidity: INLINECODE81
- Calculate target token ratio for new range: INLINECODE82
- Swap to correct ratio:
onchainos swap swap (if needed) - Deposit at new range: INLINECODE84
- On failure at any sub-step: emergency fallback deploy at 3× normal width
- Record rebalance in state, update position info
Actions (always):
- 8. Calculate performance metrics (PnL, fees claimed, IL, time-in-range)
- Build structured notification output (see Notification Tiers below)
Output: tiered notification JSON (via ---JSON--- block)
Tool Wrapper: onchainos CLI Reference
Prerequisites
CODEBLOCK4
Core DeFi Operations
| Operation | Command | Key Parameters |
|---|
| Search Pools | INLINECODE86 | chain, token, product-group |
| Pool Detail |
onchainos defi detail --investment-id <id> --chain base | investment-id |
| Calculate Entry |
onchainos defi calculate-entry --investment-id <id> --chain base --tick-lower <t> --tick-upper <t> | ticks, amounts |
| Deposit |
onchainos defi deposit --investment-id <id> --chain base --amount0 <a> --amount1 <a> --tick-lower <t> --tick-upper <t> | amounts, ticks |
| Redeem |
onchainos defi redeem --investment-id <id> --chain base --token-id <nft> --percent 100 | token-id, percent |
| Claim Fees |
onchainos defi claim --investment-id <id> --chain base --token-id <nft> | token-id |
| My Positions |
onchainos defi positions --chain base | chain |
| Position Detail |
onchainos defi position-detail --investment-id <id> --chain base --token-id <nft> | token-id |
Market & Swap Operations
| Operation | Command | Key Parameters |
|---|
| Get Price | INLINECODE94 | token address |
| Get K-line |
onchainos market kline --address <token> --chain base --bar 1H --limit 24 | bar size, limit |
| Swap Quote |
onchainos swap quote --from <A> --to <B> --amount <amt> --chain base | tokens, amount |
| Execute Swap |
onchainos swap swap --from <A> --to <B> --amount <amt> --chain base --wallet <addr> --slippage 1 | wallet, slippage |
| Approve Token |
onchainos swap approve --token <addr> --amount <amt> --chain base | token, amount |
Error Handling Protocol
Every function returns (result, failure_info). Failure info is structured:
CODEBLOCK5
Auto-retry policy: 1 retry for retriable=True with 3s delay.
Rebalance failure fallback: if deposit fails after remove, emergency deploy at 3× normal width.
Tunable Parameters
Range Configuration
| Parameter | Default | Description |
|---|
| INLINECODE101 | INLINECODE102 | ATR multiplier for low volatility (<1.5%) |
| INLINECODE103 |
3.0 | ATR multiplier for medium volatility (1.5-3%) |
|
VOL_MULTIPLIER_HIGH |
5.0 | ATR multiplier for high volatility (3-5%) |
|
VOL_MULTIPLIER_EXTREME |
8.0 | ATR multiplier for extreme volatility (>5%) |
|
VOL_THRESHOLD_LOW |
1.5 | Low/medium volatility boundary (%) |
|
VOL_THRESHOLD_HIGH |
3.0 | Medium/high volatility boundary (%) |
|
VOL_THRESHOLD_EXTREME |
5.0 | High/extreme volatility boundary (%) |
|
TREND_ASYM_FACTOR |
0.3 | Max trend asymmetry ratio (0=symmetric, 1=fully asymmetric) |
|
TREND_ASYM_THRESHOLD |
0.3 | Minimum trend strength to activate asymmetry |
Rebalance Triggers
| Parameter | Default | Description |
|---|
| INLINECODE119 | INLINECODE120 | Skip rebalance if new range <5% different |
Anti-Churn Controls
| Parameter | Default | Description |
|---|
| INLINECODE121 | INLINECODE122 | 2h minimum position hold time (seconds) |
| INLINECODE123 |
6 | Maximum rebalances per 24h period |
|
GAS_TO_FEE_RATIO |
0.5 | Skip if gas > 50% of expected fees |
Multi-Timeframe Analysis
| Parameter | Default | Description |
|---|
| INLINECODE127 | INLINECODE128 | 5-bar EMA (25min @ 5min tick) |
| INLINECODE129 |
12 | 12-bar EMA (1h @ 5min tick) |
|
MTF_LONG_PERIOD |
48 | 48-bar EMA (4h @ 5min tick) |
|
MTF_STRUCTURE_PERIOD |
96 | 96-bar (8h) for structure detection |
Risk Controls
| Parameter | Default | Description |
|---|
| INLINECODE135 | INLINECODE136 | Stop if portfolio drops 15% below cost basis |
| INLINECODE137 |
0.10 | Stop if portfolio drops 10% from peak |
|
MAX_IL_TOLERANCE_PCT |
0.05 | Hard stop if IL exceeds 5% |
|
MAX_CONSECUTIVE_ERRORS |
5 | Circuit breaker threshold |
|
COOLDOWN_AFTER_ERRORS |
3600 | 1h cooldown after circuit breaker trips |
|
GAS_RESERVE |
0.003 | Native token reserved for gas |
Execution
| Parameter | Default | Description |
|---|
| INLINECODE147 | INLINECODE148 | Slippage tolerance for swaps |
| INLINECODE149 |
3.0 | Emergency fallback range = 3× normal width |
|
DRY_RUN |
false | Fetch real data but simulate operations |
Risk Control Flow
CODEBLOCK6
Operational Interface
Sub-Commands
| Command | Purpose | Trigger | Notification |
|---|
| INLINECODE153 | 主循环:采集→分析→决策→执行,结果缓存到 INLINECODE154 | Cron 每 5min | 🔔 Trade Alert / ⚠️ Risk Alert / 📊 Hourly Pulse |
| INLINECODE155 |
用户查询入口:Portfolio 总览 + 头寸 + 收益 + 范围。优先读 5min 缓存(秒级响应),过期才实时查询 | 用户主动 | 终端输出(不推送) |
|
report | 每日绩效报告 | Cron 每日 00:00 UTC | 📈 Daily Report |
|
history | 调仓历史 | 用户主动 | 终端输出(不推送) |
|
analyze | 详细 JSON 分析(波动率、范围、效率) | AI agent | 终端输出(不推送) |
|
reset | 关闭头寸并重新部署 | 手动 | 🔔 Trade Alert |
|
close | 完全退出头寸 | 手动 | 🔔 Trade Alert |
status 触发词(用户说以下任意内容时应调用 status):
- - 查询收益、收益怎么样、赚了多少、PnL、盈亏
- 查询仓位、头寸状态、LP 状况、仓位情况
- 年化多少、APY、费用收入、手续费
- 无常损失、IL
- 总资产、Portfolio、余额
- LP 里有多少 ETH / USDC
CODEBLOCK7
Notification Tiers
脚本内部封装完整的消息格式化和可视化逻辑,通过 ---JSON--- 块输出结构化数据(含 notification 渲染块),由调度器路由到通信渠道。
| Tier | 触发条件 | 推送 |
|---|
| Trade Alert | 调仓成功或失败 | 每次交易立即推送 |
| Risk Alert |
止损/熔断/连续错误 | 立即推送 |
|
Hourly Pulse | 距上次推送 ≥
QUIET_INTERVAL 且无交易 | 每小时推送 |
|
Daily Report |
report 命令 (cron daily) | 每日推送 |
INLINECODE167 /analyze 命令为用户主动查询,直接输出到终端,不推送。status 优先从 _cached_snapshot(每 5min tick 时写入)读取已计算好的数据,无需任何 API 调用即可返回完整状态(Portfolio 跨平台总览 + 头寸 + PnL + IL + APY + LP 代币拆分)。缓存过期(>360s)时自动 fallback 到实时查询。
脚本负责:消息标题、字段组织、范围位置可视化、颜色级别、footer 上下文。调度器只需透传 notification 块到通信平台。
State Schema
CODEBLOCK8
Key fields:
- -
pool: target pool configuration (chain, tokens, fee tier, tick spacing) - INLINECODE173 : NFT position ID (null if no active position)
- INLINECODE174 : ATR at position creation (for vol shift detection)
- INLINECODE175 : full audit trail of all rebalances with costs
- INLINECODE176 : key performance metric — % of ticks where price was in range
- INLINECODE177 +
total_deposits_usd: PnL 计算的成本基准 - INLINECODE179 +
unclaimed_fee_usd: LP 手续费总收入,用于推导 IL - INLINECODE181 : string describing trigger condition, or null
Core Algorithm
CODEBLOCK9
Deployment
OpenClaw Cron (recommended)
CODEBLOCK10
Manual
CODEBLOCK11
Failure & Rollback
CODEBLOCK12
Anti-Patterns
| Pattern | Problem |
|---|
| Rebalance every tick | Gas costs eat all fee income |
| Too tight range in high vol |
Constant out-of-range, excessive rebalancing |
| Too wide range in low vol | Capital inefficiency, minimal fee capture |
| No minimum position age | Rapid back-and-forth rebalancing (churn) |
| Skip emergency fallback | Funds sit idle after failed rebalance (zero yield) |
| Ignore gas costs | L1 gas can exceed daily fee income |
| Symmetric range in trends | Miss upside in bull, excess downside in bear |
| No IL tracking | Cannot detect when IL exceeds fee income |
| Rebalance on vol change alone | Minor ATR fluctuations cause unnecessary churn — only rebalance when out of range |
| No time-in-range tracking | Cannot measure strategy effectiveness |
CL LP 自动调仓机器人 v1
由 Cron 驱动的 Uniswap V3 集中流动性自动调仓机器人,运行在 EVM L2 链上,通过 onchainos CLI 执行 DeFi 操作。核心思路:波动率决定范围宽度 — 低波动率时收紧范围提高资本效率,高波动率时放宽范围减少调仓频率和无常损失。
每个 tick:获取价格 → 波动率分析 → 范围计算 → 调仓决策 → 执行调仓 → 报告。
架构
Cron (5分钟) → Python 脚本 → onchainos CLI → OKX Web3 API → 链
↓ ↓
cllpstate.json 钱包 (TEE 签名)
↓
┌──────────────┐
│ 价格获取 │ ← onchainos swap quote / 市场价格
│ K线 ATR │ ← onchainos market kline (1H × 24)
│ 多时间框架分析 │ ← price_history (288 根K线 = 24小时)
└──────┬───────┘
↓
范围计算 (波动率自适应)
↓
调仓决策
↓
┌──────────────┐
│ 领取费用 │ ← onchainos defi claim
│ 移除流动性 │ ← onchainos defi redeem
│ 兑换比例 │ ← onchainos swap swap
│ 添加流动性 │ ← onchainos defi deposit
└──────┬───────┘
↓
结构化 JSON 输出
OKX 技能依赖 (通过 onchainos CLI — 处理认证、链解析、错误重试):
- - 价格: onchainos market price --address --chain
- K线: onchainos market kline --address --chain --bar 1H --limit 24
- 报价: onchainos swap quote --from --to --amount --chain
- 兑换: onchainos swap swap --from --to --amount --chain --wallet --slippage
- 授权: onchainos swap approve --token --amount --chain
- 池子搜索: onchainos defi search --chain --token , --product-group DEX_POOL
- 池子详情: onchainos defi detail --investment-id --chain
- 计算入场: onchainos defi calculate-entry --investment-id --chain --tick-lower --tick-upper
- 存入: onchainos defi deposit --investment-id --chain --amount0 --amount1 --tick-lower --tick-upper
- 赎回: onchainos defi redeem --investment-id --chain --token-id --percent 100
- 领取费用: onchainos defi claim --investment-id --chain --token-id
- 仓位列表: onchainos defi positions --chain
- 仓位详情: onchainos defi position-detail --investment-id --chain --token-id
第 0 步:池子选择 (首次设置)
当用户没有 config.json 或要求设置新池子时,触发此步骤。
核心原则:AI 应从用户的自然语言中提取意图,自动推断尽可能多的参数,只在信息不足时才追问。
0.1 意图识别
从用户输入中提取:
| 信息 | 示例用户输入 | 提取结果 |
|---|
| 链 | 在 Base 上做 LP | chain = base |
| 代币对 |
ETH/USDC 的流动性 | token0 = ETH, token1 = USDC |
| 风险偏好 | 稳定一点的 | pool_type = stablecoin |
| 费率等级 | 0.3% 的池子 | fee_tier = 0.3% |
缺失信息的默认推断:
- - 未指定链 → 推荐 Base(L2 gas 低,适合频繁调仓)
- 未指定代币对 → 必须追问(核心参数,无法推断)
- 未指定费率等级 → 根据代币对自动选 TVL 最大的池子
- 未指定风险偏好 → 从代币对自动分类
0.2 池子类型分类
根据代币对自动分类,不需要问用户:
| 类型 | 判断规则 | 默认参数集 |
|---|
| 稳定币对 | 两个都是稳定币(USDC/USDT/DAI/FRAX) | 窄范围、低止损 |
| 原生币/稳定币 |
一个是 ETH/WETH/WBTC,另一个是稳定币 | 标准参数 |
|
非稳定币对 | 两个都不是稳定币,但都是主流币 | 宽范围、高止损 |
|
含 Meme 币 | 代币不在主流币列表中(市值低、无 Coingecko 排名) | 极宽范围 + 强制风险确认 |
主流币白名单:ETH, WETH, WBTC, USDC, USDT, DAI, FRAX, ARB, OP, MATIC, BNB, AVAX, SOL
0.3 Meme 币风险门禁
仅当检测到 meme/低市值代币时触发。必须在继续前显示警告:
⚠️ Meme 币 LP 额外风险:
- 1. 极端无常损失 — 价格可能单方向暴涨/暴跌 90%+
- 流动性枯竭 — 池子 TVL 可能骤降,头寸无法退出
- 合约风险 — 代币可能有 honeypot/税收/暂停转账等恶意机制
- 调仓失败 — 低流动性导致 swap 滑点过大
必须获得用户明确确认后才能继续。
0.4 搜索、排序与自动选择
bash
onchainos defi search --chain --token , --product-group DEX_POOL
自动选择逻辑(用户无需手动选):
- 1. 按 TVL 降序排列
- 如果用户指定了费率等级 → 直接匹配
- 如果未指定 → 选 TVL 最大的池子(通常是最佳流动性)
- 展示选择结果供用户确认:池名、费率等级、TVL、预估池 APY(rate 字段)
费率等级参考(仅在用户问及或多池需选择时展示):
- - 0.01%: 稳定币对 · 0.05%: 高相关性对 · 0.3%: 主流对(推荐)· 1%: 高波动对
0.5 生成 config.json
自动获取详情 (onchainos defi detail) 并生成配置,无需用户手动填写。
字段映射:
- - investmentid ← 搜索结果的 investmentId
- chainid ← 搜索结果的 chainIndex
- platformid ← 详情的 analysisPlatformId(注意不是 platformId)
- feetier ← 搜索结果的 feeRate
- tickspacing ← 根据费率等级推导:0.01%→1, 0.05%→10, 0.3%→60, 1%→200
- token0/token1 ← 详情的 underlyingToken。如果代币是原生 ETH(0xeee...),LP 合约使用 WETH,需映射(Base: 0x4200000000000000000000000000000000000006)
- nativetoken ← 始终 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee(用于兑换和余额查询)
- 其余参数 ← 根据池子类型自动填入下表默认值
json
{
investment_id: <自动>,
pool_chain: <自动>,
chain_id: <自动>,
platform_id: <自动>,
native_token: 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee,
fee_tier: <自动>,
tick_spacing: <自动>,
token0: { symbol: <自动>, address: <自动>, decimals: <自动> },
token1: { symbol: <自动>, address: <自动>, dec