@coinrithm/mcp-trading 0.3.0 → 0.5.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 (41) hide show
  1. package/CHANGELOG.md +54 -1
  2. package/README.md +36 -9
  3. package/dist/agent/act.js +8 -1
  4. package/dist/agent/cli.d.ts +1 -0
  5. package/dist/agent/cli.js +58 -4
  6. package/dist/agent/client.d.ts +8 -1
  7. package/dist/agent/client.js +14 -2
  8. package/dist/agent/decision.d.ts +66 -63
  9. package/dist/agent/decision.js +95 -24
  10. package/dist/agent/decisionValidator.js +41 -1
  11. package/dist/agent/deploymentOverlay.d.ts +22 -0
  12. package/dist/agent/deploymentOverlay.js +55 -0
  13. package/dist/agent/gate.d.ts +9 -0
  14. package/dist/agent/gate.js +114 -0
  15. package/dist/agent/indicators.js +22 -7
  16. package/dist/agent/observe.js +201 -18
  17. package/dist/agent/prompt.d.ts +6 -2
  18. package/dist/agent/prompt.js +116 -26
  19. package/dist/agent/providers.d.ts +6 -0
  20. package/dist/agent/providers.js +89 -12
  21. package/dist/agent/resolve.js +28 -0
  22. package/dist/agent/resolvePm.d.ts +14 -0
  23. package/dist/agent/resolvePm.js +69 -0
  24. package/dist/agent/runner.d.ts +6 -1
  25. package/dist/agent/runner.js +312 -10
  26. package/dist/agent/scorecard.d.ts +24 -0
  27. package/dist/agent/scorecard.js +177 -0
  28. package/dist/agent/setups.d.ts +3 -0
  29. package/dist/agent/setups.js +133 -0
  30. package/dist/agent/skill.d.ts +1 -0
  31. package/dist/agent/skill.js +21 -3
  32. package/dist/agent/skillValidator.js +4 -2
  33. package/dist/agent/state.js +10 -2
  34. package/dist/agent/templates.js +8 -4
  35. package/dist/agent/types.d.ts +75 -2
  36. package/dist/agent/types.js +14 -1
  37. package/dist/agent/version.d.ts +2 -2
  38. package/dist/agent/version.js +12 -2
  39. package/dist/client.d.ts +2 -0
  40. package/dist/tools.js +28 -5
  41. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -3,7 +3,60 @@
3
3
  All notable changes to `@coinrithm/mcp-trading` are documented here. The package
4
4
  ships two binaries — `coinrithm-mcp` (the MCP server) and `coinrithm-agent` (the
5
5
  self-host agent runner) — versioned together. The CoinRithm **API contract** is
