@senpi/runtime 3.0.9-dev.20260710204324 → 3.0.9-dev.feat-strategy-compos.20260716233548

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 (108) hide show
  1. package/dist/cli/composer-commands.d.ts +37 -0
  2. package/dist/cli/composer-commands.d.ts.map +1 -0
  3. package/dist/cli/composer-commands.js +396 -0
  4. package/dist/cli/composer-commands.js.map +1 -0
  5. package/dist/cli/senpi-commands.d.ts.map +1 -1
  6. package/dist/cli/senpi-commands.js +2 -0
  7. package/dist/cli/senpi-commands.js.map +1 -1
  8. package/dist/cli/validate-runtime-config.mjs +190 -0
  9. package/dist/composer/AUTHORING.md +435 -0
  10. package/dist/composer/__init__.py +29 -0
  11. package/dist/composer/authoring/__init__.py +59 -0
  12. package/dist/composer/authoring/answers.py +297 -0
  13. package/dist/composer/authoring/archetypes/__init__.py +26 -0
  14. package/dist/composer/authoring/archetypes/_common.py +410 -0
  15. package/dist/composer/authoring/archetypes/breakout.py +134 -0
  16. package/dist/composer/authoring/archetypes/classifier.py +109 -0
  17. package/dist/composer/authoring/archetypes/skeleton.py +76 -0
  18. package/dist/composer/authoring/archetypes/thesis_fund.py +103 -0
  19. package/dist/composer/authoring/archetypes/trend_momentum.py +132 -0
  20. package/dist/composer/authoring/builder.py +191 -0
  21. package/dist/composer/authoring/emit.py +264 -0
  22. package/dist/composer/authoring/gaps.py +115 -0
  23. package/dist/composer/authoring/generate.py +131 -0
  24. package/dist/composer/authoring/presets.py +168 -0
  25. package/dist/composer/authoring/runtime_emit.py +266 -0
  26. package/dist/composer/authoring/strategy_manifest.py +94 -0
  27. package/dist/composer/cli.py +487 -0
  28. package/dist/composer/compiler/__init__.py +22 -0
  29. package/dist/composer/compiler/compile.py +739 -0
  30. package/dist/composer/examples/breakout_swing.graph.yaml +121 -0
  31. package/dist/composer/examples/conviction_scorer.graph.yaml +216 -0
  32. package/dist/composer/examples/macro_thesis_basket.graph.yaml +247 -0
  33. package/dist/composer/examples/pre_listing_classifier.graph.yaml +204 -0
  34. package/dist/composer/examples/trend_momentum_majors.graph.yaml +133 -0
  35. package/dist/composer/generated/README.md +22 -0
  36. package/dist/composer/generated/catalog.md +118 -0
  37. package/dist/composer/generated/describe.md +1168 -0
  38. package/dist/composer/generated/graph.schema.json +1946 -0
  39. package/dist/composer/primitives/__init__.py +320 -0
  40. package/dist/composer/primitives/_candles.py +76 -0
  41. package/dist/composer/primitives/adapter.py +363 -0
  42. package/dist/composer/primitives/emitters.py +142 -0
  43. package/dist/composer/primitives/filters.py +71 -0
  44. package/dist/composer/primitives/indicators.py +326 -0
  45. package/dist/composer/primitives/rankers.py +40 -0
  46. package/dist/composer/primitives/scorers.py +100 -0
  47. package/dist/composer/primitives/sources.py +979 -0
  48. package/dist/composer/primitives/stateful.py +254 -0
  49. package/dist/composer/pure_fn/__init__.py +34 -0
  50. package/dist/composer/pure_fn/checks.py +39 -0
  51. package/dist/composer/pure_fn/models.py +177 -0
  52. package/dist/composer/pure_fn/purity.py +311 -0
  53. package/dist/composer/pure_fn/runtests.py +155 -0
  54. package/dist/composer/registry/__init__.py +40 -0
  55. package/dist/composer/registry/generate.py +425 -0
  56. package/dist/composer/registry/mcp-tools-snapshot.json +193 -0
  57. package/dist/composer/registry/mcp_closure.py +311 -0
  58. package/dist/composer/registry/models.py +417 -0
  59. package/dist/composer/registry/nodes.py +1297 -0
  60. package/dist/composer/requirements.txt +21 -0
  61. package/dist/composer/scaffold_path.py +118 -0
  62. package/dist/composer/templates/__init__.py +13 -0
  63. package/dist/composer/templates/scan.py.j2 +34 -0
  64. package/dist/composer/validator/__init__.py +29 -0
  65. package/dist/composer/validator/desugar.py +133 -0
  66. package/dist/composer/validator/errors.py +227 -0
  67. package/dist/composer/validator/graph_checks.py +443 -0
  68. package/dist/composer/validator/loader.py +110 -0
  69. package/dist/composer/validator/schema_checks.py +147 -0
  70. package/dist/composer/validator/validate.py +86 -0
  71. package/dist/composer/vendoring.py +103 -0
  72. package/dist/composer/verbs/__init__.py +49 -0
  73. package/dist/composer/verbs/_box.py +308 -0
  74. package/dist/composer/verbs/check.py +254 -0
  75. package/dist/composer/verbs/close.py +494 -0
  76. package/dist/composer/verbs/deploy.py +279 -0
  77. package/dist/composer/verbs/docs.py +30 -0
  78. package/dist/composer/verbs/fund.py +498 -0
  79. package/dist/composer/verbs/install.py +586 -0
  80. package/dist/composer/verbs/runtime_validate.py +422 -0
  81. package/dist/composer/verbs/smoke.py +134 -0
  82. package/dist/composer/verbs/status.py +383 -0
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +2 -9
  85. package/dist/index.js.map +1 -1
  86. package/dist/runtime/load-runtime-config.d.ts +17 -0
  87. package/dist/runtime/load-runtime-config.d.ts.map +1 -1
  88. package/dist/runtime/load-runtime-config.js +2 -2
  89. package/dist/runtime/load-runtime-config.js.map +1 -1
  90. package/dist/runtime-api/config.d.ts +2 -2
  91. package/dist/runtime-api/config.js +4 -4
  92. package/dist/runtime-api/config.js.map +1 -1
  93. package/dist/runtime-api/handlers/ingest-signals.d.ts +3 -5
  94. package/dist/runtime-api/handlers/ingest-signals.d.ts.map +1 -1
  95. package/dist/runtime-api/handlers/ingest-signals.js +5 -14
  96. package/dist/runtime-api/handlers/ingest-signals.js.map +1 -1
  97. package/dist/runtime-api/intake/intake-mount.d.ts.map +1 -1
  98. package/dist/runtime-api/intake/intake-mount.js +2 -8
  99. package/dist/runtime-api/intake/intake-mount.js.map +1 -1
  100. package/dist/skills-manager/manifest.d.ts.map +1 -1
  101. package/dist/skills-manager/manifest.js +1 -3
  102. package/dist/skills-manager/manifest.js.map +1 -1
  103. package/dist/skills-manager/skills-manifest.json +1 -3
  104. package/package.json +4 -2
  105. package/dist/runtime-api/intake/ingest-mutex.d.ts +0 -16
  106. package/dist/runtime-api/intake/ingest-mutex.d.ts.map +0 -1
  107. package/dist/runtime-api/intake/ingest-mutex.js +0 -18
  108. package/dist/runtime-api/intake/ingest-mutex.js.map +0 -1
