@qtsurfer/api-client 0.18.0 → 0.20.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.
@@ -173,6 +173,10 @@ one doesn't.
173
173
  required: [
174
174
  "userId",
175
175
  "tier",
176
+ "maxExecute",
177
+ "maxRangeDays",
178
+ "maxSweepCartesian",
179
+ "maxImportRangeHours",
176
180
  "maxDatasets",
177
181
  "maxDatasetBytes",
178
182
  "maxTotalStorageBytes",
@@ -189,6 +193,34 @@ one doesn't.
189
193
  description: "Your current subscription tier.",
190
194
  example: "free",
191
195
  },
196
+ maxExecute: {
197
+ type: "integer",
198
+ description: `Maximum number of strategy executions (and sweeps) you can have running at the same time
199
+ through the API. Starting one past this number is answered with \`429\`, whose message
200
+ carries the same number. The value already includes any API allowance your plan has.
201
+ `,
202
+ example: 10,
203
+ },
204
+ maxRangeDays: {
205
+ type: "integer",
206
+ description:
207
+ "Maximum length, in days, of the time range of a backtest on one of your own datasets.",
208
+ example: 7,
209
+ },
210
+ maxSweepCartesian: {
211
+ type: "integer",
212
+ description: `Largest full grid, in parameter combinations, a sweep may run with the \`grid\` sampler.
213
+ A grid with more combinations is refused with \`400\`; the \`random\` and \`lhs\` samplers run
214
+ only their \`samples\` and are not held to it.
215
+ `,
216
+ example: 100,
217
+ },
218
+ maxImportRangeHours: {
219
+ type: "integer",
220
+ description:
221
+ "Maximum length, in hours, of the time range of one dataset import from an exchange.",
222
+ example: 6,
223
+ },
192
224
  maxDatasets: {
193
225
  type: "integer",
194
226
  description: "Maximum number of active datasets your tier allows.",
@@ -197,7 +229,8 @@ one doesn't.
197
229
  maxDatasetBytes: {
198
230
  type: "integer",
199
231
  format: "int64",
200
- description: "Maximum size, in bytes, of a single dataset version.",
232
+ description:
233
+ "Maximum size, in bytes, of a single dataset version as stored, that is the `bytes` of its ready version. For a CSV upload that is the converted file, not the file you upload, so estimate from the number of rows. The Datasets guide has the details.",
201
234
  example: 52428800,
202
235
  },
203
236
  maxTotalStorageBytes: {
@@ -776,6 +809,9 @@ export const SweepSpecRequestSchema = {
776
809
  type: "string",
777
810
  enum: ["grid", "random", "lhs"],
778
811
  default: "grid",
812
+ description: `\`grid\` runs every combination of the axes and is held to your plan's
813
+ \`maxSweepCartesian\` (\`GET /account\`); \`random\` and \`lhs\` run \`samples\` combinations and are not.
814
+ `,
779
815
  },
780
816
  seed: {
781
817
  type: "integer",
@@ -859,6 +895,8 @@ export const SweepBaseConfigSchema = {
859
895
  format: "double",
860
896
  exclusiveMinimum: 0,
861
897
  maximum: 100,
898
+ description:
899
+ "Share of the free balance each entry locks, in percent (0-100]. Omitted, a backtest sizes every entry with everything available.",
862
900
  },
863
901
  },
864
902
  } as const;
@@ -2025,6 +2063,13 @@ not be established without constructing the strategy.
2025
2063
  type: "string",
2026
2064
  },
2027
2065
  },
2066
+ deletedAt: {
2067
+ type: "string",
2068
+ format: "date-time",
2069
+ description: `When you deleted this strategy. Only ever present in \`GET /strategies?includeDeleted=true\`,
2070
+ and only on strategies you have deleted.
2071
+ `,
2072
+ },
2028
2073
  },
2029
2074
  } as const;
2030
2075
 
