@raintree-technology/perps 0.1.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.
Files changed (316) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +21 -0
  3. package/README.md +175 -0
  4. package/dist/adapters/aevo.d.ts +64 -0
  5. package/dist/adapters/aevo.js +899 -0
  6. package/dist/adapters/certification.d.ts +33 -0
  7. package/dist/adapters/certification.js +99 -0
  8. package/dist/adapters/decibel/order-manager.d.ts +45 -0
  9. package/dist/adapters/decibel/order-manager.js +140 -0
  10. package/dist/adapters/decibel/rest-client.d.ts +176 -0
  11. package/dist/adapters/decibel/rest-client.js +155 -0
  12. package/dist/adapters/decibel/ws-feed.d.ts +28 -0
  13. package/dist/adapters/decibel/ws-feed.js +166 -0
  14. package/dist/adapters/decibel.d.ts +108 -0
  15. package/dist/adapters/decibel.js +1377 -0
  16. package/dist/adapters/hyperliquid.d.ts +63 -0
  17. package/dist/adapters/hyperliquid.js +797 -0
  18. package/dist/adapters/index.d.ts +11 -0
  19. package/dist/adapters/index.js +12 -0
  20. package/dist/adapters/interface.d.ts +310 -0
  21. package/dist/adapters/interface.js +15 -0
  22. package/dist/adapters/orderly.d.ts +70 -0
  23. package/dist/adapters/orderly.js +936 -0
  24. package/dist/adapters/paradex.d.ts +69 -0
  25. package/dist/adapters/paradex.js +862 -0
  26. package/dist/adapters/utils.d.ts +17 -0
  27. package/dist/adapters/utils.js +122 -0
  28. package/dist/cli/command-metadata.d.ts +2 -0
  29. package/dist/cli/command-metadata.js +44 -0
  30. package/dist/cli/context.d.ts +14 -0
  31. package/dist/cli/context.js +59 -0
  32. package/dist/cli/experience.d.ts +48 -0
  33. package/dist/cli/experience.js +243 -0
  34. package/dist/cli/ink/app/AppShell.d.ts +12 -0
  35. package/dist/cli/ink/app/AppShell.js +32 -0
  36. package/dist/cli/ink/app/MetricStrip.d.ts +6 -0
  37. package/dist/cli/ink/app/MetricStrip.js +14 -0
  38. package/dist/cli/ink/app/Panel.d.ts +9 -0
  39. package/dist/cli/ink/app/Panel.js +7 -0
  40. package/dist/cli/ink/app/ascii.d.ts +2 -0
  41. package/dist/cli/ink/app/ascii.js +46 -0
  42. package/dist/cli/ink/app/index.d.ts +5 -0
  43. package/dist/cli/ink/app/index.js +4 -0
  44. package/dist/cli/ink/app/types.d.ts +15 -0
  45. package/dist/cli/ink/app/types.js +1 -0
  46. package/dist/cli/ink/components/PnL.d.ts +12 -0
  47. package/dist/cli/ink/components/PnL.js +23 -0
  48. package/dist/cli/ink/components/Spinner.d.ts +13 -0
  49. package/dist/cli/ink/components/Spinner.js +13 -0
  50. package/dist/cli/ink/components/Table.d.ts +14 -0
  51. package/dist/cli/ink/components/Table.js +42 -0
  52. package/dist/cli/ink/components/WatchHeader.d.ts +10 -0
  53. package/dist/cli/ink/components/WatchHeader.js +18 -0
  54. package/dist/cli/ink/components/index.d.ts +4 -0
  55. package/dist/cli/ink/components/index.js +4 -0
  56. package/dist/cli/ink/index.d.ts +4 -0
  57. package/dist/cli/ink/index.js +4 -0
  58. package/dist/cli/ink/render.d.ts +12 -0
  59. package/dist/cli/ink/render.js +21 -0
  60. package/dist/cli/ink/theme.d.ts +29 -0
  61. package/dist/cli/ink/theme.js +40 -0
  62. package/dist/cli/network-defaults.d.ts +10 -0
  63. package/dist/cli/network-defaults.js +35 -0
  64. package/dist/cli/output.d.ts +11 -0
  65. package/dist/cli/output.js +115 -0
  66. package/dist/cli/program.d.ts +18 -0
  67. package/dist/cli/program.js +164 -0
  68. package/dist/cli/watch.d.ts +19 -0
  69. package/dist/cli/watch.js +35 -0
  70. package/dist/client/index.d.ts +55 -0
  71. package/dist/client/index.js +157 -0
  72. package/dist/commands/account/add.d.ts +2 -0
  73. package/dist/commands/account/add.js +510 -0
  74. package/dist/commands/account/balances-simple.d.ts +5 -0
  75. package/dist/commands/account/balances-simple.js +63 -0
  76. package/dist/commands/account/index.d.ts +2 -0
  77. package/dist/commands/account/index.js +17 -0
  78. package/dist/commands/account/ls.d.ts +2 -0
  79. package/dist/commands/account/ls.js +95 -0
  80. package/dist/commands/account/positions-simple.d.ts +5 -0
  81. package/dist/commands/account/positions-simple.js +77 -0
  82. package/dist/commands/account/remove.d.ts +2 -0
  83. package/dist/commands/account/remove.js +47 -0
  84. package/dist/commands/account/set-default.d.ts +2 -0
  85. package/dist/commands/account/set-default.js +47 -0
  86. package/dist/commands/agent/index.d.ts +2 -0
  87. package/dist/commands/agent/index.js +126 -0
  88. package/dist/commands/arb/alert.d.ts +6 -0
  89. package/dist/commands/arb/alert.js +88 -0
  90. package/dist/commands/arb/basis-execute.d.ts +6 -0
  91. package/dist/commands/arb/basis-execute.js +332 -0
  92. package/dist/commands/arb/basis.d.ts +6 -0
  93. package/dist/commands/arb/basis.js +181 -0
  94. package/dist/commands/arb/compare.d.ts +6 -0
  95. package/dist/commands/arb/compare.js +216 -0
  96. package/dist/commands/arb/execute.d.ts +6 -0
  97. package/dist/commands/arb/execute.js +467 -0
  98. package/dist/commands/arb/funding.d.ts +6 -0
  99. package/dist/commands/arb/funding.js +201 -0
  100. package/dist/commands/arb/history.d.ts +6 -0
  101. package/dist/commands/arb/history.js +153 -0
  102. package/dist/commands/arb/index.d.ts +6 -0
  103. package/dist/commands/arb/index.js +29 -0
  104. package/dist/commands/arb/positions.d.ts +6 -0
  105. package/dist/commands/arb/positions.js +158 -0
  106. package/dist/commands/arb/spread.d.ts +6 -0
  107. package/dist/commands/arb/spread.js +253 -0
  108. package/dist/commands/arb/track.d.ts +6 -0
  109. package/dist/commands/arb/track.js +259 -0
  110. package/dist/commands/asset/book-simple.d.ts +5 -0
  111. package/dist/commands/asset/book-simple.js +77 -0
  112. package/dist/commands/asset/index.d.ts +2 -0
  113. package/dist/commands/asset/index.js +5 -0
  114. package/dist/commands/completion.d.ts +2 -0
  115. package/dist/commands/completion.js +161 -0
  116. package/dist/commands/config/index.d.ts +5 -0
  117. package/dist/commands/config/index.js +109 -0
  118. package/dist/commands/data/index.d.ts +31 -0
  119. package/dist/commands/data/index.js +1466 -0
  120. package/dist/commands/doctor.d.ts +2 -0
  121. package/dist/commands/doctor.js +201 -0
  122. package/dist/commands/exchange/index.d.ts +2 -0
  123. package/dist/commands/exchange/index.js +107 -0
  124. package/dist/commands/index.d.ts +2 -0
  125. package/dist/commands/index.js +48 -0
  126. package/dist/commands/markets/index.d.ts +2 -0
  127. package/dist/commands/markets/index.js +5 -0
  128. package/dist/commands/markets/ls-simple.d.ts +7 -0
  129. package/dist/commands/markets/ls-simple.js +277 -0
  130. package/dist/commands/operator/index.d.ts +2 -0
  131. package/dist/commands/operator/index.js +146 -0
  132. package/dist/commands/order/cancel-simple.d.ts +5 -0
  133. package/dist/commands/order/cancel-simple.js +104 -0
  134. package/dist/commands/order/index.d.ts +2 -0
  135. package/dist/commands/order/index.js +13 -0
  136. package/dist/commands/order/limit-simple.d.ts +5 -0
  137. package/dist/commands/order/limit-simple.js +195 -0
  138. package/dist/commands/order/market-simple.d.ts +5 -0
  139. package/dist/commands/order/market-simple.js +190 -0
  140. package/dist/commands/order/shared.d.ts +17 -0
  141. package/dist/commands/order/shared.js +51 -0
  142. package/dist/commands/order/trigger-simple.d.ts +5 -0
  143. package/dist/commands/order/trigger-simple.js +246 -0
  144. package/dist/commands/referral/index.d.ts +2 -0
  145. package/dist/commands/referral/index.js +7 -0
  146. package/dist/commands/referral/set.d.ts +2 -0
  147. package/dist/commands/referral/set.js +26 -0
  148. package/dist/commands/referral/status.d.ts +2 -0
  149. package/dist/commands/referral/status.js +31 -0
  150. package/dist/commands/replay/index.d.ts +2 -0
  151. package/dist/commands/replay/index.js +152 -0
  152. package/dist/commands/risk/analytics.d.ts +2 -0
  153. package/dist/commands/risk/analytics.js +64 -0
  154. package/dist/commands/risk/audit.d.ts +2 -0
  155. package/dist/commands/risk/audit.js +52 -0
  156. package/dist/commands/risk/index.d.ts +2 -0
  157. package/dist/commands/risk/index.js +9 -0
  158. package/dist/commands/risk/rules.d.ts +2 -0
  159. package/dist/commands/risk/rules.js +102 -0
  160. package/dist/commands/server.d.ts +2 -0
  161. package/dist/commands/server.js +208 -0
  162. package/dist/commands/setup/index.d.ts +2 -0
  163. package/dist/commands/setup/index.js +478 -0
  164. package/dist/commands/signal/index.d.ts +2 -0
  165. package/dist/commands/signal/index.js +129 -0
  166. package/dist/commands/state/index.d.ts +2 -0
  167. package/dist/commands/state/index.js +5 -0
  168. package/dist/commands/state/show.d.ts +2 -0
  169. package/dist/commands/state/show.js +105 -0
  170. package/dist/commands/strategy/index.d.ts +4 -0
  171. package/dist/commands/strategy/index.js +73 -0
  172. package/dist/commands/traces/index.d.ts +2 -0
  173. package/dist/commands/traces/index.js +76 -0
  174. package/dist/commands/ui/demo.d.ts +9 -0
  175. package/dist/commands/ui/demo.js +195 -0
  176. package/dist/commands/ui/index.d.ts +2 -0
  177. package/dist/commands/ui/index.js +7 -0
  178. package/dist/commands/ui/terminal.d.ts +2 -0
  179. package/dist/commands/ui/terminal.js +255 -0
  180. package/dist/commands/upgrade.d.ts +2 -0
  181. package/dist/commands/upgrade.js +98 -0
  182. package/dist/index.d.ts +2 -0
  183. package/dist/index.js +4 -0
  184. package/dist/lib/agent/audit.d.ts +12 -0
  185. package/dist/lib/agent/audit.js +13 -0
  186. package/dist/lib/agent/gateway.d.ts +13 -0
  187. package/dist/lib/agent/gateway.js +598 -0
  188. package/dist/lib/agent/metrics.d.ts +33 -0
  189. package/dist/lib/agent/metrics.js +175 -0
  190. package/dist/lib/agent/signature.d.ts +8 -0
  191. package/dist/lib/agent/signature.js +28 -0
  192. package/dist/lib/agent/tools.d.ts +28 -0
  193. package/dist/lib/agent/tools.js +453 -0
  194. package/dist/lib/agent/x402.d.ts +23 -0
  195. package/dist/lib/agent/x402.js +62 -0
  196. package/dist/lib/api-wallet.d.ts +69 -0
  197. package/dist/lib/api-wallet.js +101 -0
  198. package/dist/lib/balance-watcher.d.ts +25 -0
  199. package/dist/lib/balance-watcher.js +83 -0
  200. package/dist/lib/book-watcher.d.ts +25 -0
  201. package/dist/lib/book-watcher.js +48 -0
  202. package/dist/lib/config.d.ts +88 -0
  203. package/dist/lib/config.js +427 -0
  204. package/dist/lib/constants.d.ts +50 -0
  205. package/dist/lib/constants.js +84 -0
  206. package/dist/lib/contracts.d.ts +7 -0
  207. package/dist/lib/contracts.js +8 -0
  208. package/dist/lib/credential-vault.d.ts +22 -0
  209. package/dist/lib/credential-vault.js +109 -0
  210. package/dist/lib/db/accounts.d.ts +83 -0
  211. package/dist/lib/db/accounts.js +203 -0
  212. package/dist/lib/db/funding-history.d.ts +69 -0
  213. package/dist/lib/db/funding-history.js +183 -0
  214. package/dist/lib/db/index.d.ts +11 -0
  215. package/dist/lib/db/index.js +272 -0
  216. package/dist/lib/events/bus.d.ts +10 -0
  217. package/dist/lib/events/bus.js +17 -0
  218. package/dist/lib/events/types.d.ts +51 -0
  219. package/dist/lib/events/types.js +1 -0
  220. package/dist/lib/exchange.d.ts +30 -0
  221. package/dist/lib/exchange.js +84 -0
  222. package/dist/lib/execution/journal.d.ts +25 -0
  223. package/dist/lib/execution/journal.js +158 -0
  224. package/dist/lib/execution/safety.d.ts +34 -0
  225. package/dist/lib/execution/safety.js +197 -0
  226. package/dist/lib/exit-codes.d.ts +18 -0
  227. package/dist/lib/exit-codes.js +60 -0
  228. package/dist/lib/fetch.d.ts +18 -0
  229. package/dist/lib/fetch.js +66 -0
  230. package/dist/lib/fs-security.d.ts +10 -0
  231. package/dist/lib/fs-security.js +26 -0
  232. package/dist/lib/funding-tracker.d.ts +40 -0
  233. package/dist/lib/funding-tracker.js +118 -0
  234. package/dist/lib/logger.d.ts +27 -0
  235. package/dist/lib/logger.js +82 -0
  236. package/dist/lib/network-model.d.ts +13 -0
  237. package/dist/lib/network-model.js +30 -0
  238. package/dist/lib/onboarding.d.ts +133 -0
  239. package/dist/lib/onboarding.js +1459 -0
  240. package/dist/lib/operator-state.d.ts +25 -0
  241. package/dist/lib/operator-state.js +82 -0
  242. package/dist/lib/orders-watcher.d.ts +24 -0
  243. package/dist/lib/orders-watcher.js +74 -0
  244. package/dist/lib/paths.d.ts +20 -0
  245. package/dist/lib/paths.js +23 -0
  246. package/dist/lib/portfolio-watcher.d.ts +33 -0
  247. package/dist/lib/portfolio-watcher.js +95 -0
  248. package/dist/lib/position-watcher.d.ts +16 -0
  249. package/dist/lib/position-watcher.js +44 -0
  250. package/dist/lib/price-watcher.d.ts +15 -0
  251. package/dist/lib/price-watcher.js +84 -0
  252. package/dist/lib/prompts.d.ts +32 -0
  253. package/dist/lib/prompts.js +105 -0
  254. package/dist/lib/rate-limit.d.ts +32 -0
  255. package/dist/lib/rate-limit.js +88 -0
  256. package/dist/lib/risk/analytics.d.ts +39 -0
  257. package/dist/lib/risk/analytics.js +98 -0
  258. package/dist/lib/risk/drawdown.d.ts +18 -0
  259. package/dist/lib/risk/drawdown.js +49 -0
  260. package/dist/lib/risk/evaluation-log.d.ts +29 -0
  261. package/dist/lib/risk/evaluation-log.js +61 -0
  262. package/dist/lib/risk/index.d.ts +4 -0
  263. package/dist/lib/risk/index.js +4 -0
  264. package/dist/lib/risk/limits.d.ts +23 -0
  265. package/dist/lib/risk/limits.js +27 -0
  266. package/dist/lib/risk/manager.d.ts +32 -0
  267. package/dist/lib/risk/manager.js +85 -0
  268. package/dist/lib/risk/policy-middleware.d.ts +33 -0
  269. package/dist/lib/risk/policy-middleware.js +267 -0
  270. package/dist/lib/risk/position-sizer.d.ts +9 -0
  271. package/dist/lib/risk/position-sizer.js +14 -0
  272. package/dist/lib/risk/rules-store.d.ts +16 -0
  273. package/dist/lib/risk/rules-store.js +47 -0
  274. package/dist/lib/schema.d.ts +254 -0
  275. package/dist/lib/schema.js +199 -0
  276. package/dist/lib/secrets.d.ts +3 -0
  277. package/dist/lib/secrets.js +62 -0
  278. package/dist/lib/settings.d.ts +24 -0
  279. package/dist/lib/settings.js +86 -0
  280. package/dist/lib/signals.d.ts +73 -0
  281. package/dist/lib/signals.js +136 -0
  282. package/dist/lib/stable-stringify.d.ts +6 -0
  283. package/dist/lib/stable-stringify.js +17 -0
  284. package/dist/lib/state-context.d.ts +44 -0
  285. package/dist/lib/state-context.js +133 -0
  286. package/dist/lib/strategy/basis-trade.d.ts +2 -0
  287. package/dist/lib/strategy/basis-trade.js +24 -0
  288. package/dist/lib/strategy/funding-arb.d.ts +2 -0
  289. package/dist/lib/strategy/funding-arb.js +23 -0
  290. package/dist/lib/strategy/interface.d.ts +23 -0
  291. package/dist/lib/strategy/interface.js +1 -0
  292. package/dist/lib/strategy/registry.d.ts +4 -0
  293. package/dist/lib/strategy/registry.js +10 -0
  294. package/dist/lib/telemetry.d.ts +25 -0
  295. package/dist/lib/telemetry.js +101 -0
  296. package/dist/lib/trace-queries.d.ts +20 -0
  297. package/dist/lib/trace-queries.js +133 -0
  298. package/dist/lib/trace.d.ts +1 -0
  299. package/dist/lib/trace.js +4 -0
  300. package/dist/lib/trade-reputation.d.ts +6 -0
  301. package/dist/lib/trade-reputation.js +99 -0
  302. package/dist/lib/ui-tokens.d.ts +21 -0
  303. package/dist/lib/ui-tokens.js +26 -0
  304. package/dist/lib/validate.d.ts +39 -0
  305. package/dist/lib/validate.js +108 -0
  306. package/dist/lib/validation.d.ts +9 -0
  307. package/dist/lib/validation.js +64 -0
  308. package/dist/server/cache.d.ts +38 -0
  309. package/dist/server/cache.js +56 -0
  310. package/dist/server/index.d.ts +2 -0
  311. package/dist/server/index.js +89 -0
  312. package/dist/server/ipc.d.ts +18 -0
  313. package/dist/server/ipc.js +159 -0
  314. package/dist/server/subscriptions.d.ts +18 -0
  315. package/dist/server/subscriptions.js +114 -0
  316. package/package.json +124 -0