@@ -0,0 +1,1946 @@
1
+ {
2
+ "$defs": {
3
+ "params_acceleration": {
4
+ "additionalProperties": false,
5
+ "properties": {
6
+ "interval": {
7
+ "default": "4h",
8
+ "description": "Candle interval to read.",
9
+ "type": "string"
10
+ },
11
+ "long_window": {
12
+ "default": 6,
13
+ "description": "Long move window.",
14
+ "minimum": 2.0,
15
+ "type": "integer"
16
+ },
17
+ "short_window": {
18
+ "default": 3,
19
+ "description": "Short move window.",
20
+ "minimum": 1.0,
21
+ "type": "integer"
22
+ }
23
+ },
24
+ "type": "object"
25
+ },
26
+ "params_account_history_fetch": {
27
+ "additionalProperties": false,
28
+ "properties": {
29
+ "bucket_duration_ms": {
30
+ "default": 3600000,
31
+ "description": "History bucket granularity in ms (1h=3600000 default; 6h=21600000; 24h=86400000).",
32
+ "maximum": 604800000.0,
33
+ "minimum": 60000.0,
34
+ "type": "integer"
35
+ }
36
+ },
37
+ "type": "object"
38
+ },
39
+ "params_aggregate_bias": {
40
+ "additionalProperties": false,
41
+ "properties": {},
42
+ "type": "object"
43
+ },
44
+ "params_arena_leaderboard_fetch": {
45
+ "additionalProperties": false,
46
+ "properties": {
47
+ "limit": {
48
+ "default": 100,
49
+ "description": "Maximum entries to return (1-500, default 100).",
50
+ "maximum": 500.0,
51
+ "minimum": 1.0,
52
+ "type": "integer"
53
+ },
54
+ "offset": {
55
+ "default": 0,
56
+ "description": "Entries to skip for pagination (default 0).",
57
+ "minimum": 0.0,
58
+ "type": "integer"
59
+ },
60
+ "period_number": {
61
+ "default": 0,
62
+ "description": "Week/month number to query; 0 = current active period (omitted server-side).",
63
+ "minimum": 0.0,
64
+ "type": "integer"
65
+ },
66
+ "period_type": {
67
+ "default": "WEEK",
68
+ "description": "Arena period type (WEEK or MONTH; default WEEK).",
69
+ "enum": [
70
+ "WEEK",
71
+ "MONTH"
72
+ ],
73
+ "type": "string"
74
+ },
75
+ "qualified": {
76
+ "default": false,
77
+ "description": "Only return prize-eligible (qualified) agents; false = all enrolled.",
78
+ "type": "boolean"
79
+ }
80
+ },
81
+ "type": "object"
82
+ },
83
+ "params_asset_trading_limits_fetch": {
84
+ "additionalProperties": false,
85
+ "properties": {
86
+ "dex": {
87
+ "default": "",
88
+ "description": "Venue filter (e.g. 'xyz'); empty means the default venue.",
89
+ "type": "string"
90
+ }
91
+ },
92
+ "type": "object"
93
+ },
94
+ "params_breakout_detect": {
95
+ "additionalProperties": false,
96
+ "properties": {
97
+ "interval": {
98
+ "default": "1h",
99
+ "description": "Candle interval to read.",
100
+ "type": "string"
101
+ },
102
+ "window": {
103
+ "default": 168,
104
+ "description": "Prior-close window (hawk 168h).",
105
+ "minimum": 2.0,
106
+ "type": "integer"
107
+ }
108
+ },
109
+ "type": "object"
110
+ },
111
+ "params_candles_fetch": {
112
+ "additionalProperties": false,
113
+ "properties": {
114
+ "include_asset_context": {
115
+ "default": false,
116
+ "description": "Also fetch markPx/prevDayPx asset_context (thesis-fund 24h return).",
117
+ "type": "boolean"
118
+ },
119
+ "include_funding": {
120
+ "default": false,
121
+ "description": "Also fetch funding series (bison funding-alignment).",
122
+ "type": "boolean"
123
+ },
124
+ "intervals": {
125
+ "default": [
126
+ "4h"
127
+ ],
128
+ "description": "Candle intervals to fetch (stag 4h; hawk 1h+4h; bison 15m/1h/4h).",
129
+ "items": {
130
+ "type": "string"
131
+ },
132
+ "type": "array"
133
+ },
134
+ "whitelist": {
135
+ "default": [],
136
+ "description": "Static universe used when no `assets` input is wired (stag whitelist).",
137
+ "items": {
138
+ "type": "string"
139
+ },
140
+ "type": "array"
141
+ }
142
+ },
143
+ "type": "object"
144
+ },
145
+ "params_classifier_predicate": {
146
+ "additionalProperties": false,
147
+ "properties": {
148
+ "exclude_delisted": {
149
+ "default": true,
150
+ "description": "Drop delisted instruments.",
151
+ "type": "boolean"
152
+ },
153
+ "max_funding_abs": {
154
+ "default": 1e-07,
155
+ "description": "Reject if |funding| exceeds this (magpie 1e-7).",
156
+ "minimum": 0.0,
157
+ "type": "number"
158
+ },
159
+ "max_leverage": {
160
+ "default": 5.0,
161
+ "description": "Reject if venue max leverage exceeds this (magpie <=5).",
162
+ "minimum": 1.0,
163
+ "type": "number"
164
+ }
165
+ },
166
+ "type": "object"
167
+ },
168
+ "params_clearinghouse_state": {
169
+ "additionalProperties": false,
170
+ "properties": {},
171
+ "type": "object"
172
+ },
173
+ "params_cohort_cache_state": {
174
+ "additionalProperties": false,
175
+ "properties": {
176
+ "ttl_hours": {
177
+ "default": 24.0,
178
+ "description": "Refresh the stored cohort when it is older than this (whalehunter 24h).",
179
+ "minimum": 0.0,
180
+ "type": "number"
181
+ },
182
+ "version": {
183
+ "default": 1,
184
+ "description": "Config/logic version; a change busts the cache (whalehunter CACHE_VERSION).",
185
+ "minimum": 0.0,
186
+ "type": "integer"
187
+ }
188
+ },
189
+ "type": "object"
190
+ },
191
+ "params_cross_asset_flows_fetch": {
192
+ "additionalProperties": false,
193
+ "properties": {
194
+ "leader_asset": {
195
+ "default": "BTC",
196
+ "description": "The asset that moved first (default BTC \u2014 usually the only one with lag data).",
197
+ "type": "string"
198
+ },
199
+ "min_move_pct": {
200
+ "default": 2.0,
201
+ "description": "Minimum leader move percent to trigger detection (default 2%).",
202
+ "minimum": 0.0,
203
+ "type": "number"
204
+ },
205
+ "window": {
206
+ "default": "4h",
207
+ "description": "Window to check for the leader move (default '4h').",
208
+ "type": "string"
209
+ }
210
+ },
211
+ "type": "object"
212
+ },
213
+ "params_emit_single_best": {
214
+ "additionalProperties": false,
215
+ "properties": {
216
+ "min_score": {
217
+ "default": 0.0,
218
+ "description": "Floor below which nothing is emitted.",
219
+ "type": "number"
220
+ }
221
+ },
222
+ "type": "object"
223
+ },
224
+ "params_funding_history_fetch": {
225
+ "additionalProperties": false,
226
+ "properties": {
227
+ "asset": {
228
+ "default": "",
229
+ "description": "Single asset symbol; empty = all assets with extreme funding.",
230
+ "type": "string"
231
+ },
232
+ "min_annualized_pct": {
233
+ "default": 20.0,
234
+ "description": "Minimum absolute annualized funding rate to include (default 20%).",
235
+ "minimum": 0.0,
236
+ "type": "number"
237
+ },
238
+ "min_persistence_hours": {
239
+ "default": 0.0,
240
+ "description": "Minimum hours funding has persisted in the same direction (default 0).",
241
+ "minimum": 0.0,
242
+ "type": "number"
243
+ }
244
+ },
245
+ "type": "object"
246
+ },
247
+ "params_funding_regime_fetch": {
248
+ "additionalProperties": false,
249
+ "properties": {},
250
+ "type": "object"
251
+ },
252
+ "params_hard_gates_all": {
253
+ "additionalProperties": false,
254
+ "properties": {
255
+ "min_score": {
256
+ "default": 0.0,
257
+ "description": "Minimum score to keep the candidate.",
258
+ "minimum": 0.0,
259
+ "type": "number"
260
+ },
261
+ "required_gates": {
262
+ "default": [],
263
+ "description": "Feature keys that must ALL be truthy (stag's 5 gates).",
264
+ "items": {
265
+ "type": "string"
266
+ },
267
+ "type": "array"
268
+ },
269
+ "weights": {
270
+ "additionalProperties": {
271
+ "type": "number"
272
+ },
273
+ "default": {},
274
+ "description": "Feature-key -> weight for the weighted-sum score (bespoke edge slot).",
275
+ "type": "object"
276
+ }
277
+ },
278
+ "type": "object"
279
+ },
280
+ "params_held_asset_exclusion": {
281
+ "additionalProperties": false,
282
+ "properties": {},
283
+ "type": "object"
284
+ },
285
+ "params_instrument_list": {
286
+ "additionalProperties": false,
287
+ "properties": {
288
+ "dex": {
289
+ "default": "",
290
+ "description": "Venue filter (e.g. 'xyz'); empty means all venues (magpie uses 'xyz').",
291
+ "type": "string"
292
+ }
293
+ },
294
+ "type": "object"
295
+ },
296
+ "params_leaderboard_top_fetch": {
297
+ "additionalProperties": false,
298
+ "properties": {
299
+ "limit": {
300
+ "default": 100,
301
+ "description": "Top traders to return by 4h delta-PnL DESC (1-500, default 100).",
302
+ "maximum": 500.0,
303
+ "minimum": 1.0,
304
+ "type": "integer"
305
+ }
306
+ },
307
+ "type": "object"
308
+ },
309
+ "params_leaderboard_trader_fetch": {
310
+ "additionalProperties": false,
311
+ "properties": {
312
+ "trader_id": {
313
+ "description": "The trader's Ethereum address (required).",
314
+ "type": "string"
315
+ }
316
+ },
317
+ "required": [
318
+ "trader_id"
319
+ ],
320
+ "type": "object"
321
+ },
322
+ "params_live_instrument_validation": {
323
+ "additionalProperties": false,
324
+ "properties": {},
325
+ "type": "object"
326
+ },
327
+ "params_market_prices_fetch": {
328
+ "additionalProperties": false,
329
+ "properties": {
330
+ "dex": {
331
+ "default": "",
332
+ "description": "Venue filter (e.g. 'xyz'); empty means the default venue.",
333
+ "type": "string"
334
+ }
335
+ },
336
+ "type": "object"
337
+ },
338
+ "params_mcp_read": {
339
+ "additionalProperties": false,
340
+ "properties": {
341
+ "args": {
342
+ "default": {},
343
+ "description": "Arguments passed verbatim (snake_case) to the tool; {} for a zero-arg read.",
344
+ "type": "object"
345
+ },
346
+ "timeout_seconds": {
347
+ "default": 0.0,
348
+ "description": "Advisory per-read timeout hint; 0 = use the client default (transport timeouts are owned by the scaffold MCP client).",
349
+ "maximum": 120.0,
350
+ "minimum": 0.0,
351
+ "type": "number"
352
+ },
353
+ "tool": {
354
+ "description": "MCP read tool name; must be in the committed snapshot and not a mutation.",
355
+ "type": "string"
356
+ }
357
+ },
358
+ "required": [
359
+ "tool"
360
+ ],
361
+ "type": "object"
362
+ },
363
+ "params_momentum_events_fetch": {
364
+ "additionalProperties": false,
365
+ "properties": {
366
+ "asset": {
367
+ "default": "",
368
+ "description": "Filter by asset symbol (case-insensitive); empty = all assets.",
369
+ "type": "string"
370
+ },
371
+ "from_time": {
372
+ "default": "",
373
+ "description": "ISO-8601 start (maps to the tool's `from`); empty = server default (4h ago).",
374
+ "type": "string"
375
+ },
376
+ "limit": {
377
+ "default": 50,
378
+ "description": "Maximum events to return, most recent first (1-200, default 50).",
379
+ "maximum": 200.0,
380
+ "minimum": 1.0,
381
+ "type": "integer"
382
+ },
383
+ "tier": {
384
+ "default": 0,
385
+ "description": "Filter by notification tier (1|2|3); 0 = all tiers (omitted server-side).",
386
+ "maximum": 3.0,
387
+ "minimum": 0.0,
388
+ "type": "integer"
389
+ },
390
+ "to_time": {
391
+ "default": "",
392
+ "description": "ISO-8601 end (maps to the tool's `to`); empty = server default (now).",
393
+ "type": "string"
394
+ }
395
+ },
396
+ "type": "object"
397
+ },
398
+ "params_open_orders_fetch": {
399
+ "additionalProperties": false,
400
+ "properties": {},
401
+ "type": "object"
402
+ },
403
+ "params_open_positions_realized_pnl_fetch": {
404
+ "additionalProperties": false,
405
+ "properties": {
406
+ "latest": {
407
+ "default": false,
408
+ "description": "Bust the 10-min cache and fetch fresh from ClickHouse.",
409
+ "type": "boolean"
410
+ }
411
+ },
412
+ "type": "object"
413
+ },
414
+ "params_own_return_24h": {
415
+ "additionalProperties": false,
416
+ "properties": {},
417
+ "type": "object"
418
+ },
419
+ "params_pct_change": {
420
+ "additionalProperties": false,
421
+ "properties": {
422
+ "interval": {
423
+ "default": "4h",
424
+ "description": "Candle interval to read.",
425
+ "type": "string"
426
+ },
427
+ "lookback": {
428
+ "default": 42,
429
+ "description": "Bars to look back (stag 7d ~= 42 x 4h).",
430
+ "minimum": 1.0,
431
+ "type": "integer"
432
+ }
433
+ },
434
+ "type": "object"
435
+ },
436
+ "params_rank_pool_cap_to_open_slots": {
437
+ "additionalProperties": false,
438
+ "properties": {
439
+ "max_slots": {
440
+ "default": 5,
441
+ "description": "Maximum concurrent positions.",
442
+ "maximum": 50.0,
443
+ "minimum": 1.0,
444
+ "type": "integer"
445
+ },
446
+ "min_score": {
447
+ "default": 0.0,
448
+ "description": "Floor below which a candidate is dropped.",
449
+ "type": "number"
450
+ }
451
+ },
452
+ "type": "object"
453
+ },
454
+ "params_recent_high_bars_ago": {
455
+ "additionalProperties": false,
456
+ "properties": {
457
+ "interval": {
458
+ "default": "4h",
459
+ "description": "Candle interval to read.",
460
+ "type": "string"
461
+ },
462
+ "window": {
463
+ "default": 60,
464
+ "description": "Bars in the high-water window.",
465
+ "minimum": 2.0,
466
+ "type": "integer"
467
+ }
468
+ },
469
+ "type": "object"
470
+ },
471
+ "params_recent_signal_ttl_dedup": {
472
+ "additionalProperties": false,
473
+ "properties": {},
474
+ "type": "object"
475
+ },
476
+ "params_rsi": {
477
+ "additionalProperties": false,
478
+ "properties": {
479
+ "interval": {
480
+ "default": "1h",
481
+ "description": "Candle interval to read.",
482
+ "type": "string"
483
+ },
484
+ "period": {
485
+ "default": 14,
486
+ "description": "RSI lookback (default 14).",
487
+ "maximum": 100.0,
488
+ "minimum": 2.0,
489
+ "type": "integer"
490
+ }
491
+ },
492
+ "type": "object"
493
+ },
494
+ "params_signal_envelope": {
495
+ "additionalProperties": false,
496
+ "properties": {
497
+ "clamp_leverage_to_venue": {
498
+ "default": true,
499
+ "description": "Clamp leverage down to the instrument's venue max (magpie/thesis-fund).",
500
+ "type": "boolean"
501
+ },
502
+ "leverage": {
503
+ "default": 3.0,
504
+ "description": "Requested leverage before any venue clamp.",
505
+ "maximum": 50.0,
506
+ "minimum": 1.0,
507
+ "type": "number"
508
+ },
509
+ "margin_pct": {
510
+ "default": 5.0,
511
+ "description": "Percent of withdrawable to allocate, (0,100] (never a fraction or USD).",
512
+ "maximum": 100.0,
513
+ "minimum": 0.0001,
514
+ "type": "number"
515
+ },
516
+ "signal_type": {
517
+ "default": "",
518
+ "description": "Optional signal_type label carried on every emitted signal ('' = none).",
519
+ "type": "string"
520
+ },
521
+ "valid_for_seconds": {
522
+ "default": 0,
523
+ "description": "Per-signal TTL override in seconds; 0 = inherit the runtime default TTL.",
524
+ "minimum": 0.0,
525
+ "type": "integer"
526
+ }
527
+ },
528
+ "type": "object"
529
+ },
530
+ "params_sm_lean": {
531
+ "additionalProperties": false,
532
+ "properties": {
533
+ "agree_threshold": {
534
+ "default": 0.55,
535
+ "description": "Fraction of aligned SM required to count as agreeing (corpus 0.55-0.60).",
536
+ "maximum": 1.0,
537
+ "minimum": 0.0,
538
+ "type": "number"
539
+ }
540
+ },
541
+ "type": "object"
542
+ },
543
+ "params_sma": {
544
+ "additionalProperties": false,
545
+ "properties": {
546
+ "interval": {
547
+ "default": "4h",
548
+ "description": "Candle interval to read.",
549
+ "type": "string"
550
+ },
551
+ "period": {
552
+ "default": 200,
553
+ "description": "Lookback in bars (stag uses 200).",
554
+ "maximum": 1000.0,
555
+ "minimum": 1.0,
556
+ "type": "integer"
557
+ }
558
+ },
559
+ "type": "object"
560
+ },
561
+ "params_snapshot_diff_state": {
562
+ "additionalProperties": false,
563
+ "properties": {
564
+ "bucket_seconds": {
565
+ "default": 86400,
566
+ "description": "Snapshot coarsening: overwrite the current bucket until it is older than this, then open a new one (whalehunter's per-UTC-day key; 86400 = 1 day).",
567
+ "minimum": 1.0,
568
+ "type": "integer"
569
+ },
570
+ "max_snapshots": {
571
+ "default": 12,
572
+ "description": "Retain at most this many buckets; prune the oldest beyond it \u2014 THE state bound (whalehunter keep=10).",
573
+ "minimum": 2.0,
574
+ "type": "integer"
575
+ },
576
+ "value_field": {
577
+ "default": "",
578
+ "description": "Numeric sub-field to track when snapshot values are records (whalehunter tracks 'net'); '' reads the value as a float directly.",
579
+ "type": "string"
580
+ }
581
+ },
582
+ "type": "object"
583
+ },
584
+ "params_strategy_list_fetch": {
585
+ "additionalProperties": false,
586
+ "properties": {
587
+ "status": {
588
+ "default": "",
589
+ "description": "Filter by strategy status (e.g. 'ACTIVE'); empty means all.",
590
+ "type": "string"
591
+ },
592
+ "strategy_type": {
593
+ "default": "",
594
+ "description": "Filter by strategy type; empty means all.",
595
+ "type": "string"
596
+ }
597
+ },
598
+ "type": "object"
599
+ },
600
+ "params_strategy_pnl_snapshot": {
601
+ "additionalProperties": false,
602
+ "properties": {
603
+ "drawdown_reset_on_day_rollover": {
604
+ "default": false,
605
+ "description": "Reset drawdown at the day boundary (passed through to the MCP call).",
606
+ "type": "boolean"
607
+ },
608
+ "period": {
609
+ "default": "",
610
+ "description": "History period hint passed through to the MCP call; empty = default.",
611
+ "type": "string"
612
+ }
613
+ },
614
+ "type": "object"
615
+ },
616
+ "params_threshold_gate": {
617
+ "additionalProperties": false,
618
+ "properties": {
619
+ "op": {
620
+ "default": "lt",
621
+ "description": "Comparison operator: value `op` threshold (lt|lte|gt|gte).",
622
+ "enum": [
623
+ "lt",
624
+ "lte",
625
+ "gt",
626
+ "gte"
627
+ ],
628
+ "type": "string"
629
+ },
630
+ "value": {
631
+ "default": 0.0,
632
+ "description": "The threshold the per-asset feature is compared against.",
633
+ "type": "number"
634
+ }
635
+ },
636
+ "type": "object"
637
+ },
638
+ "params_top_strategies_fetch": {
639
+ "additionalProperties": false,
640
+ "properties": {
641
+ "force_fetch": {
642
+ "default": false,
643
+ "description": "Bypass the server cache and fetch fresh leaderboard data.",
644
+ "type": "boolean"
645
+ },
646
+ "limit": {
647
+ "default": 20,
648
+ "description": "Rows per page (>=1, NO server max; default 20); also the pagination page size.",
649
+ "minimum": 1.0,
650
+ "type": "integer"
651
+ },
652
+ "max_pages": {
653
+ "default": 1,
654
+ "description": "Max pages to follow via page_info.hasNextPage (default 1).",
655
+ "minimum": 1.0,
656
+ "type": "integer"
657
+ },
658
+ "offset": {
659
+ "default": 0,
660
+ "description": "Starting rank offset for pagination (default 0).",
661
+ "minimum": 0.0,
662
+ "type": "integer"
663
+ }
664
+ },
665
+ "type": "object"
666
+ },
667
+ "params_top_traders_fetch": {
668
+ "additionalProperties": false,
669
+ "properties": {
670
+ "activity_labels": {
671
+ "default": [],
672
+ "description": "Filter by activity class (DEGEN|ACTIVE|TACTICAL|PATIENT); empty = no filter.",
673
+ "items": {
674
+ "type": "string"
675
+ },
676
+ "type": "array"
677
+ },
678
+ "bias": {
679
+ "default": "ALL",
680
+ "description": "Directional-bias filter (default ALL).",
681
+ "enum": [
682
+ "LONG",
683
+ "SHORT",
684
+ "ALL"
685
+ ],
686
+ "type": "string"
687
+ },
688
+ "consistency": {
689
+ "default": [],
690
+ "description": "Filter by consistency class (ELITE|RELIABLE|STREAKY|CHOPPY); empty = no filter.",
691
+ "items": {
692
+ "type": "string"
693
+ },
694
+ "type": "array"
695
+ },
696
+ "limit": {
697
+ "default": 100,
698
+ "description": "Rows per page (1-1000); also the pagination page size.",
699
+ "maximum": 1000.0,
700
+ "minimum": 1.0,
701
+ "type": "integer"
702
+ },
703
+ "max_pages": {
704
+ "default": 1,
705
+ "description": "Max offset-pagination pages; stop early on a short page (no page_info).",
706
+ "minimum": 1.0,
707
+ "type": "integer"
708
+ },
709
+ "open_position_filter": {
710
+ "default": false,
711
+ "description": "Only include traders with at least one open position.",
712
+ "type": "boolean"
713
+ },
714
+ "risk_labels": {
715
+ "default": [],
716
+ "description": "Filter by risk class (CONSERVATIVE|BALANCED|AGGRESSIVE|SNIPER); empty = no filter.",
717
+ "items": {
718
+ "type": "string"
719
+ },
720
+ "type": "array"
721
+ },
722
+ "sort_by": {
723
+ "default": "RETURN_ON_INVESTMENT",
724
+ "description": "Ranking metric (default RETURN_ON_INVESTMENT).",
725
+ "enum": [
726
+ "RETURN_ON_INVESTMENT",
727
+ "PROFIT_AND_LOSS",
728
+ "PROFIT_AND_LOSS_REALIZED",
729
+ "PROFIT_AND_LOSS_UNREALIZED",
730
+ "WIN_RATE",
731
+ "MAX_DRAWDOWN",
732
+ "GAIN_TO_PAIN_RATIO",
733
+ "TRADER_AGE"
734
+ ],
735
+ "type": "string"
736
+ },
737
+ "time_frame": {
738
+ "description": "Performance window (REQUIRED by the advertised schema; always sent).",
739
+ "enum": [
740
+ "DAILY",
741
+ "WEEKLY",
742
+ "MONTHLY",
743
+ "ALL_TIME"
744
+ ],
745
+ "type": "string"
746
+ }
747
+ },
748
+ "required": [
749
+ "time_frame"
750
+ ],
751
+ "type": "object"
752
+ },
753
+ "params_trader_history_fetch": {
754
+ "additionalProperties": false,
755
+ "properties": {
756
+ "limit": {
757
+ "default": 100,
758
+ "description": "Maximum closed positions to return (most recent first).",
759
+ "maximum": 1000.0,
760
+ "minimum": 1.0,
761
+ "type": "integer"
762
+ },
763
+ "trader_address": {
764
+ "description": "The trader wallet whose closed-trade history to read (required).",
765
+ "type": "string"
766
+ }
767
+ },
768
+ "required": [
769
+ "trader_address"
770
+ ],
771
+ "type": "object"
772
+ },
773
+ "params_trader_positions_fetch": {
774
+ "additionalProperties": false,
775
+ "properties": {
776
+ "trader_id": {
777
+ "description": "The leaderboard trader's Ethereum address (required).",
778
+ "type": "string"
779
+ }
780
+ },
781
+ "required": [
782
+ "trader_id"
783
+ ],
784
+ "type": "object"
785
+ },
786
+ "params_trader_state_fetch": {
787
+ "additionalProperties": false,
788
+ "properties": {
789
+ "trader_address": {
790
+ "description": "The trader wallet whose current book to read (required).",
791
+ "type": "string"
792
+ }
793
+ },
794
+ "required": [
795
+ "trader_address"
796
+ ],
797
+ "type": "object"
798
+ },
799
+ "params_trader_states_fetch": {
800
+ "additionalProperties": false,
801
+ "properties": {
802
+ "include_position_age": {
803
+ "default": false,
804
+ "description": "Include per-position startTime + durationInSeconds.",
805
+ "type": "boolean"
806
+ },
807
+ "latest": {
808
+ "default": false,
809
+ "description": "Force-fresh from Hyperliquid (true) vs prefer cached (false).",
810
+ "type": "boolean"
811
+ },
812
+ "sort_open_positions_by": {
813
+ "default": "",
814
+ "description": "Sort each book by POSITION_VALUE|UNREALIZED_PNL|ENTRY_PRICE|COIN|LEVERAGE|RETURN_ON_EQUITY; empty = server default.",
815
+ "type": "string"
816
+ },
817
+ "sort_open_positions_direction": {
818
+ "default": "DESC",
819
+ "description": "Direction for the open-position sort (only applied when a sort field is set).",
820
+ "enum": [
821
+ "ASC",
822
+ "DESC"
823
+ ],
824
+ "type": "string"
825
+ },
826
+ "wallets": {
827
+ "default": [],
828
+ "description": "Static trader addresses to read when no `traders` input is wired.",
829
+ "items": {
830
+ "type": "string"
831
+ },
832
+ "type": "array"
833
+ }
834
+ },
835
+ "type": "object"
836
+ },
837
+ "params_trend_structure": {
838
+ "additionalProperties": false,
839
+ "properties": {
840
+ "interval": {
841
+ "default": "4h",
842
+ "description": "Candle interval (called at 4h and 1h).",
843
+ "type": "string"
844
+ },
845
+ "lookback": {
846
+ "default": 6,
847
+ "description": "Swing lookback in bars.",
848
+ "minimum": 2.0,
849
+ "type": "integer"
850
+ }
851
+ },
852
+ "type": "object"
853
+ },
854
+ "params_ttl_dedup_state": {
855
+ "additionalProperties": false,
856
+ "properties": {
857
+ "prune_factor": {
858
+ "default": 4,
859
+ "description": "Prune entries older than prune_factor x TTL (hawk prunes at 4x).",
860
+ "minimum": 1.0,
861
+ "type": "integer"
862
+ },
863
+ "ttl_seconds": {
864
+ "default": 240,
865
+ "description": "Dedup window in seconds (stag/hawk 240, bison/thesis-fund 180, magpie 720).",
866
+ "minimum": 1.0,
867
+ "type": "integer"
868
+ }
869
+ },
870
+ "type": "object"
871
+ },
872
+ "params_universe_discover": {
873
+ "additionalProperties": false,
874
+ "properties": {
875
+ "max_leverage_cap": {
876
+ "default": 5.0,
877
+ "description": "Reject instruments whose max leverage exceeds this (magpie <=5).",
878
+ "minimum": 1.0,
879
+ "type": "number"
880
+ },
881
+ "min_day_volume": {
882
+ "default": 0.0,
883
+ "description": "Minimum dayNtlVlm floor (magpie liquidity gate).",
884
+ "minimum": 0.0,
885
+ "type": "number"
886
+ },
887
+ "name_prefix": {
888
+ "default": "",
889
+ "description": "Require instrument name to start with this prefix (magpie 'xyz:').",
890
+ "type": "string"
891
+ }
892
+ },
893
+ "type": "object"
894
+ },
895
+ "params_volume_surge_ratio": {
896
+ "additionalProperties": false,
897
+ "properties": {
898
+ "baseline_window": {
899
+ "default": 42,
900
+ "description": "Baseline window (stag 42).",
901
+ "minimum": 1.0,
902
+ "type": "integer"
903
+ },
904
+ "interval": {
905
+ "default": "4h",
906
+ "description": "Candle interval to read.",
907
+ "type": "string"
908
+ },
909
+ "recent_window": {
910
+ "default": 6,
911
+ "description": "Recent window (stag 6).",
912
+ "minimum": 1.0,
913
+ "type": "integer"
914
+ }
915
+ },
916
+ "type": "object"
917
+ }
918
+ },
919
+ "$id": "https://senpi.ai/strategy-composer/graph.schema.json",
920
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
921
+ "additionalProperties": false,
922
+ "description": "Typed dataflow DAG for a trading strategy (D1). YAML is authored; this JSON Schema is canonical (D6). YAML anchors and merge keys are banned at the document level (enforced in the validator, slice 2). Generated from the node registry \u2014 do not edit by hand.",
923
+ "properties": {
924
+ "edges": {
925
+ "description": "Wiring: from 'nodeId.outPort' to 'nodeId.inPort' (D1).",
926
+ "items": {
927
+ "additionalProperties": false,
928
+ "properties": {
929
+ "from": {
930
+ "pattern": "^[^.]+\\.[^.]+$",
931
+ "type": "string"
932
+ },
933
+ "to": {
934
+ "pattern": "^[^.]+\\.[^.]+$",
935
+ "type": "string"
936
+ }
937
+ },
938
+ "required": [
939
+ "from",
940
+ "to"
941
+ ],
942
+ "type": "object"
943
+ },
944
+ "type": "array"
945
+ },
946
+ "metadata": {
947
+ "description": "Interview answers and authoring notes (D7); free-form.",
948
+ "type": "object"
949
+ },
950
+ "nodes": {
951
+ "description": "The DAG nodes. Each is EITHER a primitive node binding a registry `node:` to params, OR a per-graph `kind: pure_fn` node (D2 kind 2) carrying declared typed inputs/outputs and an inline `fn:` body. The per-node `node`-keyed branches below apply only to primitive nodes; a pure_fn node (no `node:`) satisfies them vacuously and is checked by the validator's purity + inline-test stage.",
952
+ "items": {
953
+ "additionalProperties": false,
954
+ "allOf": [
955
+ {
956
+ "if": {
957
+ "properties": {
958
+ "node": {
959
+ "const": "acceleration"
960
+ }
961
+ }
962
+ },
963
+ "then": {
964
+ "properties": {
965
+ "with": {
966
+ "$ref": "#/$defs/params_acceleration"
967
+ }
968
+ }
969
+ }
970
+ },
971
+ {
972
+ "if": {
973
+ "properties": {
974
+ "node": {
975
+ "const": "account_history_fetch"
976
+ }
977
+ }
978
+ },
979
+ "then": {
980
+ "properties": {
981
+ "with": {
982
+ "$ref": "#/$defs/params_account_history_fetch"
983
+ }
984
+ }
985
+ }
986
+ },
987
+ {
988
+ "if": {
989
+ "properties": {
990
+ "node": {
991
+ "const": "aggregate_bias"
992
+ }
993
+ }
994
+ },
995
+ "then": {
996
+ "properties": {
997
+ "with": {
998
+ "$ref": "#/$defs/params_aggregate_bias"
999
+ }
1000
+ }
1001
+ }
1002
+ },
1003
+ {
1004
+ "if": {
1005
+ "properties": {
1006
+ "node": {
1007
+ "const": "arena_leaderboard_fetch"
1008
+ }
1009
+ }
1010
+ },
1011
+ "then": {
1012
+ "properties": {
1013
+ "with": {
1014
+ "$ref": "#/$defs/params_arena_leaderboard_fetch"
1015
+ }
1016
+ }
1017
+ }
1018
+ },
1019
+ {
1020
+ "if": {
1021
+ "properties": {
1022
+ "node": {
1023
+ "const": "asset_trading_limits_fetch"
1024
+ }
1025
+ }
1026
+ },
1027
+ "then": {
1028
+ "properties": {
1029
+ "with": {
1030
+ "$ref": "#/$defs/params_asset_trading_limits_fetch"
1031
+ }
1032
+ }
1033
+ }
1034
+ },
1035
+ {
1036
+ "if": {
1037
+ "properties": {
1038
+ "node": {
1039
+ "const": "breakout_detect"
1040
+ }
1041
+ }
1042
+ },
1043
+ "then": {
1044
+ "properties": {
1045
+ "with": {
1046
+ "$ref": "#/$defs/params_breakout_detect"
1047
+ }
1048
+ }
1049
+ }
1050
+ },
1051
+ {
1052
+ "if": {
1053
+ "properties": {
1054
+ "node": {
1055
+ "const": "candles_fetch"
1056
+ }
1057
+ }
1058
+ },
1059
+ "then": {
1060
+ "properties": {
1061
+ "with": {
1062
+ "$ref": "#/$defs/params_candles_fetch"
1063
+ }
1064
+ }
1065
+ }
1066
+ },
1067
+ {
1068
+ "if": {
1069
+ "properties": {
1070
+ "node": {
1071
+ "const": "classifier_predicate"
1072
+ }
1073
+ }
1074
+ },
1075
+ "then": {
1076
+ "properties": {
1077
+ "with": {
1078
+ "$ref": "#/$defs/params_classifier_predicate"
1079
+ }
1080
+ }
1081
+ }
1082
+ },
1083
+ {
1084
+ "if": {
1085
+ "properties": {
1086
+ "node": {
1087
+ "const": "clearinghouse_state"
1088
+ }
1089
+ }
1090
+ },
1091
+ "then": {
1092
+ "properties": {
1093
+ "with": {
1094
+ "$ref": "#/$defs/params_clearinghouse_state"
1095
+ }
1096
+ }
1097
+ }
1098
+ },
1099
+ {
1100
+ "if": {
1101
+ "properties": {
1102
+ "node": {
1103
+ "const": "cohort_cache_state"
1104
+ }
1105
+ }
1106
+ },
1107
+ "then": {
1108
+ "properties": {
1109
+ "with": {
1110
+ "$ref": "#/$defs/params_cohort_cache_state"
1111
+ }
1112
+ }
1113
+ }
1114
+ },
1115
+ {
1116
+ "if": {
1117
+ "properties": {
1118
+ "node": {
1119
+ "const": "cross_asset_flows_fetch"
1120
+ }
1121
+ }
1122
+ },
1123
+ "then": {
1124
+ "properties": {
1125
+ "with": {
1126
+ "$ref": "#/$defs/params_cross_asset_flows_fetch"
1127
+ }
1128
+ }
1129
+ }
1130
+ },
1131
+ {
1132
+ "if": {
1133
+ "properties": {
1134
+ "node": {
1135
+ "const": "emit_single_best"
1136
+ }
1137
+ }
1138
+ },
1139
+ "then": {
1140
+ "properties": {
1141
+ "with": {
1142
+ "$ref": "#/$defs/params_emit_single_best"
1143
+ }
1144
+ }
1145
+ }
1146
+ },
1147
+ {
1148
+ "if": {
1149
+ "properties": {
1150
+ "node": {
1151
+ "const": "funding_history_fetch"
1152
+ }
1153
+ }
1154
+ },
1155
+ "then": {
1156
+ "properties": {
1157
+ "with": {
1158
+ "$ref": "#/$defs/params_funding_history_fetch"
1159
+ }
1160
+ }
1161
+ }
1162
+ },
1163
+ {
1164
+ "if": {
1165
+ "properties": {
1166
+ "node": {
1167
+ "const": "funding_regime_fetch"
1168
+ }
1169
+ }
1170
+ },
1171
+ "then": {
1172
+ "properties": {
1173
+ "with": {
1174
+ "$ref": "#/$defs/params_funding_regime_fetch"
1175
+ }
1176
+ }
1177
+ }
1178
+ },
1179
+ {
1180
+ "if": {
1181
+ "properties": {
1182
+ "node": {
1183
+ "const": "hard_gates_all"
1184
+ }
1185
+ }
1186
+ },
1187
+ "then": {
1188
+ "properties": {
1189
+ "with": {
1190
+ "$ref": "#/$defs/params_hard_gates_all"
1191
+ }
1192
+ }
1193
+ }
1194
+ },
1195
+ {
1196
+ "if": {
1197
+ "properties": {
1198
+ "node": {
1199
+ "const": "held_asset_exclusion"
1200
+ }
1201
+ }
1202
+ },
1203
+ "then": {
1204
+ "properties": {
1205
+ "with": {
1206
+ "$ref": "#/$defs/params_held_asset_exclusion"
1207
+ }
1208
+ }
1209
+ }
1210
+ },
1211
+ {
1212
+ "if": {
1213
+ "properties": {
1214
+ "node": {
1215
+ "const": "instrument_list"
1216
+ }
1217
+ }
1218
+ },
1219
+ "then": {
1220
+ "properties": {
1221
+ "with": {
1222
+ "$ref": "#/$defs/params_instrument_list"
1223
+ }
1224
+ }
1225
+ }
1226
+ },
1227
+ {
1228
+ "if": {
1229
+ "properties": {
1230
+ "node": {
1231
+ "const": "leaderboard_top_fetch"
1232
+ }
1233
+ }
1234
+ },
1235
+ "then": {
1236
+ "properties": {
1237
+ "with": {
1238
+ "$ref": "#/$defs/params_leaderboard_top_fetch"
1239
+ }
1240
+ }
1241
+ }
1242
+ },
1243
+ {
1244
+ "if": {
1245
+ "properties": {
1246
+ "node": {
1247
+ "const": "leaderboard_trader_fetch"
1248
+ }
1249
+ }
1250
+ },
1251
+ "then": {
1252
+ "properties": {
1253
+ "with": {
1254
+ "$ref": "#/$defs/params_leaderboard_trader_fetch"
1255
+ }
1256
+ }
1257
+ }
1258
+ },
1259
+ {
1260
+ "if": {
1261
+ "properties": {
1262
+ "node": {
1263
+ "const": "live_instrument_validation"
1264
+ }
1265
+ }
1266
+ },
1267
+ "then": {
1268
+ "properties": {
1269
+ "with": {
1270
+ "$ref": "#/$defs/params_live_instrument_validation"
1271
+ }
1272
+ }
1273
+ }
1274
+ },
1275
+ {
1276
+ "if": {
1277
+ "properties": {
1278
+ "node": {
1279
+ "const": "market_prices_fetch"
1280
+ }
1281
+ }
1282
+ },
1283
+ "then": {
1284
+ "properties": {
1285
+ "with": {
1286
+ "$ref": "#/$defs/params_market_prices_fetch"
1287
+ }
1288
+ }
1289
+ }
1290
+ },
1291
+ {
1292
+ "if": {
1293
+ "properties": {
1294
+ "node": {
1295
+ "const": "mcp_read"
1296
+ }
1297
+ }
1298
+ },
1299
+ "then": {
1300
+ "properties": {
1301
+ "with": {
1302
+ "$ref": "#/$defs/params_mcp_read"
1303
+ }
1304
+ }
1305
+ }
1306
+ },
1307
+ {
1308
+ "if": {
1309
+ "properties": {
1310
+ "node": {
1311
+ "const": "momentum_events_fetch"
1312
+ }
1313
+ }
1314
+ },
1315
+ "then": {
1316
+ "properties": {
1317
+ "with": {
1318
+ "$ref": "#/$defs/params_momentum_events_fetch"
1319
+ }
1320
+ }
1321
+ }
1322
+ },
1323
+ {
1324
+ "if": {
1325
+ "properties": {
1326
+ "node": {
1327
+ "const": "open_orders_fetch"
1328
+ }
1329
+ }
1330
+ },
1331
+ "then": {
1332
+ "properties": {
1333
+ "with": {
1334
+ "$ref": "#/$defs/params_open_orders_fetch"
1335
+ }
1336
+ }
1337
+ }
1338
+ },
1339
+ {
1340
+ "if": {
1341
+ "properties": {
1342
+ "node": {
1343
+ "const": "open_positions_realized_pnl_fetch"
1344
+ }
1345
+ }
1346
+ },
1347
+ "then": {
1348
+ "properties": {
1349
+ "with": {
1350
+ "$ref": "#/$defs/params_open_positions_realized_pnl_fetch"
1351
+ }
1352
+ }
1353
+ }
1354
+ },
1355
+ {
1356
+ "if": {
1357
+ "properties": {
1358
+ "node": {
1359
+ "const": "own_return_24h"
1360
+ }
1361
+ }
1362
+ },
1363
+ "then": {
1364
+ "properties": {
1365
+ "with": {
1366
+ "$ref": "#/$defs/params_own_return_24h"
1367
+ }
1368
+ }
1369
+ }
1370
+ },
1371
+ {
1372
+ "if": {
1373
+ "properties": {
1374
+ "node": {
1375
+ "const": "pct_change"
1376
+ }
1377
+ }
1378
+ },
1379
+ "then": {
1380
+ "properties": {
1381
+ "with": {
1382
+ "$ref": "#/$defs/params_pct_change"
1383
+ }
1384
+ }
1385
+ }
1386
+ },
1387
+ {
1388
+ "if": {
1389
+ "properties": {
1390
+ "node": {
1391
+ "const": "rank_pool_cap_to_open_slots"
1392
+ }
1393
+ }
1394
+ },
1395
+ "then": {
1396
+ "properties": {
1397
+ "with": {
1398
+ "$ref": "#/$defs/params_rank_pool_cap_to_open_slots"
1399
+ }
1400
+ }
1401
+ }
1402
+ },
1403
+ {
1404
+ "if": {
1405
+ "properties": {
1406
+ "node": {
1407
+ "const": "recent_high_bars_ago"
1408
+ }
1409
+ }
1410
+ },
1411
+ "then": {
1412
+ "properties": {
1413
+ "with": {
1414
+ "$ref": "#/$defs/params_recent_high_bars_ago"
1415
+ }
1416
+ }
1417
+ }
1418
+ },
1419
+ {
1420
+ "if": {
1421
+ "properties": {
1422
+ "node": {
1423
+ "const": "recent_signal_ttl_dedup"
1424
+ }
1425
+ }
1426
+ },
1427
+ "then": {
1428
+ "properties": {
1429
+ "with": {
1430
+ "$ref": "#/$defs/params_recent_signal_ttl_dedup"
1431
+ }
1432
+ }
1433
+ }
1434
+ },
1435
+ {
1436
+ "if": {
1437
+ "properties": {
1438
+ "node": {
1439
+ "const": "rsi"
1440
+ }
1441
+ }
1442
+ },
1443
+ "then": {
1444
+ "properties": {
1445
+ "with": {
1446
+ "$ref": "#/$defs/params_rsi"
1447
+ }
1448
+ }
1449
+ }
1450
+ },
1451
+ {
1452
+ "if": {
1453
+ "properties": {
1454
+ "node": {
1455
+ "const": "signal_envelope"
1456
+ }
1457
+ }
1458
+ },
1459
+ "then": {
1460
+ "properties": {
1461
+ "with": {
1462
+ "$ref": "#/$defs/params_signal_envelope"
1463
+ }
1464
+ }
1465
+ }
1466
+ },
1467
+ {
1468
+ "if": {
1469
+ "properties": {
1470
+ "node": {
1471
+ "const": "sm_lean"
1472
+ }
1473
+ }
1474
+ },
1475
+ "then": {
1476
+ "properties": {
1477
+ "with": {
1478
+ "$ref": "#/$defs/params_sm_lean"
1479
+ }
1480
+ }
1481
+ }
1482
+ },
1483
+ {
1484
+ "if": {
1485
+ "properties": {
1486
+ "node": {
1487
+ "const": "sma"
1488
+ }
1489
+ }
1490
+ },
1491
+ "then": {
1492
+ "properties": {
1493
+ "with": {
1494
+ "$ref": "#/$defs/params_sma"
1495
+ }
1496
+ }
1497
+ }
1498
+ },
1499
+ {
1500
+ "if": {
1501
+ "properties": {
1502
+ "node": {
1503
+ "const": "snapshot_diff_state"
1504
+ }
1505
+ }
1506
+ },
1507
+ "then": {
1508
+ "properties": {
1509
+ "with": {
1510
+ "$ref": "#/$defs/params_snapshot_diff_state"
1511
+ }
1512
+ }
1513
+ }
1514
+ },
1515
+ {
1516
+ "if": {
1517
+ "properties": {
1518
+ "node": {
1519
+ "const": "strategy_list_fetch"
1520
+ }
1521
+ }
1522
+ },
1523
+ "then": {
1524
+ "properties": {
1525
+ "with": {
1526
+ "$ref": "#/$defs/params_strategy_list_fetch"
1527
+ }
1528
+ }
1529
+ }
1530
+ },
1531
+ {
1532
+ "if": {
1533
+ "properties": {
1534
+ "node": {
1535
+ "const": "strategy_pnl_snapshot"
1536
+ }
1537
+ }
1538
+ },
1539
+ "then": {
1540
+ "properties": {
1541
+ "with": {
1542
+ "$ref": "#/$defs/params_strategy_pnl_snapshot"
1543
+ }
1544
+ }
1545
+ }
1546
+ },
1547
+ {
1548
+ "if": {
1549
+ "properties": {
1550
+ "node": {
1551
+ "const": "threshold_gate"
1552
+ }
1553
+ }
1554
+ },
1555
+ "then": {
1556
+ "properties": {
1557
+ "with": {
1558
+ "$ref": "#/$defs/params_threshold_gate"
1559
+ }
1560
+ }
1561
+ }
1562
+ },
1563
+ {
1564
+ "if": {
1565
+ "properties": {
1566
+ "node": {
1567
+ "const": "top_strategies_fetch"
1568
+ }
1569
+ }
1570
+ },
1571
+ "then": {
1572
+ "properties": {
1573
+ "with": {
1574
+ "$ref": "#/$defs/params_top_strategies_fetch"
1575
+ }
1576
+ }
1577
+ }
1578
+ },
1579
+ {
1580
+ "if": {
1581
+ "properties": {
1582
+ "node": {
1583
+ "const": "top_traders_fetch"
1584
+ }
1585
+ }
1586
+ },
1587
+ "then": {
1588
+ "properties": {
1589
+ "with": {
1590
+ "$ref": "#/$defs/params_top_traders_fetch"
1591
+ }
1592
+ }
1593
+ }
1594
+ },
1595
+ {
1596
+ "if": {
1597
+ "properties": {
1598
+ "node": {
1599
+ "const": "trader_history_fetch"
1600
+ }
1601
+ }
1602
+ },
1603
+ "then": {
1604
+ "properties": {
1605
+ "with": {
1606
+ "$ref": "#/$defs/params_trader_history_fetch"
1607
+ }
1608
+ }
1609
+ }
1610
+ },
1611
+ {
1612
+ "if": {
1613
+ "properties": {
1614
+ "node": {
1615
+ "const": "trader_positions_fetch"
1616
+ }
1617
+ }
1618
+ },
1619
+ "then": {
1620
+ "properties": {
1621
+ "with": {
1622
+ "$ref": "#/$defs/params_trader_positions_fetch"
1623
+ }
1624
+ }
1625
+ }
1626
+ },
1627
+ {
1628
+ "if": {
1629
+ "properties": {
1630
+ "node": {
1631
+ "const": "trader_state_fetch"
1632
+ }
1633
+ }
1634
+ },
1635
+ "then": {
1636
+ "properties": {
1637
+ "with": {
1638
+ "$ref": "#/$defs/params_trader_state_fetch"
1639
+ }
1640
+ }
1641
+ }
1642
+ },
1643
+ {
1644
+ "if": {
1645
+ "properties": {
1646
+ "node": {
1647
+ "const": "trader_states_fetch"
1648
+ }
1649
+ }
1650
+ },
1651
+ "then": {
1652
+ "properties": {
1653
+ "with": {
1654
+ "$ref": "#/$defs/params_trader_states_fetch"
1655
+ }
1656
+ }
1657
+ }
1658
+ },
1659
+ {
1660
+ "if": {
1661
+ "properties": {
1662
+ "node": {
1663
+ "const": "trend_structure"
1664
+ }
1665
+ }
1666
+ },
1667
+ "then": {
1668
+ "properties": {
1669
+ "with": {
1670
+ "$ref": "#/$defs/params_trend_structure"
1671
+ }
1672
+ }
1673
+ }
1674
+ },
1675
+ {
1676
+ "if": {
1677
+ "properties": {
1678
+ "node": {
1679
+ "const": "ttl_dedup_state"
1680
+ }
1681
+ }
1682
+ },
1683
+ "then": {
1684
+ "properties": {
1685
+ "with": {
1686
+ "$ref": "#/$defs/params_ttl_dedup_state"
1687
+ }
1688
+ }
1689
+ }
1690
+ },
1691
+ {
1692
+ "if": {
1693
+ "properties": {
1694
+ "node": {
1695
+ "const": "universe_discover"
1696
+ }
1697
+ }
1698
+ },
1699
+ "then": {
1700
+ "properties": {
1701
+ "with": {
1702
+ "$ref": "#/$defs/params_universe_discover"
1703
+ }
1704
+ }
1705
+ }
1706
+ },
1707
+ {
1708
+ "if": {
1709
+ "properties": {
1710
+ "node": {
1711
+ "const": "volume_surge_ratio"
1712
+ }
1713
+ }
1714
+ },
1715
+ "then": {
1716
+ "properties": {
1717
+ "with": {
1718
+ "$ref": "#/$defs/params_volume_surge_ratio"
1719
+ }
1720
+ }
1721
+ }
1722
+ }
1723
+ ],
1724
+ "properties": {
1725
+ "fn": {
1726
+ "description": "pure_fn body: exactly one top-level `def` (purity-checked).",
1727
+ "type": "string"
1728
+ },
1729
+ "id": {
1730
+ "description": "Unique node id within the graph.",
1731
+ "type": "string"
1732
+ },
1733
+ "inputs": {
1734
+ "description": "pure_fn declared typed input ports.",
1735
+ "items": {
1736
+ "additionalProperties": false,
1737
+ "properties": {
1738
+ "doc": {
1739
+ "type": "string"
1740
+ },
1741
+ "name": {
1742
+ "type": "string"
1743
+ },
1744
+ "type": {
1745
+ "enum": [
1746
+ "asset_list",
1747
+ "candles",
1748
+ "feature_map",
1749
+ "score_map",
1750
+ "signals",
1751
+ "scalar",
1752
+ "state",
1753
+ "record_list",
1754
+ "label",
1755
+ "raw"
1756
+ ]
1757
+ }
1758
+ },
1759
+ "required": [
1760
+ "name",
1761
+ "type"
1762
+ ],
1763
+ "type": "object"
1764
+ },
1765
+ "type": "array"
1766
+ },
1767
+ "kind": {
1768
+ "description": "Marks a per-graph pure-function node (D2 kind 2).",
1769
+ "enum": [
1770
+ "pure_fn"
1771
+ ]
1772
+ },
1773
+ "node": {
1774
+ "description": "Registry node name (primitive nodes only).",
1775
+ "enum": [
1776
+ "acceleration",
1777
+ "account_history_fetch",
1778
+ "aggregate_bias",
1779
+ "arena_leaderboard_fetch",
1780
+ "asset_trading_limits_fetch",
1781
+ "breakout_detect",
1782
+ "candles_fetch",
1783
+ "classifier_predicate",
1784
+ "clearinghouse_state",
1785
+ "cohort_cache_state",
1786
+ "cross_asset_flows_fetch",
1787
+ "emit_single_best",
1788
+ "funding_history_fetch",
1789
+ "funding_regime_fetch",
1790
+ "hard_gates_all",
1791
+ "held_asset_exclusion",
1792
+ "instrument_list",
1793
+ "leaderboard_top_fetch",
1794
+ "leaderboard_trader_fetch",
1795
+ "live_instrument_validation",
1796
+ "market_prices_fetch",
1797
+ "mcp_read",
1798
+ "momentum_events_fetch",
1799
+ "open_orders_fetch",
1800
+ "open_positions_realized_pnl_fetch",
1801
+ "own_return_24h",
1802
+ "pct_change",
1803
+ "rank_pool_cap_to_open_slots",
1804
+ "recent_high_bars_ago",
1805
+ "recent_signal_ttl_dedup",
1806
+ "rsi",
1807
+ "signal_envelope",
1808
+ "sm_lean",
1809
+ "sma",
1810
+ "snapshot_diff_state",
1811
+ "strategy_list_fetch",
1812
+ "strategy_pnl_snapshot",
1813
+ "threshold_gate",
1814
+ "top_strategies_fetch",
1815
+ "top_traders_fetch",
1816
+ "trader_history_fetch",
1817
+ "trader_positions_fetch",
1818
+ "trader_state_fetch",
1819
+ "trader_states_fetch",
1820
+ "trend_structure",
1821
+ "ttl_dedup_state",
1822
+ "universe_discover",
1823
+ "volume_surge_ratio"
1824
+ ],
1825
+ "type": "string"
1826
+ },
1827
+ "outputs": {
1828
+ "description": "pure_fn declared typed output ports.",
1829
+ "items": {
1830
+ "additionalProperties": false,
1831
+ "properties": {
1832
+ "doc": {
1833
+ "type": "string"
1834
+ },
1835
+ "name": {
1836
+ "type": "string"
1837
+ },
1838
+ "type": {
1839
+ "enum": [
1840
+ "asset_list",
1841
+ "candles",
1842
+ "feature_map",
1843
+ "score_map",
1844
+ "signals",
1845
+ "scalar",
1846
+ "state",
1847
+ "record_list",
1848
+ "label",
1849
+ "raw"
1850
+ ]
1851
+ }
1852
+ },
1853
+ "required": [
1854
+ "name",
1855
+ "type"
1856
+ ],
1857
+ "type": "object"
1858
+ },
1859
+ "type": "array"
1860
+ },
1861
+ "params": {
1862
+ "description": "pure_fn literal params (config, not edges).",
1863
+ "items": {
1864
+ "additionalProperties": false,
1865
+ "properties": {
1866
+ "default": {},
1867
+ "doc": {
1868
+ "type": "string"
1869
+ },
1870
+ "name": {
1871
+ "type": "string"
1872
+ },
1873
+ "type": {
1874
+ "enum": [
1875
+ "int",
1876
+ "float",
1877
+ "str",
1878
+ "bool",
1879
+ "list[str]",
1880
+ "map_str_float"
1881
+ ]
1882
+ }
1883
+ },
1884
+ "required": [
1885
+ "name",
1886
+ "type"
1887
+ ],
1888
+ "type": "object"
1889
+ },
1890
+ "type": "array"
1891
+ },
1892
+ "tests": {
1893
+ "description": "pure_fn inline fixture tests, run at validate time.",
1894
+ "items": {
1895
+ "additionalProperties": false,
1896
+ "properties": {
1897
+ "expect": {
1898
+ "type": "object"
1899
+ },
1900
+ "inputs": {
1901
+ "type": "object"
1902
+ },
1903
+ "name": {
1904
+ "type": "string"
1905
+ }
1906
+ },
1907
+ "required": [
1908
+ "name",
1909
+ "inputs",
1910
+ "expect"
1911
+ ],
1912
+ "type": "object"
1913
+ },
1914
+ "type": "array"
1915
+ },
1916
+ "with": {
1917
+ "description": "Node parameters.",
1918
+ "type": "object"
1919
+ }
1920
+ },
1921
+ "required": [
1922
+ "id"
1923
+ ],
1924
+ "type": "object"
1925
+ },
1926
+ "minItems": 1,
1927
+ "type": "array"
1928
+ },
1929
+ "pipeline": {
1930
+ "description": "RESERVED shorthand marker for the common linear case (D1/D6). Desugaring into nodes+edges is slice 2 and is NOT built here.",
1931
+ "items": {
1932
+ "type": "string"
1933
+ },
1934
+ "type": "array"
1935
+ },
1936
+ "version": {
1937
+ "const": 1,
1938
+ "description": "Registry/schema version."
1939
+ }
1940
+ },
1941
+ "required": [
1942
+ "nodes"
1943
+ ],
1944
+ "title": "Strategy Composer Graph",
1945
+ "type": "object"
1946
+ }