@@ -2189,6 +2234,13 @@ least one upload has finished ingesting.
2189
2234
  `,
2190
2235
  example: "dsv_8e2b4f19c6a03d7e",
2191
2236
  },
2237
+ deletedAt: {
2238
+ type: "string",
2239
+ format: "date-time",
2240
+ description: `When you deleted this dataset. Only ever present in \`GET /datasets?includeDeleted=true\`,
2241
+ and only on datasets you have deleted.
2242
+ `,
2243
+ },
2192
2244
  updatedAt: {
2193
2245
  type: "string",
2194
2246
  format: "date-time",
@@ -2847,12 +2899,12 @@ export const StartLiveRequestSchema = {
2847
2899
  enum: ["private", "public"],
2848
2900
  default: "private",
2849
2901
  description:
2850
- "A `public` run appears in `GET /live/public` and its signal channel accepts subscriptions from anyone, not only you.",
2902
+ "A `public` run appears in `GET /live/public` and its signal channel accepts subscriptions from anyone, not only you — from the moment it is promoted to `live`. While it is a `sandbox` trial, `public` is only what you asked for, and only you can read it.",
2851
2903
  },
2852
2904
  relay: {
2853
2905
  type: "boolean",
2854
2906
  default: false,
2855
- description: `Request that this run's signals be relayed over its WebSocket channel once it reaches the \`live\` stage — see the "Live execution" guide. Has no effect while the run is still in the \`sandbox\` stage, regardless of this value.`,
2907
+ description: `Request that this run's signals be relayed over its WebSocket channel, from its first signal — in the \`sandbox\` stage too, where only you can subscribe to it. See the "Live execution" guide.`,
2856
2908
  },
2857
2909
  name: {
2858
2910
  type: "string",
@@ -2860,6 +2912,73 @@ export const StartLiveRequestSchema = {
2860
2912
  description: {
2861
2913
  type: "string",
2862
2914
  },
2915
+ paper: {
2916
+ $ref: "#/components/schemas/LivePaperConfig",
2917
+ },
2918
+ },
2919
+ } as const;
2920
+
2921
+ export const LivePaperConfigSchema = {
2922
+ type: "object",
2923
+ additionalProperties: false,
2924
+ description: `Paper trading for this run: the same economics as a backtest's \`baseConfig\` (same fields,
2925
+ defaults and limits), plus \`output\`. An empty object takes every default. Each quote
2926
+ currency the run trades gets its own simulated account, opened with \`initialFunding\` in
2927
+ that currency; accounts are never added together. As returned on a run, the block is
2928
+ normalised: \`feeRate\` is resolved into \`buyFeeRate\`/\`sellFeeRate\` and defaults are filled
2929
+ in.
2930
+ `,
2931
+ properties: {
2932
+ initialFunding: {
2933
+ type: "number",
2934
+ format: "double",
2935
+ exclusiveMinimum: 0,
2936
+ maximum: 1000000000,
2937
+ default: 100,
2938
+ description:
2939
+ "Starting capital of each account, in that account's own quote currency.",
2940
+ },
2941
+ feeRate: {
2942
+ type: "number",
2943
+ format: "double",
2944
+ minimum: 0,
2945
+ default: 0.001,
2946
+ description:
2947
+ "Fee rate for both sides (0.001 = 0.1%). Accepted on start; returned resolved into the two fields below.",
2948
+ },
2949
+ buyFeeRate: {
2950
+ type: "number",
2951
+ format: "double",
2952
+ minimum: 0,
2953
+ description: "Buy-side fee rate; overrides `feeRate`.",
2954
+ },
2955
+ sellFeeRate: {
2956
+ type: "number",
2957
+ format: "double",
2958
+ minimum: 0,
2959
+ description: "Sell-side fee rate; overrides `feeRate`.",
2960
+ },
2961
+ feeLeg: {
2962
+ type: "string",
2963
+ enum: ["RECEIVED", "QUOTE", "BASE"],
2964
+ default: "RECEIVED",
2965
+ description:
2966
+ "Which asset fees are charged in. Case-insensitive on start.",
2967
+ },
2968
+ percentAmountToLock: {
2969
+ type: "number",
2970
+ format: "double",
2971
+ exclusiveMinimum: 0,
2972
+ maximum: 100,
2973
+ description:
2974
+ "Share of the account's free balance each entry locks, in percent. Omitted, the strategy's own setting applies, and without one 10%.",
2975
+ },
2976
+ output: {
2977
+ type: "string",
2978
+ enum: ["separate", "mix"],
2979
+ default: "separate",
2980
+ description: `\`separate\` keeps paper output out of the run's signals (read it with \`GET /live/{runId}/paper\`); \`mix\` also interleaves it into the run's signals as \`type: paper\`, right after the signal that caused it.`,
2981
+ },
2863
2982
  },
2864
2983
  } as const;
2865
2984
 
@@ -2892,6 +3011,23 @@ export const UpdateLiveParamsRequestSchema = {
2892
3011
  },
2893
3012
  } as const;
