perp-cli 0.6.3 → 0.7.1
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 +7 -2
- package/dist/api/public/hyperliquid.d.ts +2 -2
- package/dist/api/public/hyperliquid.js +0 -10
- package/dist/api/public/lighter.d.ts +2 -1
- package/dist/api/public/pacifica.d.ts +2 -1
- package/dist/arb/index.d.ts +7 -4
- package/dist/arb/index.js +5 -4
- package/dist/arb/sizing.d.ts +1 -1
- package/dist/arb/state.d.ts +1 -1
- package/dist/arb/state.js +4 -3
- package/dist/arb/utils.d.ts +0 -10
- package/dist/arb/utils.js +0 -42
- package/dist/bot/apex/guard.d.ts +26 -0
- package/dist/bot/apex/guard.js +86 -0
- package/dist/bot/apex/index.d.ts +6 -0
- package/dist/bot/apex/index.js +4 -0
- package/dist/bot/apex/pulse.d.ts +22 -0
- package/dist/bot/apex/pulse.js +107 -0
- package/dist/bot/apex/radar.d.ts +17 -0
- package/dist/bot/apex/radar.js +150 -0
- package/dist/bot/conditions.d.ts +1 -1
- package/dist/bot/config.d.ts +5 -1
- package/dist/bot/config.js +1 -1
- package/dist/bot/engine.d.ts +23 -2
- package/dist/bot/engine.js +296 -351
- package/dist/bot/index.d.ts +16 -0
- package/dist/bot/index.js +10 -0
- package/dist/bot/indicators.d.ts +29 -0
- package/dist/bot/indicators.js +144 -0
- package/dist/bot/reflect.d.ts +34 -0
- package/dist/bot/reflect.js +155 -0
- package/dist/bot/strategies/aggressive-taker.d.ts +36 -0
- package/dist/bot/strategies/aggressive-taker.js +125 -0
- package/dist/bot/strategies/apex-strategy.d.ts +36 -0
- package/dist/bot/strategies/apex-strategy.js +185 -0
- package/dist/bot/strategies/avellaneda-mm.d.ts +27 -0
- package/dist/bot/strategies/avellaneda-mm.js +111 -0
- package/dist/bot/strategies/basis-arb.d.ts +27 -0
- package/dist/bot/strategies/basis-arb.js +97 -0
- package/dist/bot/strategies/claude-agent.d.ts +31 -0
- package/dist/bot/strategies/claude-agent.js +155 -0
- package/dist/bot/strategies/dca-strategy.d.ts +25 -0
- package/dist/bot/strategies/dca-strategy.js +59 -0
- package/dist/bot/strategies/engine-mm.d.ts +29 -0
- package/dist/bot/strategies/engine-mm.js +141 -0
- package/dist/bot/strategies/funding-arb-strategy.d.ts +32 -0
- package/dist/bot/strategies/funding-arb-strategy.js +168 -0
- package/dist/bot/strategies/funding-arb-v2.d.ts +32 -0
- package/dist/bot/strategies/funding-arb-v2.js +222 -0
- package/dist/bot/strategies/funding-auto.d.ts +1 -0
- package/dist/bot/strategies/funding-auto.js +572 -0
- package/dist/bot/strategies/grid-mm.d.ts +25 -0
- package/dist/bot/strategies/grid-mm.js +99 -0
- package/dist/bot/strategies/grid-strategy.d.ts +39 -0
- package/dist/bot/strategies/grid-strategy.js +176 -0
- package/dist/bot/strategies/hedge-agent.d.ts +25 -0
- package/dist/bot/strategies/hedge-agent.js +79 -0
- package/dist/bot/strategies/liquidation-mm.d.ts +25 -0
- package/dist/bot/strategies/liquidation-mm.js +108 -0
- package/dist/bot/strategies/mean-reversion.d.ts +35 -0
- package/dist/bot/strategies/mean-reversion.js +118 -0
- package/dist/bot/strategies/momentum-breakout.d.ts +36 -0
- package/dist/bot/strategies/momentum-breakout.js +159 -0
- package/dist/bot/strategies/regime-mm.d.ts +25 -0
- package/dist/bot/strategies/regime-mm.js +111 -0
- package/dist/bot/strategies/rfq-agent.d.ts +25 -0
- package/dist/bot/strategies/rfq-agent.js +71 -0
- package/dist/bot/strategies/simple-mm.d.ts +25 -0
- package/dist/bot/strategies/simple-mm.js +76 -0
- package/dist/bot/strategy-registry.d.ts +9 -0
- package/dist/bot/strategy-registry.js +14 -0
- package/dist/bot/strategy-types.d.ts +64 -0
- package/dist/bot/strategy-types.js +5 -0
- package/dist/bot/trade-journal.d.ts +27 -0
- package/dist/bot/trade-journal.js +53 -0
- package/dist/bot/tui/BotDashboard.d.ts +49 -0
- package/dist/bot/tui/BotDashboard.js +93 -0
- package/dist/bot/tui/index.d.ts +6 -0
- package/dist/bot/tui/index.js +8 -0
- package/dist/bridge-engine.d.ts +0 -1
- package/dist/bridge-engine.js +0 -1
- package/dist/cache.d.ts +0 -1
- package/dist/cache.js +0 -1
- package/dist/commands/account.d.ts +1 -1
- package/dist/commands/account.js +106 -75
- package/dist/commands/agent.d.ts +1 -1
- package/dist/commands/arb/index.d.ts +1 -1
- package/dist/commands/arb/index.js +1 -1
- package/dist/commands/arb-auto.d.ts +1 -1
- package/dist/commands/arb-auto.js +1 -1
- package/dist/commands/arb.d.ts +1 -1
- package/dist/commands/bot.d.ts +1 -1
- package/dist/commands/bot.js +198 -14
- package/dist/commands/dashboard.d.ts +1 -1
- package/dist/commands/dashboard.js +1 -1
- package/dist/commands/funds.d.ts +1 -1
- package/dist/commands/funds.js +33 -20
- package/dist/commands/history.d.ts +1 -1
- package/dist/commands/history.js +5 -4
- package/dist/commands/manage.d.ts +2 -3
- package/dist/commands/manage.js +11 -18
- package/dist/commands/market.d.ts +1 -1
- package/dist/commands/market.js +7 -7
- package/dist/commands/plan.d.ts +1 -1
- package/dist/commands/rebalance.d.ts +1 -1
- package/dist/commands/rebalance.js +8 -9
- package/dist/commands/risk.d.ts +1 -1
- package/dist/commands/settings.d.ts +1 -1
- package/dist/commands/settings.js +3 -1
- package/dist/commands/trade.d.ts +1 -1
- package/dist/commands/trade.js +39 -52
- package/dist/commands/wallet.d.ts +0 -2
- package/dist/commands/wallet.js +0 -5
- package/dist/constants.d.ts +0 -3
- package/dist/constants.js +0 -4
- package/dist/cross-chain-margin.d.ts +1 -1
- package/dist/dashboard/index.d.ts +4 -0
- package/dist/dashboard/index.js +3 -0
- package/dist/dashboard/server.d.ts +1 -1
- package/dist/dashboard/server.js +1 -1
- package/dist/dashboard/ws-feeds.d.ts +1 -1
- package/dist/event-stream.d.ts +1 -1
- package/dist/exchanges/aster.d.ts +58 -0
- package/dist/exchanges/aster.js +409 -0
- package/dist/exchanges/capabilities.d.ts +74 -0
- package/dist/exchanges/capabilities.js +44 -0
- package/dist/exchanges/hyperliquid-spot.d.ts +1 -1
- package/dist/exchanges/hyperliquid-spot.js +20 -12
- package/dist/exchanges/hyperliquid.d.ts +8 -2
- package/dist/exchanges/hyperliquid.js +21 -6
- package/dist/exchanges/index.d.ts +11 -0
- package/dist/exchanges/index.js +10 -0
- package/dist/exchanges/interface.d.ts +3 -0
- package/dist/exchanges/lighter-spot.d.ts +13 -0
- package/dist/exchanges/lighter-spot.js +98 -26
- package/dist/exchanges/lighter.d.ts +9 -3
- package/dist/exchanges/lighter.js +18 -8
- package/dist/exchanges/nado.d.ts +52 -0
- package/dist/exchanges/nado.js +223 -0
- package/dist/exchanges/pacifica.d.ts +7 -1
- package/dist/exchanges/pacifica.js +17 -2
- package/dist/exchanges/registry.d.ts +13 -0
- package/dist/exchanges/registry.js +37 -0
- package/dist/exchanges/spot-interface.d.ts +9 -0
- package/dist/funding/rates.js +1 -1
- package/dist/index.js +2 -6
- package/dist/jobs.js +1 -1
- package/dist/liquidity.d.ts +1 -2
- package/dist/liquidity.js +12 -5
- package/dist/mcp-server.js +4 -2
- package/dist/pacifica/constants.d.ts +0 -3
- package/dist/pacifica/constants.js +0 -4
- package/dist/pacifica/types/account.d.ts +0 -8
- package/dist/pacifica/types/lake.d.ts +0 -6
- package/dist/pacifica/types/position.d.ts +0 -12
- package/dist/pacifica/types/ws.d.ts +0 -24
- package/dist/pacifica/types/ws.js +1 -41
- package/dist/plan-executor.d.ts +1 -1
- package/dist/rebalance.d.ts +1 -7
- package/dist/rebalance.js +0 -6
- package/dist/risk.d.ts +1 -1
- package/dist/risk.js +3 -1
- package/dist/smart-order.d.ts +1 -1
- package/dist/strategies/dca.d.ts +1 -1
- package/dist/strategies/funding-arb.d.ts +1 -1
- package/dist/strategies/funding-arb.js +193 -181
- package/dist/strategies/grid.d.ts +1 -1
- package/dist/strategies/grid.js +1 -1
- package/dist/strategies/index.d.ts +12 -0
- package/dist/strategies/index.js +7 -0
- package/dist/strategies/split-order.d.ts +1 -1
- package/dist/strategies/trailing-stop.d.ts +1 -1
- package/dist/strategies/twap.d.ts +1 -1
- package/dist/trade-validator.d.ts +1 -1
- package/package.json +7 -1
- package/skills/perp-cli/SKILL.md +20 -0
- package/skills/perp-cli/references/commands.md +22 -8
package/dist/commands/account.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { PacificaAdapter } from "../exchanges/pacifica.js";
|
|
2
|
-
import { HyperliquidAdapter } from "../exchanges/hyperliquid.js";
|
|
3
1
|
import { makeTable, formatUsd, formatPnl, printJson, jsonOk, jsonError, symbolMatch, withJsonErrors } from "../utils.js";
|
|
4
2
|
import chalk from "chalk";
|
|
5
3
|
import { assessRisk } from "../risk.js";
|
|
4
|
+
import { hasPacificaSdk, isDexCapable } from "../exchanges/capabilities.js";
|
|
6
5
|
const EXCHANGES = ["pacifica", "hyperliquid", "lighter"];
|
|
7
6
|
async function fetchExchangeSnapshot(name, getAdapter) {
|
|
8
7
|
try {
|
|
@@ -96,7 +95,7 @@ function buildSummary(snapshots) {
|
|
|
96
95
|
};
|
|
97
96
|
}
|
|
98
97
|
function pac(adapter) {
|
|
99
|
-
if (!(adapter
|
|
98
|
+
if (!hasPacificaSdk(adapter))
|
|
100
99
|
throw new Error("Market settings are only available on Pacifica.");
|
|
101
100
|
return adapter;
|
|
102
101
|
}
|
|
@@ -112,6 +111,7 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
112
111
|
try {
|
|
113
112
|
if (name === "hyperliquid") {
|
|
114
113
|
const { HyperliquidSpotAdapter } = await import("../exchanges/hyperliquid-spot.js");
|
|
114
|
+
const { HyperliquidAdapter } = await import("../exchanges/hyperliquid.js");
|
|
115
115
|
const hlSpot = new HyperliquidSpotAdapter(adapter);
|
|
116
116
|
await hlSpot.init();
|
|
117
117
|
const raw = await hlSpot.getSpotBalances();
|
|
@@ -149,7 +149,7 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
149
149
|
catch { /* spot not available */ }
|
|
150
150
|
// HL unified account: perp equity already includes spot USDC balance.
|
|
151
151
|
// Detect by checking if adapter is HL without a dex override.
|
|
152
|
-
const isUnified = name === "hyperliquid" && !adapter.dex;
|
|
152
|
+
const isUnified = name === "hyperliquid" && (!isDexCapable(adapter) || !adapter.dex);
|
|
153
153
|
const cutoff24h = Date.now() - 24 * 60 * 60 * 1000;
|
|
154
154
|
const recent = fundingPayments.filter(f => f.time >= cutoff24h);
|
|
155
155
|
const funding24h = recent.reduce((sum, f) => sum + Number(f.payment), 0);
|
|
@@ -368,7 +368,7 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
368
368
|
]);
|
|
369
369
|
}
|
|
370
370
|
// --hip3: fetch HIP-3 dex positions for HL
|
|
371
|
-
if (opts.hip3 && ex === "hyperliquid" && adapter
|
|
371
|
+
if (opts.hip3 && ex === "hyperliquid" && isDexCapable(adapter)) {
|
|
372
372
|
const hip3 = await fetchHip3Data(adapter, a => a.getPositions());
|
|
373
373
|
for (const { dex, items } of hip3) {
|
|
374
374
|
for (const p of items) {
|
|
@@ -397,7 +397,7 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
397
397
|
try {
|
|
398
398
|
const adapter = await getAdapterForExchange(ex);
|
|
399
399
|
grouped[ex] = await adapter.getPositions();
|
|
400
|
-
if (opts.hip3 && ex === "hyperliquid" && adapter
|
|
400
|
+
if (opts.hip3 && ex === "hyperliquid" && isDexCapable(adapter)) {
|
|
401
401
|
const hip3 = await fetchHip3Data(adapter, a => a.getPositions());
|
|
402
402
|
for (const { dex, items } of hip3)
|
|
403
403
|
grouped[`hip3:${dex}`] = items;
|
|
@@ -423,7 +423,7 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
423
423
|
const positions = await adapter.getPositions();
|
|
424
424
|
// --hip3: append HIP-3 dex positions
|
|
425
425
|
const hip3Positions = [];
|
|
426
|
-
if (opts.hip3 && adapter
|
|
426
|
+
if (opts.hip3 && isDexCapable(adapter)) {
|
|
427
427
|
hip3Positions.push(...await fetchHip3Data(adapter, a => a.getPositions()));
|
|
428
428
|
}
|
|
429
429
|
if (isJson()) {
|
|
@@ -494,7 +494,7 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
494
494
|
]);
|
|
495
495
|
}
|
|
496
496
|
// --hip3: fetch HIP-3 dex orders for HL
|
|
497
|
-
if (opts.hip3 && ex === "hyperliquid" && adapter
|
|
497
|
+
if (opts.hip3 && ex === "hyperliquid" && isDexCapable(adapter)) {
|
|
498
498
|
const hip3 = await fetchHip3Data(adapter, a => a.getOpenOrders());
|
|
499
499
|
for (const { dex, items } of hip3) {
|
|
500
500
|
for (const o of items) {
|
|
@@ -523,7 +523,7 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
523
523
|
try {
|
|
524
524
|
const adapter = await getAdapterForExchange(ex);
|
|
525
525
|
grouped[ex] = await adapter.getOpenOrders();
|
|
526
|
-
if (opts.hip3 && ex === "hyperliquid" && adapter
|
|
526
|
+
if (opts.hip3 && ex === "hyperliquid" && isDexCapable(adapter)) {
|
|
527
527
|
const hip3 = await fetchHip3Data(adapter, a => a.getOpenOrders());
|
|
528
528
|
for (const { dex, items } of hip3)
|
|
529
529
|
grouped[`hip3:${dex}`] = items;
|
|
@@ -549,7 +549,7 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
549
549
|
const orders = await adapter.getOpenOrders();
|
|
550
550
|
// --hip3: append HIP-3 dex orders
|
|
551
551
|
const hip3Orders = [];
|
|
552
|
-
if (opts.hip3 && adapter
|
|
552
|
+
if (opts.hip3 && isDexCapable(adapter)) {
|
|
553
553
|
hip3Orders.push(...await fetchHip3Data(adapter, a => a.getOpenOrders()));
|
|
554
554
|
}
|
|
555
555
|
if (isJson()) {
|
|
@@ -623,8 +623,9 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
623
623
|
.action(async () => {
|
|
624
624
|
const adapter = await getAdapter();
|
|
625
625
|
// Pacifica: use dedicated SDK endpoint
|
|
626
|
-
if (adapter
|
|
627
|
-
const
|
|
626
|
+
if (hasPacificaSdk(adapter)) {
|
|
627
|
+
const sdk = adapter.sdk;
|
|
628
|
+
const settings = await sdk.getAccountSettings(adapter.publicKey);
|
|
628
629
|
if (isJson())
|
|
629
630
|
return printJson(jsonOk(settings));
|
|
630
631
|
if (!Array.isArray(settings) || settings.length === 0) {
|
|
@@ -902,9 +903,19 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
902
903
|
.command("twap-orders")
|
|
903
904
|
.description("Active TWAP orders")
|
|
904
905
|
.action(async () => {
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
906
|
+
let p;
|
|
907
|
+
try {
|
|
908
|
+
const adapter = await getAdapter();
|
|
909
|
+
p = pac(adapter);
|
|
910
|
+
}
|
|
911
|
+
catch (err) {
|
|
912
|
+
if (isJson())
|
|
913
|
+
return printJson(jsonError("EXCHANGE_ERROR", err instanceof Error ? err.message : String(err)));
|
|
914
|
+
console.error(chalk.red(`\n ${err instanceof Error ? err.message : String(err)}\n`));
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
const sdk = p.sdk;
|
|
918
|
+
const orders = await sdk.getTWAPOrders(p.publicKey);
|
|
908
919
|
if (isJson())
|
|
909
920
|
return printJson(jsonOk(orders));
|
|
910
921
|
if (!orders || orders.length === 0) {
|
|
@@ -932,7 +943,73 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
932
943
|
const exchanges = opts.exchange
|
|
933
944
|
? opts.exchange.split(",").map(e => e.trim())
|
|
934
945
|
: [...EXCHANGES];
|
|
935
|
-
|
|
946
|
+
// Fetch snapshots + funding + spot ALL in parallel
|
|
947
|
+
const fundingByExSym = new Map();
|
|
948
|
+
const spotRows = [];
|
|
949
|
+
let totalSpotValue = 0;
|
|
950
|
+
const [snapshots] = await Promise.all([
|
|
951
|
+
// Phase 1: balance + positions + orders
|
|
952
|
+
Promise.all(exchanges.map(ex => fetchExchangeSnapshot(ex, getAdapterForExchange))),
|
|
953
|
+
// Phase 2: funding payments (parallel with Phase 1)
|
|
954
|
+
Promise.allSettled(exchanges.map(async (exName) => {
|
|
955
|
+
try {
|
|
956
|
+
const adapter = await getAdapterForExchange(exName);
|
|
957
|
+
const payments = await adapter.getFundingPayments(200);
|
|
958
|
+
for (const p of payments) {
|
|
959
|
+
const sym = p.symbol.replace("-PERP", "").toUpperCase();
|
|
960
|
+
const key = `${exName}:${sym}`;
|
|
961
|
+
fundingByExSym.set(key, (fundingByExSym.get(key) ?? 0) + Number(p.payment));
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
catch { /* skip */ }
|
|
965
|
+
})),
|
|
966
|
+
// Phase 3: spot balances (parallel with Phase 1+2)
|
|
967
|
+
Promise.allSettled(exchanges.map(async (exName) => {
|
|
968
|
+
try {
|
|
969
|
+
const adapter = await getAdapterForExchange(exName);
|
|
970
|
+
if (exName === "hyperliquid") {
|
|
971
|
+
const { HyperliquidSpotAdapter } = await import("../exchanges/hyperliquid-spot.js");
|
|
972
|
+
const { HyperliquidAdapter } = await import("../exchanges/hyperliquid.js");
|
|
973
|
+
const hlSpot = new HyperliquidSpotAdapter(adapter);
|
|
974
|
+
await hlSpot.init();
|
|
975
|
+
const bals = await hlSpot.getSpotBalances();
|
|
976
|
+
const markets = await hlSpot.getSpotMarkets();
|
|
977
|
+
const priceMap = new Map(markets.map(m => [m.baseToken.toUpperCase(), Number(m.markPrice)]));
|
|
978
|
+
for (const b of bals) {
|
|
979
|
+
const base = b.token.replace(/-SPOT$/i, "").toUpperCase();
|
|
980
|
+
if (base === "USDC" || Number(b.total) <= 0)
|
|
981
|
+
continue;
|
|
982
|
+
const price = priceMap.get(base) ?? 0;
|
|
983
|
+
const value = price * Number(b.total);
|
|
984
|
+
if (value < 1)
|
|
985
|
+
continue;
|
|
986
|
+
totalSpotValue += value;
|
|
987
|
+
spotRows.push([chalk.white.bold(base), chalk.gray("hyperliquid"), b.total, `$${formatUsd(price)}`, `$${formatUsd(value)}`]);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
else if (exName === "lighter") {
|
|
991
|
+
const { LighterAdapter } = await import("../exchanges/lighter.js");
|
|
992
|
+
const { LighterSpotAdapter } = await import("../exchanges/lighter-spot.js");
|
|
993
|
+
const ltSpot = new LighterSpotAdapter(adapter);
|
|
994
|
+
await ltSpot.init();
|
|
995
|
+
const bals = await ltSpot.getSpotBalances();
|
|
996
|
+
const markets = await ltSpot.getSpotMarkets();
|
|
997
|
+
const priceMap = new Map(markets.map(m => [m.baseToken.toUpperCase(), Number(m.markPrice)]));
|
|
998
|
+
for (const b of bals) {
|
|
999
|
+
if (b.token === "USDC" || b.token === "USDC_SPOT" || Number(b.total) <= 0)
|
|
1000
|
+
continue;
|
|
1001
|
+
const price = priceMap.get(b.token.toUpperCase()) ?? 0;
|
|
1002
|
+
const value = price * Number(b.total);
|
|
1003
|
+
if (value < 1)
|
|
1004
|
+
continue;
|
|
1005
|
+
totalSpotValue += value;
|
|
1006
|
+
spotRows.push([chalk.white.bold(b.token), chalk.gray("lighter"), b.total, `$${formatUsd(price)}`, `$${formatUsd(value)}`]);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
catch { /* spot not available */ }
|
|
1011
|
+
})),
|
|
1012
|
+
]);
|
|
936
1013
|
const summary = buildSummary(snapshots);
|
|
937
1014
|
if (isJson()) {
|
|
938
1015
|
return printJson(jsonOk(summary));
|
|
@@ -955,7 +1032,6 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
955
1032
|
chalk.green("connected"),
|
|
956
1033
|
];
|
|
957
1034
|
});
|
|
958
|
-
// Totals row
|
|
959
1035
|
balRows.push([
|
|
960
1036
|
chalk.cyan.bold("TOTAL"),
|
|
961
1037
|
chalk.cyan.bold(`$${formatUsd(summary.totalEquity)}`),
|
|
@@ -965,12 +1041,13 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
965
1041
|
"",
|
|
966
1042
|
]);
|
|
967
1043
|
console.log(makeTable(["Exchange", "Equity", "Available", "Margin Used", "uPnL", "Status"], balRows));
|
|
968
|
-
// ── Positions ──
|
|
969
1044
|
if (summary.positions.length > 0) {
|
|
970
1045
|
console.log(chalk.white.bold("\n Open Positions"));
|
|
971
1046
|
const posRows = summary.positions.map(p => {
|
|
972
1047
|
const sideColor = p.side === "long" ? chalk.green : chalk.red;
|
|
973
1048
|
const notional = Math.abs(Number(p.size) * Number(p.markPrice));
|
|
1049
|
+
const sym = p.symbol.replace("-PERP", "").toUpperCase();
|
|
1050
|
+
const funding = fundingByExSym.get(`${p.exchange}:${sym}`) ?? 0;
|
|
974
1051
|
return [
|
|
975
1052
|
chalk.white.bold(p.symbol),
|
|
976
1053
|
chalk.gray(p.exchange),
|
|
@@ -979,75 +1056,29 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
979
1056
|
`$${formatUsd(p.entryPrice)}`,
|
|
980
1057
|
`$${formatUsd(p.markPrice)}`,
|
|
981
1058
|
formatPnl(p.unrealizedPnl),
|
|
1059
|
+
formatPnl(funding),
|
|
982
1060
|
`$${formatUsd(notional)}`,
|
|
983
1061
|
`${p.leverage}x`,
|
|
984
1062
|
];
|
|
985
1063
|
});
|
|
986
|
-
console.log(makeTable(["Symbol", "Exchange", "Side", "Size", "Entry", "Mark", "uPnL", "Notional", "Lev"], posRows));
|
|
1064
|
+
console.log(makeTable(["Symbol", "Exchange", "Side", "Size", "Entry", "Mark", "uPnL", "Funding", "Notional", "Lev"], posRows));
|
|
987
1065
|
}
|
|
988
1066
|
else {
|
|
989
1067
|
console.log(chalk.gray("\n No open positions.\n"));
|
|
990
1068
|
}
|
|
991
|
-
// ── Spot Holdings ──
|
|
992
|
-
const spotRows = [];
|
|
993
|
-
for (const exName of exchanges) {
|
|
994
|
-
try {
|
|
995
|
-
const adapter = await getAdapterForExchange(exName);
|
|
996
|
-
if (exName === "hyperliquid") {
|
|
997
|
-
const { HyperliquidSpotAdapter } = await import("../exchanges/hyperliquid-spot.js");
|
|
998
|
-
const hlSpot = new HyperliquidSpotAdapter(adapter);
|
|
999
|
-
await hlSpot.init();
|
|
1000
|
-
const bals = await hlSpot.getSpotBalances();
|
|
1001
|
-
const markets = await hlSpot.getSpotMarkets();
|
|
1002
|
-
const priceMap = new Map(markets.map(m => [m.baseToken.toUpperCase(), Number(m.markPrice)]));
|
|
1003
|
-
for (const b of bals) {
|
|
1004
|
-
const base = b.token.replace(/-SPOT$/i, "").toUpperCase();
|
|
1005
|
-
if (base === "USDC" || Number(b.total) <= 0)
|
|
1006
|
-
continue;
|
|
1007
|
-
const price = priceMap.get(base) ?? 0;
|
|
1008
|
-
const value = price * Number(b.total);
|
|
1009
|
-
if (value < 1)
|
|
1010
|
-
continue; // skip dust
|
|
1011
|
-
spotRows.push([
|
|
1012
|
-
chalk.white.bold(base),
|
|
1013
|
-
chalk.gray("hyperliquid"),
|
|
1014
|
-
b.total,
|
|
1015
|
-
`$${formatUsd(price)}`,
|
|
1016
|
-
`$${formatUsd(value)}`,
|
|
1017
|
-
]);
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
else if (exName === "lighter") {
|
|
1021
|
-
const { LighterAdapter } = await import("../exchanges/lighter.js");
|
|
1022
|
-
const { LighterSpotAdapter } = await import("../exchanges/lighter-spot.js");
|
|
1023
|
-
const ltSpot = new LighterSpotAdapter(adapter);
|
|
1024
|
-
await ltSpot.init();
|
|
1025
|
-
const bals = await ltSpot.getSpotBalances();
|
|
1026
|
-
const markets = await ltSpot.getSpotMarkets();
|
|
1027
|
-
const priceMap = new Map(markets.map(m => [m.baseToken.toUpperCase(), Number(m.markPrice)]));
|
|
1028
|
-
for (const b of bals) {
|
|
1029
|
-
if (b.token === "USDC" || b.token === "USDC_SPOT" || Number(b.total) <= 0)
|
|
1030
|
-
continue;
|
|
1031
|
-
const price = priceMap.get(b.token.toUpperCase()) ?? 0;
|
|
1032
|
-
const value = price * Number(b.total);
|
|
1033
|
-
if (value < 1)
|
|
1034
|
-
continue;
|
|
1035
|
-
spotRows.push([
|
|
1036
|
-
chalk.white.bold(b.token),
|
|
1037
|
-
chalk.gray("lighter"),
|
|
1038
|
-
b.total,
|
|
1039
|
-
`$${formatUsd(price)}`,
|
|
1040
|
-
`$${formatUsd(value)}`,
|
|
1041
|
-
]);
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
catch { /* spot not available */ }
|
|
1046
|
-
}
|
|
1069
|
+
// ── Spot Holdings (already fetched in parallel above) ──
|
|
1047
1070
|
if (spotRows.length > 0) {
|
|
1048
1071
|
console.log(chalk.white.bold("\n Spot Holdings"));
|
|
1049
1072
|
console.log(makeTable(["Token", "Exchange", "Amount", "Price", "Value"], spotRows));
|
|
1050
1073
|
}
|
|
1074
|
+
// ── Total (perp + spot) ──
|
|
1075
|
+
if (totalSpotValue > 0) {
|
|
1076
|
+
const totalValue = summary.totalEquity + totalSpotValue;
|
|
1077
|
+
console.log(chalk.white.bold(" Total Account Value"));
|
|
1078
|
+
console.log(` Perp Equity: $${formatUsd(summary.totalEquity)}`);
|
|
1079
|
+
console.log(` Spot Value: $${formatUsd(totalSpotValue)}`);
|
|
1080
|
+
console.log(` ${chalk.cyan.bold(`Total: $${formatUsd(totalValue)}`)}`);
|
|
1081
|
+
}
|
|
1051
1082
|
// ── Risk Metrics ──
|
|
1052
1083
|
console.log(chalk.white.bold("\n Risk Metrics"));
|
|
1053
1084
|
const levelColor = {
|
package/dist/commands/agent.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import type { ExchangeAdapter } from "../exchanges/
|
|
2
|
+
import type { ExchangeAdapter } from "../exchanges/index.js";
|
|
3
3
|
export declare function registerAgentCommands(program: Command, getAdapter: () => Promise<ExchangeAdapter>, isJson: () => boolean): void;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import type
|
|
2
|
+
import { type ExchangeAdapter } from "../../exchanges/index.js";
|
|
3
3
|
export declare function registerArbManageCommands(program: Command, getAdapterForExchange: (exchange: string) => Promise<ExchangeAdapter>, isJson: () => boolean): void;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { makeTable, formatUsd, formatPnl, printJson, jsonOk } from "../../utils.js";
|
|
3
|
+
import { SPOT_PERP_TOKEN_MAP } from "../../exchanges/index.js";
|
|
3
4
|
import { readExecutionLog, logExecution } from "../../execution-log.js";
|
|
4
5
|
import { toHourlyRate, computeAnnualSpread } from "../../funding.js";
|
|
5
6
|
import { fetchPacificaPrices, fetchHyperliquidMeta, fetchLighterOrderBookDetails, fetchLighterFundingRates, } from "../../shared-api.js";
|
|
6
7
|
import { computeBasisRisk } from "../../arb-utils.js";
|
|
7
8
|
import { smartOrder } from "../../smart-order.js";
|
|
8
9
|
import { removePosition as persistRemovePosition, getPositions as getArbStatePositions, loadArbState } from "../../arb-state.js";
|
|
9
|
-
import { SPOT_PERP_TOKEN_MAP } from "../../exchanges/spot-interface.js";
|
|
10
10
|
import { fetchAllBalances, computeRebalancePlan } from "../../rebalance.js";
|
|
11
11
|
import { EXCHANGE_TO_CHAIN, getBestQuote } from "../../bridge-engine.js";
|
|
12
12
|
import { computeEnhancedStats } from "../../arb-history-stats.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { formatUsd, printJson, jsonOk, makeTable } from "../utils.js";
|
|
3
3
|
import { computeExecutableSize } from "../liquidity.js";
|
|
4
|
-
import { computeMatchedSize, computeSpotPerpMatchedSize } from "../arb/
|
|
4
|
+
import { computeMatchedSize, computeSpotPerpMatchedSize } from "../arb/index.js";
|
|
5
5
|
import { computeAnnualSpread, toHourlyRate } from "../funding.js";
|
|
6
6
|
import { fetchPacificaPricesRaw, parsePacificaRaw, fetchHyperliquidMetaRaw, parseHyperliquidMetaRaw, fetchLighterOrderBookDetailsRaw, fetchLighterFundingRatesRaw, parseLighterRaw, } from "../shared-api.js";
|
|
7
7
|
import { scanDexArb } from "../dex-asset-map.js";
|
package/dist/commands/arb.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import type { ExchangeAdapter } from "../exchanges/
|
|
2
|
+
import type { ExchangeAdapter } from "../exchanges/index.js";
|
|
3
3
|
export declare function registerArbCommands(program: Command, isJson: () => boolean, getAdapterForExchange?: (exchange: string) => Promise<ExchangeAdapter>): void;
|
|
4
4
|
export interface PriceSnapshot {
|
|
5
5
|
symbol: string;
|
package/dist/commands/bot.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import type { ExchangeAdapter } from "../exchanges/
|
|
2
|
+
import type { ExchangeAdapter } from "../exchanges/index.js";
|
|
3
3
|
export declare function registerBotCommands(program: Command, getAdapter: () => Promise<ExchangeAdapter>, getAdapterFor: (exchange: string) => Promise<ExchangeAdapter>, isJson: () => boolean): void;
|