perp-cli 0.4.2 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/README.md +46 -5
  2. package/dist/arb/reconcile.d.ts +28 -0
  3. package/dist/arb/reconcile.js +162 -0
  4. package/dist/arb/sizing.d.ts +12 -1
  5. package/dist/arb/sizing.js +38 -5
  6. package/dist/arb/state.d.ts +6 -0
  7. package/dist/cli-spec.d.ts +0 -4
  8. package/dist/cli-spec.js +8 -1
  9. package/dist/commands/account.d.ts +1 -1
  10. package/dist/commands/account.js +300 -63
  11. package/dist/commands/agent.js +16 -9
  12. package/dist/commands/arb/index.js +243 -49
  13. package/dist/commands/arb-auto.js +696 -9
  14. package/dist/commands/arb.d.ts +2 -1
  15. package/dist/commands/arb.js +535 -131
  16. package/dist/commands/bot.js +207 -0
  17. package/dist/commands/dex.js +7 -1
  18. package/dist/commands/funding.d.ts +2 -1
  19. package/dist/commands/funding.js +211 -4
  20. package/dist/commands/funds.d.ts +4 -0
  21. package/dist/commands/funds.js +741 -0
  22. package/dist/commands/history.d.ts +2 -1
  23. package/dist/commands/history.js +508 -5
  24. package/dist/commands/manage.js +6 -4
  25. package/dist/commands/market.js +35 -2
  26. package/dist/commands/multileg.d.ts +16 -0
  27. package/dist/commands/multileg.js +174 -0
  28. package/dist/commands/pnl.d.ts +12 -0
  29. package/dist/commands/pnl.js +243 -0
  30. package/dist/commands/risk.d.ts +2 -0
  31. package/dist/commands/risk.js +56 -0
  32. package/dist/commands/settings.js +147 -0
  33. package/dist/commands/stream.js +132 -55
  34. package/dist/commands/trade.d.ts +1 -1
  35. package/dist/commands/trade.js +270 -267
  36. package/dist/commands/wallet.d.ts +4 -0
  37. package/dist/commands/wallet.js +11 -1
  38. package/dist/config.d.ts +6 -1
  39. package/dist/config.js +21 -1
  40. package/dist/dashboard/ws-feeds.js +1 -1
  41. package/dist/equity-tracker.d.ts +57 -0
  42. package/dist/equity-tracker.js +209 -0
  43. package/dist/exchanges/hyperliquid-spot.d.ts +69 -0
  44. package/dist/exchanges/hyperliquid-spot.js +309 -0
  45. package/dist/exchanges/hyperliquid.d.ts +26 -5
  46. package/dist/exchanges/hyperliquid.js +171 -73
  47. package/dist/exchanges/interface.d.ts +1 -1
  48. package/dist/exchanges/lighter-spot.d.ts +55 -0
  49. package/dist/exchanges/lighter-spot.js +415 -0
  50. package/dist/exchanges/lighter.d.ts +10 -2
  51. package/dist/exchanges/lighter.js +210 -56
  52. package/dist/exchanges/pacifica.d.ts +11 -4
  53. package/dist/exchanges/pacifica.js +64 -37
  54. package/dist/exchanges/spot-interface.d.ts +45 -0
  55. package/dist/exchanges/spot-interface.js +22 -0
  56. package/dist/execution-log.d.ts +2 -2
  57. package/dist/funding/rates.d.ts +36 -0
  58. package/dist/funding/rates.js +146 -0
  59. package/dist/index.js +126 -161
  60. package/dist/liquidity.d.ts +12 -0
  61. package/dist/liquidity.js +43 -0
  62. package/dist/mcp-server.js +43 -96
  63. package/dist/signer/evm-local.d.ts +12 -0
  64. package/dist/signer/evm-local.js +19 -0
  65. package/dist/signer/index.d.ts +3 -0
  66. package/dist/signer/index.js +2 -0
  67. package/dist/signer/interface.d.ts +31 -0
  68. package/dist/signer/interface.js +7 -0
  69. package/dist/signer/solana-local.d.ts +13 -0
  70. package/dist/signer/solana-local.js +19 -0
  71. package/dist/smart-order.js +14 -3
  72. package/dist/strategies/split-order.d.ts +49 -0
  73. package/dist/strategies/split-order.js +138 -0
  74. package/dist/utils.js +7 -1
  75. package/dist/ws/market-feed.d.ts +74 -0
  76. package/dist/ws/market-feed.js +227 -0
  77. package/package.json +1 -1
  78. package/skills/perp-cli/SKILL.md +80 -4
  79. package/skills/perp-cli/references/agent-operations.md +19 -9
  80. package/skills/perp-cli/references/commands.md +54 -32
  81. package/skills/perp-cli/references/strategies.md +27 -17
  82. package/skills/perp-cli/scripts/arb-monitor.sh +74 -0
  83. package/skills/perp-cli/scripts/funding-analysis.sh +85 -0
  84. package/skills/perp-cli/scripts/preflight.sh +98 -0
  85. package/skills/perp-cli/scripts/spot-perp-scan.sh +83 -0
  86. package/skills/perp-cli/scripts/validate-arb.sh +112 -0
  87. package/skills/perp-cli/templates/arb-scan.sh +0 -15
  88. package/skills/perp-cli/templates/open-position.sh +0 -38
  89. package/skills/perp-cli/templates/wallet-setup.sh +0 -17
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Unified market data feeds for CLI streaming commands.
3
+ *
4
+ * - Hyperliquid: native WebSocket (allMids, l2Book, trades, candle)
5
+ * - Lighter: REST polling (no public market data WS)
6
+ * - Pacifica: handled via existing PacificaWSClient in stream.ts
7
+ */
8
+ import { EventEmitter } from "events";
9
+ export interface PriceUpdate {
10
+ symbol: string;
11
+ mid: number;
12
+ funding?: number;
13
+ }
14
+ export interface BookUpdate {
15
+ bids: [string, string][];
16
+ asks: [string, string][];
17
+ }
18
+ export interface TradeUpdate {
19
+ side: string;
20
+ price: string;
21
+ size: string;
22
+ time: number;
23
+ }
24
+ export interface CandleUpdate {
25
+ o: string;
26
+ h: string;
27
+ l: string;
28
+ c: string;
29
+ v: string;
30
+ t: number;
31
+ }
32
+ export declare class HyperliquidMarketFeed extends EventEmitter {
33
+ private ws;
34
+ private closed;
35
+ private reconnectTimer;
36
+ private subs;
37
+ get wsUrl(): string;
38
+ connect(): Promise<void>;
39
+ private send;
40
+ private sub;
41
+ private scheduleReconnect;
42
+ subscribePrices(): void;
43
+ subscribeBook(symbol: string): void;
44
+ subscribeTrades(symbol: string): void;
45
+ subscribeCandle(symbol: string, interval: string): void;
46
+ private handleMessage;
47
+ close(): void;
48
+ }
49
+ export interface LighterFeedOpts {
50
+ /** Polling interval for prices in ms (default: 3000) */
51
+ pricesIntervalMs?: number;
52
+ /** Polling interval for book/trades in ms (default: 2000) */
53
+ bookIntervalMs?: number;
54
+ /** Polling interval for candles in ms (default: 5000) */
55
+ candleIntervalMs?: number;
56
+ }
57
+ export declare class LighterMarketFeed extends EventEmitter {
58
+ private closed;
59
+ private timers;
60
+ private marketMap;
61
+ private pricesMs;
62
+ private bookMs;
63
+ private candleMs;
64
+ constructor(opts?: LighterFeedOpts);
65
+ connect(): Promise<void>;
66
+ private getMarketId;
67
+ private poll;
68
+ subscribePrices(): void;
69
+ subscribeBook(symbol: string): void;
70
+ subscribeTrades(symbol: string): void;
71
+ subscribeCandle(symbol: string, interval: string): void;
72
+ close(): void;
73
+ }
74
+ export declare function createMarketFeed(exchange: string): HyperliquidMarketFeed | LighterMarketFeed;
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Unified market data feeds for CLI streaming commands.
3
+ *
4
+ * - Hyperliquid: native WebSocket (allMids, l2Book, trades, candle)
5
+ * - Lighter: REST polling (no public market data WS)
6
+ * - Pacifica: handled via existing PacificaWSClient in stream.ts
7
+ */
8
+ import { EventEmitter } from "events";
9
+ // ── Hyperliquid Market Feed (native WebSocket) ──
10
+ export class HyperliquidMarketFeed extends EventEmitter {
11
+ ws = null;
12
+ closed = false;
13
+ reconnectTimer = null;
14
+ subs = [];
15
+ get wsUrl() { return "wss://api.hyperliquid.xyz/ws"; }
16
+ async connect() {
17
+ const { WebSocket } = await import("ws");
18
+ return new Promise((resolve, reject) => {
19
+ this.ws = new WebSocket(this.wsUrl);
20
+ this.ws.on("open", () => {
21
+ // Re-subscribe on reconnect
22
+ for (const sub of this.subs)
23
+ this.send({ method: "subscribe", subscription: sub });
24
+ this.emit("connected");
25
+ resolve();
26
+ });
27
+ this.ws.on("error", (err) => {
28
+ if (!this.closed)
29
+ reject(err);
30
+ });
31
+ this.ws.on("close", () => {
32
+ if (!this.closed) {
33
+ this.emit("disconnected");
34
+ this.scheduleReconnect();
35
+ }
36
+ });
37
+ this.ws.on("message", (raw) => {
38
+ try {
39
+ this.handleMessage(JSON.parse(String(raw)));
40
+ }
41
+ catch { /* ignore */ }
42
+ });
43
+ });
44
+ }
45
+ send(data) {
46
+ if (this.ws?.readyState === 1)
47
+ this.ws.send(JSON.stringify(data));
48
+ }
49
+ sub(subscription) {
50
+ this.subs.push(subscription);
51
+ this.send({ method: "subscribe", subscription });
52
+ }
53
+ scheduleReconnect() {
54
+ if (this.closed)
55
+ return;
56
+ this.reconnectTimer = setTimeout(async () => {
57
+ try {
58
+ await this.connect();
59
+ }
60
+ catch {
61
+ this.scheduleReconnect();
62
+ }
63
+ }, 3000);
64
+ }
65
+ subscribePrices() { this.sub({ type: "allMids" }); }
66
+ subscribeBook(symbol) { this.sub({ type: "l2Book", coin: symbol.toUpperCase() }); }
67
+ subscribeTrades(symbol) { this.sub({ type: "trades", coin: symbol.toUpperCase() }); }
68
+ subscribeCandle(symbol, interval) {
69
+ this.sub({ type: "candle", coin: symbol.toUpperCase(), interval });
70
+ }
71
+ handleMessage(msg) {
72
+ const channel = String(msg.channel ?? "");
73
+ const data = msg.data;
74
+ if (!data)
75
+ return;
76
+ if (channel === "allMids") {
77
+ const mids = (data.mids ?? data);
78
+ const updates = Object.entries(mids).map(([symbol, mid]) => ({
79
+ symbol, mid: Number(mid),
80
+ }));
81
+ this.emit("prices", updates);
82
+ }
83
+ else if (channel === "l2Book") {
84
+ const d = data;
85
+ const levels = d.levels;
86
+ if (levels) {
87
+ this.emit("book", {
88
+ bids: levels[0].map((l) => [l.px, l.sz]),
89
+ asks: levels[1].map((l) => [l.px, l.sz]),
90
+ });
91
+ }
92
+ }
93
+ else if (channel === "trades") {
94
+ const trades = Array.isArray(data) ? data : [];
95
+ for (const t of trades) {
96
+ // HL side: "A" = sell (ask), "B" = buy (bid)
97
+ const rawSide = String(t.side ?? "");
98
+ this.emit("trade", {
99
+ side: rawSide === "A" ? "sell" : rawSide === "B" ? "buy" : rawSide,
100
+ price: String(t.px ?? ""),
101
+ size: String(t.sz ?? ""),
102
+ time: Number(t.time ?? Date.now()),
103
+ });
104
+ }
105
+ }
106
+ else if (channel === "candle") {
107
+ const d = data;
108
+ this.emit("candle", {
109
+ o: String(d.o ?? ""), h: String(d.h ?? ""), l: String(d.l ?? ""),
110
+ c: String(d.c ?? ""), v: String(d.v ?? ""), t: Number(d.t ?? 0),
111
+ });
112
+ }
113
+ }
114
+ close() {
115
+ this.closed = true;
116
+ if (this.reconnectTimer)
117
+ clearTimeout(this.reconnectTimer);
118
+ if (this.ws) {
119
+ this.ws.close();
120
+ this.ws = null;
121
+ }
122
+ }
123
+ }
124
+ // ── Lighter Market Feed (REST polling) ──
125
+ const LIGHTER_BASE = "https://mainnet.zklighter.elliot.ai/api/v1";
126
+ export class LighterMarketFeed extends EventEmitter {
127
+ closed = false;
128
+ timers = [];
129
+ marketMap = new Map();
130
+ pricesMs;
131
+ bookMs;
132
+ candleMs;
133
+ constructor(opts) {
134
+ super();
135
+ this.pricesMs = opts?.pricesIntervalMs ?? 3000;
136
+ this.bookMs = opts?.bookIntervalMs ?? 2000;
137
+ this.candleMs = opts?.candleIntervalMs ?? 5000;
138
+ }
139
+ async connect() {
140
+ const res = await fetch(`${LIGHTER_BASE}/orderBookDetails`);
141
+ const json = await res.json();
142
+ for (const m of json.order_book_details ?? []) {
143
+ if (m.market_type === "perp")
144
+ this.marketMap.set(m.symbol.toUpperCase(), m.market_id);
145
+ }
146
+ this.emit("connected");
147
+ }
148
+ getMarketId(symbol) {
149
+ const id = this.marketMap.get(symbol.toUpperCase());
150
+ if (id === undefined)
151
+ throw new Error(`Unknown Lighter market: ${symbol}`);
152
+ return id;
153
+ }
154
+ poll(fn, intervalMs) {
155
+ fn().catch(() => { });
156
+ this.timers.push(setInterval(() => { if (!this.closed)
157
+ fn().catch(() => { }); }, intervalMs));
158
+ }
159
+ subscribePrices() {
160
+ this.poll(async () => {
161
+ const res = await fetch(`${LIGHTER_BASE}/orderBookDetails`);
162
+ const json = await res.json();
163
+ const updates = (json.order_book_details ?? [])
164
+ .filter(m => m.market_type === "perp")
165
+ .map(m => ({ symbol: m.symbol, mid: m.last_trade_price }));
166
+ this.emit("prices", updates);
167
+ }, this.pricesMs);
168
+ }
169
+ subscribeBook(symbol) {
170
+ const marketId = this.getMarketId(symbol);
171
+ this.poll(async () => {
172
+ const res = await fetch(`${LIGHTER_BASE}/orderBookOrders?market_id=${marketId}&limit=20`);
173
+ const json = await res.json();
174
+ this.emit("book", {
175
+ bids: (json.bids ?? []).map(b => [b.price, b.remaining_base_amount]),
176
+ asks: (json.asks ?? []).map(a => [a.price, a.remaining_base_amount]),
177
+ });
178
+ }, this.bookMs);
179
+ }
180
+ subscribeTrades(symbol) {
181
+ const marketId = this.getMarketId(symbol);
182
+ let lastTid = 0;
183
+ this.poll(async () => {
184
+ const res = await fetch(`${LIGHTER_BASE}/recentTrades?market_id=${marketId}&limit=20`);
185
+ const json = await res.json();
186
+ for (const t of json.trades ?? []) {
187
+ if (t.timestamp > lastTid) {
188
+ lastTid = t.timestamp;
189
+ this.emit("trade", {
190
+ side: t.is_maker_ask ? "buy" : "sell",
191
+ price: t.price,
192
+ size: t.size,
193
+ time: t.timestamp,
194
+ });
195
+ }
196
+ }
197
+ }, this.bookMs);
198
+ }
199
+ subscribeCandle(symbol, interval) {
200
+ const marketId = this.getMarketId(symbol);
201
+ this.poll(async () => {
202
+ const now = Math.floor(Date.now() / 1000);
203
+ const res = await fetch(`${LIGHTER_BASE}/candles?market_id=${marketId}&resolution=${interval}&count_back=1&end_timestamp=${now}`);
204
+ const json = await res.json();
205
+ const c = json.candles?.[0];
206
+ if (c) {
207
+ this.emit("candle", {
208
+ o: c.open, h: c.high, l: c.low, c: c.close, v: c.volume, t: c.timestamp,
209
+ });
210
+ }
211
+ }, this.candleMs);
212
+ }
213
+ close() {
214
+ this.closed = true;
215
+ for (const t of this.timers)
216
+ clearInterval(t);
217
+ this.timers = [];
218
+ }
219
+ }
220
+ // ── Factory ──
221
+ export function createMarketFeed(exchange) {
222
+ if (exchange === "hyperliquid")
223
+ return new HyperliquidMarketFeed();
224
+ if (exchange === "lighter")
225
+ return new LighterMarketFeed();
226
+ throw new Error(`Use PacificaWSClient for pacifica, not createMarketFeed`);
227
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perp-cli",
3
- "version": "0.4.2",
3
+ "version": "0.4.9",
4
4
  "description": "Multi-DEX Perpetual Futures CLI - Pacifica, Hyperliquid, Lighter",
5
5
  "bin": {
6
6
  "perp": "dist/index.js",
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: perp-cli
3
- description: "Multi-DEX perpetual futures trading CLI for Pacifica (Solana), Hyperliquid (EVM), and Lighter (Ethereum). Use when user asks to trade perps, check funding rates, bridge USDC, manage positions, scan arbitrage opportunities, or mentions perp-cli, hypurrquant, Pacifica, Hyperliquid, or Lighter exchanges."
3
+ description: "Multi-DEX perpetual futures trading CLI for Pacifica (Solana), Hyperliquid (EVM), and Lighter (Ethereum). Use when user asks to: trade perps, check funding rates, scan arbitrage (perp-perp or spot-perp), delta-neutral strategies, bridge USDC, manage positions/orders, deposit/withdraw, spot+perp hedge, or mentions perp-cli, hypurrquant, Pacifica, Hyperliquid, Lighter, HyperEVM, funding arb, U-token (UBTC/UETH/USOL)."
4
4
  allowed-tools: "Bash(perp:*), Bash(npx perp-cli:*), Bash(npx -y perp-cli:*)"
5
5
  license: MIT
6
6
  metadata:
7
7
  author: hypurrquant
8
- version: "0.4.2"
8
+ version: "0.4.9"
9
9
  ---
10
10
 
11
11
  # perp-cli Agent Guide
@@ -60,6 +60,8 @@ perp --json arb exec <SYM> <longEx> <shortEx> <$> --leverage <N> --isolated # e
60
60
  # Single exchange trading (when not doing arb)
61
61
  perp --json -e <EX> trade market <SYM> buy <SIZE>
62
62
  perp --json -e <EX> trade market <SYM> buy <SIZE> --smart # IOC limit at best ask + 1 tick (less slippage)
63
+ perp --json -e <EX> trade market <SYM> buy <SIZE> --split # orderbook-aware split for large orders
64
+ perp --json -e <EX> trade split <SYM> buy 5000 # dedicated split command (USD notional)
63
65
  perp --json -e <EX> trade close <SYM>
64
66
  perp --json -e <EX> trade close <SYM> --smart # smart close at best bid/ask
65
67
 
@@ -96,11 +98,17 @@ perp --json -e <EX> trade market <SYM> buy <SIZE> --smart
96
98
  perp --json -e <EX> trade close <SYM> --smart
97
99
  perp --json arb exec <SYM> <longEx> <shortEx> <$> --smart # smart arb entry
98
100
  perp --json arb close <SYM> --smart # smart arb close
101
+
102
+ # Split order: orderbook-aware execution for large orders
103
+ # Reads depth before each slice, IOC limit within slippage tolerance
104
+ perp --json -e <EX> trade split <SYM> buy 5000 # split $5000 into depth-based slices
105
+ perp --json -e <EX> trade split <SYM> sell 10000 --max-slices 5 --delay 2000
106
+ perp --json -e <EX> trade market <SYM> buy <SIZE> --split # split via market command flag
99
107
  ```
100
108
 
101
109
  All string outputs are auto-sanitized (control chars stripped, prompt injection patterns blocked).
102
110
 
103
- ## Arb Workflow
111
+ ## Arb Workflow (Perp-Perp)
104
112
 
105
113
  ```
106
114
  1. perp --json portfolio → check balances across all exchanges
@@ -119,6 +127,39 @@ All string outputs are auto-sanitized (control chars stripped, prompt injection
119
127
  → --pair <longEx>:<shortEx>: specify which pair if multiple
120
128
  ```
121
129
 
130
+ ## Spot+Perp Arb Workflow
131
+
132
+ Spot has 0 funding cost → spread = |perp funding rate|. Only needs 1 exchange with spot + any exchange with perp.
133
+
134
+ **Spot exchanges:** HL (Hyperliquid), LT (Lighter). Pacifica is perp-only.
135
+ **U-token mapping:** HL spot uses Unit protocol bridged tokens — UBTC=BTC, UETH=ETH, USOL=SOL, UFART=FARTCOIN. Resolved automatically.
136
+
137
+ ```
138
+ 1. perp --json arb scan --mode spot-perp → find spot+perp opportunities
139
+ perp --json arb scan --mode all → perp-perp + spot-perp combined
140
+ 2. [Show opportunity to user, get confirmation]
141
+ 3. perp --json arb spot-exec <SYM> <spotEx> <perpEx> <$>
142
+ Examples:
143
+ perp --json arb spot-exec ETH hl hl 100 # ETH spot(HL/UETH) + perp(HL)
144
+ perp --json arb spot-exec BTC hl lt 50 # BTC spot(HL/UBTC) + perp(LT)
145
+ perp --json arb spot-exec LINK lt hl 100 # LINK spot(LT) + perp(HL)
146
+ → cross-validates spot vs perp price (>5% deviation = abort, wrong token)
147
+ → sequential execution if same exchange (nonce collision avoidance)
148
+ → parallel execution if different exchanges
149
+ → auto-rollback if one leg fails
150
+ Options:
151
+ --leverage <N> set perp leverage before entry
152
+ --isolated use isolated margin on perp side
153
+ 4. perp --json arb status → shows spot-perp positions (spot leg labeled)
154
+ 5. perp --json arb spot-close <SYM> --spot-exch <hl|lt>
155
+ → sells spot + buys back perp simultaneously
156
+ ```
157
+
158
+ **Available spot+perp pairs (13):**
159
+ - HL spot: BTC (UBTC), ETH (UETH), SOL (USOL), FARTCOIN (UFART), HYPE, AZTEC, STABLE
160
+ - LT spot: ETH, AZTEC, AAVE, LINK, UNI, LIT, LDO, SKY
161
+ - All have perps on HL and LT. Pacifica perps available when API is up.
162
+
122
163
  ## Position Sizing
123
164
 
124
165
  - Single position < **80%** of that exchange's available balance
@@ -165,7 +206,7 @@ If `error.retryable` is `false`, do NOT retry — fix the cause first.
165
206
 
166
207
  | Error | Action |
167
208
  |-------|--------|
168
- | `RATE_LIMITED` | wait 5s, retry (max 3) |
209
+ | `RATE_LIMITED` | wait 5-10s, retry (max 3). Lighter rate limits are strict — space commands 3s+ apart |
169
210
  | `EXCHANGE_UNREACHABLE` | wait 10s, retry. 3x fail → skip that exchange |
170
211
  | `TIMEOUT` | wait 5s, retry (max 3) |
171
212
  | `INSUFFICIENT_BALANCE` | reduce size or bridge funds to that exchange |
@@ -175,6 +216,41 @@ If `error.retryable` is `false`, do NOT retry — fix the cause first.
175
216
  | `MARGIN_INSUFFICIENT` | reduce leverage or close existing positions |
176
217
  | `DUPLICATE_ORDER` | already submitted — check positions, don't retry |
177
218
  | Lighter `invalid signature` | check ~/.perp/.env or `perp --json -e lighter manage setup-api-key` |
219
+ | Lighter `invalid account index` | rate limit caused init failure — wait 10s and retry the command |
220
+ | Lighter `--smart` not filling | Lighter IOC limit orders may not fill — use regular market order (without `--smart`) |
221
+
222
+ ## Examples
223
+
224
+ **User: "펀딩레이트 아비트라지 기회 찾아줘"**
225
+ ```bash
226
+ perp --json portfolio # check balances
227
+ perp --json arb scan --mode all --min 5 # scan perp-perp + spot-perp
228
+ # → show results, recommend best opportunity, ask for confirmation
229
+ ```
230
+
231
+ **User: "ETH spot-perp 아비트라지 실행해줘 $100"**
232
+ ```bash
233
+ perp --json arb scan --mode spot-perp # verify opportunity exists
234
+ perp --json --dry-run arb spot-exec ETH hl hl 100 # dry-run first
235
+ # → show dry-run result, ask for confirmation
236
+ perp --json arb spot-exec ETH hl hl 100 # execute after confirmation
237
+ perp --json arb status # verify positions
238
+ ```
239
+
240
+ **User: "내 포지션 상태 확인해줘"**
241
+ ```bash
242
+ perp --json portfolio # balances + positions + risk
243
+ perp --json arb status # arb-specific PnL + funding
244
+ ```
245
+
246
+ **User: "Hyperliquid에서 SOL 롱 0.5개"**
247
+ ```bash
248
+ perp --json -e hl market mid SOL # current price
249
+ perp --json -e hl trade check SOL buy 0.5 # pre-validate
250
+ perp --json --dry-run -e hl trade market SOL buy 0.5 # dry-run
251
+ # → show cost estimate, ask for confirmation
252
+ perp --json -e hl trade market SOL buy 0.5 --smart # execute with smart order
253
+ ```
178
254
 
179
255
  ## Referrals (Optional)
180
256
 
@@ -123,27 +123,28 @@ perp --json -e hl account info # USDC deposited on exchange
123
123
  ### Deposit to Exchange
124
124
  ```bash
125
125
  # Hyperliquid (from Arbitrum wallet)
126
- perp --json deposit hyperliquid 100
126
+ perp --json funds deposit hyperliquid 100
127
127
 
128
128
  # Pacifica (from Solana wallet)
129
- perp --json deposit pacifica 100
129
+ perp --json funds deposit pacifica 100
130
130
 
131
131
  # Lighter (multiple routes)
132
- perp --json deposit lighter info # show all available routes
133
- perp --json deposit lighter cctp arb 100 # via CCTP from Arbitrum
132
+ perp --json funds deposit lighter info # show all available routes
133
+ perp --json funds deposit lighter cctp arbitrum 100 # via CCTP from Arbitrum
134
134
  ```
135
135
 
136
136
  ### Withdraw from Exchange
137
137
  ```bash
138
- perp --json withdraw hyperliquid 100
139
- perp --json withdraw pacifica 100
138
+ perp --json funds withdraw hyperliquid 100
139
+ perp --json funds withdraw pacifica 100
140
+ perp --json funds withdraw lighter 100
140
141
  ```
141
142
 
142
143
  ### Bridge Between Chains
143
144
  When you need to move USDC between exchanges on different chains:
144
145
  ```bash
145
146
  # 1. Withdraw from source exchange
146
- perp --json withdraw pacifica 500
147
+ perp --json funds withdraw pacifica 500
147
148
 
148
149
  # 2. Quote the bridge
149
150
  perp --json bridge quote --from solana --to arbitrum --amount 500
@@ -155,7 +156,7 @@ perp --json bridge send --from solana --to arbitrum --amount 500
155
156
  perp --json bridge status <orderId>
156
157
 
157
158
  # 5. Deposit to destination exchange
158
- perp --json deposit hyperliquid 500
159
+ perp --json funds deposit hyperliquid 500
159
160
  ```
160
161
 
161
162
  ## Order Types & Execution
@@ -168,6 +169,15 @@ perp --json -e hl trade buy BTC 0.01 # shorthand
168
169
  perp --json -e hl trade sell BTC 0.01 # shorthand
169
170
  ```
170
171
 
172
+ ### Split Orders (orderbook-aware, for large orders)
173
+ ```bash
174
+ perp --json -e hl trade split BTC buy 5000 # split $5000 into depth-based slices
175
+ perp --json -e hl trade split BTC sell 10000 --max-slippage 0.5 --max-slices 5
176
+ perp --json -e hl trade market BTC buy 0.5 --split # split via market command flag
177
+ ```
178
+ Returns `{ slices[], filledUsd, avgPrice, totalSlippagePct, status }`.
179
+ Status: `complete` (all filled), `partial` (some filled), `failed` (none filled).
180
+
171
181
  ### Limit Orders (execute at specific price)
172
182
  ```bash
173
183
  perp --json -e hl trade buy BTC 0.01 -p 60000 # buy at $60,000
@@ -238,7 +248,7 @@ Error case:
238
248
  - `trade market`, `trade buy`, `trade sell` — will open duplicate positions
239
249
  - `trade close` — may error if already closed, but harmless
240
250
  - `bridge send` — will send duplicate transfers
241
- - `deposit`, `withdraw` — will move funds twice
251
+ - `funds deposit`, `funds withdraw` — will move funds twice
242
252
 
243
253
  **For non-idempotent commands:** always verify the result before retrying. Check positions or balances to confirm whether the first attempt succeeded.
244
254
 
@@ -7,16 +7,17 @@ All commands support `--json` for structured output. Always use `--json` when ca
7
7
  perp --json market list # all markets with prices, funding, volume
8
8
  perp --json market prices # cross-exchange price comparison
9
9
  perp --json market mid <SYMBOL> # mid price (fast)
10
- perp --json market info <SYMBOL> # tick size, min order, max leverage
10
+ perp --json market info <SYMBOL> # mark/index price, funding, volume, OI, max leverage
11
11
  perp --json market book <SYMBOL> # orderbook (bids/asks)
12
12
  perp --json market trades <SYMBOL> # recent trades
13
13
  perp --json market funding <SYMBOL> # funding rate history
14
14
  perp --json market kline <SYM> <INTERVAL> # OHLCV candles (1m,5m,15m,1h,4h,1d)
15
+ perp --json market hip3 # list HIP-3 deployed perp dexes (Hyperliquid only)
15
16
  ```
16
17
 
17
18
  ## Account (read-only, safe)
18
19
  ```bash
19
- perp --json account info # balance, equity, margin, PnL
20
+ perp --json account balance # perp balance + spot holdings + 24h funding (alias: account info)
20
21
  perp --json account positions # open positions
21
22
  perp --json account orders # open/pending orders
22
23
  perp --json account history # order history
@@ -24,7 +25,6 @@ perp --json account trades # trade fill history
24
25
  perp --json account funding-history # funding payments
25
26
  perp --json account pnl # profit & loss
26
27
  perp --json account margin <SYMBOL> # position margin info
27
- perp --json status # combined: balance + positions + orders
28
28
  perp --json portfolio # cross-exchange unified view
29
29
  ```
30
30
 
@@ -60,22 +60,29 @@ perp --json trade leverage <SYMBOL> <N> # set leverage
60
60
  # Advanced orders
61
61
  perp --json trade scale-tp <SYMBOL> --levels '<PRICE1>:<PCT>,<PRICE2>:<PCT>'
62
62
  perp --json trade scale-in <SYMBOL> <SIDE> --levels '<PRICE1>:<SIZE>,<PRICE2>:<SIZE>'
63
- perp --json trade trailing-stop <SYMBOL> # trailing stop with callback %
64
- perp --json trade twap <SYMBOL> <SIDE> <SIZE> <DURATION>
65
63
  perp --json trade pnl-track # real-time PnL tracker
64
+
65
+ # Split execution (orderbook-aware)
66
+ perp --json trade split <SYMBOL> <buy|sell> <USD> # split large order into depth-based slices
67
+ perp --json trade split <SYM> buy 5000 --max-slippage 0.5 --max-slices 5 --delay 2000 --min-slice 200
68
+ perp --json trade market <SYM> buy <SIZE> --split # split via market command flag
69
+ perp --json trade market <SYM> buy <SIZE> --split --max-slippage 0.5
66
70
  ```
67
71
 
68
- ## Deposit & Withdraw
72
+ ## Funds (Deposit, Withdraw, Transfer, Bridge)
69
73
  ```bash
70
- perp --json deposit pacifica <AMOUNT>
71
- perp --json deposit hyperliquid <AMOUNT>
72
- perp --json deposit lighter ethereum <AMOUNT> # L1 direct (min 1 USDC)
73
- perp --json deposit lighter cctp arbitrum <AMOUNT> # CCTP (min 5 USDC)
74
- perp --json deposit lighter info # all Lighter deposit routes
75
- perp --json withdraw pacifica <AMOUNT>
76
- perp --json withdraw hyperliquid <AMOUNT>
77
- perp --json deposit info # deposit instructions
78
- perp --json withdraw info # withdrawal instructions
74
+ perp --json funds deposit pacifica <AMOUNT>
75
+ perp --json funds deposit hyperliquid <AMOUNT>
76
+ perp --json funds deposit lighter ethereum <AMOUNT> # L1 direct (min 1 USDC)
77
+ perp --json funds deposit lighter cctp arbitrum <AMOUNT> # CCTP (min 5 USDC)
78
+ perp --json funds deposit lighter info # all Lighter deposit routes
79
+ perp --json funds withdraw pacifica <AMOUNT>
80
+ perp --json funds withdraw hyperliquid <AMOUNT>
81
+ perp --json funds withdraw lighter <AMOUNT>
82
+ perp --json funds transfer <AMOUNT> <ADDRESS> # HL internal transfer (instant)
83
+ perp --json funds bridge --from <CHAIN> --to <CHAIN> --amount <AMT> --recipient <ADDR> # CCTP bridge
84
+ perp --json funds bridge-status --hash <HASH> # check CCTP bridge status
85
+ perp --json funds info # combined deposit & withdrawal info
79
86
  ```
80
87
 
81
88
  ## Bridge (Cross-chain USDC)
@@ -89,11 +96,26 @@ perp --json bridge status <ORDER_ID>
89
96
 
90
97
  ## Arbitrage
91
98
  ```bash
99
+ # Perp-Perp arb
92
100
  perp --json arb scan --min <BPS> # find opportunities (>N bps spread) — PRIMARY command
93
- perp --json arb funding # detailed funding analysis
101
+ perp --json arb exec <SYM> <longEx> <shortEx> <$> # execute perp-perp arb
102
+ perp --json arb close <SYM> # close perp-perp arb
103
+ perp --json arb status # monitor open arb positions
104
+ perp --json arb funding-earned # actual funding payments
105
+
106
+ # Spot+Perp arb (spot funding = 0, spread = |perp funding|)
107
+ perp --json arb scan --mode spot-perp # scan spot+perp opportunities
108
+ perp --json arb scan --mode all # both perp-perp + spot-perp
109
+ perp --json arb spot-exec <SYM> <spotEx> <perpEx> <$> # execute spot+perp arb
110
+ perp --json arb spot-close <SYM> --spot-exch <hl|lt> # close spot+perp arb
111
+ # spotEx: hl (Hyperliquid) or lt (Lighter). perpEx: hl, lt, pac.
112
+ # HL spot uses U-tokens: BTC→UBTC, ETH→UETH, SOL→USOL (auto-resolved)
113
+
114
+ # Other arb tools
115
+ perp --json arb rates # funding rates across all DEXs (detailed)
116
+ perp --json arb prices # cross-exchange price gaps
94
117
  perp --json arb dex # HIP-3 cross-dex arb (Hyperliquid)
95
- perp --json gap show # cross-exchange price gaps
96
- # NOTE: 'arb rates' is deprecated — use 'arb scan' instead
118
+ # Deprecated: 'gap show' → use 'arb prices'; 'funding rates/spread' → use 'arb rates/scan'
97
119
  ```
98
120
 
99
121
  ## Wallet Management
@@ -115,30 +137,30 @@ perp --json risk liquidation-distance # % distance from liquidation for AL
115
137
  perp --json risk limits # view current risk limits
116
138
  perp --json risk limits --min-liq-distance 30 --max-leverage 5 # set risk limits
117
139
  perp --json risk check --notional 1000 --leverage 3 # pre-trade risk check
118
- perp --json health # exchange connectivity & latency
119
- perp --json analytics summary # trading performance
120
- perp --json analytics pnl # P&L breakdown
140
+ perp --json agent ping # exchange connectivity & latency
141
+ perp --json history summary # trading performance
142
+ perp --json history pnl # P&L breakdown by exchange
143
+ perp --json history funding # funding payment aggregation
144
+ perp --json history report # full performance report (summary + pnl + funding)
145
+ perp --json history perf --period daily # daily PnL breakdown (replaces daily-pnl)
146
+ perp --json history perf --period weekly # weekly PnL breakdown (replaces weekly-pnl)
147
+ perp --json history perf --period summary # performance summary stats
121
148
  perp --json history list # execution audit trail
122
149
  ```
123
150
 
124
- ## Automated Strategies
151
+ ## Automated Strategies (bot)
125
152
  ```bash
126
- perp --json run grid <SYMBOL> --range <PCT> --grids <N> --size <USD>
127
- perp --json run dca <SYMBOL> <SIDE> <AMOUNT> <INTERVAL>
128
- perp --json run funding-arb # auto funding arb
153
+ perp --json bot twap <SYMBOL> <SIDE> <SIZE> <DURATION> # TWAP execution
154
+ perp --json bot grid <SYMBOL> --range <PCT> --grids <N> --size <USD>
155
+ perp --json bot dca <SYMBOL> <SIDE> <AMOUNT> <INTERVAL>
156
+ perp --json bot trailing-stop <SYMBOL> # trailing stop with callback %
157
+ perp --json bot funding-arb # auto funding arb
129
158
  perp --json bot quick-grid <SYMBOL> # quick grid bot
130
159
  perp --json bot quick-arb # quick arb bot
131
160
  perp --json jobs list # list running jobs
132
161
  perp --json jobs stop <ID> # stop a job
133
162
  ```
134
163
 
135
- ## Alerts
136
- ```bash
137
- perp --json alert add # add price/funding/pnl/liquidation alert
138
- perp --json alert list # list active alerts
139
- perp --json alert remove <ID> # remove alert
140
- ```
141
-
142
164
  ## Command Discovery
143
165
  ```bash
144
166
  perp schema # Full CLI schema as JSON