6
- versioned separately (see `openapi.yaml` `info.version`, currently `1.4.0`).
6
+ versioned separately (see `openapi.yaml` `info.version`, currently `1.5.0`).
7
+
8
+ ## 0.5.0
9
+
10
+ Agent-runner quality + reliability release. `coinrithm-agent` got materially
11
+ smarter and less noisy; `coinrithm-mcp` is unchanged in shape. Bundles the work
12
+ since 0.4.0.
13
+
14
+ - **Prediction markets are a first-class venue** in the decide prompt: a short
15
+ `pmN` ref so small models trade PM reliably, eligible-outcome filtering (only
16
+ backend-openable outcomes reach the model), and futures-capped agents steered
17
+ to PM (a separate budget) instead of re-rejecting.
18
+ - **PM anti-churn — now actually effective.** The candidate list is pre-filtered
19
+ to exclude markets the agent already holds, and the runner + server both block
20
+ re-betting a held market+outcome (no more one-agent, 25-identical-bets churn).
21
+ An earlier version read the wrong `/positions/pm` fields and was silently dead;
22
+ fixed.
23
+ - **Settlement-feedback learning loop.** The agent sees how its own recent bets
24
+ actually resolved (win/loss/void + realized PnL) as reflective context, so it
25
+ learns from outcomes across cycles.
26
+ - **Per-trade reasoning stays honest about the market.** A multi-action decision
27
+ no longer stamps its primary rationale onto a secondary trade about a different
28
+ market — the trade's public Arena "why" always matches the market it's on.
29
+ - **Futures reliability.** The model is unblinded to per-position mark /
30
+ liquidation / stop / take-profit prices; take-profit is auto-clamped to a valid
31
+ R:R target off the stop (kills the `take_profit_not_*_mark` reject waves); and a
32
+ marking-down PM book now trips the equity-drawdown kill-switch too.
33
+ - **News capability.** Recent high-importance news for the watchlist coins is fed
34
+ into the decide context as a market-catalyst layer.
35
+ - **Robustness + contract accuracy.** Scheduler/runner hardening, flat-state
36
+ prompt steers (weak models stop hallucinating closes), manage-enum
37
+ normalization, and the PM contract now documents real entry friction rather
38
+ than a disclose-only stance.
39
+ - **Security.** `hono` bumped to 4.12.27 (high-severity advisories: serve-static
40
+ path traversal, CORS wildcard-with-credentials, body-limit bypass).
41
+ - **Docs.** The npm README leads with value / free / OKF / Studio; stale
42
+ scheduler and `minDecidedTrades` claims corrected.
43
+
44
+ ## 0.4.0
45
+
46
+ - **Deterministic scorecard engine (`computeScorecard`).** The reproducible-
47
+ evaluation engine for `coinrithm.agent.scorecard.v1` — pure math over an
48
+ agent's realized track record (no network, no model): realized PnL, win rate,
49
+ expectancy, profit factor, reward-to-risk, Sharpe, Sortino, deflated /
50
+ probabilistic Sharpe (Bailey & López de Prado — skill vs luck with a multiple-
51
+ testing penalty), max drawdown, and Brier + ECE calibration for probabilistic
52
+ calls. Same inputs → identical metrics **and** a sha256 `contentHash` of the
53
+ canonicalized result, so a scorecard whose hash doesn't reproduce isn't
54
+ trusted. Metrics are computed AFTER the run from immutable evidence (leakage-
55
+ separation), so tuning-to-the-metric is structurally impossible. Returns
56
+ `null` for thin records — never a fabricated number.
57
+ - **Resolver: committable file metadata + functionality pin.** The OKF resolver
58
+ now carries per-file metadata and pins functionality through resolution, so a
59
+ bundle's behavior is reproducible from its committed files.
7
60
 
8
61
  ## 0.3.0
9
62
 
package/README.md CHANGED
@@ -1,22 +1,45 @@
1
1
  # @coinrithm/mcp-trading
2
2
 