2894
3013
 
3014
+ export const SendLiveCommandRequestSchema = {
3015
+ type: "object",
3016
+ required: ["command"],
3017
+ properties: {
3018
+ command: {
3019
+ type: "string",
3020
+ description: "The command's text — non-blank.",
3021
+ },
3022
+ properties: {
3023
+ type: "object",
3024
+ additionalProperties: true,
3025
+ description:
3026
+ "An optional map of your own choosing, alongside command. Absent means none; when given, it must be a JSON object, and `command` and `properties` are the only keys the body may carry. Each entry lands as a top-level entry on the strategy's `CommandRequest` — no key is off limits, since the command's own text is kept separately.",
3027
+ },
3028
+ },
3029
+ } as const;
3030
+
2895
3031
  export const LiveRunSchema = {
2896
3032
  type: "object",
2897
3033
  required: [
@@ -2932,11 +3068,12 @@ export const LiveRunSchema = {
2932
3068
  type: "string",
2933
3069
  enum: ["SANDBOX", "LIVE"],
2934
3070
  description:
2935
- "A new run always starts `SANDBOX` — a trial run compared against a second execution for agreement — and moves to `LIVE` once it passes.",
3071
+ "A new run always starts `SANDBOX`, a 24-hour trial in which it is compared against a second execution and checked for resource use and stability. A run that passes moves to `LIVE` automatically when the 24 hours are up.",
2936
3072
  },
2937
3073
  state: {
2938
3074
  type: "string",
2939
- description: `\`STARTING\` until first observed running; otherwise the runner's own reported state (e.g. \`RUNNING\`).`,
3075
+ description:
3076
+ "The run's health right now: `STARTING` (no runner has reported on it yet), `RUNNING`, `LAGGING` (behind the market data, usually while catching up; clears by itself), `HUNG` (stuck inside one strategy call for longer than allowed; clears when it returns), `DEGRADED` (its independent executions produced different signals), `FAILED` (refused, could not start or failed while running; `reason` says why) or `STOPPED`. `LAGGING`, `HUNG` and `DEGRADED` come and go on a running run. The set may grow: read an unknown value as a running run with something to look at. See the Live execution guide.",
2940
3077
  },
2941
3078
  desired: {
2942
3079
  type: "string",
@@ -2946,8 +3083,17 @@ export const LiveRunSchema = {
2946
3083
  },
2947
3084
  reason: {
2948
3085
  type: "string",
2949
- description:
2950
- "Present only when the run stopped because it exceeded its resource allowance.",
3086
+ description: `Why the run stopped or failed, when there is something to say; absent otherwise. It is never a
3087
+ stack trace or an internal message. Either \`resource: ...\` (the platform stopped the run for
3088
+ exceeding its resource allowance; the text says which limit) or one of a fixed set of sentences for
3089
+ a \`FAILED\` run: the strategy cannot consume the source type the run was started with, the run's
3090
+ definition was refused, the run could not start after several attempts, the strategy failed while
3091
+ processing data, the run lost its data feed, or the generic \`The run failed.\`. The set may grow:
3092
+ read an unrecognised sentence as a failure and do not parse it. A \`FAILED\` run usually stays
3093
+ \`desired: RUNNING\` until you stop it, and counts as active (\`409\` on a new start, and toward your
3094
+ live-run limit) until then; one that can never run because its strategy cannot consume its source
3095
+ type is stopped by the platform itself (\`desired: STOPPED\`), so it holds no place.
3096
+ `,
2951
3097
  },
2952
3098
  sources: {
2953
3099
  type: "array",
@@ -2966,7 +3112,7 @@ export const LiveRunSchema = {
2966
3112
  },
2967
3113
  relay: {
2968
3114
  type: "boolean",
2969
- description: `Whether this run's signals are being relayed over the WebSocket channel described in the "Live execution" guide, right now. This is the effective value — \`false\` on a \`sandbox\` run regardless of what was requested at start; matches the requested value once \`stage\` reaches \`live\`.`,
3115
+ description: `Whether this run's signals are relayed over the WebSocket channel described in the "Live execution" guide. It is the value requested at start, in either stage.`,
2970
3116
  },
2971
3117
  startedAtMs: {
2972
3118
  type: "integer",
@@ -2977,7 +3123,16 @@ export const LiveRunSchema = {
2977
3123
  type: "object",
2978
3124
  additionalProperties: true,
2979
3125
  description:
2980
- "The sandbox trial's promotion verdict, once one exists. Shape is not yet stabilized as public API — treat as opaque diagnostics.",
3126
+ "The sandbox trial's promotion verdict. Absent for the whole 24-hour trial and present once it ends, so an absent `gate` means the trial has not finished. `passed` is the verdict; the rest is diagnostic detail whose shape is not yet stabilized as public API: treat it as opaque.",
3127
+ },
3128
+ paper: {
3129
+ allOf: [
3130
+ {
3131
+ $ref: "#/components/schemas/LivePaperConfig",
3132
+ },
3133
+ ],
3134
+ description:
3135
+ "The run's paper trading configuration as accepted at start, normalised. Absent when the run has no paper trading.",
2981
3136
  },
2982
3137
  },
2983
3138
  } as const;
@@ -3055,11 +3210,12 @@ export const LiveRunSummarySchema = {
3055
3210
  type: "string",
3056
3211
  enum: ["SANDBOX", "LIVE"],
3057
3212
  description:
3058
- "A new run always starts `SANDBOX` — a trial run compared against a second execution for agreement — and moves to `LIVE` once it passes.",
3213
+ "A new run always starts `SANDBOX`, a 24-hour trial in which it is compared against a second execution and checked for resource use and stability. A run that passes moves to `LIVE` automatically when the 24 hours are up.",
3059
3214
  },
3060
3215
  state: {
3061
3216
  type: "string",
3062
- description: `\`STARTING\` until first observed running; otherwise the runner's own reported state (e.g. \`RUNNING\`).`,
3217
+ description:
3218
+ "The run's health right now: `STARTING` (no runner has reported on it yet), `RUNNING`, `LAGGING` (behind the market data, usually while catching up; clears by itself), `HUNG` (stuck inside one strategy call for longer than allowed; clears when it returns), `DEGRADED` (its independent executions produced different signals), `FAILED` (refused, could not start or failed while running; `reason` says why) or `STOPPED`. `LAGGING`, `HUNG` and `DEGRADED` come and go on a running run. The set may grow: read an unknown value as a running run with something to look at. See the Live execution guide.",
3063
3219
  },
3064
3220
  desired: {
3065
3221
  type: "string",
@@ -3067,6 +3223,20 @@ export const LiveRunSummarySchema = {
3067
3223
  description:
3068
3224
  "What you last asked for. `state` can lag this briefly after `DELETE`.",
3069
3225
  },
3226
+ reason: {
3227
+ type: "string",
3228
+ description: `Why the run stopped or failed, when there is something to say; absent otherwise. It is never a
3229
+ stack trace or an internal message. Either \`resource: ...\` (the platform stopped the run for
3230
+ exceeding its resource allowance; the text says which limit) or one of a fixed set of sentences for
3231
+ a \`FAILED\` run: the strategy cannot consume the source type the run was started with, the run's
3232
+ definition was refused, the run could not start after several attempts, the strategy failed while
3233
+ processing data, the run lost its data feed, or the generic \`The run failed.\`. The set may grow:
3234
+ read an unrecognised sentence as a failure and do not parse it. A \`FAILED\` run usually stays
3235
+ \`desired: RUNNING\` until you stop it, and counts as active (\`409\` on a new start, and toward your
3236
+ live-run limit) until then; one that can never run because its strategy cannot consume its source
3237
+ type is stopped by the platform itself (\`desired: STOPPED\`), so it holds no place.
3238
+ `,
3239
+ },
3070
3240
  sources: {
3071
3241
  type: "array",
3072
3242
  items: {
@@ -3191,6 +3361,217 @@ export const LiveSignalPageSchema = {
3191
3361
  },
3192
3362
  } as const;
3193
3363
 
3364
+ export const LivePaperSchema = {
3365
+ type: "object",
3366
+ required: ["runId", "stage", "accounts"],
3367
+ properties: {
3368
+ runId: {
3369
+ type: "string",
3370
+ },
3371
+ stage: {
3372
+ type: "string",
3373
+ enum: ["SANDBOX", "LIVE"],
3374
+ },
3375
+ accounts: {
3376
+ type: "array",
3377
+ items: {
3378
+ $ref: "#/components/schemas/LivePaperAccount",
3379
+ },
3380
+ },
3381
+ },
3382
+ } as const;
3383
+
3384
+ export const LivePaperAccountSchema = {
3385
+ type: "object",
3386
+ required: [
3387
+ "currency",
3388
+ "initialFunding",
3389
+ "equity",
3390
+ "realisedPnl",
3391
+ "trades",
3392
+ "gaps",
3393
+ "openPositions",
3394
+ ],
3395
+ description: "One simulated account — one per quote currency the run trades.",
3396
+ properties: {
3397
+ currency: {
3398
+ type: "string",
3399
+ description: "The account's quote currency; every amount below is in it.",
3400
+ },
3401
+ initialFunding: {
3402
+ type: "number",
3403
+ format: "double",
3404
+ },
3405
+ equity: {
3406
+ type: "number",
3407
+ format: "double",
3408
+ description: "Latest recorded equity — see `equityKind`.",
3409
+ },
3410
+ equityAtMs: {
3411
+ type: "integer",
3412
+ format: "int64",
3413
+ description:
3414
+ "Market time of that value. Absent while the account holds its starting capital.",
3415
+ },
3416
+ equityKind: {
3417
+ type: "string",
3418
+ enum: ["equity", "mark"],
3419
+ description: `\`equity\` at a closed trade, \`mark\` at a periodic mark-to-market (includes open positions at market price).`,
3420
+ },
3421
+ realisedPnl: {
3422
+ type: "number",
3423
+ format: "double",
3424
+ description: "Sum of the PnL of the closed trades.",
3425
+ },
3426
+ trades: {
3427
+ type: "integer",
3428
+ format: "int64",
3429
+ description: "Closed trades.",
3430
+ },
3431
+ gaps: {
3432
+ type: "integer",
3433
+ description:
3434
+ "Times open positions were lost because the run was restarted with them open.",
3435
+ },
3436
+ openPositions: {
3437
+ type: "array",
3438
+ items: {
3439
+ $ref: "#/components/schemas/LivePaperPosition",
3440
+ },
3441
+ },
3442
+ kpi: {
3443
+ $ref: "#/components/schemas/LivePaperKpi",
3444
+ },
3445
+ },
3446
+ } as const;
3447
+
3448
+ export const LivePaperPositionSchema = {
3449
+ type: "object",
3450
+ required: ["instrument", "base", "cost"],
3451
+ properties: {
3452
+ instrument: {
3453
+ type: "string",
3454
+ example: "BTC/USDT",
3455
+ },
3456
+ base: {
3457
+ type: "number",
3458
+ format: "double",
3459
+ description: "Amount held, in the base asset.",
3460
+ },
3461
+ cost: {
3462
+ type: "number",
3463
+ format: "double",
3464
+ description: "What it cost, in the account's currency.",
3465
+ },
3466
+ },
3467
+ } as const;
3468
+
3469
+ export const LivePaperKpiSchema = {
3470
+ type: "object",
3471
+ description:
3472
+ "The same KPIs a backtest reports, over the trades closed so far. Absent until the first closed trade is recorded.",
3473
+ properties: {
3474
+ totalTrades: {
3475
+ type: "integer",
3476
+ format: "int64",
3477
+ },
3478
+ winCount: {
3479
+ type: "integer",
3480
+ format: "int64",
3481
+ },
3482
+ lossCount: {
3483
+ type: "integer",
3484
+ format: "int64",
3485
+ },
3486
+ winRate: {
3487
+ type: "number",
3488
+ format: "double",
3489
+ description: "Ratio (0.5 = half the trades won).",
3490
+ },
3491
+ pnlTotal: {
3492
+ type: "number",
3493
+ format: "double",
3494
+ },
3495
+ pnlTotalPercent: {
3496
+ type: "number",
3497
+ format: "double",
3498
+ description: "Percent of `initialFunding` (0-100 scale).",
3499
+ },
3500
+ sharpeRatio: {
3501
+ type: ["number", "null"],
3502
+ format: "double",
3503
+ },
3504
+ sortinoRatio: {
3505
+ type: ["number", "null"],
3506
+ format: "double",
3507
+ },
3508
+ cagr: {
3509
+ type: ["number", "null"],
3510
+ format: "double",
3511
+ description: "Ratio (0.15 for 15%).",
3512
+ },
3513
+ maxDrawdown: {
3514
+ type: "number",
3515
+ format: "double",
3516
+ },
3517
+ maxDrawdownPercent: {
3518
+ type: "number",
3519
+ format: "double",
3520
+ description: "Percent (0-100 scale).",
3521
+ },
3522
+ },
3523
+ } as const;
3524
+
3525
+ export const LivePaperEquityPageSchema = {
3526
+ type: "object",
3527
+ required: ["points"],
3528
+ properties: {
3529
+ points: {
3530
+ type: "array",
3531
+ items: {
3532
+ $ref: "#/components/schemas/LivePaperEquityPoint",
3533
+ },
3534
+ },
3535
+ _links: {
3536
+ type: "object",
3537
+ properties: {
3538
+ next: {
3539
+ type: "object",
3540
+ properties: {
3541
+ href: {
3542
+ type: "string",
3543
+ },
3544
+ },
3545
+ },
3546
+ },
3547
+ },
3548
+ },
3549
+ } as const;
3550
+
3551
+ export const LivePaperEquityPointSchema = {
3552
+ type: "object",
3553
+ required: ["currency", "kind", "eventTsMs"],
3554
+ properties: {
3555
+ currency: {
3556
+ type: "string",
3557
+ },
3558
+ kind: {
3559
+ type: "string",
3560
+ enum: ["equity", "mark", "gap"],
3561
+ },
3562
+ eventTsMs: {
3563
+ type: "integer",
3564
+ format: "int64",
3565
+ description: "Market time of the point.",
3566
+ },
3567
+ equity: {
3568
+ type: "number",
3569
+ format: "double",
3570
+ description: "Absent on a `gap`.",
3571
+ },
3572
+ },
3573
+ } as const;
3574
+
3194
3575
  export const LiveSignalSchema = {
3195
3576
  type: "object",
3196
3577
  required: [
@@ -3230,11 +3611,12 @@ export const LiveSignalSchema = {
3230
3611
  },
3231
3612
  type: {
3232
3613
  type: "string",
3233
- enum: ["hint", "info", "marker", "command"],
3614
+ enum: ["hint", "info", "marker", "command", "paper"],
3615
+ description: `\`paper\` items appear only for a run whose \`paper.output\` is \`mix\`; they are not relayed over the WebSocket channel.`,
3234
3616
  },
3235
3617
  kind: {
3236
3618
  type: ["string", "null"],
3237
- description: `\`BUY\`/\`SELL\` for a \`hint\`, the command name for a \`command\`, absent otherwise.`,
3619
+ description: `\`BUY\`/\`SELL\` for a \`hint\`, the command name for a \`command\`; for \`paper\`, what the item is: \`fill\`, \`trade\`, \`equity\`, \`mark\`, \`kpi\` or \`gap\`. Absent otherwise.`,
3238
3620
  },
3239
3621
  eventTsMs: {
3240
3622
  type: "integer",
@@ -3247,7 +3629,16 @@ export const LiveSignalSchema = {
3247
3629
  description: "Time it was published — always at or after `eventTsMs`.",
3248
3630
  },
3249
3631
  instrument: {
3250
- $ref: "#/components/schemas/LiveSignalInstrument",
3632
+ anyOf: [
3633
+ {
3634
+ $ref: "#/components/schemas/LiveSignalInstrument",
3635
+ },
3636
+ {
3637
+ type: "null",
3638
+ },
3639
+ ],
3640
+ description:
3641
+ "The instrument the signal is about. `null` only for a `paper` item about a whole account (`equity`, `mark`, `kpi`), whose `data.currency` names the account.",
3251
3642
  },
3252
3643
  order: {
3253
3644
  $ref: "#/components/schemas/LiveSignalOrder",
@@ -3255,7 +3646,8 @@ export const LiveSignalSchema = {
3255
3646
  data: {
3256
3647
  type: "object",
3257
3648
  additionalProperties: true,
3258
- description: "The signal's own free-form payload.",
3649
+ description:
3650
+ "The signal's own free-form payload, what the strategy put there with `signal.set(...)`. Whoever may read the run may read it, so on a `public` run it is public. A signal whose `data` is over 8 KiB (8,192 bytes of its JSON) is not pushed on the WebSocket channel, and `GET /live/{runId}/signals` returns it whole.",
3259
3651
  },
3260
3652
  regenerated: {
3261
3653
  type: "boolean",
@@ -3341,3 +3733,24 @@ export const LiveParamsUpdateResultSchema = {
3341
3733
  },
3342
3734
  },
3343
3735
  } as const;
3736
+
3737
+ export const LiveCommandResultSchema = {
3738
+ type: "object",
3739
+ required: ["runId", "commandId", "effectiveAtMs"],
3740
+ properties: {
3741
+ runId: {
3742
+ type: "string",
3743
+ },
3744
+ commandId: {
3745
+ type: "string",
3746
+ description:
3747
+ "This command's own id, generated fresh for this call. A retried request is a second, distinct command — this endpoint takes no idempotency key.",
3748
+ },
3749
+ effectiveAtMs: {
3750
+ type: "integer",
3751
+ format: "int64",
3752
+ description:
3753
+ "Epoch milliseconds — the market position every execution applies this command at.",
3754
+ },
3755
+ },
3756
+ } as const;