@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,146 @@
1
+ import { getOutputOptions } from "../../cli/program.js";
2
+ import { output, outputError, outputSuccess } from "../../cli/output.js";
3
+ import { withJsonContract } from "../../lib/contracts.js";
4
+ import { readOperatorState, setKillSwitch } from "../../lib/operator-state.js";
5
+ import { getTelemetrySnapshot, resetTelemetry, summarizeFailureRates } from "../../lib/telemetry.js";
6
+ export function registerOperatorCommands(program) {
7
+ const operator = program
8
+ .command("operator")
9
+ .alias("bot")
10
+ .description("Operator controls, heartbeat, and kill-switch");
11
+ operator
12
+ .command("status")
13
+ .description("Show latest heartbeat and kill-switch status")
14
+ .action(function () {
15
+ const outputOpts = getOutputOptions(this);
16
+ const state = readOperatorState();
17
+ const heartbeat = state.heartbeat;
18
+ const halted = state.killSwitch.enabled || (heartbeat?.halted ?? false);
19
+ const haltReason = state.killSwitch.enabled
20
+ ? state.killSwitch.reason ?? "Manual kill switch enabled"
21
+ : heartbeat?.haltReason;
22
+ const status = {
23
+ halted,
24
+ haltReason,
25
+ killSwitch: state.killSwitch,
26
+ heartbeat: heartbeat ?? null,
27
+ };
28
+ if (outputOpts.json) {
29
+ output(status, outputOpts);
30
+ return;
31
+ }
32
+ console.log("\nOperator Status:\n");
33
+ console.log(` Halted: ${halted ? "YES" : "NO"}`);
34
+ if (haltReason) {
35
+ console.log(` Halt reason: ${haltReason}`);
36
+ }
37
+ console.log(` Kill switch: ${state.killSwitch.enabled ? "ON" : "OFF"}`);
38
+ if (state.killSwitch.updatedAt > 0) {
39
+ console.log(` Updated: ${new Date(state.killSwitch.updatedAt).toISOString()}`);
40
+ }
41
+ console.log("");
42
+ if (!heartbeat) {
43
+ console.log(" No heartbeat recorded yet.");
44
+ console.log(" Run an order/arb execution command to emit a heartbeat snapshot.\n");
45
+ return;
46
+ }
47
+ console.log(" Latest Heartbeat:");
48
+ console.log(` Exchange: ${heartbeat.exchange}`);
49
+ if (heartbeat.market)
50
+ console.log(` Market: ${heartbeat.market}`);
51
+ console.log(` Equity: $${heartbeat.equity.toFixed(2)}`);
52
+ console.log(` Exposure: $${heartbeat.exposureUsd.toFixed(2)}`);
53
+ console.log(` Drawdown: ${heartbeat.drawdownPct.toFixed(2)}%`);
54
+ console.log(` Peak: $${heartbeat.peakEquity.toFixed(2)}`);
55
+ console.log(` Halted: ${heartbeat.halted ? "YES" : "NO"}`);
56
+ if (heartbeat.haltReason) {
57
+ console.log(` Reason: ${heartbeat.haltReason}`);
58
+ }
59
+ console.log(` Updated: ${new Date(heartbeat.updatedAt).toISOString()} (${formatAge(Date.now() - heartbeat.updatedAt)} ago)`);
60
+ console.log("");
61
+ });
62
+ operator
63
+ .command("halt [reason]")
64
+ .description("Enable manual kill switch")
65
+ .action(function (reason) {
66
+ const outputOpts = getOutputOptions(this);
67
+ const state = setKillSwitch(true, reason);
68
+ if (outputOpts.json) {
69
+ output({ success: true, killSwitch: state.killSwitch }, outputOpts);
70
+ return;
71
+ }
72
+ outputSuccess("Kill switch enabled");
73
+ if (state.killSwitch.reason) {
74
+ console.log(` Reason: ${state.killSwitch.reason}`);
75
+ }
76
+ console.log("");
77
+ });
78
+ operator
79
+ .command("resume")
80
+ .description("Disable manual kill switch")
81
+ .action(function () {
82
+ const outputOpts = getOutputOptions(this);
83
+ const state = setKillSwitch(false);
84
+ if (outputOpts.json) {
85
+ output({ success: true, killSwitch: state.killSwitch }, outputOpts);
86
+ return;
87
+ }
88
+ outputSuccess("Kill switch disabled");
89
+ if (state.heartbeat?.halted) {
90
+ outputError("Circuit breaker is still halted by drawdown. Use safer sizing or reset state if intentional.");
91
+ }
92
+ console.log("");
93
+ });
94
+ operator
95
+ .command("telemetry")
96
+ .description("Show auth/funding reliability telemetry")
97
+ .option("--reset", "Reset telemetry counters after printing")
98
+ .action(function () {
99
+ const outputOpts = getOutputOptions(this);
100
+ const opts = this.opts();
101
+ const snapshot = getTelemetrySnapshot();
102
+ const rates = summarizeFailureRates(snapshot);
103
+ if (outputOpts.json) {
104
+ output(withJsonContract("operator.telemetry.snapshot", {
105
+ snapshot,
106
+ rates,
107
+ }), outputOpts);
108
+ }
109
+ else {
110
+ console.log("\nTelemetry:\n");
111
+ console.log(` Updated: ${new Date(snapshot.updatedAt).toISOString()}`);
112
+ console.log(` Counters: ${Object.keys(snapshot.counters).length}`);
113
+ if (rates.length === 0) {
114
+ console.log(" No telemetry events recorded yet.\n");
115
+ }
116
+ else {
117
+ console.log("");
118
+ for (const row of rates) {
119
+ console.log(` ${row.metric}: total=${row.total} failRate=${(row.failureRate * 100).toFixed(1)}% successRate=${(row.successRate * 100).toFixed(1)}%`);
120
+ }
121
+ console.log("");
122
+ }
123
+ }
124
+ if (opts.reset) {
125
+ resetTelemetry();
126
+ if (!outputOpts.json) {
127
+ outputSuccess("Telemetry counters reset");
128
+ }
129
+ }
130
+ });
131
+ }
132
+ function formatAge(ms) {
133
+ if (ms < 1_000)
134
+ return `${ms}ms`;
135
+ const seconds = Math.floor(ms / 1_000);
136
+ if (seconds < 60)
137
+ return `${seconds}s`;
138
+ const minutes = Math.floor(seconds / 60);
139
+ if (minutes < 60)
140
+ return `${minutes}m ${seconds % 60}s`;
141
+ const hours = Math.floor(minutes / 60);
142
+ if (hours < 24)
143
+ return `${hours}h ${minutes % 60}m`;
144
+ const days = Math.floor(hours / 24);
145
+ return `${days}d ${hours % 24}h`;
146
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Simple cancel order command using the adapter interface
3
+ */
4
+ import { Command } from "commander";
5
+ export declare function registerCancelOrderSimpleCommand(order: Command): void;
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Simple cancel order command using the adapter interface
3
+ */
4
+ import { getContext, getOutputOptions, getSelectedExchange } from "../../cli/program.js";
5
+ import { output, outputError, outputSuccess } from "../../cli/output.js";
6
+ import { getExchangeAdapter } from "../../lib/exchange.js";
7
+ import { getExchangeCredentials } from "../../lib/config.js";
8
+ export function registerCancelOrderSimpleCommand(order) {
9
+ order
10
+ .command("cancel <orderId> <symbol>")
11
+ .description("Cancel an order by ID")
12
+ .action(async function (orderId, symbol) {
13
+ const ctx = getContext(this);
14
+ const outputOpts = getOutputOptions(this);
15
+ const exchangeId = getSelectedExchange(this);
16
+ let connected = false;
17
+ try {
18
+ const adapter = getExchangeAdapter();
19
+ const credentials = getExchangeCredentials(ctx.config, exchangeId, {
20
+ requireTrading: true,
21
+ });
22
+ await adapter.connect({
23
+ testnet: ctx.config.testnet,
24
+ rpcUrl: credentials.fullnodeUrl,
25
+ wsUrl: credentials.wsUrl,
26
+ credentials,
27
+ });
28
+ connected = true;
29
+ // Normalize market
30
+ let market = symbol.toUpperCase();
31
+ if (!market.includes("-")) {
32
+ market = `${market}-PERP`;
33
+ }
34
+ const success = await adapter.cancelOrder({
35
+ orderId,
36
+ market,
37
+ });
38
+ if (outputOpts.json) {
39
+ output({ success, orderId, market }, outputOpts);
40
+ }
41
+ else {
42
+ if (success) {
43
+ outputSuccess(`Order ${orderId} cancelled`);
44
+ }
45
+ else {
46
+ outputError(`Failed to cancel order ${orderId}`);
47
+ }
48
+ }
49
+ }
50
+ catch (err) {
51
+ outputError(err instanceof Error ? err.message : String(err));
52
+ process.exit(1);
53
+ }
54
+ finally {
55
+ if (connected)
56
+ await getExchangeAdapter().disconnect().catch(() => undefined);
57
+ }
58
+ });
59
+ // Cancel all orders
60
+ order
61
+ .command("cancel-all [symbol]")
62
+ .description("Cancel all open orders (optionally for a specific market)")
63
+ .action(async function (symbol) {
64
+ const ctx = getContext(this);
65
+ const outputOpts = getOutputOptions(this);
66
+ const exchangeId = getSelectedExchange(this);
67
+ let connected = false;
68
+ try {
69
+ const adapter = getExchangeAdapter();
70
+ const credentials = getExchangeCredentials(ctx.config, exchangeId, {
71
+ requireTrading: true,
72
+ });
73
+ await adapter.connect({
74
+ testnet: ctx.config.testnet,
75
+ rpcUrl: credentials.fullnodeUrl,
76
+ wsUrl: credentials.wsUrl,
77
+ credentials,
78
+ });
79
+ connected = true;
80
+ let market;
81
+ if (symbol) {
82
+ market = symbol.toUpperCase();
83
+ if (!market.includes("-")) {
84
+ market = `${market}-PERP`;
85
+ }
86
+ }
87
+ const count = await adapter.cancelAllOrders(market);
88
+ if (outputOpts.json) {
89
+ output({ cancelled: count, market: market ?? "all" }, outputOpts);
90
+ }
91
+ else {
92
+ outputSuccess(`Cancelled ${count} orders${market ? ` for ${market}` : ""}`);
93
+ }
94
+ }
95
+ catch (err) {
96
+ outputError(err instanceof Error ? err.message : String(err));
97
+ process.exit(1);
98
+ }
99
+ finally {
100
+ if (connected)
101
+ await getExchangeAdapter().disconnect().catch(() => undefined);
102
+ }
103
+ });
104
+ }
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerOrderCommands(program: Command): void;
@@ -0,0 +1,13 @@
1
+ import { registerLimitOrderSimpleCommand } from "./limit-simple.js";
2
+ import { registerMarketOrderSimpleCommand } from "./market-simple.js";
3
+ import { registerCancelOrderSimpleCommand } from "./cancel-simple.js";
4
+ import { registerTriggerOrderSimpleCommands } from "./trigger-simple.js";
5
+ export function registerOrderCommands(program) {
6
+ const order = program
7
+ .command("order")
8
+ .description("Order management and trading (requires authentication)");
9
+ registerLimitOrderSimpleCommand(order);
10
+ registerMarketOrderSimpleCommand(order);
11
+ registerTriggerOrderSimpleCommands(order);
12
+ registerCancelOrderSimpleCommand(order);
13
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Simple limit order command using the adapter interface
3
+ */
4
+ import { Command } from "commander";
5
+ export declare function registerLimitOrderSimpleCommand(order: Command): void;
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Simple limit order command using the adapter interface
3
+ */
4
+ import { getContext, getOutputOptions, getSelectedExchange } from "../../cli/program.js";
5
+ import { output, outputError, outputSuccess } from "../../cli/output.js";
6
+ import { getExchangeAdapter } from "../../lib/exchange.js";
7
+ import { getExchangeCredentials } from "../../lib/config.js";
8
+ import { RiskPolicyMiddleware } from "../../lib/risk/policy-middleware.js";
9
+ import { executeOrderWithSafety } from "../../lib/execution/safety.js";
10
+ import { runWithExecutionJournal } from "../../lib/execution/journal.js";
11
+ import { normalizeMarket, normalizeSide } from "./shared.js";
12
+ import { withJsonContract } from "../../lib/contracts.js";
13
+ import { inferExitCode } from "../../lib/exit-codes.js";
14
+ export function registerLimitOrderSimpleCommand(order) {
15
+ order
16
+ .command("limit <side> <symbol> <size> <price>")
17
+ .description("Place a limit order (side: buy/long or sell/short)")
18
+ .option("--reduce-only", "Reduce-only order")
19
+ .option("--post-only", "Post-only order (maker only)")
20
+ .option("--confidence <0-1>", "Signal confidence for risk policy (default: 1.0)")
21
+ .option("--tp <pct>", "Attach take-profit (% from entry)")
22
+ .option("--sl <pct>", "Attach stop-loss (% from entry)")
23
+ .option("--no-close-then-flip", "Disable auto close-then-flip behavior")
24
+ .option("--idempotency-key <key>", "Idempotency key for safe retries")
25
+ .action(async function (side, symbol, size, price) {
26
+ const ctx = getContext(this);
27
+ const outputOpts = getOutputOptions(this);
28
+ const exchangeId = getSelectedExchange(this);
29
+ const opts = this.opts();
30
+ try {
31
+ // Normalize inputs
32
+ const market = normalizeMarket(symbol);
33
+ const requestedSize = parseFloat(size);
34
+ if (!Number.isFinite(requestedSize) || requestedSize <= 0) {
35
+ throw new Error("Size must be a positive number");
36
+ }
37
+ const limitPrice = parseFloat(price);
38
+ if (!Number.isFinite(limitPrice) || limitPrice <= 0) {
39
+ throw new Error("Price must be a positive number");
40
+ }
41
+ const normalizedSide = normalizeSide(side);
42
+ const closeThenFlip = opts.closeThenFlip ?? true;
43
+ const confidence = opts.confidence ? parseFloat(opts.confidence) : 1;
44
+ if (!Number.isFinite(confidence) || confidence < 0 || confidence > 1) {
45
+ throw new Error("Confidence must be a number between 0 and 1");
46
+ }
47
+ const shouldAttachTpSl = opts.tp !== undefined || opts.sl !== undefined;
48
+ const tp = opts.tp !== undefined ? parseFloat(opts.tp) : ctx.config.executionSafety.takeProfitPct;
49
+ const sl = opts.sl !== undefined ? parseFloat(opts.sl) : ctx.config.executionSafety.stopLossPct;
50
+ if (shouldAttachTpSl) {
51
+ if (!Number.isFinite(tp) || tp <= 0)
52
+ throw new Error("TP must be a positive number");
53
+ if (!Number.isFinite(sl) || sl <= 0)
54
+ throw new Error("SL must be a positive number");
55
+ }
56
+ const adapter = getExchangeAdapter();
57
+ const credentials = getExchangeCredentials(ctx.config, exchangeId, {
58
+ requireTrading: true,
59
+ });
60
+ await adapter.connect({
61
+ testnet: ctx.config.testnet,
62
+ rpcUrl: credentials.fullnodeUrl,
63
+ wsUrl: credentials.wsUrl,
64
+ credentials,
65
+ });
66
+ try {
67
+ const riskPolicy = new RiskPolicyMiddleware(ctx.config, exchangeId);
68
+ const riskDecision = await riskPolicy.evaluateOrder(adapter, {
69
+ market,
70
+ side: normalizedSide,
71
+ requestedSizeBase: requestedSize,
72
+ referencePriceUsd: limitPrice,
73
+ confidence,
74
+ reason: "cli:order:limit",
75
+ });
76
+ if (!riskDecision.allowed || riskDecision.adjustedSizeBase <= 0) {
77
+ throw new Error(riskDecision.reason ?? "Order blocked by risk policy");
78
+ }
79
+ const finalSize = riskDecision.adjustedSizeBase;
80
+ const journaled = await runWithExecutionJournal({
81
+ idempotencyKey: opts.idempotencyKey,
82
+ metadata: {
83
+ command: "order.limit",
84
+ exchange: exchangeId,
85
+ testnet: ctx.config.testnet,
86
+ market,
87
+ side: normalizedSide,
88
+ orderType: "limit",
89
+ },
90
+ request: {
91
+ market,
92
+ side: normalizedSide,
93
+ requestedSize: requestedSize.toFixed(8),
94
+ limitPrice: limitPrice.toFixed(8),
95
+ reduceOnly: opts.reduceOnly ?? false,
96
+ postOnly: opts.postOnly ?? false,
97
+ confidence,
98
+ closeThenFlip,
99
+ tp: shouldAttachTpSl ? tp : null,
100
+ sl: shouldAttachTpSl ? sl : null,
101
+ },
102
+ execute: async () => {
103
+ const execution = await executeOrderWithSafety(adapter, {
104
+ market,
105
+ side: normalizedSide,
106
+ type: "limit",
107
+ size: finalSize.toFixed(8),
108
+ price: limitPrice.toString(),
109
+ reduceOnly: opts.reduceOnly,
110
+ postOnly: opts.postOnly,
111
+ }, {
112
+ closeThenFlip,
113
+ spreadAwarePricing: false,
114
+ attachTpSl: shouldAttachTpSl,
115
+ tpSlConfig: shouldAttachTpSl
116
+ ? { takeProfitPct: tp, stopLossPct: sl }
117
+ : undefined,
118
+ });
119
+ return {
120
+ order: execution.order,
121
+ risk: {
122
+ requestedSize,
123
+ adjustedSize: finalSize,
124
+ adjustedNotionalUsd: riskDecision.adjustedSizeUsd,
125
+ referencePrice: limitPrice,
126
+ },
127
+ safety: {
128
+ closedOppositePosition: execution.closedOppositePosition,
129
+ tpSlOrderIds: execution.tpSlOrderIds,
130
+ },
131
+ };
132
+ },
133
+ });
134
+ const response = {
135
+ ...journaled.result.order,
136
+ risk: journaled.result.risk,
137
+ safety: journaled.result.safety,
138
+ idempotency: {
139
+ key: journaled.idempotencyKey,
140
+ replayed: journaled.replayed,
141
+ autoGenerated: journaled.autoGeneratedKey,
142
+ journalId: journaled.journalId,
143
+ },
144
+ };
145
+ if (outputOpts.json) {
146
+ output(withJsonContract("order.execution.result", {
147
+ executionStatus: journaled.replayed ? "replayed" : "executed",
148
+ ...response,
149
+ }), outputOpts);
150
+ }
151
+ else {
152
+ outputSuccess(journaled.replayed ? "Order replayed from idempotency journal!" : "Order placed!");
153
+ console.log(` Order ID: ${response.id}`);
154
+ console.log(` Market: ${response.market}`);
155
+ console.log(` Side: ${response.side.toUpperCase()}`);
156
+ console.log(` Size: ${response.size}`);
157
+ console.log(` Price: $${response.price}`);
158
+ console.log(` Status: ${response.status}`);
159
+ if (Math.abs(response.risk.adjustedSize - response.risk.requestedSize) > 1e-12) {
160
+ console.log(` Risk Size: adjusted from ${response.risk.requestedSize} to ${response.risk.adjustedSize.toFixed(8)}`);
161
+ }
162
+ if (response.safety.closedOppositePosition) {
163
+ console.log(" Safety: closed opposite position before opening new side");
164
+ }
165
+ if (response.safety.tpSlOrderIds.length > 0) {
166
+ console.log(` TP/SL: attached (${response.safety.tpSlOrderIds.join(", ")})`);
167
+ }
168
+ console.log(` Idempotency: ${response.idempotency.key}` +
169
+ (response.idempotency.replayed ? " (replayed)" : ""));
170
+ console.log("");
171
+ }
172
+ }
173
+ finally {
174
+ await adapter.disconnect();
175
+ }
176
+ }
177
+ catch (err) {
178
+ const code = inferExitCode(err);
179
+ const message = err instanceof Error ? err.message : String(err);
180
+ if (outputOpts.json) {
181
+ output(withJsonContract("order.execution.result", {
182
+ status: "error",
183
+ error: {
184
+ message,
185
+ exitCode: code,
186
+ },
187
+ }), outputOpts);
188
+ }
189
+ else {
190
+ outputError(message);
191
+ }
192
+ process.exit(code);
193
+ }
194
+ });
195
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Simple market order command using the adapter interface
3
+ */
4
+ import { Command } from "commander";
5
+ export declare function registerMarketOrderSimpleCommand(order: Command): void;
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Simple market order command using the adapter interface
3
+ */
4
+ import { getContext, getOutputOptions, getSelectedExchange } from "../../cli/program.js";
5
+ import { output, outputError, outputSuccess } from "../../cli/output.js";
6
+ import { getExchangeAdapter } from "../../lib/exchange.js";
7
+ import { getExchangeCredentials } from "../../lib/config.js";
8
+ import { RiskPolicyMiddleware } from "../../lib/risk/policy-middleware.js";
9
+ import { executeOrderWithSafety } from "../../lib/execution/safety.js";
10
+ import { runWithExecutionJournal } from "../../lib/execution/journal.js";
11
+ import { normalizeMarket, normalizeSide } from "./shared.js";
12
+ import { withJsonContract } from "../../lib/contracts.js";
13
+ import { inferExitCode } from "../../lib/exit-codes.js";
14
+ export function registerMarketOrderSimpleCommand(order) {
15
+ order
16
+ .command("market <side> <symbol> <size>")
17
+ .description("Place a market order (side: buy/long or sell/short)")
18
+ .option("--reduce-only", "Reduce-only order")
19
+ .option("--confidence <0-1>", "Signal confidence for risk policy (default: 1.0)")
20
+ .option("--tp <pct>", "Attach take-profit (% from entry)")
21
+ .option("--sl <pct>", "Attach stop-loss (% from entry)")
22
+ .option("--no-close-then-flip", "Disable auto close-then-flip behavior")
23
+ .option("--no-spread-aware", "Disable spread-aware execution pricing")
24
+ .option("--idempotency-key <key>", "Idempotency key for safe retries")
25
+ .action(async function (side, symbol, size) {
26
+ const ctx = getContext(this);
27
+ const outputOpts = getOutputOptions(this);
28
+ const exchangeId = getSelectedExchange(this);
29
+ const opts = this.opts();
30
+ try {
31
+ // Normalize inputs
32
+ const market = normalizeMarket(symbol);
33
+ const requestedSize = parseFloat(size);
34
+ if (!Number.isFinite(requestedSize) || requestedSize <= 0) {
35
+ throw new Error("Size must be a positive number");
36
+ }
37
+ const normalizedSide = normalizeSide(side);
38
+ const closeThenFlip = opts.closeThenFlip ?? true;
39
+ const spreadAware = opts.spreadAware ?? true;
40
+ const confidence = opts.confidence ? parseFloat(opts.confidence) : 1;
41
+ if (!Number.isFinite(confidence) || confidence < 0 || confidence > 1) {
42
+ throw new Error("Confidence must be a number between 0 and 1");
43
+ }
44
+ const shouldAttachTpSl = opts.tp !== undefined || opts.sl !== undefined;
45
+ const tp = opts.tp !== undefined ? parseFloat(opts.tp) : ctx.config.executionSafety.takeProfitPct;
46
+ const sl = opts.sl !== undefined ? parseFloat(opts.sl) : ctx.config.executionSafety.stopLossPct;
47
+ if (shouldAttachTpSl) {
48
+ if (!Number.isFinite(tp) || tp <= 0)
49
+ throw new Error("TP must be a positive number");
50
+ if (!Number.isFinite(sl) || sl <= 0)
51
+ throw new Error("SL must be a positive number");
52
+ }
53
+ const adapter = getExchangeAdapter();
54
+ const credentials = getExchangeCredentials(ctx.config, exchangeId, {
55
+ requireTrading: true,
56
+ });
57
+ await adapter.connect({
58
+ testnet: ctx.config.testnet,
59
+ rpcUrl: credentials.fullnodeUrl,
60
+ wsUrl: credentials.wsUrl,
61
+ credentials,
62
+ });
63
+ try {
64
+ const riskPolicy = new RiskPolicyMiddleware(ctx.config, exchangeId);
65
+ const riskDecision = await riskPolicy.evaluateOrder(adapter, {
66
+ market,
67
+ side: normalizedSide,
68
+ requestedSizeBase: requestedSize,
69
+ confidence,
70
+ reason: "cli:order:market",
71
+ });
72
+ if (!riskDecision.allowed || riskDecision.adjustedSizeBase <= 0) {
73
+ throw new Error(riskDecision.reason ?? "Order blocked by risk policy");
74
+ }
75
+ const finalSize = riskDecision.adjustedSizeBase;
76
+ const journaled = await runWithExecutionJournal({
77
+ idempotencyKey: opts.idempotencyKey,
78
+ metadata: {
79
+ command: "order.market",
80
+ exchange: exchangeId,
81
+ testnet: ctx.config.testnet,
82
+ market,
83
+ side: normalizedSide,
84
+ orderType: "market",
85
+ },
86
+ request: {
87
+ market,
88
+ side: normalizedSide,
89
+ requestedSize: requestedSize.toFixed(8),
90
+ reduceOnly: opts.reduceOnly ?? false,
91
+ confidence,
92
+ closeThenFlip,
93
+ spreadAware,
94
+ spreadOffset: ctx.config.executionSafety.spreadOffset,
95
+ tp: shouldAttachTpSl ? tp : null,
96
+ sl: shouldAttachTpSl ? sl : null,
97
+ },
98
+ execute: async () => {
99
+ const execution = await executeOrderWithSafety(adapter, {
100
+ market,
101
+ side: normalizedSide,
102
+ type: "market",
103
+ size: finalSize.toFixed(8),
104
+ reduceOnly: opts.reduceOnly,
105
+ }, {
106
+ closeThenFlip,
107
+ spreadAwarePricing: spreadAware,
108
+ spreadOffset: ctx.config.executionSafety.spreadOffset,
109
+ attachTpSl: shouldAttachTpSl,
110
+ tpSlConfig: shouldAttachTpSl
111
+ ? { takeProfitPct: tp, stopLossPct: sl }
112
+ : undefined,
113
+ });
114
+ return {
115
+ order: execution.order,
116
+ risk: {
117
+ requestedSize,
118
+ adjustedSize: finalSize,
119
+ adjustedNotionalUsd: riskDecision.adjustedSizeUsd,
120
+ referencePrice: riskDecision.referencePriceUsd,
121
+ },
122
+ safety: {
123
+ closedOppositePosition: execution.closedOppositePosition,
124
+ tpSlOrderIds: execution.tpSlOrderIds,
125
+ pricing: execution.pricing,
126
+ },
127
+ };
128
+ },
129
+ });
130
+ const response = {
131
+ ...journaled.result.order,
132
+ risk: journaled.result.risk,
133
+ safety: journaled.result.safety,
134
+ idempotency: {
135
+ key: journaled.idempotencyKey,
136
+ replayed: journaled.replayed,
137
+ autoGenerated: journaled.autoGeneratedKey,
138
+ journalId: journaled.journalId,
139
+ },
140
+ };
141
+ if (outputOpts.json) {
142
+ output(withJsonContract("order.execution.result", {
143
+ executionStatus: journaled.replayed ? "replayed" : "executed",
144
+ ...response,
145
+ }), outputOpts);
146
+ }
147
+ else {
148
+ outputSuccess(journaled.replayed ? "Order replayed from idempotency journal!" : "Market order placed!");
149
+ console.log(` Order ID: ${response.id}`);
150
+ console.log(` Market: ${response.market}`);
151
+ console.log(` Side: ${response.side.toUpperCase()}`);
152
+ console.log(` Size: ${response.size}`);
153
+ console.log(` Status: ${response.status}`);
154
+ if (Math.abs(response.risk.adjustedSize - response.risk.requestedSize) > 1e-12) {
155
+ console.log(` Risk Size: adjusted from ${response.risk.requestedSize} to ${response.risk.adjustedSize.toFixed(8)}`);
156
+ }
157
+ if (response.safety.closedOppositePosition) {
158
+ console.log(" Safety: closed opposite position before opening new side");
159
+ }
160
+ if (response.safety.tpSlOrderIds.length > 0) {
161
+ console.log(` TP/SL: attached (${response.safety.tpSlOrderIds.join(", ")})`);
162
+ }
163
+ console.log(` Idempotency: ${response.idempotency.key}` +
164
+ (response.idempotency.replayed ? " (replayed)" : ""));
165
+ console.log("");
166
+ }
167
+ }
168
+ finally {
169
+ await adapter.disconnect();
170
+ }
171
+ }
172
+ catch (err) {
173
+ const code = inferExitCode(err);
174
+ const message = err instanceof Error ? err.message : String(err);
175
+ if (outputOpts.json) {
176
+ output(withJsonContract("order.execution.result", {
177
+ status: "error",
178
+ error: {
179
+ message,
180
+ exitCode: code,
181
+ },
182
+ }), outputOpts);
183
+ }
184
+ else {
185
+ outputError(message);
186
+ }
187
+ process.exit(code);
188
+ }
189
+ });
190
+ }