perp-cli 0.12.15 → 0.14.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 +278 -31
- package/dist/_stderr-filter.js +0 -1
- package/dist/agent-wallet/lighter-keystore.d.ts +11 -0
- package/dist/agent-wallet/lighter-keystore.js +92 -10
- package/dist/agent-wallet/passphrase.d.ts +1 -1
- package/dist/agent-wallet/passphrase.js +16 -3
- package/dist/agent-wallet/store.d.ts +37 -4
- package/dist/agent-wallet/store.js +132 -0
- package/dist/agent-wallet/venue-keystore.d.ts +14 -0
- package/dist/agent-wallet/venue-keystore.js +121 -0
- package/dist/api/public/hyperliquid.js +4 -4
- package/dist/api/public/lighter.js +5 -5
- package/dist/api/public/pacifica.d.ts +0 -1
- package/dist/api/public/pacifica.js +4 -13
- package/dist/api/public/urls.d.ts +9 -1
- package/dist/api/public/urls.js +35 -13
- package/dist/arb/file-lock.d.ts +11 -0
- package/dist/arb/file-lock.js +74 -0
- package/dist/arb/index.d.ts +2 -2
- package/dist/arb/index.js +2 -2
- package/dist/arb/pending-entry.d.ts +32 -0
- package/dist/arb/pending-entry.js +77 -0
- package/dist/arb/sizing.d.ts +6 -13
- package/dist/arb/sizing.js +12 -51
- package/dist/arb/state.d.ts +45 -12
- package/dist/arb/state.js +214 -42
- package/dist/arb/utils.d.ts +20 -6
- package/dist/arb/utils.js +43 -39
- package/dist/bot/conditions.d.ts +4 -4
- package/dist/bot/conditions.js +11 -6
- package/dist/bot/config.d.ts +17 -1
- package/dist/bot/config.js +48 -12
- package/dist/bot/engine.d.ts +61 -2
- package/dist/bot/engine.js +610 -144
- package/dist/bot/fill-size.d.ts +7 -0
- package/dist/bot/fill-size.js +18 -0
- package/dist/bot/index.d.ts +1 -1
- package/dist/bot/index.js +1 -1
- package/dist/bot/perp-order.d.ts +99 -0
- package/dist/bot/perp-order.js +299 -0
- package/dist/bot/presets.d.ts +7 -0
- package/dist/bot/presets.js +17 -0
- package/dist/bot/quarantine.d.ts +75 -0
- package/dist/bot/quarantine.js +190 -0
- package/dist/bot/quote-rules.d.ts +23 -0
- package/dist/bot/quote-rules.js +69 -0
- package/dist/bot/strategies/avellaneda-mm.d.ts +32 -2
- package/dist/bot/strategies/avellaneda-mm.js +72 -70
- package/dist/bot/strategies/basis-arb.js +2 -0
- package/dist/bot/strategies/dca-strategy.d.ts +2 -0
- package/dist/bot/strategies/dca-strategy.js +5 -0
- package/dist/bot/strategies/funding-arb-strategy.d.ts +43 -3
- package/dist/bot/strategies/funding-arb-strategy.js +571 -380
- package/dist/bot/strategies/funding-arb-utils.d.ts +48 -23
- package/dist/bot/strategies/funding-arb-utils.js +159 -195
- package/dist/bot/strategies/funding-arb-v2.d.ts +32 -0
- package/dist/bot/strategies/funding-arb-v2.js +258 -47
- package/dist/bot/strategies/funding-auto.js +215 -194
- package/dist/bot/strategies/spot-perp-arb-strategy.d.ts +14 -0
- package/dist/bot/strategies/spot-perp-arb-strategy.js +217 -50
- package/dist/bot/strategies/spot-perp-executor.d.ts +73 -19
- package/dist/bot/strategies/spot-perp-executor.js +319 -120
- package/dist/bot/strategies/spot-perp-state.d.ts +43 -0
- package/dist/bot/strategies/spot-perp-state.js +70 -0
- package/dist/bot/strategy-types.d.ts +6 -0
- package/dist/bot/tui/BotDashboard.d.ts +7 -2
- package/dist/bot/tui/BotDashboard.js +6 -3
- package/dist/bridge-engine.d.ts +120 -19
- package/dist/bridge-engine.js +710 -422
- package/dist/bridge-signers.d.ts +54 -0
- package/dist/bridge-signers.js +161 -0
- package/dist/cache.d.ts +4 -1
- package/dist/cache.js +11 -0
- package/dist/cli-flags.d.ts +50 -0
- package/dist/cli-flags.js +104 -0
- package/dist/cli-program.d.ts +35 -0
- package/dist/cli-program.js +286 -0
- package/dist/cli-spec.js +1 -1
- package/dist/client-id-tracker.js +11 -2
- package/dist/commands/account.d.ts +7 -1
- package/dist/commands/account.js +74 -84
- package/dist/commands/agent-import.d.ts +114 -0
- package/dist/commands/agent-import.js +794 -0
- package/dist/commands/agent.d.ts +232 -2
- package/dist/commands/agent.js +1858 -955
- package/dist/commands/alerts.d.ts +1 -0
- package/dist/commands/alerts.js +31 -28
- package/dist/commands/arb/index.d.ts +60 -1
- package/dist/commands/arb/index.js +381 -384
- package/dist/commands/arb-auto.d.ts +132 -4
- package/dist/commands/arb-auto.js +1474 -967
- package/dist/commands/arb.d.ts +3 -1
- package/dist/commands/arb.js +62 -30
- package/dist/commands/bot.js +127 -47
- package/dist/commands/bridge.d.ts +2 -1
- package/dist/commands/bridge.js +339 -192
- package/dist/commands/builder.d.ts +55 -0
- package/dist/commands/builder.js +387 -0
- package/dist/commands/funds-onchain.d.ts +32 -0
- package/dist/commands/funds-onchain.js +286 -0
- package/dist/commands/funds.d.ts +25 -0
- package/dist/commands/funds.js +939 -245
- package/dist/commands/history.js +72 -45
- package/dist/commands/init.d.ts +107 -15
- package/dist/commands/init.js +1116 -249
- package/dist/commands/jobs.d.ts +2 -1
- package/dist/commands/jobs.js +77 -15
- package/dist/commands/manage.js +136 -91
- package/dist/commands/market.d.ts +4 -1
- package/dist/commands/market.js +35 -32
- package/dist/commands/outcome.d.ts +10 -0
- package/dist/commands/outcome.js +396 -0
- package/dist/commands/plan.js +52 -12
- package/dist/commands/portfolio.d.ts +1 -0
- package/dist/commands/portfolio.js +60 -72
- package/dist/commands/rebalance.d.ts +2 -1
- package/dist/commands/rebalance.js +33 -43
- package/dist/commands/risk.js +46 -19
- package/dist/commands/settings.d.ts +1 -0
- package/dist/commands/settings.js +246 -51
- package/dist/commands/trade.d.ts +50 -0
- package/dist/commands/trade.js +1943 -695
- package/dist/commands/wallet.d.ts +30 -1
- package/dist/commands/wallet.js +316 -337
- package/dist/config.d.ts +60 -9
- package/dist/config.js +252 -82
- package/dist/constants.d.ts +29 -4
- package/dist/constants.js +62 -20
- package/dist/dashboard/server.d.ts +2 -0
- package/dist/dashboard/server.js +9 -6
- package/dist/dashboard/ui.js +6 -4
- package/dist/dashboard/ws-feeds.js +20 -8
- package/dist/dex-asset-map.js +5 -3
- package/dist/errors.d.ts +122 -0
- package/dist/errors.js +194 -0
- package/dist/event-stream.js +75 -19
- package/dist/evm-master-tx.d.ts +59 -0
- package/dist/evm-master-tx.js +154 -0
- package/dist/exchanges/adapter-network.d.ts +10 -0
- package/dist/exchanges/adapter-network.js +10 -0
- package/dist/exchanges/arcus/adapter.d.ts +196 -0
- package/dist/exchanges/arcus/adapter.js +1092 -0
- package/dist/exchanges/arcus/agent.d.ts +55 -0
- package/dist/exchanges/arcus/agent.js +188 -0
- package/dist/exchanges/arcus/client.d.ts +63 -0
- package/dist/exchanges/arcus/client.js +285 -0
- package/dist/exchanges/arcus/public.d.ts +65 -0
- package/dist/exchanges/arcus/public.js +138 -0
- package/dist/exchanges/arcus/signing.d.ts +176 -0
- package/dist/exchanges/arcus/signing.js +288 -0
- package/dist/exchanges/arcus/spot-chain.d.ts +60 -0
- package/dist/exchanges/arcus/spot-chain.js +241 -0
- package/dist/exchanges/arcus/spot-router.d.ts +177 -0
- package/dist/exchanges/arcus/spot-router.js +183 -0
- package/dist/exchanges/arcus/spot.d.ts +109 -0
- package/dist/exchanges/arcus/spot.js +645 -0
- package/dist/exchanges/aster-funds.d.ts +127 -0
- package/dist/exchanges/aster-funds.js +252 -0
- package/dist/exchanges/aster-nonce.d.ts +2 -0
- package/dist/exchanges/aster-nonce.js +107 -0
- package/dist/exchanges/aster-spot.d.ts +117 -0
- package/dist/exchanges/aster-spot.js +686 -0
- package/dist/exchanges/aster-typed-data.d.ts +133 -7
- package/dist/exchanges/aster-typed-data.js +121 -7
- package/dist/exchanges/aster.d.ts +219 -6
- package/dist/exchanges/aster.js +1023 -153
- package/dist/exchanges/builder-fee.d.ts +254 -0
- package/dist/exchanges/builder-fee.js +421 -0
- package/dist/exchanges/canonical-symbols.d.ts +32 -0
- package/dist/exchanges/canonical-symbols.js +96 -0
- package/dist/exchanges/capabilities.d.ts +7 -1
- package/dist/exchanges/capabilities.js +7 -0
- package/dist/exchanges/hl-signing.d.ts +165 -0
- package/dist/exchanges/hl-signing.js +158 -0
- package/dist/exchanges/hyperliquid-outcome.d.ts +211 -0
- package/dist/exchanges/hyperliquid-outcome.js +646 -0
- package/dist/exchanges/hyperliquid-spot.d.ts +44 -5
- package/dist/exchanges/hyperliquid-spot.js +308 -117
- package/dist/exchanges/hyperliquid.d.ts +462 -57
- package/dist/exchanges/hyperliquid.js +1575 -449
- package/dist/exchanges/index.d.ts +6 -0
- package/dist/exchanges/index.js +4 -0
- package/dist/exchanges/interface.d.ts +63 -10
- package/dist/exchanges/interface.js +18 -3
- package/dist/exchanges/ioc-outcome.d.ts +44 -0
- package/dist/exchanges/ioc-outcome.js +57 -0
- package/dist/exchanges/legacy-trading-v2.d.ts +39 -0
- package/dist/exchanges/legacy-trading-v2.js +940 -0
- package/dist/exchanges/lighter-public.d.ts +43 -0
- package/dist/exchanges/lighter-public.js +276 -0
- package/dist/exchanges/lighter-rh-deposit.d.ts +62 -0
- package/dist/exchanges/lighter-rh-deposit.js +185 -0
- package/dist/exchanges/lighter-signer.d.ts +123 -0
- package/dist/exchanges/lighter-signer.js +215 -0
- package/dist/exchanges/lighter-spot.d.ts +91 -13
- package/dist/exchanges/lighter-spot.js +595 -233
- package/dist/exchanges/lighter.d.ts +611 -39
- package/dist/exchanges/lighter.js +1890 -649
- package/dist/exchanges/ondo/adapter.d.ts +166 -0
- package/dist/exchanges/ondo/adapter.js +835 -0
- package/dist/exchanges/ondo/agent.d.ts +31 -0
- package/dist/exchanges/ondo/agent.js +101 -0
- package/dist/exchanges/ondo/client.d.ts +60 -0
- package/dist/exchanges/ondo/client.js +297 -0
- package/dist/exchanges/ondo/funds.d.ts +122 -0
- package/dist/exchanges/ondo/funds.js +290 -0
- package/dist/exchanges/ondo/public.d.ts +95 -0
- package/dist/exchanges/ondo/public.js +214 -0
- package/dist/exchanges/ondo/spot.d.ts +127 -0
- package/dist/exchanges/ondo/spot.js +392 -0
- package/dist/exchanges/outcome-interface.d.ts +140 -0
- package/dist/exchanges/outcome-interface.js +16 -0
- package/dist/exchanges/pacifica-spot.d.ts +83 -0
- package/dist/exchanges/pacifica-spot.js +324 -0
- package/dist/exchanges/pacifica-typed-data.d.ts +30 -13
- package/dist/exchanges/pacifica-typed-data.js +57 -9
- package/dist/exchanges/pacifica.d.ts +288 -4
- package/dist/exchanges/pacifica.js +1013 -76
- package/dist/exchanges/precision.d.ts +47 -0
- package/dist/exchanges/precision.js +209 -0
- package/dist/exchanges/qfex/adapter.d.ts +341 -0
- package/dist/exchanges/qfex/adapter.js +1383 -0
- package/dist/exchanges/qfex/agent.d.ts +58 -0
- package/dist/exchanges/qfex/agent.js +188 -0
- package/dist/exchanges/qfex/client.d.ts +54 -0
- package/dist/exchanges/qfex/client.js +138 -0
- package/dist/exchanges/qfex/errors.d.ts +70 -0
- package/dist/exchanges/qfex/errors.js +236 -0
- package/dist/exchanges/qfex/public.d.ts +122 -0
- package/dist/exchanges/qfex/public.js +268 -0
- package/dist/exchanges/qfex/signing.d.ts +160 -0
- package/dist/exchanges/qfex/signing.js +283 -0
- package/dist/exchanges/qfex/ws-transport.d.ts +294 -0
- package/dist/exchanges/qfex/ws-transport.js +798 -0
- package/dist/exchanges/rate-limiter.d.ts +12 -0
- package/dist/exchanges/rate-limiter.js +64 -0
- package/dist/exchanges/registry.d.ts +14 -2
- package/dist/exchanges/registry.js +20 -32
- package/dist/exchanges/slippage.d.ts +37 -0
- package/dist/exchanges/slippage.js +70 -0
- package/dist/exchanges/spot-factory.d.ts +166 -0
- package/dist/exchanges/spot-factory.js +431 -0
- package/dist/exchanges/spot-interface.d.ts +98 -4
- package/dist/exchanges/spot-interface.js +27 -1
- package/dist/exchanges/spot-result.d.ts +79 -0
- package/dist/exchanges/spot-result.js +273 -0
- package/dist/exchanges/trading-v2.d.ts +117 -0
- package/dist/exchanges/trading-v2.js +301 -0
- package/dist/exchanges/venue-types.d.ts +231 -0
- package/dist/exchanges/venue-types.js +87 -0
- package/dist/exchanges/venue.d.ts +211 -0
- package/dist/exchanges/venue.js +132 -0
- package/dist/exchanges/venues/arcus.d.ts +8 -0
- package/dist/exchanges/venues/arcus.js +109 -0
- package/dist/exchanges/venues/aster.d.ts +49 -0
- package/dist/exchanges/venues/aster.js +176 -0
- package/dist/exchanges/venues/create-helpers.d.ts +18 -0
- package/dist/exchanges/venues/create-helpers.js +199 -0
- package/dist/exchanges/venues/hyperliquid.d.ts +23 -0
- package/dist/exchanges/venues/hyperliquid.js +126 -0
- package/dist/exchanges/venues/index.d.ts +16 -0
- package/dist/exchanges/venues/index.js +26 -0
- package/dist/exchanges/venues/lighter-family.d.ts +92 -0
- package/dist/exchanges/venues/lighter-family.js +166 -0
- package/dist/exchanges/venues/lighter-rh.d.ts +7 -0
- package/dist/exchanges/venues/lighter-rh.js +58 -0
- package/dist/exchanges/venues/lighter.d.ts +6 -0
- package/dist/exchanges/venues/lighter.js +55 -0
- package/dist/exchanges/venues/ondo.d.ts +34 -0
- package/dist/exchanges/venues/ondo.js +140 -0
- package/dist/exchanges/venues/pacifica.d.ts +8 -0
- package/dist/exchanges/venues/pacifica.js +95 -0
- package/dist/exchanges/venues/qfex.d.ts +28 -0
- package/dist/exchanges/venues/qfex.js +132 -0
- package/dist/execution-log.js +10 -2
- package/dist/funding/legacy-public.d.ts +31 -0
- package/dist/funding/legacy-public.js +369 -0
- package/dist/funding/normalize.d.ts +28 -16
- package/dist/funding/normalize.js +61 -29
- package/dist/funding/rates.d.ts +46 -11
- package/dist/funding/rates.js +228 -277
- package/dist/guardrail/perp-guardrail.js +0 -0
- package/dist/index.js +157 -682
- package/dist/jobs.d.ts +84 -6
- package/dist/jobs.js +239 -41
- package/dist/landing.d.ts +14 -0
- package/dist/landing.js +36 -0
- package/dist/mcp-server.d.ts +14 -4
- package/dist/mcp-server.js +820 -402
- package/dist/mcp-trade-guard.d.ts +16 -0
- package/dist/mcp-trade-guard.js +59 -0
- package/dist/pacifica/client.d.ts +41 -10
- package/dist/pacifica/client.js +167 -63
- package/dist/pacifica/constants.d.ts +0 -1
- package/dist/pacifica/constants.js +0 -5
- package/dist/pacifica/deposit.d.ts +30 -3
- package/dist/pacifica/deposit.js +119 -2
- package/dist/pacifica/faucet.d.ts +29 -0
- package/dist/pacifica/faucet.js +100 -0
- package/dist/pacifica/sign-tx.d.ts +15 -0
- package/dist/pacifica/sign-tx.js +41 -0
- package/dist/pacifica/types/account.d.ts +28 -4
- package/dist/pacifica/types/lake.d.ts +20 -5
- package/dist/pacifica/types/lake.js +4 -0
- package/dist/pacifica/types/market.d.ts +5 -0
- package/dist/pacifica/types/order.d.ts +4 -1
- package/dist/pacifica/types/position.d.ts +9 -1
- package/dist/plan-executor.d.ts +10 -5
- package/dist/plan-executor.js +165 -54
- package/dist/position-history.js +13 -0
- package/dist/rebalance.d.ts +26 -2
- package/dist/rebalance.js +86 -7
- package/dist/relay-swap.d.ts +232 -0
- package/dist/relay-swap.js +630 -0
- package/dist/risk.js +5 -1
- package/dist/secret-env.d.ts +15 -0
- package/dist/secret-env.js +36 -0
- package/dist/settings.d.ts +169 -6
- package/dist/settings.js +219 -38
- package/dist/signer/ows-evm.d.ts +13 -0
- package/dist/signer/ows-evm.js +22 -0
- package/dist/smart-order.d.ts +9 -0
- package/dist/smart-order.js +53 -8
- package/dist/strategies/dca.d.ts +6 -2
- package/dist/strategies/dca.js +66 -26
- package/dist/strategies/funding-arb.d.ts +11 -1
- package/dist/strategies/funding-arb.js +202 -89
- package/dist/strategies/grid.d.ts +31 -0
- package/dist/strategies/grid.js +89 -11
- package/dist/strategies/pending-stop.d.ts +8 -0
- package/dist/strategies/pending-stop.js +12 -0
- package/dist/strategies/split-order.d.ts +45 -17
- package/dist/strategies/split-order.js +157 -91
- package/dist/strategies/trailing-stop.d.ts +2 -1
- package/dist/strategies/trailing-stop.js +52 -6
- package/dist/strategies/twap.d.ts +6 -1
- package/dist/strategies/twap.js +39 -11
- package/dist/trade-validator.d.ts +22 -0
- package/dist/trade-validator.js +119 -15
- package/dist/utils/numeric.d.ts +46 -0
- package/dist/utils/numeric.js +79 -0
- package/dist/utils.d.ts +19 -0
- package/dist/utils.js +96 -19
- package/dist/withdraw-gate.d.ts +49 -0
- package/dist/withdraw-gate.js +131 -0
- package/package.json +15 -6
- package/skills/perp-cli/SKILL.md +338 -134
- package/skills/perp-cli/references/agent-operations.md +181 -92
- package/skills/perp-cli/references/commands.md +475 -132
- package/skills/perp-cli/references/strategies.md +44 -38
- package/skills/perp-cli/scripts/arb-monitor.sh +22 -17
- package/skills/perp-cli/scripts/funding-analysis.sh +20 -10
- package/skills/perp-cli/scripts/preflight.sh +21 -14
- package/skills/perp-cli/scripts/spot-perp-scan.sh +12 -7
- package/skills/perp-cli/scripts/validate-arb.sh +33 -16
- package/vendor/lighter-signer/SHA256SUMS +2 -0
- package/vendor/lighter-signer/VERSION +8 -0
- package/vendor/lighter-signer/lighter-signer.wasm +0 -0
- package/vendor/lighter-signer/wasm_exec.js +575 -0
- package/dist/bot/strategies/funding-arb-v2-strategy.d.ts +0 -42
- package/dist/bot/strategies/funding-arb-v2-strategy.js +0 -864
package/dist/commands/arb.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import type { ExchangeAdapter } from "../exchanges/index.js";
|
|
3
|
+
import "../exchanges/venues/index.js";
|
|
3
4
|
export declare function registerArbCommands(program: Command, isJson: () => boolean, getAdapterForExchange?: (exchange: string) => Promise<ExchangeAdapter>): void;
|
|
4
5
|
export interface PriceSnapshot {
|
|
5
6
|
symbol: string;
|
|
@@ -26,6 +27,7 @@ export declare function handleRates(isJson: () => boolean, opts: {
|
|
|
26
27
|
all?: boolean;
|
|
27
28
|
minSpread: string;
|
|
28
29
|
top?: string;
|
|
30
|
+
includeUnverified?: boolean;
|
|
29
31
|
}): Promise<void>;
|
|
30
32
|
export declare function handleBasisScan(isJson: () => boolean, opts: {
|
|
31
33
|
minBasis: string;
|
|
@@ -37,7 +39,7 @@ export declare function handleDexScan(isJson: () => boolean, opts: {
|
|
|
37
39
|
includeNative: boolean;
|
|
38
40
|
top: string;
|
|
39
41
|
}): Promise<void>;
|
|
40
|
-
export declare function handleCompare(isJson: () => boolean, symbol: string): Promise<void>;
|
|
42
|
+
export declare function handleCompare(isJson: () => boolean, symbol: string, includeUnverified?: boolean): Promise<void>;
|
|
41
43
|
export declare function handleFundingHistory(isJson: () => boolean, opts: {
|
|
42
44
|
symbol: string;
|
|
43
45
|
hours: string;
|
package/dist/commands/arb.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { makeTable, formatUsd, formatPercent, formatPnl, printJson, jsonOk, withJsonErrors, logSettledRejections } from "../utils.js";
|
|
2
2
|
import chalk from "chalk";
|
|
3
|
-
import {
|
|
3
|
+
import { toHourlyRate, annualizeHourlyRate, estimateHourlyFundingFromHourly } from "../funding.js";
|
|
4
4
|
import { fetchAllFundingRates, fetchSymbolFundingRates, TOP_SYMBOLS, } from "../funding-rates.js";
|
|
5
5
|
import { saveFundingSnapshot, getHistoricalRates, getCompoundedAnnualReturn, getExchangeCompoundingHours, } from "../funding-history.js";
|
|
6
|
+
import { getVenue, listVenuesWithRole, tryResolveVenueId } from "../exchanges/venue.js";
|
|
7
|
+
import "../exchanges/venues/index.js";
|
|
6
8
|
import { fetchPacificaPrices, fetchHyperliquidMeta, fetchLighterOrderBookDetails, fetchLighterFundingRates, fetchPacificaPricesRaw, parsePacificaRaw, fetchHyperliquidAllMidsRaw, fetchLighterOrderBookDetailsRaw, } from "../shared-api.js";
|
|
7
9
|
import { scanDexArb } from "../dex-asset-map.js";
|
|
8
10
|
async function fetchPacificaRates() {
|
|
@@ -12,7 +14,6 @@ async function fetchPacificaRates() {
|
|
|
12
14
|
symbol: p.symbol,
|
|
13
15
|
fundingRate: p.funding,
|
|
14
16
|
markPrice: p.mark,
|
|
15
|
-
nextFunding: p.nextFunding ?? 0,
|
|
16
17
|
}));
|
|
17
18
|
}
|
|
18
19
|
async function fetchHyperliquidRates() {
|
|
@@ -40,7 +41,6 @@ async function fetchAsterRates() {
|
|
|
40
41
|
continue;
|
|
41
42
|
const fundingRate = Number(p.lastFundingRate);
|
|
42
43
|
const markPrice = Number(p.markPrice);
|
|
43
|
-
const nextFunding = Number(p.nextFundingTime);
|
|
44
44
|
if (!Number.isFinite(fundingRate) || !Number.isFinite(markPrice) || markPrice <= 0) {
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
@@ -49,7 +49,6 @@ async function fetchAsterRates() {
|
|
|
49
49
|
symbol: rawSym.replace(/USDT$/, ""),
|
|
50
50
|
fundingRate,
|
|
51
51
|
markPrice,
|
|
52
|
-
nextFunding: Number.isFinite(nextFunding) ? nextFunding : 0,
|
|
53
52
|
});
|
|
54
53
|
}
|
|
55
54
|
return out;
|
|
@@ -237,8 +236,17 @@ function formatAvgRate(rate) {
|
|
|
237
236
|
const color = annualPct > 0 ? chalk.red : annualPct < 0 ? chalk.green : chalk.white;
|
|
238
237
|
return color(`${annualPct.toFixed(1)}%`);
|
|
239
238
|
}
|
|
239
|
+
/** Short venue label: first alias (or id), upper-cased — e.g. PAC, HL, LT, AST, LRH, ONDO-PERPS. */
|
|
240
|
+
function venueAbbr(e) {
|
|
241
|
+
const id = tryResolveVenueId(e);
|
|
242
|
+
if (id === null)
|
|
243
|
+
return e.toUpperCase();
|
|
244
|
+
const def = getVenue(id);
|
|
245
|
+
return (def.aliases[0] ?? def.id).toUpperCase();
|
|
246
|
+
}
|
|
240
247
|
function printSnapshotTable(snapshot) {
|
|
241
|
-
const exAbbr =
|
|
248
|
+
const exAbbr = venueAbbr;
|
|
249
|
+
const columns = listVenuesWithRole("marketData");
|
|
242
250
|
if (snapshot.symbols.length === 0) {
|
|
243
251
|
console.log(chalk.gray(" No funding rate data available.\n"));
|
|
244
252
|
return;
|
|
@@ -272,23 +280,23 @@ function printSnapshotTable(snapshot) {
|
|
|
272
280
|
}
|
|
273
281
|
}
|
|
274
282
|
const rows = snapshot.symbols.map(s => {
|
|
275
|
-
const
|
|
276
|
-
const hlRate = s.rates.find(r => r.exchange === "hyperliquid");
|
|
277
|
-
const ltRate = s.rates.find(r => r.exchange === "lighter");
|
|
278
|
-
const astRate = s.rates.find(r => r.exchange === "aster");
|
|
283
|
+
const rateOf = (id) => s.rates.find(r => r.exchange === id);
|
|
279
284
|
const spreadColor = s.maxSpreadAnnual >= 30 ? chalk.green : s.maxSpreadAnnual >= 10 ? chalk.yellow : chalk.white;
|
|
280
|
-
|
|
285
|
+
// Historical-average source preference: HL, PAC, LT, AST, then whichever venue quoted.
|
|
286
|
+
const bestRate = rateOf("hyperliquid") ?? rateOf("pacifica") ?? rateOf("lighter") ?? rateOf("aster") ?? s.rates[0];
|
|
281
287
|
const trend = trendMap.get(s.symbol) ?? chalk.gray("-");
|
|
282
288
|
return [
|
|
283
|
-
chalk.white.bold(s.symbol),
|
|
284
|
-
|
|
285
|
-
|
|
289
|
+
chalk.white.bold(s.symbol),
|
|
290
|
+
...columns.map(v => {
|
|
291
|
+
const r = rateOf(v.id);
|
|
292
|
+
return r ? formatPercent(r.fundingRate) : chalk.gray("-");
|
|
293
|
+
}),
|
|
286
294
|
spreadColor(`${s.maxSpreadAnnual.toFixed(1)}%`), trend,
|
|
287
295
|
s.maxSpreadAnnual >= 5 ? `${exAbbr(s.shortExchange)}>${exAbbr(s.longExchange)}` : chalk.gray("-"),
|
|
288
296
|
formatAvgRate(bestRate?.historicalAvg?.avg8h), formatAvgRate(bestRate?.historicalAvg?.avg24h), formatAvgRate(bestRate?.historicalAvg?.avg7d),
|
|
289
297
|
];
|
|
290
298
|
});
|
|
291
|
-
console.log(makeTable(["Symbol",
|
|
299
|
+
console.log(makeTable(["Symbol", ...columns.map(v => v.displayName), "Spread", "24h", "Direction", "Avg 8h", "Avg 24h", "Avg 7d"], rows));
|
|
292
300
|
console.log(chalk.gray(`\n ${snapshot.symbols.length} symbols compared across exchanges.\n`));
|
|
293
301
|
}
|
|
294
302
|
function printFundingExchangeStatus(snapshot) {
|
|
@@ -299,7 +307,7 @@ function printFundingExchangeStatus(snapshot) {
|
|
|
299
307
|
console.log(chalk.gray(` Exchange status: ${statuses.join(" ")}\n`));
|
|
300
308
|
}
|
|
301
309
|
function printDetailedComparison(comparison) {
|
|
302
|
-
const exAbbr =
|
|
310
|
+
const exAbbr = venueAbbr;
|
|
303
311
|
console.log(chalk.cyan.bold(` ${comparison.symbol} Funding Rate Comparison\n`));
|
|
304
312
|
console.log(` Mark Price: $${formatUsd(comparison.bestMarkPrice)}\n`);
|
|
305
313
|
for (const r of comparison.rates) {
|
|
@@ -315,6 +323,13 @@ function printDetailedComparison(comparison) {
|
|
|
315
323
|
}
|
|
316
324
|
// registerFundingSubcommands removed — use 'arb scan --rates/--compare/--history/--positions' instead
|
|
317
325
|
// ── Exported handler functions for use by arb-auto.ts scan routing ──
|
|
326
|
+
/** One-line stderr notice when rows of unverified-funding venues are shown (--include-unverified). */
|
|
327
|
+
function warnUnverifiedFunding(rates) {
|
|
328
|
+
const venues = [...new Set(rates.filter(r => !r.fundingVerified).map(r => r.exchange))];
|
|
329
|
+
if (venues.length === 0)
|
|
330
|
+
return;
|
|
331
|
+
process.stderr.write(`[warn] ${venues.join(", ")}: funding rates are UNVERIFIED (unit not confirmed against funding payments; annualized values overstate venues whose funding accrues only during market hours). Shown on request — not for trading decisions.\n`);
|
|
332
|
+
}
|
|
318
333
|
export async function handleRates(isJson, opts) {
|
|
319
334
|
const minSpread = parseFloat(opts.minSpread);
|
|
320
335
|
let filterSymbols;
|
|
@@ -326,9 +341,15 @@ export async function handleRates(isJson, opts) {
|
|
|
326
341
|
filterSymbols = TOP_SYMBOLS;
|
|
327
342
|
if (!isJson())
|
|
328
343
|
console.log(chalk.cyan(" Fetching funding rates from all exchanges...\n"));
|
|
329
|
-
|
|
344
|
+
// With --include-unverified and no symbol filter, show every matched symbol: the default
|
|
345
|
+
// TOP_SYMBOLS list is crypto-only and would hide every market of an equity venue.
|
|
346
|
+
if (opts.includeUnverified === true && !opts.symbol && !opts.symbols)
|
|
347
|
+
filterSymbols = undefined;
|
|
348
|
+
const snapshot = await fetchAllFundingRates({ symbols: filterSymbols, minSpread, includeUnverified: opts.includeUnverified === true });
|
|
349
|
+
warnUnverifiedFunding(snapshot.symbols.flatMap(s => s.rates));
|
|
350
|
+
// Unverified rates are never written to the funding history (it feeds averages and bots).
|
|
330
351
|
try {
|
|
331
|
-
const allRates = snapshot.symbols.flatMap(s => s.rates);
|
|
352
|
+
const allRates = snapshot.symbols.flatMap(s => s.rates).filter(r => r.fundingVerified);
|
|
332
353
|
if (allRates.length > 0)
|
|
333
354
|
saveFundingSnapshot(allRates);
|
|
334
355
|
}
|
|
@@ -467,10 +488,12 @@ export async function handleDexScan(isJson, opts) {
|
|
|
467
488
|
console.log(chalk.gray(` A: OI>$1M B: OI>$100K C: OI>$10K D: OI<$10K (thin — high risk)`));
|
|
468
489
|
console.log(chalk.gray(` Note: HIP-3 dexes charge 2x fees. Factor into net profitability.\n`));
|
|
469
490
|
}
|
|
470
|
-
export async function handleCompare(isJson, symbol) {
|
|
491
|
+
export async function handleCompare(isJson, symbol, includeUnverified = false) {
|
|
471
492
|
if (!isJson())
|
|
472
493
|
console.log(chalk.cyan(` Fetching funding rates for ${symbol.toUpperCase()}...\n`));
|
|
473
|
-
const comparison = await fetchSymbolFundingRates(symbol);
|
|
494
|
+
const comparison = await fetchSymbolFundingRates(symbol, includeUnverified);
|
|
495
|
+
if (comparison)
|
|
496
|
+
warnUnverifiedFunding(comparison.rates);
|
|
474
497
|
if (!comparison) {
|
|
475
498
|
if (isJson())
|
|
476
499
|
return printJson(jsonOk({ symbol: symbol.toUpperCase(), available: false }));
|
|
@@ -497,7 +520,7 @@ export async function handleFundingHistory(isJson, opts) {
|
|
|
497
520
|
return printJson(jsonOk({ symbol, hours, startTime: startTime.toISOString(), endTime: endTime.toISOString(), rates: data }));
|
|
498
521
|
}
|
|
499
522
|
console.log(chalk.cyan.bold(` ${symbol} Funding Rate History (last ${hours}h)\n`));
|
|
500
|
-
const exAbbr =
|
|
523
|
+
const exAbbr = venueAbbr;
|
|
501
524
|
let hasData = false;
|
|
502
525
|
for (const ex of exchanges) {
|
|
503
526
|
const rates = getHistoricalRates(symbol, ex, startTime, endTime);
|
|
@@ -519,16 +542,18 @@ export async function handleFundingPositions(isJson, getAdapterForExchange, opts
|
|
|
519
542
|
console.log(chalk.cyan(" Fetching positions and funding rates...\n"));
|
|
520
543
|
const results = [];
|
|
521
544
|
const exchangeErrors = {};
|
|
545
|
+
const fundingUnknown = [];
|
|
522
546
|
await Promise.all(targetExchanges.map(async (exchange) => {
|
|
523
547
|
try {
|
|
524
548
|
const adapter = await getAdapterForExchange(exchange);
|
|
525
549
|
const [positions, markets, fp] = await Promise.all([adapter.getPositions(), adapter.getMarkets(), adapter.getFundingPayments(100).catch(() => [])]);
|
|
526
550
|
if (positions.length === 0)
|
|
527
551
|
return;
|
|
528
|
-
const fm = new Map();
|
|
552
|
+
/* rate null = the venue reports no funding rate for the market (never read as 0) */ const fm = new Map();
|
|
529
553
|
for (const m of markets) {
|
|
530
554
|
const sym = m.symbol.toUpperCase().replace(/-PERP$/, "");
|
|
531
|
-
|
|
555
|
+
const rate = m.fundingRate === null || !Number.isFinite(Number(m.fundingRate)) ? null : Number(m.fundingRate);
|
|
556
|
+
fm.set(sym, { rate, markPrice: Number(m.markPrice) || 0, fundingHours: m.fundingHours });
|
|
532
557
|
}
|
|
533
558
|
const dayAgo = Date.now() - 86400000;
|
|
534
559
|
const af = new Map();
|
|
@@ -548,13 +573,18 @@ export async function handleFundingPositions(isJson, getAdapterForExchange, opts
|
|
|
548
573
|
for (const pos of positions) {
|
|
549
574
|
const sym = pos.symbol.toUpperCase().replace(/-PERP$/, "");
|
|
550
575
|
const fd = fm.get(sym);
|
|
551
|
-
|
|
576
|
+
if (fd === undefined || fd.rate === null) {
|
|
577
|
+
fundingUnknown.push(`${exchange}:${sym}`);
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
const fr = fd.rate;
|
|
552
581
|
const mk = Number(pos.markPrice) || fd?.markPrice || 0;
|
|
553
582
|
const sz = Math.abs(Number(pos.size));
|
|
554
583
|
const nu = sz * mk;
|
|
555
|
-
const
|
|
556
|
-
const
|
|
557
|
-
const
|
|
584
|
+
const fh = fd ? fd.fundingHours : null; /* market basis first (§10.1) */
|
|
585
|
+
const hr = fh !== null ? fr / fh : toHourlyRate(fr, exchange);
|
|
586
|
+
const ap = annualizeHourlyRate(hr);
|
|
587
|
+
const hp = estimateHourlyFundingFromHourly(hr, nu, pos.side);
|
|
558
588
|
const a = af.get(sym);
|
|
559
589
|
results.push({ exchange, symbol: sym, side: pos.side, size: pos.size, entryPrice: pos.entryPrice, markPrice: pos.markPrice, unrealizedPnl: pos.unrealizedPnl, leverage: pos.leverage, notionalUsd: nu, fundingRate: fr, hourlyRate: hr, annualPct: ap, hourlyPayment: hp, dailyPayment: hp * 24, actualReceived24h: a?.received ?? 0, actualPaid24h: a?.paid ?? 0, actualNet24h: (a?.received ?? 0) - (a?.paid ?? 0) });
|
|
560
590
|
}
|
|
@@ -565,8 +595,8 @@ export async function handleFundingPositions(isJson, getAdapterForExchange, opts
|
|
|
565
595
|
}));
|
|
566
596
|
if (results.length === 0) {
|
|
567
597
|
if (isJson())
|
|
568
|
-
return printJson(jsonOk({ positions: [], totals: { predicted: { hourly: 0, daily: 0 }, actual24h: { net: 0 }, notionalUsd: 0 }, errors: exchangeErrors }));
|
|
569
|
-
console.log(chalk.gray(" No open positions.\n"));
|
|
598
|
+
return printJson(jsonOk({ positions: [], totals: { predicted: { hourly: 0, daily: 0 }, actual24h: { net: 0 }, notionalUsd: 0 }, fundingUnknown, errors: exchangeErrors }));
|
|
599
|
+
console.log(chalk.gray(fundingUnknown.length > 0 ? ` No positions with a published funding rate (funding unknown: ${fundingUnknown.join(", ")}).\n` : " No open positions.\n"));
|
|
570
600
|
return;
|
|
571
601
|
}
|
|
572
602
|
results.sort((a, b) => Math.abs(b.dailyPayment) - Math.abs(a.dailyPayment));
|
|
@@ -575,11 +605,13 @@ export async function handleFundingPositions(isJson, getAdapterForExchange, opts
|
|
|
575
605
|
const tN = results.reduce((s, r) => s + r.notionalUsd, 0);
|
|
576
606
|
const tA = results.reduce((s, r) => s + r.actualNet24h, 0);
|
|
577
607
|
if (isJson())
|
|
578
|
-
return printJson(jsonOk({ positions: results.map(r => ({ exchange: r.exchange, symbol: r.symbol, side: r.side, size: r.size, notionalUsd: +r.notionalUsd.toFixed(2), fundingRate: r.fundingRate, annualPct: +r.annualPct.toFixed(2), predicted: { hourly: +r.hourlyPayment.toFixed(6), daily: +r.dailyPayment.toFixed(4) }, actual24h: { received: +r.actualReceived24h.toFixed(6), paid: +r.actualPaid24h.toFixed(6), net: +r.actualNet24h.toFixed(6) }, unrealizedPnl: r.unrealizedPnl })), totals: { predicted: { hourly: +tH.toFixed(6), daily: +tD.toFixed(4) }, actual24h: { net: +tA.toFixed(6) }, notionalUsd: +tN.toFixed(2) }, errors: Object.keys(exchangeErrors).length > 0 ? exchangeErrors : undefined }));
|
|
579
|
-
const exAbbr =
|
|
608
|
+
return printJson(jsonOk({ positions: results.map(r => ({ exchange: r.exchange, symbol: r.symbol, side: r.side, size: r.size, notionalUsd: +r.notionalUsd.toFixed(2), fundingRate: r.fundingRate, annualPct: +r.annualPct.toFixed(2), predicted: { hourly: +r.hourlyPayment.toFixed(6), daily: +r.dailyPayment.toFixed(4) }, actual24h: { received: +r.actualReceived24h.toFixed(6), paid: +r.actualPaid24h.toFixed(6), net: +r.actualNet24h.toFixed(6) }, unrealizedPnl: r.unrealizedPnl })), totals: { predicted: { hourly: +tH.toFixed(6), daily: +tD.toFixed(4) }, actual24h: { net: +tA.toFixed(6) }, notionalUsd: +tN.toFixed(2) }, fundingUnknown, errors: Object.keys(exchangeErrors).length > 0 ? exchangeErrors : undefined }));
|
|
609
|
+
const exAbbr = venueAbbr;
|
|
580
610
|
console.log(chalk.cyan.bold(" Position Funding Impact\n"));
|
|
581
611
|
const rows = results.map(r => { const sc = r.side === "long" ? chalk.green : chalk.red; const rc = r.fundingRate > 0 ? chalk.red : r.fundingRate < 0 ? chalk.green : chalk.white; const as = r.actualNet24h !== 0 ? (r.actualNet24h > 0 ? chalk.green : chalk.red)(`${r.actualNet24h > 0 ? "+" : ""}$${r.actualNet24h.toFixed(4)}`) : chalk.gray("-"); return [chalk.white.bold(exAbbr(r.exchange)), chalk.white.bold(r.symbol), sc(r.side.toUpperCase()), `$${formatUsd(r.notionalUsd)}`, rc(formatPercent(r.fundingRate)), rc(`${r.annualPct.toFixed(1)}%`), as, formatPnl(r.unrealizedPnl)]; });
|
|
582
612
|
console.log(makeTable(["Ex", "Symbol", "Side", "Notional", "Rate(now)", "Annual(now)", "Actual 24h", "uPnL"], rows));
|
|
583
613
|
console.log(`\n Total: $${formatUsd(tN)} | Actual 24h: ${tA >= 0 ? "+" : ""}$${tA.toFixed(4)} | Predicted: ${tD >= 0 ? "-" : "+"}$${Math.abs(tD).toFixed(4)}/d\n`);
|
|
614
|
+
if (fundingUnknown.length > 0)
|
|
615
|
+
console.log(chalk.yellow(` Funding rate not published (excluded, not counted as 0): ${fundingUnknown.join(", ")}\n`));
|
|
584
616
|
});
|
|
585
617
|
}
|