perp-cli 0.11.0 → 0.12.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.
Files changed (240) hide show
  1. package/README.md +30 -25
  2. package/dist/_stderr-filter.d.ts +0 -0
  3. package/dist/_stderr-filter.js +30 -0
  4. package/dist/agent-wallet/expiry.d.ts +15 -0
  5. package/dist/agent-wallet/expiry.js +26 -0
  6. package/dist/agent-wallet/lighter-keystore.d.ts +34 -0
  7. package/dist/agent-wallet/lighter-keystore.js +232 -0
  8. package/dist/agent-wallet/passphrase.d.ts +13 -0
  9. package/dist/agent-wallet/passphrase.js +54 -0
  10. package/dist/agent-wallet/signing-strategy.d.ts +67 -0
  11. package/dist/agent-wallet/signing-strategy.js +51 -0
  12. package/dist/agent-wallet/store.d.ts +37 -0
  13. package/dist/agent-wallet/store.js +172 -0
  14. package/dist/api/public/_http.d.ts +15 -0
  15. package/dist/api/public/_http.js +24 -0
  16. package/dist/api/public/hyperliquid.js +36 -24
  17. package/dist/api/public/lighter.d.ts +7 -1
  18. package/dist/api/public/lighter.js +85 -37
  19. package/dist/api/public/pacifica.js +47 -18
  20. package/dist/bridge-engine.js +102 -49
  21. package/dist/cli-spec.js +1 -2
  22. package/dist/commands/account.js +2 -500
  23. package/dist/commands/agent.d.ts +8 -2
  24. package/dist/commands/agent.js +1903 -366
  25. package/dist/commands/alerts.js +3 -1
  26. package/dist/commands/arb/index.js +37 -7
  27. package/dist/commands/arb-auto.js +44 -11
  28. package/dist/commands/arb.js +83 -34
  29. package/dist/commands/bot.d.ts +1 -1
  30. package/dist/commands/bot.js +18 -14
  31. package/dist/commands/bridge.d.ts +1 -1
  32. package/dist/commands/bridge.js +4 -4
  33. package/dist/commands/funds.d.ts +1 -1
  34. package/dist/commands/funds.js +18 -68
  35. package/dist/commands/jobs.d.ts +1 -1
  36. package/dist/commands/jobs.js +2 -2
  37. package/dist/commands/manage.d.ts +1 -1
  38. package/dist/commands/manage.js +12 -84
  39. package/dist/commands/plan.d.ts +1 -1
  40. package/dist/commands/plan.js +2 -2
  41. package/dist/commands/portfolio.d.ts +19 -3
  42. package/dist/commands/portfolio.js +747 -163
  43. package/dist/commands/rebalance.d.ts +1 -1
  44. package/dist/commands/rebalance.js +18 -12
  45. package/dist/commands/risk.js +2 -6
  46. package/dist/commands/settings.js +30 -53
  47. package/dist/commands/trade.js +16 -15
  48. package/dist/commands/wallet.d.ts +2 -1
  49. package/dist/commands/wallet.js +756 -28
  50. package/dist/errors.d.ts +64 -0
  51. package/dist/errors.js +82 -2
  52. package/dist/event-stream.js +12 -1
  53. package/dist/exchanges/aster-typed-data.d.ts +156 -0
  54. package/dist/exchanges/aster-typed-data.js +189 -0
  55. package/dist/exchanges/aster.d.ts +60 -11
  56. package/dist/exchanges/aster.js +278 -136
  57. package/dist/exchanges/hyperliquid.d.ts +14 -0
  58. package/dist/exchanges/hyperliquid.js +84 -34
  59. package/dist/exchanges/lighter-spot.js +14 -3
  60. package/dist/exchanges/lighter.d.ts +66 -0
  61. package/dist/exchanges/lighter.js +199 -27
  62. package/dist/exchanges/pacifica-typed-data.d.ts +75 -0
  63. package/dist/exchanges/pacifica-typed-data.js +74 -0
  64. package/dist/exchanges/pacifica.d.ts +29 -1
  65. package/dist/exchanges/pacifica.js +94 -6
  66. package/dist/funding/rates.js +59 -21
  67. package/dist/guardrail/perp-guardrail.js +9 -1
  68. package/dist/index.d.ts +1 -1
  69. package/dist/index.js +268 -360
  70. package/dist/jobs.js +3 -1
  71. package/dist/mcp-server.js +85 -83
  72. package/dist/position-history.js +47 -4
  73. package/dist/settings.d.ts +67 -3
  74. package/dist/settings.js +1 -2
  75. package/dist/signer/ows-evm.d.ts +14 -0
  76. package/dist/signer/ows-evm.js +28 -9
  77. package/dist/smart-order.d.ts +8 -2
  78. package/dist/smart-order.js +46 -11
  79. package/dist/strategies/funding-arb.js +29 -8
  80. package/dist/trade-validator.js +30 -5
  81. package/dist/utils.d.ts +10 -0
  82. package/dist/utils.js +19 -0
  83. package/package.json +2 -2
  84. package/skills/perp-cli/SKILL.md +23 -14
  85. package/skills/perp-cli/references/agent-operations.md +6 -4
  86. package/skills/perp-cli/references/commands.md +55 -34
  87. package/skills/perp-cli/scripts/preflight.sh +4 -4
  88. package/skills/perp-cli/scripts/spot-perp-scan.sh +2 -2
  89. package/dist/__tests__/alert-logic.test.d.ts +0 -1
  90. package/dist/__tests__/alert-logic.test.js +0 -107
  91. package/dist/__tests__/arb-auto-3dex.test.d.ts +0 -1
  92. package/dist/__tests__/arb-auto-3dex.test.js +0 -397
  93. package/dist/__tests__/arb-history-stats.test.d.ts +0 -1
  94. package/dist/__tests__/arb-history-stats.test.js +0 -176
  95. package/dist/__tests__/arb-logic.test.d.ts +0 -1
  96. package/dist/__tests__/arb-logic.test.js +0 -84
  97. package/dist/__tests__/arb-manage.test.d.ts +0 -1
  98. package/dist/__tests__/arb-manage.test.js +0 -253
  99. package/dist/__tests__/arb-new-features.test.d.ts +0 -1
  100. package/dist/__tests__/arb-new-features.test.js +0 -457
  101. package/dist/__tests__/arb-sizing.test.d.ts +0 -1
  102. package/dist/__tests__/arb-sizing.test.js +0 -48
  103. package/dist/__tests__/arb-state.test.d.ts +0 -1
  104. package/dist/__tests__/arb-state.test.js +0 -284
  105. package/dist/__tests__/arb-userflow.test.d.ts +0 -1
  106. package/dist/__tests__/arb-userflow.test.js +0 -945
  107. package/dist/__tests__/arb-utils.test.d.ts +0 -1
  108. package/dist/__tests__/arb-utils.test.js +0 -264
  109. package/dist/__tests__/bot-conditions.test.d.ts +0 -1
  110. package/dist/__tests__/bot-conditions.test.js +0 -341
  111. package/dist/__tests__/client-id-tracker.test.d.ts +0 -1
  112. package/dist/__tests__/client-id-tracker.test.js +0 -137
  113. package/dist/__tests__/commands/new-atomic-commands.test.d.ts +0 -1
  114. package/dist/__tests__/commands/new-atomic-commands.test.js +0 -502
  115. package/dist/__tests__/commands/order-intent.test.d.ts +0 -1
  116. package/dist/__tests__/commands/order-intent.test.js +0 -600
  117. package/dist/__tests__/commands/trade-commands.test.d.ts +0 -1
  118. package/dist/__tests__/commands/trade-commands.test.js +0 -821
  119. package/dist/__tests__/config.test.d.ts +0 -1
  120. package/dist/__tests__/config.test.js +0 -86
  121. package/dist/__tests__/cross-chain-margin.test.d.ts +0 -1
  122. package/dist/__tests__/cross-chain-margin.test.js +0 -287
  123. package/dist/__tests__/dex-asset-map.test.d.ts +0 -1
  124. package/dist/__tests__/dex-asset-map.test.js +0 -191
  125. package/dist/__tests__/errors.test.d.ts +0 -1
  126. package/dist/__tests__/errors.test.js +0 -110
  127. package/dist/__tests__/event-stream.test.d.ts +0 -1
  128. package/dist/__tests__/event-stream.test.js +0 -276
  129. package/dist/__tests__/exchanges/interface.test.d.ts +0 -1
  130. package/dist/__tests__/exchanges/interface.test.js +0 -132
  131. package/dist/__tests__/exchanges/mock-adapter.d.ts +0 -69
  132. package/dist/__tests__/exchanges/mock-adapter.js +0 -137
  133. package/dist/__tests__/execution-log.test.d.ts +0 -1
  134. package/dist/__tests__/execution-log.test.js +0 -106
  135. package/dist/__tests__/funding-calc.test.d.ts +0 -1
  136. package/dist/__tests__/funding-calc.test.js +0 -71
  137. package/dist/__tests__/funding-history.test.d.ts +0 -1
  138. package/dist/__tests__/funding-history.test.js +0 -343
  139. package/dist/__tests__/funding-rates.test.d.ts +0 -1
  140. package/dist/__tests__/funding-rates.test.js +0 -342
  141. package/dist/__tests__/funding.test.d.ts +0 -1
  142. package/dist/__tests__/funding.test.js +0 -173
  143. package/dist/__tests__/gap-logic.test.d.ts +0 -1
  144. package/dist/__tests__/gap-logic.test.js +0 -43
  145. package/dist/__tests__/hip3-dex.test.d.ts +0 -1
  146. package/dist/__tests__/hip3-dex.test.js +0 -234
  147. package/dist/__tests__/integration/agent-features.integration.test.d.ts +0 -1
  148. package/dist/__tests__/integration/agent-features.integration.test.js +0 -553
  149. package/dist/__tests__/integration/atomic-commands.integration.test.d.ts +0 -13
  150. package/dist/__tests__/integration/atomic-commands.integration.test.js +0 -246
  151. package/dist/__tests__/integration/bridge-simulation.integration.test.d.ts +0 -1
  152. package/dist/__tests__/integration/bridge-simulation.integration.test.js +0 -453
  153. package/dist/__tests__/integration/bridge-strict.integration.test.d.ts +0 -1
  154. package/dist/__tests__/integration/bridge-strict.integration.test.js +0 -812
  155. package/dist/__tests__/integration/bridge.integration.test.d.ts +0 -1
  156. package/dist/__tests__/integration/bridge.integration.test.js +0 -309
  157. package/dist/__tests__/integration/cli-e2e.integration.test.d.ts +0 -1
  158. package/dist/__tests__/integration/cli-e2e.integration.test.js +0 -202
  159. package/dist/__tests__/integration/dex-arb.integration.test.d.ts +0 -1
  160. package/dist/__tests__/integration/dex-arb.integration.test.js +0 -116
  161. package/dist/__tests__/integration/envelope-consistency.integration.test.d.ts +0 -13
  162. package/dist/__tests__/integration/envelope-consistency.integration.test.js +0 -205
  163. package/dist/__tests__/integration/hip3-dex.integration.test.d.ts +0 -1
  164. package/dist/__tests__/integration/hip3-dex.integration.test.js +0 -147
  165. package/dist/__tests__/integration/hyperliquid.integration.test.d.ts +0 -1
  166. package/dist/__tests__/integration/hyperliquid.integration.test.js +0 -79
  167. package/dist/__tests__/integration/lighter.integration.test.d.ts +0 -1
  168. package/dist/__tests__/integration/lighter.integration.test.js +0 -53
  169. package/dist/__tests__/integration/new-commands-e2e.integration.test.d.ts +0 -9
  170. package/dist/__tests__/integration/new-commands-e2e.integration.test.js +0 -236
  171. package/dist/__tests__/integration/order-verification.integration.test.d.ts +0 -1
  172. package/dist/__tests__/integration/order-verification.integration.test.js +0 -321
  173. package/dist/__tests__/integration/pacifica.integration.test.d.ts +0 -1
  174. package/dist/__tests__/integration/pacifica.integration.test.js +0 -75
  175. package/dist/__tests__/integration/response-shapes.integration.test.d.ts +0 -1
  176. package/dist/__tests__/integration/response-shapes.integration.test.js +0 -278
  177. package/dist/__tests__/liquidity.test.d.ts +0 -1
  178. package/dist/__tests__/liquidity.test.js +0 -225
  179. package/dist/__tests__/plan-executor.test.d.ts +0 -1
  180. package/dist/__tests__/plan-executor.test.js +0 -314
  181. package/dist/__tests__/position-history.test.d.ts +0 -1
  182. package/dist/__tests__/position-history.test.js +0 -367
  183. package/dist/__tests__/retry.test.d.ts +0 -1
  184. package/dist/__tests__/retry.test.js +0 -310
  185. package/dist/__tests__/risk-assessment.test.d.ts +0 -1
  186. package/dist/__tests__/risk-assessment.test.js +0 -288
  187. package/dist/__tests__/security-adversarial.test.d.ts +0 -1
  188. package/dist/__tests__/security-adversarial.test.js +0 -574
  189. package/dist/__tests__/strategies.test.d.ts +0 -1
  190. package/dist/__tests__/strategies.test.js +0 -539
  191. package/dist/__tests__/trade-execution.test.d.ts +0 -1
  192. package/dist/__tests__/trade-execution.test.js +0 -129
  193. package/dist/__tests__/trade-validator.test.d.ts +0 -1
  194. package/dist/__tests__/trade-validator.test.js +0 -655
  195. package/dist/__tests__/utils.test.d.ts +0 -1
  196. package/dist/__tests__/utils.test.js +0 -76
  197. package/dist/arb/reconcile.d.ts +0 -28
  198. package/dist/arb/reconcile.js +0 -162
  199. package/dist/commands/alert.d.ts +0 -2
  200. package/dist/commands/alert.js +0 -421
  201. package/dist/commands/analytics.d.ts +0 -3
  202. package/dist/commands/analytics.js +0 -311
  203. package/dist/commands/arb-manage.d.ts +0 -5
  204. package/dist/commands/arb-manage.js +0 -5
  205. package/dist/commands/dashboard.d.ts +0 -3
  206. package/dist/commands/dashboard.js +0 -176
  207. package/dist/commands/deposit.d.ts +0 -4
  208. package/dist/commands/deposit.js +0 -573
  209. package/dist/commands/dex.d.ts +0 -3
  210. package/dist/commands/dex.js +0 -120
  211. package/dist/commands/env.d.ts +0 -2
  212. package/dist/commands/env.js +0 -136
  213. package/dist/commands/funding.d.ts +0 -3
  214. package/dist/commands/funding.js +0 -554
  215. package/dist/commands/gap.d.ts +0 -2
  216. package/dist/commands/gap.js +0 -305
  217. package/dist/commands/health.d.ts +0 -2
  218. package/dist/commands/health.js +0 -67
  219. package/dist/commands/multileg.d.ts +0 -16
  220. package/dist/commands/multileg.js +0 -174
  221. package/dist/commands/ows.d.ts +0 -2
  222. package/dist/commands/ows.js +0 -887
  223. package/dist/commands/pnl.d.ts +0 -12
  224. package/dist/commands/pnl.js +0 -243
  225. package/dist/commands/run.d.ts +0 -3
  226. package/dist/commands/run.js +0 -202
  227. package/dist/commands/stream.d.ts +0 -5
  228. package/dist/commands/stream.js +0 -200
  229. package/dist/commands/withdraw.d.ts +0 -3
  230. package/dist/commands/withdraw.js +0 -187
  231. package/dist/exchanges/edgex.d.ts +0 -62
  232. package/dist/exchanges/edgex.js +0 -552
  233. package/dist/exchanges/nado.d.ts +0 -52
  234. package/dist/exchanges/nado.js +0 -223
  235. package/dist/funding/index.d.ts +0 -3
  236. package/dist/funding/index.js +0 -3
  237. package/dist/retry.d.ts +0 -74
  238. package/dist/retry.js +0 -129
  239. package/dist/ws/market-feed.d.ts +0 -74
  240. package/dist/ws/market-feed.js +0 -227