3
- CoinRithm paper-trading toolkit. Two binaries:
3
+ **Deploy an AI trading agent with paper money — for free.** Give any model
4
+ (Claude, GPT, Gemini, Llama…) a 50,000 mUSD virtual account and let it trade
5
+ spot, futures, and prediction markets on
6
+ [CoinRithm](https://coinrithm.com/agentic-trading). No real money, no exchange,
7
+ no risk — a proving ground to show an agent works *before* anything is on the
8
+ line, with a public **Agent Arena** leaderboard ranked by realized paper PnL.
9
+
10
+ Agents are **OKF bundles** — an open, model-agnostic folder of markdown + YAML
11
+ (strategy, persona, hard caps) that any runtime can read. Two ways to run the
12
+ **same** bundle:
13
+
14
+ - **Managed — nothing to install.** Build and deploy an agent in your browser
15
+ with the **Agent Studio** (CoinRithm → My Agents → Studio): fork a house agent
16
+ or write one from scratch, and CoinRithm runs it **free on Llama 3.1 8B**
17
+ (NVIDIA NIM) on an always-on scheduler. The fastest path to a live agent.
18
+ - **Self-host — this package.** Bring your own model key and run the
19
+ `observe→decide→validate→act` loop on your machine, or wire the MCP server
20
+ into Claude Desktop / Cursor / Codex.
21
+
22
+ This package ships two binaries:
4
23
 
5
24
  - **`coinrithm-mcp`** — an MCP server that lets an AI agent paper-trade on
6
25
  CoinRithm (spot, futures, prediction markets) using a personal API key.
7
26
  - **`coinrithm-agent`** — a self-host **agent runner**: author an agent as a
8
- folder and run an observe→decide→validate→act loop with your own model key
9
- (paper: spot, futures, prediction markets). See [Agent runner](#agent-runner-coinrithm-agent) below.
27
+ folder and run an `observe→decide→validate→act` loop with your own model key,
28
+ **dry-run by default**. See [Agent runner](#agent-runner-coinrithm-agent) below.
10
29
 
11
30
  > **Paper trading only** — virtual funds (50,000 mUSD). Not financial advice.
12
31
 
13
- ## Install / build
32
+ ## Quick start
14
33
 
15
34
  ```bash
16
- npm install
17
- npm run build
35
+ # Run the MCP server with your CoinRithm key (no install needed):
36
+ COINRITHM_API_KEY=crk_live_… npx -y @coinrithm/mcp-trading
18
37
  ```
19
38
 
39
+ Get a `crk_live_…` key from CoinRithm → Profile → API Keys. To author and run a
40
+ self-host agent instead, see [Agent runner](#agent-runner-coinrithm-agent).
41
+ Building from source? `npm install && npm run build`.
42
+
20
43
  ## Agent runner (`coinrithm-agent`)
21
44
 
22
45
  This package also ships a **self-host agent runner**. You write an agent as a
@@ -33,8 +56,10 @@ COINRITHM_API_KEY=crk_live_… ANTHROPIC_API_KEY=sk-ant-… \
33
56
  ```
34
57
 
35
58
  Full guide (env vars, fail-closed guarantees, folder layout):
36
- **[docs/agent-runner.md](../../docs/agent-runner.md)**. The CoinRithm hosted
37
- scheduler runs this same engine for you (later).
59
+ **[docs/agent-runner.md](https://github.com/CoinRithm/coinrithm-agent-trading/blob/main/docs/agent-runner.md)**.
60
+ The CoinRithm hosted scheduler runs this same engine for you — see the
61
+ [scheduler README](../../packages/scheduler/README.md) for the built,
62
+ DB-driven runtime.
38
63
 
39
64
  ## Two ways to run
40
65
 
@@ -176,7 +201,9 @@ least that long before retrying.
176
201
 
177
202
  ## Agent Arena
178
203
 
179
- Opted-in agents are publicly ranked by realized PnL (min 3 decided trades) at
204
+ Opted-in agents are publicly ranked by realized PnL every agent with any
205
+ decided (win/loss) trade is listed (a small-sample asterisk flags thin records;
206
+ the live gate is surfaced as `minDecidedTrades` in the response) at
180
207
  [coinrithm.com](https://coinrithm.com/agentic-trading) — set `agentName` /
181
208
  `agentPublic` / `agentModel` on your key to join, then check your standing
182
209
  with `get_arena_leaderboard` / `get_arena_agent`. Pass `window: "7d" | "30d"`
package/dist/agent/act.js CHANGED
@@ -79,6 +79,10 @@ export async function executeAction(client, action, observation, trace, idempote
79
79
  positionId: action.positionId,
80
80
  stopLossPrice: action.stopLossPrice ?? undefined,
81
81
  takeProfitPrice: action.takeProfitPrice ?? undefined,
82
+ // Deterministic key (sltp:<posId>) so a retried cycle can't double-send,
83
+ // consistent with the open/close/place ops. Server-side this op is also
84
+ // idempotent (absolute-value set), so the key is belt-and-braces.
85
+ idempotencyKey,
82
86
  agentTrace: trace,
83
87
  });
84
88
  }
@@ -98,7 +102,10 @@ export async function executeAction(client, action, observation, trace, idempote
98
102
  });
99
103
  }
100
104
  if (action.type === "spot_cancel") {
101
- return client.cancelSpotOrder(action.orderId, trace);
105
+ // Deterministic key (cancel:<orderId>) so a retried cycle can't double-send,
106
+ // consistent with the open/place ops. Server-side a re-cancel is a no-op, so
107
+ // the key is belt-and-braces.
108
+ return client.cancelSpotOrder(action.orderId, idempotencyKey, trace);
102
109
  }
103
110
  if (action.type === "pm_open") {
104
111
  return client.openPmPosition({
@@ -13,6 +13,7 @@ export declare function cmdValidate(path: string, mode?: SkillValidationMode): C
13
13
  export declare function cmdLock(path: string): CmdResult;
14
14
  export declare function cmdEject(path: string): CmdResult;
15
15
  export declare function cmdInspect(path: string, json?: boolean): CmdResult;
16
+ export declare function acquireLock(stateFile: string): (() => void) | null;
16
17
  export declare function cmdRun(path: string, opts?: {
17
18
  once?: boolean;
18
19
  live?: boolean;
package/dist/agent/cli.js CHANGED
@@ -192,17 +192,52 @@ export function cmdInspect(path, json = false) {
192
192
  ];
193
193
  return { ok: v.valid, code: 0, lines, data: output };
194
194
  }
195
+ // Is a process still alive? signal 0 probes without sending — ESRCH means it's
196
+ // gone, EPERM means it exists but we can't signal it (still alive). Unknown PIDs
197
+ // (NaN / non-positive) are treated as alive so we never reclaim a malformed lock.
198
+ function pidIsAlive(pid) {
199
+ if (!Number.isInteger(pid) || pid <= 0)
200
+ return true;
201
+ try {
202
+ process.kill(pid, 0);
203
+ return true;
204
+ }
205
+ catch (e) {
206
+ return e.code !== "ESRCH";
207
+ }
208
+ }
195
209
  // Acquire an exclusive per-agent run lock (O_EXCL). Returns a release fn, or
196
- // null if another runner already holds it — so two runners can't race one
197
- // state file and bypass the daily / write caps.
198
- function acquireLock(stateFile) {
210
+ // null if another LIVE runner already holds it — so two runners can't race one
211
+ // state file and bypass the daily / write caps. Stale-aware: if the existing
212
+ // lock names a PID that is no longer alive (the prior runner was Ctrl-C'd /
213
+ // killed without unwinding its finally), the orphaned lock is reclaimed instead
214
+ // of trapping every subsequent `run` until a manual delete.
215
+ export function acquireLock(stateFile) {
199
216
  const lock = `${stateFile}.lock`;
200
217
  let fd;
201
218
  try {
202
219
  fd = openSync(lock, "wx");
203
220
  }
204
221
  catch {
205
- return null;
222
+ // Lock exists. Reclaim it only if its owner PID is provably dead.
223
+ let ownerAlive = true;
224
+ try {
225
+ const prior = JSON.parse(readFileSync(lock, "utf8"));
226
+ ownerAlive = pidIsAlive(Number(prior?.pid));
227
+ }
228
+ catch {
229
+ // Unreadable / unparseable lock — treat as held (conservative).
230
+ return null;
231
+ }
232
+ if (ownerAlive)
233
+ return null;
234
+ try {
235
+ unlinkSync(lock);
236
+ fd = openSync(lock, "wx"); // re-acquire; if we lose a race, bail out.
237
+ }
238
+ catch {
239
+ return null;
240
+ }
206
241
  }
207
242
  try {
208
243
  writeFileSync(fd, JSON.stringify({ pid: process.pid }));
@@ -210,7 +245,11 @@ function acquireLock(stateFile) {
210
245
  catch {
211
246
  /* best effort */
212
247
  }
248
+ let released = false;
213
249
  return () => {
250
+ if (released)
251
+ return;
252
+ released = true;
214
253
  try {
215
254
  closeSync(fd);
216
255
  }
@@ -253,6 +292,19 @@ export async function cmdRun(path, opts = {}) {
253
292
  if (!release) {
254
293
  return fail([`another runner holds ${stateFile}.lock — only one runner per agent at a time`]);
255
294
  }
295
+ // A self-host `run` is a cadence-paced loop users stop with Ctrl-C. Node exits
296
+ // on SIGINT/SIGTERM WITHOUT unwinding the finally across the awaited loop, so
297
+ // free the lock from a signal handler too (otherwise every later run is
298
+ // trapped on the orphaned .lock). Removed in the finally so repeated in-proc
299
+ // runs (tests) don't leak listeners; re-exit preserves normal Ctrl-C exit.
300
+ const onSignal = (sig) => {
301
+ release();
302
+ process.removeListener("SIGINT", onSignal);
303
+ process.removeListener("SIGTERM", onSignal);
304
+ process.kill(process.pid, sig);
305
+ };
306
+ process.on("SIGINT", onSignal);
307
+ process.on("SIGTERM", onSignal);
256
308
  try {
257
309
  let state;
258
310
  try {
@@ -297,6 +349,8 @@ export async function cmdRun(path, opts = {}) {
297
349
  return { ok: true, code: 0, lines, data: results };
298
350
  }
299
351
  finally {
352
+ process.removeListener("SIGINT", onSignal);
353
+ process.removeListener("SIGTERM", onSignal);
300
354
  release();
301
355
  }
302
356
  }
@@ -52,6 +52,12 @@ export declare class CoinRithmClient {
52
52
  source?: string;
53
53
  limit?: number;
54
54
  }, trace?: AgentTrace): Promise<ApiResult>;
55
+ agentNews(query: {
56
+ coins: string;
57
+ limit?: number;
58
+ hours?: number;
59
+ minImportance?: number;
60
+ }, trace?: AgentTrace): Promise<ApiResult>;
55
61
  pmPositions(query?: {
56
62
  updatedSince?: string;
57
63
  }, trace?: AgentTrace): Promise<ApiResult>;
@@ -81,6 +87,7 @@ export declare class CoinRithmClient {
81
87
  positionId: number;
82
88
  stopLossPrice?: number | null;
83
89
  takeProfitPrice?: number | null;
90
+ idempotencyKey?: string;
84
91
  agentTrace?: AgentTrace;
85
92
  }): Promise<ApiResult>;
86
93
  placeSpotOrder(body: {
@@ -93,7 +100,7 @@ export declare class CoinRithmClient {
93
100
  idempotencyKey: string;
94
101
  agentTrace?: AgentTrace;
95
102
  }): Promise<ApiResult>;
96
- cancelSpotOrder(orderId: number, trace?: AgentTrace): Promise<ApiResult>;
103
+ cancelSpotOrder(orderId: number, idempotencyKey?: string, trace?: AgentTrace): Promise<ApiResult>;
97
104
  openPmPosition(body: {
98
105
  source: string;
99
106
  slug: string;
@@ -136,6 +136,15 @@ export class CoinRithmClient {
136
136
  discoverPmMarkets(query, trace) {
137
137
  return this.request("GET", "/api/agent/pm/discover", { query, trace });
138
138
  }
139
+ agentNews(query, trace) {
140
+ return this.request("GET", "/api/agent/news", { query, trace });
141
+ }
142
+ // GET /api/agent/positions/pm. Response (data: unknown — parsed defensively in
143
+ // observe): { positions: [...open + unrealized mark...], recentlyResolved: [...
144
+ // the caller's OWN bets that settled win/loss/void with realized pnl since the
145
+ // delta cursor; settlement-feedback loop...], updatedSince, asOf }. The
146
+ // `recentlyResolved` array is ADDITIVE (older backends omit it → observe degrades
147
+ // to []); the open `positions` shape is unchanged.
139
148
  pmPositions(query, trace) {
140
149
  return this.request("GET", "/api/agent/positions/pm", { query, trace });
141
150
  }
@@ -155,8 +164,11 @@ export class CoinRithmClient {
155
164
  placeSpotOrder(body) {
156
165
  return this.request("POST", "/api/agent/spot/order", { body });
157
166
  }
158
- cancelSpotOrder(orderId, trace) {
159
- return this.request("POST", `/api/agent/spot/order/${orderId}/cancel`, { trace });
167
+ cancelSpotOrder(orderId, idempotencyKey, trace) {
168
+ return this.request("POST", `/api/agent/spot/order/${orderId}/cancel`, {
169
+ body: idempotencyKey !== undefined ? { idempotencyKey } : undefined,
170
+ trace,
171
+ });
160
172
  }
161
173
  openPmPosition(body) {
162
174
  return this.request("POST", "/api/agent/pm/open", { body });
@@ -4,128 +4,131 @@ export declare const actionSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<
4
4
  type: z.ZodLiteral<"futures_open">;
5
5
  symbol: z.ZodString;
6
6
  side: z.ZodEnum<["long", "short"]>;
7
- leverage: z.ZodNumber;
8
- marginMusd: z.ZodNumber;
9
- stopLossPrice: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
10
- takeProfitPrice: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
11
- confidence: z.ZodOptional<z.ZodNumber>;
7
+ leverage: z.ZodEffects<z.ZodTypeAny, any, unknown>;
8
+ marginMusd: z.ZodEffects<z.ZodTypeAny, any, unknown>;
9
+ stopLossPrice: z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodTypeAny, any, unknown>>>;
10
+ takeProfitPrice: z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodTypeAny, any, unknown>>>;
11
+ confidence: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodTypeAny, any, unknown>>>, any, unknown>;
12
12
  rationaleSummary: z.ZodOptional<z.ZodString>;
13
13
  }, "strict", z.ZodTypeAny, {
14
14
  symbol: string;
15
15
  side: "long" | "short";
16
- leverage: number;
17
- marginMusd: number;
18
16
  type: "futures_open";
19
- stopLossPrice?: number | null | undefined;
20
- takeProfitPrice?: number | null | undefined;
21
- confidence?: number | undefined;
17
+ leverage?: any;
18
+ marginMusd?: any;
19
+ stopLossPrice?: any;
20
+ takeProfitPrice?: any;
21
+ confidence?: any;
22
22
  rationaleSummary?: string | undefined;
23
23
  }, {
24
24
  symbol: string;
25
25
  side: "long" | "short";
26
- leverage: number;
27
- marginMusd: number;
28
26
  type: "futures_open";
29
- stopLossPrice?: number | null | undefined;
30
- takeProfitPrice?: number | null | undefined;
31
- confidence?: number | undefined;
27
+ leverage?: unknown;
28
+ marginMusd?: unknown;
29
+ stopLossPrice?: unknown;
30
+ takeProfitPrice?: unknown;
31
+ confidence?: unknown;
32
32
  rationaleSummary?: string | undefined;
33
33
  }>, z.ZodObject<{
34
34
  type: z.ZodLiteral<"futures_close">;
35
- positionId: z.ZodNumber;
36
- fraction: z.ZodOptional<z.ZodNumber>;
37
- confidence: z.ZodOptional<z.ZodNumber>;
35
+ positionId: z.ZodEffects<z.ZodTypeAny, any, unknown>;
36
+ fraction: z.ZodOptional<z.ZodEffects<z.ZodTypeAny, any, unknown>>;
37
+ confidence: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodTypeAny, any, unknown>>>, any, unknown>;
38
38
  rationaleSummary: z.ZodOptional<z.ZodString>;
39
39
  }, "strict", z.ZodTypeAny, {
40
- positionId: number;
41
40
  type: "futures_close";
42
- fraction?: number | undefined;
43
- confidence?: number | undefined;
41
+ positionId?: any;
42
+ fraction?: any;
43
+ confidence?: any;
44
44
  rationaleSummary?: string | undefined;
45
45
  }, {
46
- positionId: number;
47
46
  type: "futures_close";
48
- fraction?: number | undefined;
49
- confidence?: number | undefined;
47
+ positionId?: unknown;
48
+ fraction?: unknown;
49
+ confidence?: unknown;
50
50
  rationaleSummary?: string | undefined;
51
51
  }>, z.ZodObject<{
52
52
  type: z.ZodLiteral<"futures_set_sltp">;
53
- positionId: z.ZodNumber;
54
- stopLossPrice: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
55
- takeProfitPrice: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
53
+ positionId: z.ZodEffects<z.ZodTypeAny, any, unknown>;
54
+ stopLossPrice: z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodTypeAny, any, unknown>>>;
55
+ takeProfitPrice: z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodTypeAny, any, unknown>>>;
56
56
  }, "strict", z.ZodTypeAny, {
57
- positionId: number;
58
57
  type: "futures_set_sltp";
59
- stopLossPrice?: number | null | undefined;
60
- takeProfitPrice?: number | null | undefined;
58
+ stopLossPrice?: any;
59
+ takeProfitPrice?: any;
60
+ positionId?: any;
61
61
  }, {
62
- positionId: number;
63
62
  type: "futures_set_sltp";
64
- stopLossPrice?: number | null | undefined;
65
- takeProfitPrice?: number | null | undefined;
63
+ stopLossPrice?: unknown;
64
+ takeProfitPrice?: unknown;
65
+ positionId?: unknown;
66
66
  }>, z.ZodObject<{
67
67
  type: z.ZodLiteral<"spot_order">;
68
68
  symbol: z.ZodString;
69
69
  side: z.ZodEnum<["buy", "sell"]>;
70
70
  orderType: z.ZodEnum<["market", "limit", "stop"]>;
71
- quantity: z.ZodNumber;
72
- limitPrice: z.ZodOptional<z.ZodNumber>;
73
- stopPrice: z.ZodOptional<z.ZodNumber>;
74
- confidence: z.ZodOptional<z.ZodNumber>;
71
+ quantity: z.ZodEffects<z.ZodTypeAny, any, unknown>;
72
+ limitPrice: z.ZodOptional<z.ZodEffects<z.ZodTypeAny, any, unknown>>;
73
+ stopPrice: z.ZodOptional<z.ZodEffects<z.ZodTypeAny, any, unknown>>;
74
+ confidence: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodTypeAny, any, unknown>>>, any, unknown>;
75
75
  rationaleSummary: z.ZodOptional<z.ZodString>;
76
76
  }, "strict", z.ZodTypeAny, {
77
77
  symbol: string;
78
78
  side: "buy" | "sell";
79
79
  orderType: "limit" | "market" | "stop";
80
- quantity: number;
81
80
  type: "spot_order";
82
- limitPrice?: number | undefined;
83
- stopPrice?: number | undefined;
84
- confidence?: number | undefined;
81
+ quantity?: any;
82
+ limitPrice?: any;
83
+ stopPrice?: any;
84
+ confidence?: any;
85
85
  rationaleSummary?: string | undefined;
86
86
  }, {
87
87
  symbol: string;
88
88
  side: "buy" | "sell";
89
89
  orderType: "limit" | "market" | "stop";
90
- quantity: number;
91
90
  type: "spot_order";
92
- limitPrice?: number | undefined;
93
- stopPrice?: number | undefined;
94
- confidence?: number | undefined;
91
+ quantity?: unknown;
92
+ limitPrice?: unknown;
93
+ stopPrice?: unknown;
94
+ confidence?: unknown;
95
95
  rationaleSummary?: string | undefined;
96
96
  }>, z.ZodObject<{
97
97
  type: z.ZodLiteral<"spot_cancel">;
98
- orderId: z.ZodNumber;
98
+ orderId: z.ZodEffects<z.ZodTypeAny, any, unknown>;
99
99
  }, "strict", z.ZodTypeAny, {
100
100
  type: "spot_cancel";
101
- orderId: number;
101
+ orderId?: any;
102
102
  }, {
103
103
  type: "spot_cancel";
104
- orderId: number;
104
+ orderId?: unknown;
105
105
  }>, z.ZodObject<{
106
106
  type: z.ZodLiteral<"pm_open">;
107
- source: z.ZodString;
108
- slug: z.ZodString;
109
- outcomeExternalMarketId: z.ZodString;
110
- stakeMusd: z.ZodNumber;
111
- confidence: z.ZodOptional<z.ZodNumber>;
107
+ ref: z.ZodOptional<z.ZodString>;
108
+ source: z.ZodOptional<z.ZodString>;
109
+ slug: z.ZodOptional<z.ZodString>;
110
+ outcomeExternalMarketId: z.ZodOptional<z.ZodString>;
111
+ stakeMusd: z.ZodEffects<z.ZodTypeAny, any, unknown>;
112
+ confidence: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodTypeAny, any, unknown>>>, any, unknown>;
112
113
  rationaleSummary: z.ZodOptional<z.ZodString>;
113
114
  }, "strict", z.ZodTypeAny, {
114
- source: string;
115
- slug: string;
116
- outcomeExternalMarketId: string;
117
- stakeMusd: number;
118
115
  type: "pm_open";
119
- confidence?: number | undefined;
116
+ source?: string | undefined;
117
+ slug?: string | undefined;
118
+ outcomeExternalMarketId?: string | undefined;
119
+ stakeMusd?: any;
120
+ confidence?: any;
120
121
  rationaleSummary?: string | undefined;
122
+ ref?: string | undefined;
121
123
  }, {
122
- source: string;
123
- slug: string;
124
- outcomeExternalMarketId: string;
125
- stakeMusd: number;
126
124
  type: "pm_open";
127
- confidence?: number | undefined;
125
+ source?: string | undefined;
126
+ slug?: string | undefined;
127
+ outcomeExternalMarketId?: string | undefined;
128
+ stakeMusd?: unknown;
129
+ confidence?: unknown;
128
130
  rationaleSummary?: string | undefined;
131
+ ref?: string | undefined;
129
132
  }>]>;
130
133
  export type ParseDecisionResult = {
131
134
  ok: true;