perp-cli 0.14.2 → 0.15.0
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.
- package/README.md +152 -13
- package/dist/agent-wallet/store.d.ts +3 -2
- package/dist/agent-wallet/store.js +2 -2
- package/dist/api/public/hyperliquid.js +4 -0
- package/dist/api/public/pacifica.js +83 -13
- package/dist/api/public/urls.d.ts +2 -0
- package/dist/api/public/urls.js +3 -0
- package/dist/arb/utils.d.ts +1 -2
- package/dist/arb/utils.js +1 -2
- package/dist/bot/apex/pulse.js +3 -0
- package/dist/bot/apex/radar.js +2 -1
- package/dist/bot/engine.d.ts +10 -1
- package/dist/bot/engine.js +14 -6
- package/dist/bot/indicators.d.ts +7 -0
- package/dist/bot/indicators.js +16 -0
- package/dist/bot/perp-order.d.ts +4 -4
- package/dist/bot/perp-order.js +5 -5
- package/dist/bot/quarantine.d.ts +1 -1
- package/dist/bot/quarantine.js +1 -1
- package/dist/bot/strategies/apex-strategy.js +3 -2
- package/dist/bot/strategies/engine-mm.js +6 -5
- package/dist/bot/strategies/funding-arb-strategy.js +9 -9
- package/dist/bot/strategies/funding-arb-utils.d.ts +15 -2
- package/dist/bot/strategies/funding-arb-utils.js +43 -24
- package/dist/bot/strategies/funding-auto.js +2 -2
- package/dist/bot/strategies/liquidation-mm.d.ts +1 -0
- package/dist/bot/strategies/liquidation-mm.js +8 -2
- package/dist/bot/strategies/momentum-breakout.d.ts +1 -0
- package/dist/bot/strategies/momentum-breakout.js +11 -3
- package/dist/bot/strategies/spot-perp-arb-strategy.js +23 -12
- package/dist/bot/strategies/spot-perp-executor.d.ts +1 -1
- package/dist/bot/strategies/spot-perp-executor.js +1 -1
- package/dist/bot/strategy-types.d.ts +2 -1
- package/dist/bot/tui/BotDashboard.d.ts +1 -1
- package/dist/bot/tui/BotDashboard.js +1 -1
- package/dist/cache.js +12 -6
- package/dist/cli-program.d.ts +15 -0
- package/dist/cli-program.js +125 -5
- package/dist/commands/agent-import.d.ts +7 -0
- package/dist/commands/agent-import.js +30 -1
- package/dist/commands/agent.d.ts +6 -3
- package/dist/commands/agent.js +160 -12
- package/dist/commands/arb/index.js +4 -4
- package/dist/commands/arb-auto.js +21 -17
- package/dist/commands/arb.d.ts +12 -0
- package/dist/commands/arb.js +61 -143
- package/dist/commands/bot.js +1 -1
- package/dist/commands/builder.js +1 -1
- package/dist/commands/funds.js +113 -3
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +27 -7
- package/dist/commands/manage.js +23 -21
- package/dist/commands/market.js +168 -36
- package/dist/commands/options.d.ts +9 -0
- package/dist/commands/options.js +134 -0
- package/dist/commands/pacifica-earn.d.ts +5 -0
- package/dist/commands/pacifica-earn.js +468 -0
- package/dist/commands/pacifica-orders.d.ts +14 -0
- package/dist/commands/pacifica-orders.js +142 -0
- package/dist/commands/portfolio.js +32 -47
- package/dist/commands/rebalance.d.ts +1 -0
- package/dist/commands/rebalance.js +15 -0
- package/dist/commands/risk.d.ts +11 -2
- package/dist/commands/risk.js +39 -44
- package/dist/commands/trade.d.ts +1 -0
- package/dist/commands/trade.js +63 -58
- package/dist/commands/wallet.js +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.js +15 -4
- package/dist/constants.js +6 -0
- package/dist/dashboard/server.js +1 -1
- package/dist/dashboard/ui.js +1 -1
- package/dist/errors.d.ts +24 -1
- package/dist/errors.js +25 -3
- package/dist/exchanges/arcus/adapter.d.ts +7 -7
- package/dist/exchanges/arcus/adapter.js +12 -12
- package/dist/exchanges/arcus/agent.d.ts +1 -1
- package/dist/exchanges/arcus/agent.js +1 -1
- package/dist/exchanges/arcus/client.js +1 -1
- package/dist/exchanges/arcus/signing.d.ts +2 -3
- package/dist/exchanges/arcus/signing.js +1 -1
- package/dist/exchanges/arcus/spot-chain.d.ts +1 -1
- package/dist/exchanges/arcus/spot-chain.js +1 -1
- package/dist/exchanges/arcus/spot-router.d.ts +1 -1
- package/dist/exchanges/arcus/spot-router.js +2 -2
- package/dist/exchanges/arcus/spot.d.ts +2 -3
- package/dist/exchanges/arcus/spot.js +2 -3
- package/dist/exchanges/aster-spot.d.ts +3 -3
- package/dist/exchanges/aster-spot.js +6 -9
- package/dist/exchanges/aster-typed-data.d.ts +1 -1
- package/dist/exchanges/aster-typed-data.js +1 -1
- package/dist/exchanges/aster.d.ts +9 -4
- package/dist/exchanges/aster.js +125 -55
- package/dist/exchanges/builder-fee.d.ts +1 -1
- package/dist/exchanges/builder-fee.js +13 -2
- package/dist/exchanges/canonical-symbols.d.ts +1 -2
- package/dist/exchanges/canonical-symbols.js +26 -2
- package/dist/exchanges/derive/client.d.ts +37 -0
- package/dist/exchanges/derive/client.js +135 -0
- package/dist/exchanges/derive/options.d.ts +68 -0
- package/dist/exchanges/derive/options.js +360 -0
- package/dist/exchanges/extended/adapter.d.ts +82 -0
- package/dist/exchanges/extended/adapter.js +179 -0
- package/dist/exchanges/extended/client.d.ts +38 -0
- package/dist/exchanges/extended/client.js +88 -0
- package/dist/exchanges/extended/public.d.ts +130 -0
- package/dist/exchanges/extended/public.js +429 -0
- package/dist/exchanges/grvt/adapter.d.ts +86 -0
- package/dist/exchanges/grvt/adapter.js +206 -0
- package/dist/exchanges/grvt/client.d.ts +25 -0
- package/dist/exchanges/grvt/client.js +86 -0
- package/dist/exchanges/grvt/public.d.ts +151 -0
- package/dist/exchanges/grvt/public.js +438 -0
- package/dist/exchanges/hyperliquid-spot.d.ts +1 -1
- package/dist/exchanges/hyperliquid-spot.js +5 -5
- package/dist/exchanges/hyperliquid.d.ts +22 -16
- package/dist/exchanges/hyperliquid.js +80 -55
- package/dist/exchanges/index.d.ts +1 -1
- package/dist/exchanges/index.js +1 -1
- package/dist/exchanges/interface.d.ts +97 -8
- package/dist/exchanges/interface.js +19 -2
- package/dist/exchanges/ioc-outcome.d.ts +1 -1
- package/dist/exchanges/ioc-outcome.js +1 -1
- package/dist/exchanges/legacy-trading-v2.d.ts +2 -2
- package/dist/exchanges/legacy-trading-v2.js +7 -2
- package/dist/exchanges/lighter-public.d.ts +2 -2
- package/dist/exchanges/lighter-public.js +2 -2
- package/dist/exchanges/lighter-signer.d.ts +1 -1
- package/dist/exchanges/lighter-signer.js +1 -1
- package/dist/exchanges/lighter-spot.d.ts +3 -4
- package/dist/exchanges/lighter-spot.js +6 -7
- package/dist/exchanges/lighter.d.ts +11 -11
- package/dist/exchanges/lighter.js +28 -14
- package/dist/exchanges/ondo/adapter.d.ts +5 -6
- package/dist/exchanges/ondo/adapter.js +16 -14
- package/dist/exchanges/ondo/agent.d.ts +1 -1
- package/dist/exchanges/ondo/agent.js +1 -1
- package/dist/exchanges/ondo/client.d.ts +1 -1
- package/dist/exchanges/ondo/client.js +2 -2
- package/dist/exchanges/ondo/public.d.ts +8 -1
- package/dist/exchanges/ondo/public.js +13 -2
- package/dist/exchanges/ondo/spot.d.ts +2 -2
- package/dist/exchanges/ondo/spot.js +3 -3
- package/dist/exchanges/options-interface.d.ts +158 -0
- package/dist/exchanges/options-interface.js +17 -0
- package/dist/exchanges/options-venues.d.ts +12 -0
- package/dist/exchanges/options-venues.js +35 -0
- package/dist/exchanges/pacifica-atomic.d.ts +211 -0
- package/dist/exchanges/pacifica-atomic.js +440 -0
- package/dist/exchanges/pacifica-decimal.d.ts +10 -0
- package/dist/exchanges/pacifica-decimal.js +51 -0
- package/dist/exchanges/pacifica-presigned.d.ts +53 -0
- package/dist/exchanges/pacifica-presigned.js +141 -0
- package/dist/exchanges/pacifica-print.d.ts +200 -0
- package/dist/exchanges/pacifica-print.js +417 -0
- package/dist/exchanges/pacifica-spot.d.ts +2 -2
- package/dist/exchanges/pacifica-spot.js +3 -3
- package/dist/exchanges/pacifica-typed-data.d.ts +1 -1
- package/dist/exchanges/pacifica-typed-data.js +1 -1
- package/dist/exchanges/pacifica-vaults.d.ts +121 -0
- package/dist/exchanges/pacifica-vaults.js +264 -0
- package/dist/exchanges/pacifica.d.ts +32 -5
- package/dist/exchanges/pacifica.js +114 -48
- package/dist/exchanges/precision.d.ts +3 -1
- package/dist/exchanges/precision.js +9 -2
- package/dist/exchanges/qfex/adapter.d.ts +18 -5
- package/dist/exchanges/qfex/adapter.js +32 -12
- package/dist/exchanges/qfex/agent.d.ts +1 -1
- package/dist/exchanges/qfex/agent.js +1 -1
- package/dist/exchanges/qfex/client.d.ts +1 -1
- package/dist/exchanges/qfex/client.js +1 -1
- package/dist/exchanges/qfex/errors.d.ts +1 -1
- package/dist/exchanges/qfex/errors.js +2 -2
- package/dist/exchanges/qfex/public.d.ts +3 -3
- package/dist/exchanges/qfex/public.js +3 -3
- package/dist/exchanges/qfex/signing.d.ts +2 -2
- package/dist/exchanges/qfex/signing.js +4 -5
- package/dist/exchanges/qfex/ws-transport.d.ts +2 -2
- package/dist/exchanges/qfex/ws-transport.js +3 -3
- package/dist/exchanges/rate-limiter.d.ts +1 -1
- package/dist/exchanges/rate-limiter.js +5 -2
- package/dist/exchanges/registry.d.ts +1 -1
- package/dist/exchanges/registry.js +1 -1
- package/dist/exchanges/risex/adapter.d.ts +148 -0
- package/dist/exchanges/risex/adapter.js +796 -0
- package/dist/exchanges/risex/agent.d.ts +154 -0
- package/dist/exchanges/risex/agent.js +384 -0
- package/dist/exchanges/risex/client.d.ts +47 -0
- package/dist/exchanges/risex/client.js +174 -0
- package/dist/exchanges/risex/nonce.d.ts +43 -0
- package/dist/exchanges/risex/nonce.js +212 -0
- package/dist/exchanges/risex/public.d.ts +64 -0
- package/dist/exchanges/risex/public.js +150 -0
- package/dist/exchanges/risex/session.d.ts +71 -0
- package/dist/exchanges/risex/session.js +171 -0
- package/dist/exchanges/risex/typed-data.d.ts +173 -0
- package/dist/exchanges/risex/typed-data.js +240 -0
- package/dist/exchanges/risex/units.d.ts +29 -0
- package/dist/exchanges/risex/units.js +104 -0
- package/dist/exchanges/slippage.d.ts +1 -1
- package/dist/exchanges/slippage.js +1 -1
- package/dist/exchanges/spot-factory.d.ts +3 -3
- package/dist/exchanges/spot-factory.js +7 -7
- package/dist/exchanges/spot-interface.d.ts +5 -5
- package/dist/exchanges/spot-interface.js +2 -2
- package/dist/exchanges/spot-result.d.ts +3 -3
- package/dist/exchanges/spot-result.js +3 -3
- package/dist/exchanges/trading-v2.d.ts +3 -3
- package/dist/exchanges/trading-v2.js +9 -6
- package/dist/exchanges/txflow/adapter.d.ts +54 -0
- package/dist/exchanges/txflow/adapter.js +118 -0
- package/dist/exchanges/txflow/client.d.ts +47 -0
- package/dist/exchanges/txflow/client.js +153 -0
- package/dist/exchanges/txflow/public.d.ts +76 -0
- package/dist/exchanges/txflow/public.js +284 -0
- package/dist/exchanges/unknown-symbol.d.ts +29 -0
- package/dist/exchanges/unknown-symbol.js +51 -0
- package/dist/exchanges/variational/adapter.d.ts +71 -0
- package/dist/exchanges/variational/adapter.js +137 -0
- package/dist/exchanges/variational/client.d.ts +21 -0
- package/dist/exchanges/variational/client.js +66 -0
- package/dist/exchanges/variational/public.d.ts +126 -0
- package/dist/exchanges/variational/public.js +430 -0
- package/dist/exchanges/venue-types.d.ts +6 -7
- package/dist/exchanges/venue-types.js +2 -2
- package/dist/exchanges/venue.d.ts +51 -8
- package/dist/exchanges/venue.js +54 -4
- package/dist/exchanges/venues/arcus.d.ts +1 -2
- package/dist/exchanges/venues/arcus.js +5 -4
- package/dist/exchanges/venues/aster.d.ts +2 -2
- package/dist/exchanges/venues/aster.js +6 -4
- package/dist/exchanges/venues/create-helpers.d.ts +1 -1
- package/dist/exchanges/venues/create-helpers.js +3 -3
- package/dist/exchanges/venues/extended.d.ts +21 -0
- package/dist/exchanges/venues/extended.js +96 -0
- package/dist/exchanges/venues/grvt.d.ts +30 -0
- package/dist/exchanges/venues/grvt.js +98 -0
- package/dist/exchanges/venues/hyperliquid.d.ts +2 -2
- package/dist/exchanges/venues/hyperliquid.js +10 -8
- package/dist/exchanges/venues/index.d.ts +7 -2
- package/dist/exchanges/venues/index.js +8 -2
- package/dist/exchanges/venues/lighter-family.d.ts +7 -9
- package/dist/exchanges/venues/lighter-family.js +9 -11
- package/dist/exchanges/venues/lighter-rh.d.ts +2 -2
- package/dist/exchanges/venues/lighter-rh.js +7 -5
- package/dist/exchanges/venues/lighter.d.ts +1 -1
- package/dist/exchanges/venues/lighter.js +5 -3
- package/dist/exchanges/venues/ondo.d.ts +1 -1
- package/dist/exchanges/venues/ondo.js +5 -3
- package/dist/exchanges/venues/pacifica.d.ts +2 -2
- package/dist/exchanges/venues/pacifica.js +6 -4
- package/dist/exchanges/venues/qfex.d.ts +1 -1
- package/dist/exchanges/venues/qfex.js +4 -2
- package/dist/exchanges/venues/risex-release.d.ts +14 -0
- package/dist/exchanges/venues/risex-release.js +14 -0
- package/dist/exchanges/venues/risex.d.ts +31 -0
- package/dist/exchanges/venues/risex.js +116 -0
- package/dist/exchanges/venues/txflow.d.ts +18 -0
- package/dist/exchanges/venues/txflow.js +77 -0
- package/dist/exchanges/venues/variational.d.ts +21 -0
- package/dist/exchanges/venues/variational.js +85 -0
- package/dist/execution-log.d.ts +1 -1
- package/dist/funding/legacy-public.d.ts +1 -1
- package/dist/funding/legacy-public.js +9 -4
- package/dist/funding/normalize.d.ts +1 -1
- package/dist/funding/normalize.js +1 -1
- package/dist/funding/rates.d.ts +44 -4
- package/dist/funding/rates.js +56 -12
- package/dist/index.js +7 -6
- package/dist/jobs.d.ts +1 -0
- package/dist/jobs.js +25 -1
- package/dist/landing.d.ts +2 -0
- package/dist/landing.js +1 -1
- package/dist/mcp-pacifica-earn.d.ts +9 -0
- package/dist/mcp-pacifica-earn.js +58 -0
- package/dist/mcp-server.js +113 -59
- package/dist/pacifica/client.d.ts +67 -4
- package/dist/pacifica/client.js +170 -8
- package/dist/pacifica/rate-limit.d.ts +144 -0
- package/dist/pacifica/rate-limit.js +267 -0
- package/dist/pacifica/types/order.d.ts +2 -1
- package/dist/plan-executor.js +7 -2
- package/dist/rebalance.js +1 -1
- package/dist/risk.d.ts +2 -1
- package/dist/risk.js +2 -4
- package/dist/settings.d.ts +32 -3
- package/dist/signer/ows-evm.d.ts +1 -1
- package/dist/signer/ows-evm.js +1 -1
- package/dist/smart-order.d.ts +1 -1
- package/dist/smart-order.js +1 -1
- package/dist/strategies/funding-arb.d.ts +1 -1
- package/dist/strategies/funding-arb.js +1 -1
- package/dist/trade-validator.d.ts +1 -1
- package/dist/trade-validator.js +9 -4
- package/dist/utils.d.ts +12 -3
- package/dist/utils.js +11 -3
- package/dist/venue-health.d.ts +40 -0
- package/dist/venue-health.js +75 -0
- package/dist/withdraw-gate.d.ts +1 -1
- package/dist/withdraw-gate.js +1 -1
- package/dist/ws/index.d.ts +959 -0
- package/dist/ws/index.js +4295 -0
- package/dist/ws/node.d.ts +975 -0
- package/dist/ws/node.js +4366 -0
- package/dist/ws/pacifica-instrument.d.ts +8 -0
- package/dist/ws/pacifica-instrument.js +8 -0
- package/dist/ws-cli/credentials.d.ts +62 -0
- package/dist/ws-cli/credentials.js +126 -0
- package/package.json +58 -10
- package/skills/perp-cli/SKILL.md +62 -9
- package/skills/perp-cli/references/agent-operations.md +7 -0
- package/skills/perp-cli/references/commands.md +76 -5
- package/skills/perp-cli/references/ws-library.md +492 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/perp-cli)
|
|
5
5
|
[](https://github.com/hypurrquant/perp-cli/blob/main/LICENSE)
|
|
6
6
|
|
|
7
|
-
Multi-DEX perpetual futures CLI — **Pacifica** (Solana), **Hyperliquid** (HyperEVM), **Lighter** (Ethereum), **Aster** (BNB Chain), **Lighter RH** (Robinhood chain), **Ondo Perps** (off-chain), **Arcus** (Robinhood chain), **QFEX** (off-chain, TradFi perps).
|
|
7
|
+
Multi-DEX perpetual futures CLI — **Pacifica** (Solana), **Hyperliquid** (HyperEVM), **Lighter** (Ethereum), **Aster** (BNB Chain), **Lighter RH** (Robinhood chain), **Ondo Perps** (off-chain), **Arcus** (Robinhood chain), **QFEX** (off-chain, TradFi perps), **RISEx** (RISE chain — read-only in 0.15.0, trading in a later release), **TxFlow** (market data only — unofficial API), **Variational Omni** (market data only — official API, RFQ venue), **GRVT** (market data only — official API; trading in a later release), **Extended** (Starknet, market data only — official API; trading in a later release), and **Derive** options data (read-only).
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npm install -g perp-cli # global install
|
|
@@ -16,7 +16,7 @@ npx -y perp-cli --json portfolio
|
|
|
16
16
|
|
|
17
17
|
## Features
|
|
18
18
|
|
|
19
|
-
- **
|
|
19
|
+
- **13 perp venues** — trade on 8: Pacifica, Hyperliquid, Lighter, Aster, Lighter RH, Ondo Perps, Arcus, QFEX (bridge / perp-perp arb cover the original four); market data on RISEx (read-only in 0.15.0, trading in a later release) TxFlow (unofficial API, read-only), Variational (official API, read-only — no public trading API yet) GRVT (official API, read-only in this version — trading in a later release) and Extended (official API, read-only in this version — trading in a later release); plus **Derive** options data (read-only). See the [support matrix](#support-matrix)
|
|
20
20
|
- **Funding Rate Arb** — perp-perp + spot-perp scan & one-command dual-leg execution
|
|
21
21
|
- **Portfolio** — single call returns balances, positions, risk level across all exchanges
|
|
22
22
|
- **Funds** — deposit, withdraw, transfer, multi-provider bridge (cctp/relay/debridge), inter-exchange rebalance — all in one group
|
|
@@ -24,6 +24,31 @@ npx -y perp-cli --json portfolio
|
|
|
24
24
|
- **Agent-First Design** — `--json`, `--fields`, `--ndjson`, `--dry-run`, runtime schema introspection
|
|
25
25
|
- **Safety** — pre-trade validation, response sanitization, client-id deduplication
|
|
26
26
|
|
|
27
|
+
## Support matrix
|
|
28
|
+
|
|
29
|
+
What each venue supports in this release, derived from the code (venue definitions in `src/exchanges/venues/*.ts`, `perp-cli/ws` codecs in `src/ws/codecs/`, the `funds deposit|withdraw` commands, the options registry). ✅ = implemented and available; — = not available. This says what perp-cli **offers**, not what was run with real money — for that see [What works — mainnet verification](#what-works--mainnet-verification-2026-10-13).
|
|
30
|
+
|
|
31
|
+
| Venue | Market data (CLI) | Funding | WS stream (`perp-cli/ws`) | Trading | Deposit via perp-cli | Withdraw via perp-cli | Extras | API |
|
|
32
|
+
|---|---|---|---|---|---|---|---|---|
|
|
33
|
+
| Hyperliquid (incl. HIP-3 via `--dex`) | ✅ | ✅ hourly | ✅ public + user (HIP-3 dexes opt-in) | ✅ | ✅ (USDC from Arbitrum) | ✅ (CCTP) | spot, outcomes (HIP-4), native TWAP | official |
|
|
34
|
+
| Pacifica | ✅ | ✅ hourly | ✅ public + user | ✅ | ✅ | ✅ | spot (unified margin), native TWAP (master-signed only); Print (`perp print`), Vaults (`perp vault`; deposit master-only) and Atomic basket (`trade atomic`) — each not yet verified live; legacy `wallet manage lake`: `create` still works, `deposit` / `withdraw` refuse and point to `perp vault` | official |
|
|
35
|
+
| Lighter | ✅ | ✅ hourly | ✅ public + user | ✅ | ✅ (L1 or CCTP) | ✅ | spot, client-side TWAP | official |
|
|
36
|
+
| Lighter RH | ✅ | ✅ hourly | ✅ public + user (mainnet; testnet WS → HTTP 403) | ✅ | ✅ (USDG, mainnet) | ✅ (`-e lighter-rh funds withdraw lighter`) | spot, client-side TWAP | official |
|
|
37
|
+
| Aster | ✅ | ✅ per symbol | ✅ public only (user channels: known gap) | ✅ | ✅ (USDT / USDC, mainnet) | ✅ (agent with `--can-withdraw --ip-whitelist`) | spot, client-side TWAP | official |
|
|
38
|
+
| Ondo Perps | ✅ | ✅ hourly | — | ✅ | ✅ (USDC, mainnet) | — (the API allows none; web app)⁴ | spot, client-side TWAP | official |
|
|
39
|
+
| Arcus | ✅ | ✅ hourly | ✅ public + user | ✅ | — (web app) | ✅ (to the account owner) | spot (on-chain swaps), client-side TWAP | official |
|
|
40
|
+
| QFEX | ✅ | unverified (display only, `--include-unverified`) | — | ✅ (no resting reduce-only, no automation — see [QFEX](#qfex)) | address only | — (disabled for now; web app)⁵ | — | official |
|
|
41
|
+
| RISEx | ✅ | ✅ hourly | — | — (**read-only in 0.15.0**; trading in a later release) | — (app only) | — (app only) | account reads by address | official |
|
|
42
|
+
| TxFlow | ✅ | unverified (display only, `--include-unverified`) | — | — (market data only) | — | — | — | **unofficial** |
|
|
43
|
+
| Variational | ✅ (`market book` = RFQ quotes, not an order book) | unverified (display only, `--include-unverified`); interval per market (1h / 4h / 8h) | — | — (market data only) | — | — | equities / ETFs / commodities; pre-IPO (not matched) | official |
|
|
44
|
+
| GRVT | ✅ | unverified (display only, `--include-unverified`); interval per market (4h / 8h) | — (per-instrument streams only) | — (market data only in this version; trading in a later release) | — | — | equities / ETFs, commodities; pre-IPO not matched | official |
|
|
45
|
+
| Extended | ✅ (crypto plus equities / ETFs / commodities / indices / FX) | unverified (display only, `--include-unverified`), hourly; `_24_5` equities print 0 off-hours | — (one socket per stream; not supported yet) | — (read-only in 0.15.0) | — | — | asset-class column; pre-IPO and ambiguous tickers not matched | official |
|
|
46
|
+
| Derive | options only (`perp -e derive options …`) | — | — | — (**read-only**; trading in a later release) | — | — | options: underlyings, expiries, chain (IV, greeks), quote | official |
|
|
47
|
+
|
|
48
|
+
- **Funding** ✅ = the rate's unit is verified against settled payments (`fundingVerified`), so the venue takes part in `arb scan` and funding strategies; unverified venues are shown only with `--include-unverified`, never ranked or traded.
|
|
49
|
+
- **WS stream** = `perp-cli/ws` / `@hypurrquant/perp-ws` channels: public = all-market / per-market state and `bbo`; user = account, positions, orders, fills. `book` / `trades` channels are not available yet on any venue.
|
|
50
|
+
- **Client-side TWAP** = `trade twap` / `strategy twap` slicing on venues without a native TWAP (refused on QFEX by its automation gate).
|
|
51
|
+
|
|
27
52
|
## Setup
|
|
28
53
|
|
|
29
54
|
```bash
|
|
@@ -34,7 +59,7 @@ pbpaste | OWS_PASSPHRASE="$PP" perp wallet set pac --name pac # Pacifica (Sola
|
|
|
34
59
|
# The active wallet serves every venue; one EVM key covers HL / Lighter / Aster.
|
|
35
60
|
# Lighter trading also needs: perp wallet agent approve lighter
|
|
36
61
|
|
|
37
|
-
# Or the interactive setup wizard (
|
|
62
|
+
# Or the interactive setup wizard (every trading venue): picks / creates / imports an OWS
|
|
38
63
|
# vault wallet, network, venues, registers agent wallets (y/N confirmation before
|
|
39
64
|
# any signature — never moves funds), explains + sets the slippage bound, and the
|
|
40
65
|
# default venue. It never writes keys to ~/.perp/.env.
|
|
@@ -111,6 +136,11 @@ Secrets are stored once (see `docs/SSOT_RULES.md` Rule #3): Lighter RH → `~/.p
|
|
|
111
136
|
| Ondo Perps | `ondo` (`ondo-perps`) | yes | Off-chain engine; limit TIF GTC (default) / IOC / ALO; restricted: US, PA |
|
|
112
137
|
| QFEX | `qfex` (`qf`) | yes (see **QFEX** below) | Custodial, off-chain engine; equities / indices / commodities, cross margin, USDC; limit TIF GTC (default) / IOC / FOK / ALO; testnet = QFEX UAT; restricted: US, GB, ES and others |
|
|
113
138
|
| Arcus | `arcus` | yes | Robinhood chain, USDG collateral; limit TIF GTC (default, sent as GTT) / IOC / FOK / ALO; restricted: US, CA, GB; **access whitelist** — unlisted addresses are rejected (request access at arcus.xyz) |
|
|
139
|
+
| RISEx | `risex` (`rise`) | **no — read-only in 0.15.0** (trading in a later release; see **RISEx** below) | Fully on-chain order book on RISE chain, USDC; official API. Market data, funding and account reads by address; every trade / agent / bot path → `CAPABILITY_UNSUPPORTED`; deposits / withdrawals in the RISEx app only |
|
|
140
|
+
| Variational | `variational` (`var`, `omni`) | **no — market data only** (see **Variational** below) | Variational Omni, an RFQ venue (one market maker, no order book); official read-only API, no public trading API yet. Funding is unverified (shown only with `--include-unverified`); restricted: US, CA and others |
|
|
141
|
+
| GRVT | `grvt` (`grv`) | **no — market data only in this version** (trading in a later release; see **GRVT** below) | Hybrid perps exchange, USDT collateral; official Market Data API. Funding is unverified (shown only with `--include-unverified`); testnet = `-n testnet`; trading needs KYC; restricted: US, CA, SG, HK and others |
|
|
142
|
+
| Extended | `extended` (`ext`, `x10`) | **no — market data only in this version** (trading in a later release; see **Extended** below) | Perps order book on Starknet (formerly X10), USD collateral; official public API. Crypto plus RWA (equities, ETFs, indices, commodities, FX). Funding is unverified (shown only with `--include-unverified`); testnet = Sepolia (`-n testnet`); restricted: US, GB, CA, HK and others |
|
|
143
|
+
| TxFlow | `txflow` (`txf`) | **no — market data only** | **UNOFFICIAL API**: TxFlow has no official API yet; perp-cli reads the undocumented API its web app uses. It may change or break without notice. Funding is unverified (shown only with `--include-unverified`) |
|
|
114
144
|
|
|
115
145
|
- **Time in force:** `trade limit` defaults to `GTC` on every venue (common names `GTC | IOC | FOK | ALO`; a TIF the venue does not offer → `CAPABILITY_UNSUPPORTED`). Lighter post-only (`ALO`) is disabled until verified on the venue.
|
|
116
146
|
- **TP/SL on an entry:** `trade market|buy|sell|limit ... --tp <px> --sl <px>` means the same on every venue — *protect this entry's verified fill*. The direction is checked before anything is sent (long: tp > reference > sl; short: the reverse; reference = mark for market entries, the limit price for limit entries). Ondo attaches the legs to the order; Arcus sends an entry+TP/SL batch; Hyperliquid / Lighter / Aster verify the entry fill, then place reduce-only TP/SL trigger orders sized to it (only market or `--tif IOC` entries — a resting entry → `CAPABILITY_UNSUPPORTED`); Pacifica verifies the fill, then sets position TP/SL (refused if the symbol already has a position or TP/SL — never overwritten). Entry outcome unknown → `ORDER_PENDING` and **no** TP/SL (the position may be unprotected); entry filled but a leg failed → `ORDER_PARTIAL` (not retryable) with the entry result and which legs were placed — do not re-enter, finish with `trade tpsl`.
|
|
@@ -123,7 +153,7 @@ Secrets are stored once (see `docs/SSOT_RULES.md` Rule #3): Lighter RH → `~/.p
|
|
|
123
153
|
|
|
124
154
|
### What works — mainnet verification (2026-10-13)
|
|
125
155
|
|
|
126
|
-
Every mark below comes from a real-money mainnet run, not from code reading — at the venue minimum, with the per-venue cap raised to about $25–30 for multi-slice / multi-level checks and about $110 for the Hyperliquid TWAP.
|
|
156
|
+
Every mark below comes from a real-money mainnet run, not from code reading — at the venue minimum, with the per-venue cap raised to about $25–30 for multi-slice / multi-level checks and about $110 for the Hyperliquid TWAP.
|
|
127
157
|
|
|
128
158
|
✅ verified live · ⛔ not supported (refused before anything is sent) · ❌ implemented but not run on mainnet yet · — not offered by the venue
|
|
129
159
|
|
|
@@ -143,10 +173,15 @@ Every mark below comes from a real-money mainnet run, not from code reading —
|
|
|
143
173
|
| `account margin` with a position | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
144
174
|
| Spot (`trade spot-*`) | ✅ | — | ✅ | ✅ | ✅ | ❌ (needs USDT) | ✅ | ❌ (needs an Arcus-issued key) | — |
|
|
145
175
|
| Deposit via perp-cli | ✅ | (HL) | ✅ | ✅ | ✅ | ✅ | ✅ | — (web app) | — (address only) |
|
|
146
|
-
| Withdraw |
|
|
176
|
+
| Withdraw (to your own address)⁶ | ✅ | (HL) | ✅ | ✅ | ✅ | ✅ (`--asset USDC`) | ⛔⁴ | ✅ | ⛔⁵ |
|
|
177
|
+
|
|
178
|
+
RISEx, TxFlow, Variational, GRVT and Extended are not in this table: none trades in this release. RISEx trading (shipped but disabled in 0.15.0) was exercised on **testnet** only (2026-10-14); no mainnet RISEx order has been run.
|
|
147
179
|
|
|
148
180
|
² perp-cli has no native TWAP for this venue: `trade twap` runs the client-side TWAP (slices) instead. Whether the venue's API offers one is not checked.
|
|
149
|
-
³ Verified in the session; no saved log file.
|
|
181
|
+
³ Verified in the session; no saved log file.
|
|
182
|
+
⁴ Not available: the Ondo Perps API does not allow withdrawals (`funds withdraw ondo` → `CAPABILITY_UNSUPPORTED`). Withdraw in the Ondo web app.
|
|
183
|
+
⁵ Disabled in perp-cli for now (`funds withdraw qfex` → `CAPABILITY_UNSUPPORTED`). Withdraw in the QFEX web app.
|
|
184
|
+
⁶ Mainnet, 2026-10-13: one withdrawal per venue to the account's own address, received amount checked on the destination chain — `funds withdraw hyperliquid 12.22` (Arbitrum USDC), `funds withdraw pacifica 12.98` (Solana USDC), `-e lighter funds withdraw lighter 15.95` (Ethereum USDC), `-e lighter-rh funds withdraw lighter 12.96` and `funds withdraw arcus 9.94` (Robinhood Chain USDG), `funds withdraw aster 8.74 --chain arbitrum --asset USDC` (Arbitrum USDC).
|
|
150
185
|
|
|
151
186
|
Automation, verified live (bounded runs at minimum size, stopped and flattened afterwards):
|
|
152
187
|
|
|
@@ -157,7 +192,17 @@ Automation, verified live (bounded runs at minimum size, stopped and flattened a
|
|
|
157
192
|
| Execution helpers | `strategy twap` (Aster), `trade twap --background` (Arcus), `strategy plan execute` (9 of 10 action types — `cancel_order` not run), `perp background stop` (graceful: orders cancelled, positions listed) |
|
|
158
193
|
| Hyperliquid HIP-4 outcomes | GTC place / cancel, IOC buy, `outcome sell --all` / `--size` |
|
|
159
194
|
|
|
160
|
-
|
|
195
|
+
Funds and bridge, verified live (mainnet, 2026-10-13 — `funds bridge send` runs, `funds rebalance plan` + `execute --withdraw-only` after a $11 HL deposit, alerts rule commands without a channel):
|
|
196
|
+
|
|
197
|
+
| Area | Verified | Not verified |
|
|
198
|
+
|---|---|---|
|
|
199
|
+
| `funds bridge send` | deBridge Arbitrum → Solana USDC (OWS-signed); Relay swaps Arbitrum ETH → Robinhood ETH, Robinhood USDG → Solana SOL / USDC, Robinhood USDG → Arbitrum USDC | CCTP routes; any **Solana-source** bridge (the OWS Solana signing path is covered by mocked tests only) |
|
|
200
|
+
| `funds bridge exchange` | — | everything; the HyperCore → Solana CCTP route (`--from hyperliquid --to pacifica`) is suspected broken (Solana recipient encoding) |
|
|
201
|
+
| `funds rebalance` | `plan`; `execute --withdraw-only` (HL → Arbitrum) | `execute --auto-bridge` (no gas pre-check yet) |
|
|
202
|
+
| `funds transfer` | — | HL `usdSend`, QFEX account transfer (need a receiving account) |
|
|
203
|
+
| alerts | rule `add` / `list` / `remove`; `test` / `start` refuse without a channel | Telegram / Discord delivery (needs a bot token) |
|
|
204
|
+
|
|
205
|
+
Not run on mainnet yet: subaccounts, builder fees, `strategy claude-agent` (needs an Anthropic key), dashboard.
|
|
161
206
|
|
|
162
207
|
### QFEX
|
|
163
208
|
|
|
@@ -190,7 +235,96 @@ Known caveat: cancelling a stop / TP right after its position was closed can ans
|
|
|
190
235
|
|
|
191
236
|
Order outcomes are never guessed: an IOC / market order is final only on a venue terminal frame (nothing filled → `ORDER_REJECTED`, `reason: iocNoFill`); anything unclear after the order was sent is `ORDER_PENDING` with the `c:<id>` to check — never resubmit. perp-cli never enables QFEX cancel-on-disconnect, but **another connection of the same user that enabled it (e.g. the official QFEX CLI) cancels all of the account's orders when that connection drops**.
|
|
192
237
|
|
|
193
|
-
**Withdrawals** are
|
|
238
|
+
**Withdrawals** are disabled in perp-cli for now (`funds withdraw qfex` → `CAPABILITY_UNSUPPORTED`, also under `--dry-run`); withdraw in the QFEX web app. Subaccounts: `perp -e qfex funds transfer <amount> primary --from <account uuid>`.
|
|
239
|
+
|
|
240
|
+
### RISEx (read-only in 0.15.0 — trading in a later release)
|
|
241
|
+
|
|
242
|
+
RISEx is a fully on-chain perps order book on RISE chain (USDC collateral), reached through its **official** API. New venues ship in phases: in this release perp-cli reads RISEx data only; trading comes in a later release.
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
perp -e risex market list # public; funding = last settled hourly rate (verified)
|
|
246
|
+
perp -e risex market book BTC # also: prices | info | trades | kline | funding
|
|
247
|
+
perp arb scan --rates # RISEx rows in the funding comparison
|
|
248
|
+
perp health # RISEx is probed as an official venue
|
|
249
|
+
perp -e risex account positions --ows <master> # account reads are public by address — nothing is signed
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
- **Refused in this release** (`CAPABILITY_UNSUPPORTED`, "RISEx trading is planned for a later perp-cli release", before any key is read or request is sent — also under `--dry-run`): every `perp -e risex trade …` write, `trade multi` / `arb exec` / `arb auto` legs, every `strategy …` command (bots, plans, TWAP / grid / DCA, `--exchanges` legs), `wallet agent approve|import|revoke|rotate risex` (`revoke --force` only clears the local record), `perp setup --venues risex`, `funds faucet risex`, and the MCP `trade_preview` / `trade_execute` / `trade_close` tools. `arb scan --basis` covers trading venues only, so RISEx is not in it; in `arb scan` a pair with a RISEx leg is marked `executable: false` / "(read-only)".
|
|
253
|
+
- **Funds:** deposits and withdrawals are done in the RISEx app (app.rise.trade). `funds deposit|withdraw risex`, `funds transfer -e risex` and `funds rebalance execute` with risex refuse with `CAPABILITY_UNSUPPORTED` (also under `--dry-run`).
|
|
254
|
+
- The trading code (session signer restricted on-chain to trading only, EIP-712 permits) ships with its tests but is switched off by one flag (`RISEX_TRADING_ENABLED` in `src/exchanges/venues/risex-release.ts`).
|
|
255
|
+
|
|
256
|
+
### TxFlow (market data only — UNOFFICIAL API)
|
|
257
|
+
|
|
258
|
+
TxFlow publishes no official API yet. perp-cli reads the **undocumented** API that app.txflow.com uses — read-only, and it may change or be blocked at any time. Every JSON row carries `venueApi: "unofficial"` (`apiStatus` in mixed tables and MCP output); human output adds a footnote.
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
perp -e txflow market list | info <SYM> | book <SYM> | trades <SYM> | kline <SYM> 1h
|
|
262
|
+
perp arb scan --rates --include-unverified # TxFlow funding (percent per hour on the venue, shown as a fraction), display only
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Every trade / account / portfolio / funds (deposit, withdraw, transfer, rebalance) / agent / builder / strategy / arb exec command and every MCP account or trading tool refuses TxFlow with `CAPABILITY_UNSUPPORTED` before any request. There is no funding history and no testnet; a market whose funding interval cannot be proven to be 1 hour shows funding as unknown.
|
|
266
|
+
|
|
267
|
+
### Variational (market data only — official API)
|
|
268
|
+
|
|
269
|
+
Variational Omni is an RFQ venue: its single market maker (the OLP) quotes every trade, so there is no order book. perp-cli reads its **official**, documented read-only API (one `GET /metadata/v2/stats` call for every market, shared for 5 s; venue limit 10 requests / 10 s per IP). Variational has no public trading API yet.
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
perp -e variational market list | prices | info <SYM> # perps by base (BTC), swaps keep the suffix (XAU-SWAP)
|
|
273
|
+
perp -e variational market book BTC # the OLP's indicative RFQ quotes at fixed sizes — not an order book
|
|
274
|
+
perp -e variational market funding BTC # current terms: per interval (1h / 4h / 8h per market), hourly, APR
|
|
275
|
+
perp arb scan --rates --include-unverified # Variational funding rows, display only
|
|
276
|
+
perp health # probed as an official venue
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
- **Funding is unverified:** the published rate is a moving prediction for the next payment and cannot be checked against settled payments (no public account API), so it is shown only with `--include-unverified` — never ranked, traded or saved to funding history. There is no funding history endpoint.
|
|
280
|
+
- **Symbols:** TradFi perps (equities, ETFs, commodities) are classified explicitly; `US500-PERP` is the SPDR S&P 500 ETF (compared as `SPY`); pre-IPO markets, swaps, `SPX` (SPX6900) and `QNT` (Quant) are never matched across venues. No index price, tick, lot, leverage or base-unit open interest is published (shown as `-` / null).
|
|
281
|
+
- **Refused** (`CAPABILITY_UNSUPPORTED`, before any request — also under `--dry-run`): every trade / account / portfolio / funds / agent / builder / strategy / arb exec command and every MCP account or trading tool. No testnet, no WebSocket.
|
|
282
|
+
|
|
283
|
+
### GRVT (market data only — official API)
|
|
284
|
+
|
|
285
|
+
GRVT is a hybrid perps exchange (off-chain matching, USDT collateral). perp-cli reads its **official**, keyless Market Data API (`POST https://market-data.grvt.io/full/v1/…`; testnet `-n testnet`). In this version GRVT is read-only; trading is planned for a later release.
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
perp -e grvt market list | prices | info <SYM> # base tickers (BTC, KPEPE, XAU, AAPL); BTC_USDT_Perp also accepted
|
|
289
|
+
perp -e grvt market book BTC # order book (10 / 50 / 100 / 500 levels served)
|
|
290
|
+
perp -e grvt market funding BTC # settled funding history (per 4h / 8h interval)
|
|
291
|
+
perp -e grvt market trades | kline BTC … # public tape / candles
|
|
292
|
+
perp arb scan --rates --include-unverified # GRVT funding rows, display only
|
|
293
|
+
perp health # probed as an official venue
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
- **Funding is unverified:** the interval is per market (4h or 8h); market rows carry GRVT's indicative rate for the running interval (`fundingRateKind: "predicted"`), converted from percent to a fraction per interval. It has not been checked against settled payments, so it is shown only with `--include-unverified` — never ranked or traded.
|
|
297
|
+
- **Symbols:** crypto by ticker; equities / ETFs by ticker from a reviewed list; XAU / XAG / CL / BZ → GOLD / SILVER / WTI / Brent; pre-IPO markets (OPENAI, ANTHROPIC, SPACEX) and ambiguous tickers are never matched across venues. No lot step is published (`stepSize` null); max leverage comes from GRVT's margin rules (`market list|prices|info`, cached up to 6 h — `leverageAsOf`).
|
|
298
|
+
- **Requests:** GRVT has no bulk ticker, so a full market read is one ticker per market (~185 requests, ~5 s), reused for 15 s; documented limits (1500 / min for tickers, 500 / min otherwise) are enforced by the venue limiter.
|
|
299
|
+
- **Refused** (`CAPABILITY_UNSUPPORTED`, "GRVT is read-only (market data) in this version; trading is planned for a later release", before any request — also under `--dry-run`): every trade / account / portfolio / funds / agent / builder / strategy / arb exec command, `setup --venues grvt`, and every MCP account or trading tool. No `perp-cli/ws` codec (GRVT streams are per instrument, capped below its market count).
|
|
300
|
+
|
|
301
|
+
### Extended (market data only — official API)
|
|
302
|
+
|
|
303
|
+
Extended (formerly X10) is a perps order book on Starknet (USD collateral) listing crypto and RWA markets (equities, ETFs, indices, commodities, FX). perp-cli reads its **official**, keyless public API (`https://api.starknet.extended.exchange/api/v1`; testnet Sepolia `-n testnet`). In this version Extended is read-only; trading is planned for a later release.
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
perp -e extended market list | prices | info <SYM> # base tickers (BTC, TSLA, SPX500M); wire names (TSLA_24_5-USD) also accepted
|
|
307
|
+
perp -e extended market book TSLA # order book (RFQ markets: the indicative book)
|
|
308
|
+
perp -e extended market funding ETH # applied hourly funding prints
|
|
309
|
+
perp -e extended market trades | kline BTC … # public tape / candles
|
|
310
|
+
perp arb scan --rates --include-unverified # Extended funding rows, display only
|
|
311
|
+
perp health # probed as an official venue
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
- **Funding is unverified:** applied once per hour, a fraction per hour rounded to 6 decimals. Market rows carry the current hour's accruing rate (`fundingRateKind: "accruing"`); `market funding` shows the applied prints. It has not been checked against an account's funding payments, and `_24_5` equities print 0 while their underlying is closed, so it is shown only with `--include-unverified` — never ranked or traded.
|
|
315
|
+
- **Symbols:** the asset name without the `_24_5` suffix (`TSLA_24_5-USD` → `TSLA`); `market list` shows an asset-class column. Crypto by ticker; equities / ETFs by ticker; XAU / XAG / WTI / XBR → GOLD / SILVER / WTI / Brent, SPX500M / TECH100M → SPX / NDX. Pre-IPO markets, RWA tickers that are crypto tickers elsewhere (PURR, QNT, BB, ON, ADI, BOT), XIAOMI and the crypto `SPX` (SPX6900) are never matched across venues.
|
|
316
|
+
- **Refused** (`CAPABILITY_UNSUPPORTED`, "Extended is read-only (market data) in this version; trading is planned for a later release", before any request — also under `--dry-run`): every trade / account / portfolio / funds / agent / builder / strategy / arb exec command, `setup --venues extended`, and every MCP account or trading tool. No `perp-cli/ws` codec (Extended streams are one socket per stream URL, with no subscribe frame).
|
|
317
|
+
|
|
318
|
+
### Options market data — Derive (read-only)
|
|
319
|
+
|
|
320
|
+
Derive (derive.xyz) options through its official public API — keyless; no orders, no account, no signing (trading in a later release). Derive is not a perp venue: `-e derive` works only with `perp options`.
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
perp --json -e derive options underlyings
|
|
324
|
+
perp --json -e derive options expiries ETH
|
|
325
|
+
perp --json -e derive options chain ETH --expiry 2026-12-25 --strikes 10 # bid/ask, mark, IV, greeks, OI per strike
|
|
326
|
+
perp --json -e derive options quote ETH-20261225-3500-P
|
|
327
|
+
```
|
|
194
328
|
|
|
195
329
|
### Spot trading
|
|
196
330
|
|
|
@@ -233,6 +367,9 @@ perp --json -e <EX> trade spot-balance
|
|
|
233
367
|
| `account` | Balance, positions, orders, margin |
|
|
234
368
|
| `trade` | Market/limit/stop orders, close, scale, split execution |
|
|
235
369
|
| `outcome` | Hyperliquid Outcome (HIP-4) — binary/range contracts, quoted per outcome (outcomeMeta `quoteToken`, USDC today), no leverage |
|
|
370
|
+
| `options` | Options market data, read-only (Derive: `-e derive options underlyings / expiries / chain / quote`) |
|
|
371
|
+
| `print` | Pacifica Print — strike orders earning a premium per cycle: games, quote, positions, history, events, deposit / cancel (`--dry-run`) |
|
|
372
|
+
| `vault` | Pacifica vaults (API: lakes) — list, info, positions, deposit (master wallet only) / withdraw (`--dry-run`) |
|
|
236
373
|
| `arb` | Funding rate arb — scan, exec, close, monitor (perp-perp & spot-perp) |
|
|
237
374
|
| `strategy` | 19 bot algorithms (grid, dca, twap, APEX, REFLECT, presets) + nested scripted plans |
|
|
238
375
|
| `funds` | Deposit, withdraw, transfer, cross-chain bridge (multi-provider), inter-exchange rebalance |
|
|
@@ -326,11 +463,9 @@ perp --json funds deposit hyperliquid 100
|
|
|
326
463
|
perp --json funds withdraw pacifica 50
|
|
327
464
|
perp --json funds deposit lighter-rh 10 # USDG on Robinhood Chain (approve + deposit, mainnet)
|
|
328
465
|
perp --json -e lighter-rh funds withdraw lighter 10 # USDG → Robinhood Chain
|
|
329
|
-
perp --json --dry-run funds withdraw ondo 10 --to <ADDRESS> # plan only, nothing sent
|
|
330
466
|
perp --json funds deposit aster 8 # USDT → Aster vault on BNB Chain (--chain arbitrum / --asset USDC; mainnet)
|
|
331
467
|
perp --json funds withdraw aster 8 --chain bsc # USDT → your own address (agent needs --can-withdraw --ip-whitelist)
|
|
332
468
|
perp --json funds deposit ondo 12 --probe 2 # USDC transfer to your Ondo funding address (Arbitrum; --chain ethereum)
|
|
333
|
-
perp --json funds address-book add ondo <MASTER_ADDR> # SIWE challenge → Ondo withdrawal address book
|
|
334
469
|
perp --json funds withdraw arcus 10 # to the Arcus account owner
|
|
335
470
|
perp --json funds transfer 100 <ADDRESS> # HL internal transfer (instant)
|
|
336
471
|
perp --json funds bridge quote --from solana --to arbitrum --amount 100
|
|
@@ -401,7 +536,7 @@ Global flags: `--json`, `--fields <f>`, `--ndjson`, `--dry-run`, `--dex <name>`
|
|
|
401
536
|
|
|
402
537
|
[](https://glama.ai/mcp/servers/hypurrquant/perp-cli)
|
|
403
538
|
|
|
404
|
-
perp-cli includes a full-featured MCP server (
|
|
539
|
+
perp-cli includes a full-featured MCP server (29 tools, 3 resources, 2 prompts) for Claude Desktop, Cursor, and other MCP clients.
|
|
405
540
|
|
|
406
541
|
**No API keys required for market data** — explore prices, orderbooks, funding rates, and arb opportunities without any setup. Add keys only when you want to trade.
|
|
407
542
|
|
|
@@ -427,9 +562,13 @@ For trading and account data, run `perp setup` first: the MCP server reads the s
|
|
|
427
562
|
}
|
|
428
563
|
```
|
|
429
564
|
|
|
430
|
-
**Read-only tools (no keys):** `get_markets`, `get_orderbook`, `get_funding_rates`, `get_prices`, `arb_scan`, `health_check`
|
|
565
|
+
**Read-only tools (no keys):** `get_markets`, `get_orderbook`, `get_funding_rates`, `get_prices`, `get_outcome_markets`, `get_outcome_view`, `get_outcome_book`, `get_option_expiries`, `get_option_chain`, `get_option_quote` (Derive options), `pacifica_print_products`, `pacifica_print_quote`, `pacifica_print_positions`, `pacifica_vaults` (Pacifica Print / vaults; writes are CLI-only), `arb_scan`, `health_check`
|
|
566
|
+
|
|
567
|
+
**Advisor tools (no keys):** `suggest_command`, `explain_command`
|
|
568
|
+
|
|
569
|
+
**Account & trading tools (keys required):** `get_balance`, `get_positions`, `get_open_orders`, `get_outcome_positions`, `portfolio`, `trade_preview`, `trade_execute`, `trade_close`, `get_funding_analysis`, `get_pnl_analysis`, `get_arb_compare`
|
|
431
570
|
|
|
432
|
-
|
|
571
|
+
- `get_markets` / `get_orderbook` add `meta.apiStatus` (`"unofficial"` + `apiNote` for TxFlow); `get_prices` lists `meta.unofficialApiVenues`; `health_check` rows carry `apiStatus`. Account / trading tools refuse TxFlow with `CAPABILITY_UNSUPPORTED`; `trade_preview` / `trade_execute` / `trade_close` refuse RISEx (read-only in 0.15.0) before any credential is read.
|
|
433
572
|
|
|
434
573
|
**Resources:** `market://prices`, `market://funding-rates`, `perp://schema`
|
|
435
574
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentMeta, AgentSource, AnyAgentMeta, ArcusAgentMeta, OndoAgentMeta, QfexAgentMeta } from "../settings.js";
|
|
1
|
+
import type { AgentMeta, AgentSource, AnyAgentMeta, ArcusAgentMeta, OndoAgentMeta, QfexAgentMeta, RisexAgentMeta } from "../settings.js";
|
|
2
2
|
import type { Network } from "../exchanges/venue-types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Attempt to acquire the lockfile for an exchange's agent-approve operation.
|
|
@@ -56,6 +56,7 @@ type VenueAgentMap = {
|
|
|
56
56
|
ondo: OndoAgentMeta;
|
|
57
57
|
arcus: ArcusAgentMeta;
|
|
58
58
|
qfex: QfexAgentMeta;
|
|
59
|
+
risex: RisexAgentMeta;
|
|
59
60
|
};
|
|
60
61
|
/** Named agent, or the only/first registered one when agentName is omitted. */
|
|
61
62
|
export declare function getVenueAgent<V extends keyof VenueAgentMap>(venue: V, agentName?: string): VenueAgentMap[V] | null;
|
|
@@ -65,6 +66,6 @@ export declare function setVenueAgent<V extends keyof VenueAgentMap>(venue: V, m
|
|
|
65
66
|
export declare function deleteVenueAgent(venue: keyof VenueAgentMap, agentName: string): boolean;
|
|
66
67
|
export declare function listVenueAgents(): Array<{
|
|
67
68
|
exchange: keyof VenueAgentMap;
|
|
68
|
-
meta: OndoAgentMeta | ArcusAgentMeta | QfexAgentMeta;
|
|
69
|
+
meta: OndoAgentMeta | ArcusAgentMeta | QfexAgentMeta | RisexAgentMeta;
|
|
69
70
|
}>;
|
|
70
71
|
export {};
|
|
@@ -91,7 +91,7 @@ function isPidAlive(pid) {
|
|
|
91
91
|
* agentName is omitted.
|
|
92
92
|
*/
|
|
93
93
|
/** Venues whose agents use a non-legacy meta shape (see getVenueAgent). */
|
|
94
|
-
const NON_LEGACY_AGENT_VENUES = new Set(["ondo", "arcus", "qfex"]);
|
|
94
|
+
const NON_LEGACY_AGENT_VENUES = new Set(["ondo", "arcus", "qfex", "risex"]);
|
|
95
95
|
function assertLegacyAgentVenue(exchange) {
|
|
96
96
|
if (NON_LEGACY_AGENT_VENUES.has(exchange)) {
|
|
97
97
|
throw new PerpError("INVALID_PARAMS", `${exchange} agents use a venue-specific meta; call getVenueAgent("${exchange}")`);
|
|
@@ -294,7 +294,7 @@ export function deleteVenueAgent(venue, agentName) {
|
|
|
294
294
|
export function listVenueAgents() {
|
|
295
295
|
const settings = loadSettings();
|
|
296
296
|
const out = [];
|
|
297
|
-
for (const v of ["ondo", "arcus", "qfex"]) {
|
|
297
|
+
for (const v of ["ondo", "arcus", "qfex", "risex"]) {
|
|
298
298
|
const m = settings.agents?.[v];
|
|
299
299
|
if (m)
|
|
300
300
|
for (const meta of Object.values(m))
|
|
@@ -22,6 +22,8 @@ export function fetchHyperliquidMeta() {
|
|
|
22
22
|
const ctxs = (json[1] ?? []);
|
|
23
23
|
const out = [];
|
|
24
24
|
universe.forEach((asset, i) => {
|
|
25
|
+
if (asset.isDelisted === true)
|
|
26
|
+
return; // delisted: zeroed funding / mark history, not a market
|
|
25
27
|
const ctx = (ctxs[i] ?? {});
|
|
26
28
|
const symbol = String(asset.name ?? "");
|
|
27
29
|
const funding = Number(ctx.funding);
|
|
@@ -49,6 +51,8 @@ export function parseHyperliquidMetaRaw(raw) {
|
|
|
49
51
|
const ctxs = (raw[1] ?? []);
|
|
50
52
|
const assets = (universe?.universe ?? []);
|
|
51
53
|
assets.forEach((a, i) => {
|
|
54
|
+
if (a.isDelisted === true)
|
|
55
|
+
return; // delisted: not a market (zeroed funding)
|
|
52
56
|
const ctx = (ctxs[i] ?? {});
|
|
53
57
|
const sym = String(a.name ?? "");
|
|
54
58
|
if (!sym)
|
|
@@ -1,17 +1,84 @@
|
|
|
1
|
-
import { PACIFICA_API_URL, sharedApiNetwork } from "./urls.js";
|
|
1
|
+
import { PACIFICA_API_URL, PACIFICA_INFO_URL, sharedApiNetwork } from "./urls.js";
|
|
2
|
+
import { PerpError } from "../../errors.js";
|
|
3
|
+
import { isPacificaPerpetual } from "../../ws/pacifica-instrument.js";
|
|
2
4
|
import { assertOk } from "./_http.js";
|
|
3
5
|
import { withCache, TTL_MARKET } from "../../cache.js";
|
|
6
|
+
import { getNetworkConfig } from "../../pacifica/constants.js";
|
|
7
|
+
import { PACIFICA_COST_STANDARD, PACIFICA_READ_NEED, pacificaRateLimiter } from "../../pacifica/rate-limit.js";
|
|
4
8
|
// ── Fetchers ──
|
|
9
|
+
const publicRate = () => pacificaRateLimiter(getNetworkConfig(sharedApiNetwork()).restUrl, undefined, "unsigned");
|
|
10
|
+
/**
|
|
11
|
+
* Unauthenticated GET through the shared Pacifica credit limiter (the IP quota the adapter's
|
|
12
|
+
* keyless client also spends): headers recorded, HTTP 429 → RATE_LIMITED. Never waits
|
|
13
|
+
* (maxWaitMs 0): arb / dashboard callers settle venues with allSettled, so a nearly spent quota
|
|
14
|
+
* fails this leg fast (RATE_LIMITED, nothing sent) instead of stalling the scan.
|
|
15
|
+
*/
|
|
16
|
+
async function pacificaPublicGet(url, what) {
|
|
17
|
+
const rate = publicRate();
|
|
18
|
+
const ticket = await rate.acquire(what, { ...PACIFICA_READ_NEED, maxWaitMs: 0 });
|
|
19
|
+
let res;
|
|
20
|
+
try {
|
|
21
|
+
res = await fetch(url);
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
ticket.release();
|
|
25
|
+
}
|
|
26
|
+
rate.observe(res);
|
|
27
|
+
if (res.status === 429)
|
|
28
|
+
throw rate.rateLimitedError(what, res, await res.text());
|
|
29
|
+
return res;
|
|
30
|
+
}
|
|
31
|
+
const INFO_REMEDIATION = "The Pacifica /info response shape changed; retry, and report it if it persists";
|
|
32
|
+
/**
|
|
33
|
+
* Symbols of GET /info rows with instrument_type "perpetual". `/info/prices` also lists spot
|
|
34
|
+
* markets (SOL-USDC) — they must not reach arb / funding-arb as perps. A row without the field
|
|
35
|
+
* cannot be classified → EXCHANGE_ERROR (same rule as the adapter's getMarkets).
|
|
36
|
+
* Cached as a string[] (the file cache is JSON: a Set would come back as `{}`); the Set is built
|
|
37
|
+
* outside withCache.
|
|
38
|
+
*/
|
|
39
|
+
async function fetchPacificaPerpSymbols() {
|
|
40
|
+
const symbols = await withCache(`pub:pac:${sharedApiNetwork()}:perps:list`, TTL_MARKET, async () => {
|
|
41
|
+
const res = await pacificaPublicGet(PACIFICA_INFO_URL, "GET /info");
|
|
42
|
+
await assertOk(res, "Pacifica info");
|
|
43
|
+
const json = (await res.json());
|
|
44
|
+
if (json === null || typeof json !== "object" || !Array.isArray(json.data)) {
|
|
45
|
+
throw new PerpError("EXCHANGE_ERROR", "Pacifica GET /info has no data array", { exchange: "pacifica", remediation: INFO_REMEDIATION });
|
|
46
|
+
}
|
|
47
|
+
const out = [];
|
|
48
|
+
for (const m of json.data) {
|
|
49
|
+
if (m === null || typeof m !== "object" || Array.isArray(m)) {
|
|
50
|
+
throw new PerpError("EXCHANGE_ERROR", `Pacifica GET /info row is not an object: ${JSON.stringify(m)}`, { exchange: "pacifica", remediation: INFO_REMEDIATION });
|
|
51
|
+
}
|
|
52
|
+
const row = m;
|
|
53
|
+
if (typeof row.instrument_type !== "string") {
|
|
54
|
+
throw new PerpError("EXCHANGE_ERROR", `Pacifica /info row ${String(row.symbol)} has no instrument_type`, { exchange: "pacifica", remediation: INFO_REMEDIATION });
|
|
55
|
+
}
|
|
56
|
+
if (isPacificaPerpetual(row))
|
|
57
|
+
out.push(String(row.symbol));
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
});
|
|
61
|
+
if (!Array.isArray(symbols)) {
|
|
62
|
+
// A cache entry from before the string[] format (or a corrupt one) is not trusted.
|
|
63
|
+
throw new PerpError("EXCHANGE_ERROR", "Pacifica /info perp list cache entry is not a list", { exchange: "pacifica", remediation: INFO_REMEDIATION });
|
|
64
|
+
}
|
|
65
|
+
return new Set(symbols);
|
|
66
|
+
}
|
|
67
|
+
/** `/info/prices` envelope reduced to perp rows (`{ data }`, the shape parsePacificaRaw reads). */
|
|
68
|
+
async function fetchPacificaPerpPrices() {
|
|
69
|
+
const [res, perps] = await Promise.all([pacificaPublicGet(PACIFICA_API_URL, "GET /info/prices"), fetchPacificaPerpSymbols()]);
|
|
70
|
+
await assertOk(res, "Pacifica prices");
|
|
71
|
+
const json = await res.json();
|
|
72
|
+
const data = json.data ?? json;
|
|
73
|
+
if (!Array.isArray(data))
|
|
74
|
+
return { data: [] };
|
|
75
|
+
return { data: data.filter((p) => perps.has(String(p.symbol))) };
|
|
76
|
+
}
|
|
5
77
|
export function fetchPacificaPrices() {
|
|
6
78
|
// SSOT rule #2: error must propagate. Row-level skipping is applied for
|
|
7
79
|
// missing/invalid mark or funding so a 0 doesn't reach downstream paths.
|
|
8
|
-
return withCache(`pub:pac:${sharedApiNetwork()}:prices`, TTL_MARKET, async () => {
|
|
9
|
-
const
|
|
10
|
-
await assertOk(res, "Pacifica prices");
|
|
11
|
-
const json = await res.json();
|
|
12
|
-
const data = json.data ?? json;
|
|
13
|
-
if (!Array.isArray(data))
|
|
14
|
-
return [];
|
|
80
|
+
return withCache(`pub:pac:${sharedApiNetwork()}:prices:perp`, TTL_MARKET, async () => {
|
|
81
|
+
const { data } = await fetchPacificaPerpPrices();
|
|
15
82
|
const out = [];
|
|
16
83
|
for (const p of data) {
|
|
17
84
|
const symbol = String(p.symbol ?? "");
|
|
@@ -32,11 +99,8 @@ export function fetchPacificaPricesRaw() {
|
|
|
32
99
|
// Callers should wrap with Promise.allSettled to keep multi-DEX comparisons
|
|
33
100
|
// running when one DEX is down. Non-2xx responses are also rejected so a
|
|
34
101
|
// 5xx JSON body cannot fulfill as if it were valid data.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
await assertOk(res, "Pacifica prices");
|
|
38
|
-
return res.json();
|
|
39
|
-
});
|
|
102
|
+
// Perp rows only (spot SOL-USDC dropped via /info instrument_type).
|
|
103
|
+
return withCache(`pub:pac:${sharedApiNetwork()}:prices:raw:perp`, TTL_MARKET, fetchPacificaPerpPrices);
|
|
40
104
|
}
|
|
41
105
|
export function parsePacificaRaw(raw) {
|
|
42
106
|
const rates = new Map();
|
|
@@ -64,11 +128,17 @@ export function parsePacificaRaw(raw) {
|
|
|
64
128
|
// ── Health check ──
|
|
65
129
|
export async function pingPacifica() {
|
|
66
130
|
const start = Date.now();
|
|
131
|
+
// A health probe asks the venue itself (never throttled locally — an exhausted quota shows as the
|
|
132
|
+
// venue's HTTP 429), but its cost and headers go through the shared limiter.
|
|
133
|
+
const rate = publicRate();
|
|
134
|
+
const ticket = rate.track(PACIFICA_COST_STANDARD);
|
|
67
135
|
try {
|
|
68
136
|
const res = await fetch(PACIFICA_API_URL);
|
|
137
|
+
ticket.settle(res);
|
|
69
138
|
return { ok: res.ok, latencyMs: Date.now() - start, status: res.status };
|
|
70
139
|
}
|
|
71
140
|
catch {
|
|
141
|
+
ticket.release();
|
|
72
142
|
return { ok: false, latencyMs: Date.now() - start, status: 0 };
|
|
73
143
|
}
|
|
74
144
|
}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
type LegacyPublicVenue = "pacifica" | "hyperliquid" | "aster";
|
|
9
9
|
export declare function legacyPublicBaseUrl(venue: LegacyPublicVenue, net: "mainnet" | "testnet"): string;
|
|
10
10
|
export declare let PACIFICA_API_URL: string;
|
|
11
|
+
/** GET /info (instrument_type: which `prices` rows are perps). */
|
|
12
|
+
export declare let PACIFICA_INFO_URL: string;
|
|
11
13
|
export declare let HYPERLIQUID_API_URL: string;
|
|
12
14
|
export declare let LIGHTER_API_URL: string;
|
|
13
15
|
/** Network selected by the CLI entry point (setSharedApiNetwork). */
|
package/dist/api/public/urls.js
CHANGED
|
@@ -35,6 +35,8 @@ const TESTNET_URLS = {
|
|
|
35
35
|
lighter: "https://testnet.zklighter.elliot.ai",
|
|
36
36
|
};
|
|
37
37
|
export let PACIFICA_API_URL = MAINNET_URLS.pacifica;
|
|
38
|
+
/** GET /info (instrument_type: which `prices` rows are perps). */
|
|
39
|
+
export let PACIFICA_INFO_URL = `${PAC_MAINNET_REST}/info`;
|
|
38
40
|
export let HYPERLIQUID_API_URL = MAINNET_URLS.hyperliquid;
|
|
39
41
|
export let LIGHTER_API_URL = MAINNET_URLS.lighter;
|
|
40
42
|
let _sharedNetwork = "mainnet";
|
|
@@ -50,6 +52,7 @@ export function setSharedApiNetwork(network) {
|
|
|
50
52
|
_sharedNetwork = network;
|
|
51
53
|
const urls = network === "testnet" ? TESTNET_URLS : MAINNET_URLS;
|
|
52
54
|
PACIFICA_API_URL = urls.pacifica;
|
|
55
|
+
PACIFICA_INFO_URL = `${network === "testnet" ? PAC_TESTNET_REST : PAC_MAINNET_REST}/info`;
|
|
53
56
|
HYPERLIQUID_API_URL = urls.hyperliquid;
|
|
54
57
|
LIGHTER_API_URL = urls.lighter;
|
|
55
58
|
}
|
package/dist/arb/utils.d.ts
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* Settlement schedules per venue (UTC hours when settlement occurs), generated
|
|
6
|
-
* from `VenueDefinition.settlementIntervalHours`, anchored at 00:00 UTC
|
|
7
|
-
* (design §10.1, §10.13 #1). Venues whose interval is per-market (Aster)
|
|
6
|
+
* from `VenueDefinition.settlementIntervalHours`, anchored at 00:00 UTC. Venues whose interval is per-market (Aster)
|
|
8
7
|
* have no entry — pass the market's interval to getLastSettlement().
|
|
9
8
|
*/
|
|
10
9
|
export declare const SETTLEMENT_SCHEDULES: Record<string, number[]>;
|
package/dist/arb/utils.js
CHANGED
|
@@ -8,8 +8,7 @@ import { ensureVenuesRegistered } from "../exchanges/venues/index.js";
|
|
|
8
8
|
ensureVenuesRegistered();
|
|
9
9
|
/**
|
|
10
10
|
* Settlement schedules per venue (UTC hours when settlement occurs), generated
|
|
11
|
-
* from `VenueDefinition.settlementIntervalHours`, anchored at 00:00 UTC
|
|
12
|
-
* (design §10.1, §10.13 #1). Venues whose interval is per-market (Aster)
|
|
11
|
+
* from `VenueDefinition.settlementIntervalHours`, anchored at 00:00 UTC. Venues whose interval is per-market (Aster)
|
|
13
12
|
* have no entry — pass the market's interval to getLastSettlement().
|
|
14
13
|
*/
|
|
15
14
|
export const SETTLEMENT_SCHEDULES = Object.fromEntries(listVenues()
|
package/dist/bot/apex/pulse.js
CHANGED
|
@@ -20,6 +20,9 @@ export function tierRank(tier) {
|
|
|
20
20
|
}
|
|
21
21
|
export function detectPulse(current, history) {
|
|
22
22
|
const symbol = "unknown"; // caller sets the actual symbol
|
|
23
|
+
// Unknown OI → no pulse signal (the OI change cannot be computed).
|
|
24
|
+
if (current.openInterest === null)
|
|
25
|
+
return { symbol, tier: "NONE", confidence: 0, oiChange: 0, volumeRatio: 0 };
|
|
23
26
|
const currentOi = parseFloat(current.openInterest);
|
|
24
27
|
const currentVolume = current.volume24h;
|
|
25
28
|
const past = history.get(symbol) ?? [];
|
package/dist/bot/apex/radar.js
CHANGED
|
@@ -20,7 +20,8 @@ function scoreStructure(snapshot) {
|
|
|
20
20
|
else if (vol > 1_000_000)
|
|
21
21
|
score += 15;
|
|
22
22
|
// OI component (0-50): higher open interest = more conviction
|
|
23
|
-
|
|
23
|
+
// null (unknown) → no OI score, the same as below every threshold — never a parsed fake 0.
|
|
24
|
+
const oi = snapshot.openInterest === null ? NaN : parseFloat(snapshot.openInterest);
|
|
24
25
|
if (oi > 50_000_000)
|
|
25
26
|
score += 50;
|
|
26
27
|
else if (oi > 20_000_000)
|
package/dist/bot/engine.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExchangeAdapter } from "../exchanges/index.js";
|
|
2
2
|
import { filledOf } from "./fill-size.js";
|
|
3
3
|
import type { BotConfig } from "./config.js";
|
|
4
|
-
import type { StrategyAction } from "./strategy-types.js";
|
|
4
|
+
import type { StrategyAction, EnrichedSnapshot } from "./strategy-types.js";
|
|
5
5
|
import { type QuoteRules } from "./quote-rules.js";
|
|
6
6
|
import "./strategies/grid-strategy.js";
|
|
7
7
|
import "./strategies/dca-strategy.js";
|
|
@@ -87,6 +87,15 @@ export declare function executeActions(adapter: ExchangeAdapter, symbol: string,
|
|
|
87
87
|
filled: number;
|
|
88
88
|
}>;
|
|
89
89
|
export { filledOf };
|
|
90
|
+
/**
|
|
91
|
+
* The tick's market snapshot. `unknown` names a failed orderbook / klines read (null = both
|
|
92
|
+
* read): the empty arrays in `snapshot` then are NOT data — the engine skips the tick of a
|
|
93
|
+
* strategy that reads them (MARKET_DATA_STRATEGIES).
|
|
94
|
+
*/
|
|
95
|
+
export declare function getEnrichedSnapshot(adapter: ExchangeAdapter, symbol: string, log: BotLog): Promise<{
|
|
96
|
+
snapshot: EnrichedSnapshot;
|
|
97
|
+
unknown: string | null;
|
|
98
|
+
}>;
|
|
90
99
|
/** TUI positions of one venue; a failed read → `error` set (shown "unavailable"), never an empty list. */
|
|
91
100
|
export declare function fetchPositions(adapter: ExchangeAdapter, symbol: string, exchangeName?: string): Promise<{
|
|
92
101
|
positions: import("./tui/index.js").Position[];
|