@@ -1,76 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { formatUsd, formatPnl, formatPercent, printJson } from "../utils.js";
3
- describe("formatUsd", () => {
4
- it("formats numeric strings", () => {
5
- expect(formatUsd("1234.5")).toBe("1,234.50");
6
- });
7
- it("formats numbers", () => {
8
- expect(formatUsd(99999.999)).toBe("100,000.00");
9
- });
10
- it("returns original string for NaN", () => {
11
- expect(formatUsd("abc")).toBe("abc");
12
- });
13
- it("formats zero", () => {
14
- expect(formatUsd(0)).toBe("0.00");
15
- });
16
- it("formats negative numbers", () => {
17
- expect(formatUsd(-42.1)).toBe("-42.10");
18
- });
19
- });
20
- describe("formatPnl", () => {
21
- it("positive PnL has + prefix", () => {
22
- const result = formatPnl(100);
23
- expect(result).toContain("+$100.00");
24
- });
25
- it("negative PnL has - prefix", () => {
26
- const result = formatPnl(-50);
27
- expect(result).toContain("-$50.00");
28
- });
29
- it("zero PnL", () => {
30
- const result = formatPnl(0);
31
- expect(result).toContain("$0.00");
32
- });
33
- it("handles string input", () => {
34
- const result = formatPnl("123.456");
35
- expect(result).toContain("$123.46");
36
- });
37
- it("handles NaN", () => {
38
- expect(formatPnl("abc")).toBe("abc");
39
- });
40
- });
41
- describe("formatPercent", () => {
42
- it("positive percent", () => {
43
- const result = formatPercent(0.0015);
44
- expect(result).toContain("+0.1500%");
45
- });
46
- it("negative percent", () => {
47
- const result = formatPercent(-0.0025);
48
- expect(result).toContain("-0.2500%");
49
- });
50
- it("zero percent", () => {
51
- const result = formatPercent(0);
52
- expect(result).toContain("0.0000%");
53
- });
54
- it("handles NaN", () => {
55
- expect(formatPercent("abc")).toBe("abc");
56
- });
57
- });
58
- describe("printJson", () => {
59
- it("outputs valid JSON to console", () => {
60
- const logs = [];
61
- const origLog = console.log;
62
- console.log = (...args) => logs.push(args.join(" "));
63
- printJson({ a: 1, b: "hello" });
64
- console.log = origLog;
65
- const parsed = JSON.parse(logs[0]);
66
- expect(parsed).toEqual({ a: 1, b: "hello" });
67
- });
68
- it("handles arrays", () => {
69
- const logs = [];
70
- const origLog = console.log;
71
- console.log = (...args) => logs.push(args.join(" "));
72
- printJson([1, 2, 3]);
73
- console.log = origLog;
74
- expect(JSON.parse(logs[0])).toEqual([1, 2, 3]);
75
- });
76
- });
@@ -1,28 +0,0 @@
1
- import type { ExchangeAdapter } from "../exchanges/interface.js";
2
- export interface ReconciliationIssue {
3
- type: "orphan" | "phantom" | "size_mismatch";
4
- symbol: string;
5
- exchange: string;
6
- side: "long" | "short";
7
- localSize: number | null;
8
- exchangeSize: number | null;
9
- severity: "warning" | "critical";
10
- suggestion: string;
11
- }
12
- export interface ReconciliationResult {
13
- issues: ReconciliationIssue[];
14
- healthy: number;
15
- fixesApplied?: string[];
16
- }
17
- /**
18
- * Reconcile local arb state with actual exchange positions.
19
- *
20
- * Detects three types of issues:
21
- * - **Orphan**: Position exists on exchange but not in local arb state (manual entry?)
22
- * - **Phantom**: Position exists in local state but not on exchange (liquidated? manually closed?)
23
- * - **Size mismatch**: Both exist but sizes differ beyond tolerance
24
- */
25
- export declare function reconcileArbPositions(adapters: Map<string, ExchangeAdapter>, opts?: {
26
- fix?: boolean;
27
- tolerancePct?: number;
28
- }): Promise<ReconciliationResult>;
@@ -1,162 +0,0 @@
1
- import { getPositions, removePosition, updatePosition } from "./state.js";
2
- /** Normalize symbol for comparison (strip -PERP suffix, uppercase) */
3
- function normalizeSymbol(symbol) {
4
- return symbol.toUpperCase().replace(/-PERP$/, "");
5
- }
6
- /** Find a matching exchange position by symbol */
7
- function findExchangePosition(positions, symbol, side) {
8
- const norm = normalizeSymbol(symbol);
9
- return positions.find(p => normalizeSymbol(p.symbol) === norm && p.side === side);
10
- }
11
- /**
12
- * Reconcile local arb state with actual exchange positions.
13
- *
14
- * Detects three types of issues:
15
- * - **Orphan**: Position exists on exchange but not in local arb state (manual entry?)
16
- * - **Phantom**: Position exists in local state but not on exchange (liquidated? manually closed?)
17
- * - **Size mismatch**: Both exist but sizes differ beyond tolerance
18
- */
19
- export async function reconcileArbPositions(adapters, opts) {
20
- const tolerancePct = opts?.tolerancePct ?? 1;
21
- const shouldFix = opts?.fix ?? false;
22
- const issues = [];
23
- const fixesApplied = [];
24
- let healthy = 0;
25
- const localPositions = getPositions();
26
- // Fetch all exchange positions
27
- const exchangePositions = new Map();
28
- for (const [name, adapter] of adapters) {
29
- try {
30
- const pos = await adapter.getPositions();
31
- exchangePositions.set(name, pos);
32
- }
33
- catch {
34
- exchangePositions.set(name, []);
35
- }
36
- }
37
- // Track which exchange positions are accounted for
38
- const accountedFor = new Set(); // "exchange:symbol:side"
39
- // Check each local arb position against exchange
40
- for (const arb of localPositions) {
41
- // Check long leg
42
- const longPositions = exchangePositions.get(arb.longExchange) ?? [];
43
- const longMatch = findExchangePosition(longPositions, arb.symbol, "long");
44
- if (!longMatch) {
45
- issues.push({
46
- type: "phantom",
47
- symbol: arb.symbol,
48
- exchange: arb.longExchange,
49
- side: "long",
50
- localSize: arb.longSize,
51
- exchangeSize: null,
52
- severity: "critical",
53
- suggestion: `Local state has long ${arb.symbol} on ${arb.longExchange} but exchange has no position. May have been liquidated or manually closed.`,
54
- });
55
- if (shouldFix) {
56
- removePosition(arb.symbol);
57
- fixesApplied.push(`Removed phantom position ${arb.symbol} (long leg missing on ${arb.longExchange})`);
58
- continue; // Skip short leg check since we removed the position
59
- }
60
- }
61
- else {
62
- accountedFor.add(`${arb.longExchange}:${normalizeSymbol(arb.symbol)}:long`);
63
- const exchangeSize = Math.abs(Number(longMatch.size));
64
- const localSize = Math.abs(arb.longSize);
65
- const diffPct = localSize > 0 ? (Math.abs(exchangeSize - localSize) / localSize) * 100 : 0;
66
- if (diffPct > tolerancePct) {
67
- issues.push({
68
- type: "size_mismatch",
69
- symbol: arb.symbol,
70
- exchange: arb.longExchange,
71
- side: "long",
72
- localSize,
73
- exchangeSize,
74
- severity: "warning",
75
- suggestion: `Long size mismatch: local ${localSize} vs exchange ${exchangeSize} (${diffPct.toFixed(1)}% diff). Partial fill or manual adjustment?`,
76
- });
77
- if (shouldFix) {
78
- updatePosition(arb.symbol, { longSize: exchangeSize });
79
- fixesApplied.push(`Updated ${arb.symbol} long size: ${localSize} → ${exchangeSize}`);
80
- }
81
- }
82
- else {
83
- healthy++;
84
- }
85
- }
86
- // Check short leg
87
- const shortPositions = exchangePositions.get(arb.shortExchange) ?? [];
88
- const shortMatch = findExchangePosition(shortPositions, arb.symbol, "short");
89
- if (!shortMatch) {
90
- // Don't double-report if we already removed via fix
91
- if (shouldFix && !getPositions().find(p => p.symbol === arb.symbol))
92
- continue;
93
- issues.push({
94
- type: "phantom",
95
- symbol: arb.symbol,
96
- exchange: arb.shortExchange,
97
- side: "short",
98
- localSize: arb.shortSize,
99
- exchangeSize: null,
100
- severity: "critical",
101
- suggestion: `Local state has short ${arb.symbol} on ${arb.shortExchange} but exchange has no position. May have been liquidated or manually closed.`,
102
- });
103
- if (shouldFix) {
104
- removePosition(arb.symbol);
105
- fixesApplied.push(`Removed phantom position ${arb.symbol} (short leg missing on ${arb.shortExchange})`);
106
- }
107
- }
108
- else {
109
- accountedFor.add(`${arb.shortExchange}:${normalizeSymbol(arb.symbol)}:short`);
110
- const exchangeSize = Math.abs(Number(shortMatch.size));
111
- const localSize = Math.abs(arb.shortSize);
112
- const diffPct = localSize > 0 ? (Math.abs(exchangeSize - localSize) / localSize) * 100 : 0;
113
- if (diffPct > tolerancePct) {
114
- issues.push({
115
- type: "size_mismatch",
116
- symbol: arb.symbol,
117
- exchange: arb.shortExchange,
118
- side: "short",
119
- localSize,
120
- exchangeSize,
121
- severity: "warning",
122
- suggestion: `Short size mismatch: local ${localSize} vs exchange ${exchangeSize} (${diffPct.toFixed(1)}% diff). Partial fill or manual adjustment?`,
123
- });
124
- if (shouldFix) {
125
- updatePosition(arb.symbol, { shortSize: exchangeSize });
126
- fixesApplied.push(`Updated ${arb.symbol} short size: ${localSize} → ${exchangeSize}`);
127
- }
128
- }
129
- else {
130
- healthy++;
131
- }
132
- }
133
- }
134
- // Check for orphan positions (on exchange but not in local state)
135
- for (const [exchangeName, positions] of exchangePositions) {
136
- for (const pos of positions) {
137
- const key = `${exchangeName}:${normalizeSymbol(pos.symbol)}:${pos.side}`;
138
- if (!accountedFor.has(key)) {
139
- // Check if this exchange is used in any arb position
140
- const isArbExchange = localPositions.some(p => p.longExchange === exchangeName || p.shortExchange === exchangeName);
141
- // Only report orphans on exchanges that are part of arb state
142
- if (isArbExchange || localPositions.length > 0) {
143
- issues.push({
144
- type: "orphan",
145
- symbol: pos.symbol,
146
- exchange: exchangeName,
147
- side: pos.side,
148
- localSize: null,
149
- exchangeSize: Math.abs(Number(pos.size)),
150
- severity: "warning",
151
- suggestion: `Position on ${exchangeName} not tracked in arb state. Manual entry or untracked strategy?`,
152
- });
153
- }
154
- }
155
- }
156
- }
157
- return {
158
- issues,
159
- healthy,
160
- ...(fixesApplied.length > 0 ? { fixesApplied } : {}),
161
- };
162
- }
@@ -1,2 +0,0 @@
1
- import { Command } from "commander";
2
- export declare function registerAlertCommands(program: Command, isJson: () => boolean, getAdapterFor?: (exchange: string) => Promise<import("../exchanges/interface.js").ExchangeAdapter>): void;