@@ -0,0 +1,105 @@
1
+ import { getContext, getOutputOptions, getSelectedExchange } from "../../cli/program.js";
2
+ import { output, outputError } from "../../cli/output.js";
3
+ import { withJsonContract } from "../../lib/contracts.js";
4
+ import { getExchangeAdapter } from "../../lib/exchange.js";
5
+ import { getExchangeCredentials } from "../../lib/config.js";
6
+ import { buildStateContext } from "../../lib/state-context.js";
7
+ export function registerStateShowCommand(state) {
8
+ state
9
+ .command("show")
10
+ .description("Show current portfolio state context")
11
+ .action(async function () {
12
+ const ctx = getContext(this);
13
+ const outputOpts = getOutputOptions(this);
14
+ const exchangeId = getSelectedExchange(this);
15
+ const adapter = getExchangeAdapter();
16
+ let connected = false;
17
+ try {
18
+ const credentials = getExchangeCredentials(ctx.config, exchangeId, {
19
+ requireReadAccess: true,
20
+ });
21
+ await adapter.connect({
22
+ testnet: ctx.config.testnet,
23
+ rpcUrl: credentials.fullnodeUrl,
24
+ wsUrl: credentials.wsUrl,
25
+ credentials,
26
+ });
27
+ connected = true;
28
+ const stateCtx = await buildStateContext(adapter, exchangeId, ctx.config);
29
+ if (outputOpts.json) {
30
+ output(withJsonContract("state.context", stateCtx), outputOpts);
31
+ return;
32
+ }
33
+ // Human-readable output
34
+ console.log("\nPortfolio State:\n");
35
+ console.log(` Exchange: ${stateCtx.exchange}`);
36
+ console.log(` Equity: $${stateCtx.equity.toFixed(2)}`);
37
+ console.log(` Available: $${stateCtx.availableBalance.toFixed(2)}`);
38
+ console.log(` Margin Used: $${stateCtx.marginUsed.toFixed(2)}`);
39
+ console.log(` Exposure: $${stateCtx.totalExposureUsd.toFixed(2)}`);
40
+ console.log(` Leverage: ${stateCtx.leverageUsed.toFixed(2)}x`);
41
+ const pnlSign = stateCtx.netUnrealizedPnl >= 0 ? "+" : "";
42
+ console.log(` Unrealized PnL: ${pnlSign}$${stateCtx.netUnrealizedPnl.toFixed(2)}`);
43
+ console.log(` Drawdown: ${stateCtx.drawdownFromPeakPct.toFixed(2)}%`);
44
+ console.log(` Peak Equity: $${stateCtx.peakEquity.toFixed(2)}`);
45
+ console.log(` Halted: ${stateCtx.halted ? "YES" : "NO"}`);
46
+ if (stateCtx.haltReason) {
47
+ console.log(` Halt Reason: ${stateCtx.haltReason}`);
48
+ }
49
+ // Positions
50
+ console.log(`\n Positions (${stateCtx.positionCount}):\n`);
51
+ if (stateCtx.positions.length === 0) {
52
+ console.log(" No open positions.");
53
+ }
54
+ else {
55
+ for (const pos of stateCtx.positions) {
56
+ const posPnlSign = pos.unrealizedPnl >= 0 ? "+" : "";
57
+ console.log(` ${pos.market} ${pos.side.toUpperCase()}`);
58
+ console.log(` Size: ${pos.size} @ $${pos.entryPrice.toFixed(2)}`);
59
+ console.log(` Mark: $${pos.markPrice.toFixed(2)}`);
60
+ console.log(` Notional: $${pos.notionalUsd.toFixed(2)}`);
61
+ console.log(` PnL: ${posPnlSign}$${pos.unrealizedPnl.toFixed(2)}`);
62
+ console.log(` Leverage: ${pos.leverage}x (${pos.marginType})`);
63
+ if (pos.liquidationPrice !== null) {
64
+ console.log(` Liq Price: $${pos.liquidationPrice.toFixed(2)}`);
65
+ }
66
+ console.log("");
67
+ }
68
+ }
69
+ // Open orders
70
+ console.log(` Open Orders (${stateCtx.openOrderCount}):\n`);
71
+ if (stateCtx.openOrders.length === 0) {
72
+ console.log(" No open orders.");
73
+ }
74
+ else {
75
+ for (const ord of stateCtx.openOrders) {
76
+ console.log(` ${ord.market} ${ord.side} ${ord.type} ${ord.size} @ ${ord.price ?? "market"}`);
77
+ }
78
+ }
79
+ // Errors
80
+ if (stateCtx.errors.length > 0) {
81
+ console.log(`\n Errors (${stateCtx.errors.length}):\n`);
82
+ for (const err of stateCtx.errors) {
83
+ console.log(` - ${err}`);
84
+ }
85
+ }
86
+ // Risk limits
87
+ console.log("\n Risk Limits:\n");
88
+ console.log(` Max Position: $${stateCtx.riskLimits.maxPositionSizeUsd.toFixed(2)}`);
89
+ console.log(` Max Exposure: $${stateCtx.riskLimits.maxTotalExposureUsd.toFixed(2)}`);
90
+ console.log(` Max Leverage: ${stateCtx.riskLimits.maxLeverage}x`);
91
+ console.log(` Max Drawdown: ${stateCtx.riskLimits.maxDrawdownPct}%`);
92
+ console.log(` Min Confidence: ${stateCtx.riskLimits.minSignalConfidence}`);
93
+ console.log("");
94
+ }
95
+ catch (err) {
96
+ outputError(err instanceof Error ? err.message : String(err));
97
+ process.exitCode = 1;
98
+ }
99
+ finally {
100
+ if (connected) {
101
+ await adapter.disconnect().catch(() => undefined);
102
+ }
103
+ }
104
+ });
105
+ }
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ import "../../lib/strategy/funding-arb.js";
3
+ import "../../lib/strategy/basis-trade.js";
4
+ export declare function registerStrategyCommands(program: Command): void;
@@ -0,0 +1,73 @@
1
+ import { getOutputOptions } from "../../cli/program.js";
2
+ import { output, outputError } from "../../cli/output.js";
3
+ import { withJsonContract } from "../../lib/contracts.js";
4
+ import { listStrategies, getStrategy } from "../../lib/strategy/registry.js";
5
+ import "../../lib/strategy/funding-arb.js";
6
+ import "../../lib/strategy/basis-trade.js";
7
+ export function registerStrategyCommands(program) {
8
+ const strategy = program.command("strategy").description("Strategy definitions and metadata");
9
+ strategy
10
+ .command("ls")
11
+ .description("List registered strategies")
12
+ .action(function () {
13
+ const outputOpts = getOutputOptions(this);
14
+ const strategies = listStrategies();
15
+ if (outputOpts.json) {
16
+ output(withJsonContract("strategy.list", { strategies }), outputOpts);
17
+ return;
18
+ }
19
+ const rows = strategies.map((s) => ({
20
+ id: s.id,
21
+ name: s.name,
22
+ shape: s.shape,
23
+ legs: String(s.legs),
24
+ exchanges: s.exchanges,
25
+ }));
26
+ output(rows, outputOpts);
27
+ });
28
+ strategy
29
+ .command("describe <id>")
30
+ .description("Describe a strategy in detail")
31
+ .action(function (id) {
32
+ const outputOpts = getOutputOptions(this);
33
+ const s = getStrategy(id);
34
+ if (!s) {
35
+ outputError(`Strategy "${id}" not found`);
36
+ process.exit(1);
37
+ }
38
+ if (outputOpts.json) {
39
+ output(withJsonContract("strategy.describe", s), outputOpts);
40
+ return;
41
+ }
42
+ console.log("");
43
+ console.log(` Name: ${s.name}`);
44
+ console.log(` ID: ${s.id}`);
45
+ console.log(` Description: ${s.description}`);
46
+ console.log(` Shape: ${s.shape}`);
47
+ console.log(` Legs: ${s.legs}`);
48
+ console.log(` Exchanges: ${s.exchanges}`);
49
+ console.log("");
50
+ console.log(` Entry Signal: ${s.entrySignal}`);
51
+ console.log(` Exit Signal: ${s.exitSignal}`);
52
+ console.log("");
53
+ if (s.parameters.length > 0) {
54
+ console.log(" Parameters:");
55
+ for (const p of s.parameters) {
56
+ const def = p.default !== undefined ? ` (default: ${p.default})` : "";
57
+ console.log(` ${p.name} [${p.type}]${def} — ${p.description}`);
58
+ }
59
+ console.log("");
60
+ }
61
+ const rp = s.riskProfile;
62
+ if (rp.maxPositionSizeUsd || rp.maxLeverage || rp.maxDrawdownPct) {
63
+ console.log(" Risk Profile:");
64
+ if (rp.maxPositionSizeUsd)
65
+ console.log(` Max Position Size: $${rp.maxPositionSizeUsd}`);
66
+ if (rp.maxLeverage)
67
+ console.log(` Max Leverage: ${rp.maxLeverage}x`);
68
+ if (rp.maxDrawdownPct)
69
+ console.log(` Max Drawdown: ${rp.maxDrawdownPct}%`);
70
+ console.log("");
71
+ }
72
+ });
73
+ }
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerTracesCommands(program: Command): void;
@@ -0,0 +1,76 @@
1
+ import { listTraces } from "../../lib/trace-queries.js";
2
+ import { withJsonContract } from "../../lib/contracts.js";
3
+ import { output } from "../../cli/output.js";
4
+ import { getOutputOptions } from "../../cli/program.js";
5
+ function formatTimestamp(ms) {
6
+ const d = new Date(ms);
7
+ const year = d.getFullYear();
8
+ const month = String(d.getMonth() + 1).padStart(2, "0");
9
+ const day = String(d.getDate()).padStart(2, "0");
10
+ const hours = String(d.getHours()).padStart(2, "0");
11
+ const minutes = String(d.getMinutes()).padStart(2, "0");
12
+ return `${year}-${month}-${day} ${hours}:${minutes}`;
13
+ }
14
+ function truncateId(id, maxLen = 36) {
15
+ if (id.length <= maxLen)
16
+ return id;
17
+ return `${id.slice(0, maxLen - 3)}...`;
18
+ }
19
+ function formatStatus(journalStatus, riskDenials) {
20
+ if (riskDenials > 0)
21
+ return "denied";
22
+ return journalStatus ?? "-";
23
+ }
24
+ export function registerTracesCommands(program) {
25
+ const traces = program
26
+ .command("traces")
27
+ .description("Session and trace dashboard");
28
+ traces
29
+ .command("ls")
30
+ .description("List recent traces")
31
+ .option("--last <minutes>", "Time window in minutes", "60")
32
+ .option("--exchange <id>", "Filter by exchange")
33
+ .option("--market <symbol>", "Filter by market")
34
+ .option("--status <status>", "Filter by outcome (succeeded, failed, denied)")
35
+ .option("--limit <n>", "Max results", "50")
36
+ .action((opts, command) => {
37
+ const { json } = getOutputOptions(command);
38
+ const minutes = Number.parseInt(opts.last, 10);
39
+ const limit = Number.parseInt(opts.limit, 10);
40
+ const traces = listTraces({
41
+ minutes,
42
+ exchange: opts.exchange,
43
+ market: opts.market,
44
+ status: opts.status,
45
+ limit,
46
+ });
47
+ if (json) {
48
+ output(withJsonContract("traces.list", { traces, window: { minutes } }), { json });
49
+ return;
50
+ }
51
+ if (traces.length === 0) {
52
+ console.log(`\nNo traces found in the last ${minutes} minutes.\n`);
53
+ return;
54
+ }
55
+ console.log(`\nRecent Traces (last ${minutes} min):\n`);
56
+ const rows = traces.map((t) => ({
57
+ "Trace ID": truncateId(t.traceId),
58
+ Time: formatTimestamp(t.lastSeen),
59
+ Exchange: t.exchange,
60
+ Market: t.markets.join(", ") || "-",
61
+ Evals: String(t.riskEvaluations),
62
+ Denials: String(t.riskDenials),
63
+ Journal: String(t.journalEntries),
64
+ Status: formatStatus(t.journalStatus, t.riskDenials),
65
+ }));
66
+ output(rows, { json: false });
67
+ console.log(`\n${traces.length} trace${traces.length === 1 ? "" : "s"} found`);
68
+ });
69
+ traces
70
+ .command("show <trace-id>")
71
+ .description("Show trace details (alias for replay)")
72
+ .action((traceId) => {
73
+ console.log(`\nRun: perps replay ${traceId}\n`);
74
+ process.exitCode = 0;
75
+ });
76
+ }
@@ -0,0 +1,9 @@
1
+ import type { Command } from "commander";
2
+ export interface UIDemoJsonPreview {
3
+ command: "ui demo";
4
+ intervalMs: number;
5
+ interactive: false;
6
+ note: string;
7
+ }
8
+ export declare function getUIDemoJsonPreview(intervalMs: number): UIDemoJsonPreview;
9
+ export declare function registerUIDemoCommand(ui: Command): void;
@@ -0,0 +1,195 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from "react";
3
+ import { Box, Text, render, useApp, useInput } from "ink";
4
+ import { getOutputOptions } from "../../cli/program.js";
5
+ import { output, outputError } from "../../cli/output.js";
6
+ import { AppShell, MetricStrip, Panel, Table, colors, toBar, toSparkline, } from "../../cli/ink/index.js";
7
+ import { parsePositiveInt } from "../../lib/validate.js";
8
+ const DEFAULT_INTERVAL_MS = 500;
9
+ const MIN_INTERVAL_MS = 100;
10
+ const INITIAL_EQUITY = 10_000;
11
+ const HISTORY_LENGTH = 72;
12
+ const MARKET_SEEDS = [
13
+ { market: "BTC-PERP", basePrice: 64_250, baseVolumeM: 86 },
14
+ { market: "ETH-PERP", basePrice: 3_410, baseVolumeM: 54 },
15
+ { market: "SOL-PERP", basePrice: 146, baseVolumeM: 37 },
16
+ { market: "BNB-PERP", basePrice: 612, baseVolumeM: 19 },
17
+ { market: "ARB-PERP", basePrice: 1.02, baseVolumeM: 8 },
18
+ ];
19
+ export function getUIDemoJsonPreview(intervalMs) {
20
+ return {
21
+ command: "ui demo",
22
+ intervalMs,
23
+ interactive: false,
24
+ note: "Run without --json to launch the offline synthetic terminal preview.",
25
+ };
26
+ }
27
+ function formatCurrency(value, decimals = 2) {
28
+ return value.toLocaleString("en-US", {
29
+ minimumFractionDigits: decimals,
30
+ maximumFractionDigits: decimals,
31
+ });
32
+ }
33
+ function buildMarkets(tick) {
34
+ return MARKET_SEEDS.map((seed, index) => {
35
+ const momentum = Math.sin((tick + index * 2) / 7) * 2.2;
36
+ const meanReversion = Math.cos((tick + index) / 19) * 0.75;
37
+ const changePct = momentum + meanReversion;
38
+ const price = seed.basePrice * (1 + changePct / 100);
39
+ const fundingPct = Math.sin((tick + index * 5) / 13) * 0.035;
40
+ const volumeM = seed.baseVolumeM * (1 + Math.abs(Math.sin((tick + index * 3) / 4)) * 0.8);
41
+ let signal = "FLAT";
42
+ if (changePct > 1.1 && fundingPct < 0.02)
43
+ signal = "LONG";
44
+ if (changePct < -1.1 && fundingPct > -0.02)
45
+ signal = "SHORT";
46
+ return {
47
+ market: seed.market,
48
+ price,
49
+ changePct,
50
+ fundingPct,
51
+ volumeM,
52
+ signal,
53
+ };
54
+ });
55
+ }
56
+ function createInitialState() {
57
+ return {
58
+ tick: 0,
59
+ startedAt: Date.now(),
60
+ equity: INITIAL_EQUITY,
61
+ equityHistory: Array.from({ length: HISTORY_LENGTH }, () => INITIAL_EQUITY),
62
+ markets: buildMarkets(0),
63
+ latencyMs: 58,
64
+ };
65
+ }
66
+ function nextState(previous) {
67
+ const tick = previous.tick + 1;
68
+ const equityDelta = Math.sin(tick / 8) * 14 + Math.cos(tick / 3) * 7;
69
+ const equity = Math.max(5_000, previous.equity + equityDelta);
70
+ const equityHistory = [...previous.equityHistory.slice(-(HISTORY_LENGTH - 1)), equity];
71
+ const latencyMs = Math.round(45 + Math.abs(Math.sin(tick / 5)) * 95 + Math.abs(Math.cos(tick / 13)) * 20);
72
+ return {
73
+ tick,
74
+ startedAt: previous.startedAt,
75
+ equity,
76
+ equityHistory,
77
+ markets: buildMarkets(tick),
78
+ latencyMs,
79
+ };
80
+ }
81
+ function signalColor(signal) {
82
+ if (signal === "LONG")
83
+ return colors.profit;
84
+ if (signal === "SHORT")
85
+ return colors.loss;
86
+ return colors.muted;
87
+ }
88
+ function Dashboard({ intervalMs }) {
89
+ const [state, setState] = useState(createInitialState);
90
+ const { exit } = useApp();
91
+ useInput((input, key) => {
92
+ if (input.toLowerCase() === "q" || key.escape || (key.ctrl && input.toLowerCase() === "c")) {
93
+ exit();
94
+ }
95
+ });
96
+ useEffect(() => {
97
+ const timer = setInterval(() => {
98
+ setState((previous) => nextState(previous));
99
+ }, intervalMs);
100
+ return () => clearInterval(timer);
101
+ }, [intervalMs]);
102
+ const pnl = state.equity - INITIAL_EQUITY;
103
+ const pnlSign = pnl >= 0 ? "+" : "";
104
+ const uptimeSeconds = Math.floor((Date.now() - state.startedAt) / 1_000);
105
+ const liveSignals = state.markets.filter((row) => row.signal !== "FLAT").length;
106
+ const statusTone = state.latencyMs > 170 ? "danger" : state.latencyMs > 120 ? "warning" : "success";
107
+ const metrics = [
108
+ {
109
+ label: "Equity",
110
+ value: `$${formatCurrency(state.equity)}`,
111
+ delta: `${pnlSign}$${formatCurrency(pnl)}`,
112
+ tone: pnl >= 0 ? "success" : "danger",
113
+ },
114
+ { label: "Latency", value: `${state.latencyMs}ms`, tone: statusTone },
115
+ { label: "Signals", value: String(liveSignals), tone: liveSignals > 0 ? "info" : "neutral" },
116
+ { label: "Uptime", value: `${uptimeSeconds}s`, tone: "neutral" },
117
+ ];
118
+ const columns = useMemo(() => [
119
+ { key: "market", header: "Market" },
120
+ {
121
+ key: "price",
122
+ header: "Price",
123
+ align: "right",
124
+ render: (value) => _jsxs(Text, { children: ["$", formatCurrency(value)] }),
125
+ },
126
+ {
127
+ key: "changePct",
128
+ header: "24h %",
129
+ align: "right",
130
+ render: (value) => {
131
+ const change = value;
132
+ const sign = change >= 0 ? "+" : "";
133
+ return (_jsxs(Text, { color: change >= 0 ? colors.profit : colors.loss, children: [sign, change.toFixed(2), "%"] }));
134
+ },
135
+ },
136
+ {
137
+ key: "fundingPct",
138
+ header: "Funding",
139
+ align: "right",
140
+ render: (value) => {
141
+ const funding = value;
142
+ const sign = funding >= 0 ? "+" : "";
143
+ return (_jsxs(Text, { color: funding >= 0 ? colors.profit : colors.loss, children: [sign, funding.toFixed(4), "%"] }));
144
+ },
145
+ },
146
+ {
147
+ key: "volumeM",
148
+ header: "Vol(M)",
149
+ align: "right",
150
+ render: (value) => _jsx(Text, { children: formatCurrency(value, 1) }),
151
+ },
152
+ {
153
+ key: "signal",
154
+ header: "Signal",
155
+ align: "right",
156
+ render: (value) => _jsx(Text, { color: signalColor(value), children: value }),
157
+ },
158
+ ], []);
159
+ const strongest = [...state.markets]
160
+ .sort((left, right) => Math.abs(right.changePct) - Math.abs(left.changePct))
161
+ .slice(0, 3);
162
+ return (_jsxs(AppShell, { title: "Perps Terminal Preview", subtitle: "Synthetic stream for offline UI validation", status: [
163
+ { label: "LIVE", tone: "success" },
164
+ { label: `LAT ${state.latencyMs}ms`, tone: statusTone },
165
+ ], lastUpdated: new Date(), shortcuts: [
166
+ { key: "q", label: "quit" },
167
+ { key: "esc", label: "quit" },
168
+ ], children: [_jsx(MetricStrip, { metrics: metrics }), _jsx(Box, { flexDirection: "column", marginBottom: 1, children: _jsxs(Panel, { title: "Equity Curve", subtitle: "ASCII sparkline and momentum bars", tone: "info", children: [_jsx(Text, { children: toSparkline(state.equityHistory, 64) }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: strongest.map((market) => (_jsxs(Box, { children: [_jsx(Text, { color: colors.muted, children: market.market.padEnd(8) }), _jsx(Text, { children: " " }), _jsx(Text, { children: toBar(Math.abs(market.changePct), 4, 20, market.changePct >= 0 ? "+" : "-", ".") }), _jsxs(Text, { color: market.changePct >= 0 ? colors.profit : colors.loss, children: [" ", market.changePct >= 0 ? "+" : "", market.changePct.toFixed(2), "%"] })] }, market.market))) })] }) }), _jsx(Panel, { title: "Market Tape", subtitle: "Reusable table component", tone: "neutral", children: _jsx(Table, { data: state.markets, columns: columns }) })] }));
169
+ }
170
+ export function registerUIDemoCommand(ui) {
171
+ ui
172
+ .command("demo")
173
+ .description("Run an offline synthetic dashboard preview")
174
+ .option("-i, --interval <ms>", "Refresh interval in milliseconds", String(DEFAULT_INTERVAL_MS))
175
+ .action(async function (options) {
176
+ const outputOpts = getOutputOptions(this);
177
+ try {
178
+ const intervalMs = parsePositiveInt(options.interval, "interval", DEFAULT_INTERVAL_MS);
179
+ if (intervalMs < MIN_INTERVAL_MS) {
180
+ throw new Error(`interval must be >= ${MIN_INTERVAL_MS}ms`);
181
+ }
182
+ if (outputOpts.json) {
183
+ output(getUIDemoJsonPreview(intervalMs), outputOpts);
184
+ return;
185
+ }
186
+ const { waitUntilExit, unmount } = render(_jsx(Dashboard, { intervalMs: intervalMs }));
187
+ await waitUntilExit();
188
+ unmount();
189
+ }
190
+ catch (err) {
191
+ outputError(err instanceof Error ? err.message : String(err));
192
+ process.exit(1);
193
+ }
194
+ });
195
+ }
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerUICommands(program: Command): void;
@@ -0,0 +1,7 @@
1
+ import { registerUIDemoCommand } from "./demo.js";
2
+ import { registerUITerminalCommand } from "./terminal.js";
3
+ export function registerUICommands(program) {
4
+ const ui = program.command("ui").description("Terminal dashboards for live ops and diagnostics");
5
+ registerUITerminalCommand(ui);
6
+ registerUIDemoCommand(ui);
7
+ }
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerUITerminalCommand(ui: Command): void;