@qtsurfer/api-client 0.19.0 → 0.21.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",
@@ -2027,6 +2063,13 @@ not be established without constructing the strategy.
2027
2063
  type: "string",
2028
2064
  },
2029
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
+ },
2030
2073
  },
2031
2074
  } as const;
2032
2075
 
@@ -2191,6 +2234,13 @@ least one upload has finished ingesting.
2191
2234
  `,
2192
2235
  example: "dsv_8e2b4f19c6a03d7e",
2193
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
+ },
2194
2244
  updatedAt: {
2195
2245
  type: "string",
2196
2246
  format: "date-time",
@@ -2849,12 +2899,23 @@ export const StartLiveRequestSchema = {
2849
2899
  enum: ["private", "public"],
2850
2900
  default: "private",
2851
2901
  description:
2852
- "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.",
2853
2903
  },
2854
2904
  relay: {
2855
2905
  type: "boolean",
2856
2906
  default: false,
2857
- 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.`,
2908
+ },
2909
+ stream: {
2910
+ type: "boolean",
2911
+ default: false,
2912
+ description: `Ask for a **stream URL**: a secret address that a simple client, or a service that passes your signals
2913
+ on to others, can open as a plain WebSocket to receive this run's signals as they are produced, one JSON
2914
+ text frame per signal, with none of the live-execution protocol around it. The URL comes back as
2915
+ \`streamUrl\` in the response to this call. Available from the \`sandbox\` stage on, on the plans that may
2916
+ broadcast; any other plan gets \`429\`. It can be asked for **only when the run is started** (not added
2917
+ later), and it also turns \`relay\` on. See the "Live execution" guide, "A plain WebSocket stream of a run".
2918
+ `,
2858
2919
  },
2859
2920
  name: {
2860
2921
  type: "string",
@@ -2961,6 +3022,23 @@ export const UpdateLiveParamsRequestSchema = {
2961
3022
  },
2962
3023
  } as const;
2963
3024
 
3025
+ export const SendLiveCommandRequestSchema = {
3026
+ type: "object",
3027
+ required: ["command"],
3028
+ properties: {
3029
+ command: {
3030
+ type: "string",
3031
+ description: "The command's text — non-blank.",
3032
+ },
3033
+ properties: {
3034
+ type: "object",
3035
+ additionalProperties: true,
3036
+ description:
3037
+ "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.",
3038
+ },
3039
+ },
3040
+ } as const;
3041
+
2964
3042
  export const LiveRunSchema = {
2965
3043
  type: "object",
2966
3044
  required: [
@@ -3001,11 +3079,12 @@ export const LiveRunSchema = {
3001
3079
  type: "string",
3002
3080
  enum: ["SANDBOX", "LIVE"],
3003
3081
  description:
3004
- "A new run always starts `SANDBOX` — a trial run compared against a second execution for agreement — and moves to `LIVE` once it passes.",
3082
+ "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.",
3005
3083
  },
3006
3084
  state: {
3007
3085
  type: "string",
3008
- description: `\`STARTING\` until first observed running; otherwise the runner's own reported state (e.g. \`RUNNING\`).`,
3086
+ description:
3087
+ "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.",
3009
3088
  },
3010
3089
  desired: {
3011
3090
  type: "string",
@@ -3015,8 +3094,17 @@ export const LiveRunSchema = {
3015
3094
  },
3016
3095
  reason: {
3017
3096
  type: "string",
3018
- description:
3019
- "Present only when the run stopped because it exceeded its resource allowance.",
3097
+ description: `Why the run stopped or failed, when there is something to say; absent otherwise. It is never a
3098
+ stack trace or an internal message. Either \`resource: ...\` (the platform stopped the run for
3099
+ exceeding its resource allowance; the text says which limit) or one of a fixed set of sentences for
3100
+ a \`FAILED\` run: the strategy cannot consume the source type the run was started with, the run's
3101
+ definition was refused, the run could not start after several attempts, the strategy failed while
3102
+ processing data, the run lost its data feed, or the generic \`The run failed.\`. The set may grow:
3103
+ read an unrecognised sentence as a failure and do not parse it. A \`FAILED\` run usually stays
3104
+ \`desired: RUNNING\` until you stop it, and counts as active (\`409\` on a new start, and toward your
3105
+ live-run limit) until then; one that can never run because its strategy cannot consume its source
3106
+ type is stopped by the platform itself (\`desired: STOPPED\`), so it holds no place.
3107
+ `,
3020
3108
  },
3021
3109
  sources: {
3022
3110
  type: "array",
@@ -3035,7 +3123,7 @@ export const LiveRunSchema = {
3035
3123
  },
3036
3124
  relay: {
3037
3125
  type: "boolean",
3038
- 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\`.`,
3126
+ 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.`,
3039
3127
  },
3040
3128
  startedAtMs: {
3041
3129
  type: "integer",
@@ -3046,7 +3134,7 @@ export const LiveRunSchema = {
3046
3134
  type: "object",
3047
3135
  additionalProperties: true,
3048
3136
  description:
3049
- "The sandbox trial's promotion verdict, once one exists. Shape is not yet stabilized as public API — treat as opaque diagnostics.",
3137
+ "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.",
3050
3138
  },
3051
3139
  paper: {
3052
3140
  allOf: [
@@ -3057,6 +3145,144 @@ export const LiveRunSchema = {
3057
3145
  description:
3058
3146
  "The run's paper trading configuration as accepted at start, normalised. Absent when the run has no paper trading.",
3059
3147
  },
3148
+ stats: {
3149
+ allOf: [
3150
+ {
3151
+ $ref: "#/components/schemas/LiveRunStats",
3152
+ },
3153
+ ],
3154
+ description: `The run's latest counters. Returned by the two reads, \`GET /strategy/{strategyId}/live\` and
3155
+ \`GET /live/{runId}\`; never by starting or stopping a run. Absent until the first snapshot exists
3156
+ (a run that has just started), and absent is not zero.
3157
+ `,
3158
+ },
3159
+ },
3160
+ } as const;
3161
+
3162
+ export const LiveRunStatsSchema = {
3163
+ type: "object",
3164
+ required: ["processed", "opsPerSecond", "instrumentsSeen", "asOfMs", "stale"],
3165
+ description: `What a run has been doing, as of its last snapshot. The platform refreshes it about once a minute
3166
+ while the run is being executed, so \`opsPerSecond\` is an average over that interval, not an
3167
+ instantaneous rate.
3168
+ `,
3169
+ properties: {
3170
+ processed: {
3171
+ type: "integer",
3172
+ format: "int64",
3173
+ description:
3174
+ "Updates of instruments the run has accepted since it started executing. It can start again from zero if the run is restarted.",
3175
+ },
3176
+ opsPerSecond: {
3177
+ type: "number",
3178
+ description:
3179
+ "Updates accepted per second over the last refresh interval. `0` when none arrived.",
3180
+ },
3181
+ instrumentsSeen: {
3182
+ type: "integer",
3183
+ description:
3184
+ "How many distinct instruments the run has received an update for.",
3185
+ },
3186
+ asOfMs: {
3187
+ type: "integer",
3188
+ format: "int64",
3189
+ description: "Epoch milliseconds when these counters were last written.",
3190
+ },
3191
+ progressedAtMs: {
3192
+ type: "integer",
3193
+ format: "int64",
3194
+ description: `Epoch milliseconds of the last snapshot in which \`processed\` had grown. Absent until the run has
3195
+ processed anything. A run fed by a source that updates rarely (a funding rate, for example) can
3196
+ stay flat for hours: that is how such a run behaves, not a fault.
3197
+ `,
3198
+ },
3199
+ stale: {
3200
+ type: "boolean",
3201
+ description: `\`true\` when the run is meant to be running (\`desired\` is \`RUNNING\`) and its counters have not
3202
+ been refreshed for several refresh intervals: the platform has stopped updating them, which is
3203
+ worth checking against \`state\`. \`false\` otherwise. A run whose \`processed\` is flat is not stale;
3204
+ \`progressedAtMs\` is how to tell it apart.
3205
+ `,
3206
+ },
3207
+ },
3208
+ } as const;
3209
+
3210
+ export const LiveRunDetailSchema = {
3211
+ description:
3212
+ "A run as returned by `GET /live/{runId}`, the full state of `LiveRun` plus when it last changed.",
3213
+ allOf: [
3214
+ {
3215
+ $ref: "#/components/schemas/LiveRun",
3216
+ },
3217
+ {
3218
+ type: "object",
3219
+ required: ["updatedAtMs"],
3220
+ properties: {
3221
+ updatedAtMs: {
3222
+ type: "integer",
3223
+ format: "int64",
3224
+ description:
3225
+ "Epoch milliseconds of the run's last change, from any cause. It only moves forward, so of two reads of the same run the one with the larger value is the newer.",
3226
+ },
3227
+ },
3228
+ },
3229
+ ],
3230
+ } as const;
3231
+
3232
+ export const LiveRunWithStreamSchema = {
3233
+ description: `A run as \`LiveRun\` describes it, plus its \`streamUrl\` when it has one. It is what **starting a run** and
3234
+ \`GET /strategy/{strategyId}/live\` return: your own run, read with your own credentials. Stopping a run
3235
+ and \`GET /live/{runId}\` return \`LiveRun\`, which never carries the URL.
3236
+ `,
3237
+ allOf: [
3238
+ {
3239
+ $ref: "#/components/schemas/LiveRun",
3240
+ },
3241
+ {
3242
+ type: "object",
3243
+ properties: {
3244
+ streamUrl: {
3245
+ type: "string",
3246
+ format: "uri",
3247
+ description: `The run's secret stream URL (\`wss://…\`). **Treat it like a password**: anyone who holds it can read
3248
+ this run's signals, from the sandbox stage on. Present only when the run was started with
3249
+ \`stream: true\`, is wanted running, has not had its stream revoked, and your plan still lets you
3250
+ broadcast; absent otherwise (a plan that lets you broadcast again gets the same URL back). Rotate
3251
+ it with \`POST /live/{runId}/stream\` if it leaks, revoke it with \`DELETE /live/{runId}/stream\`.
3252
+ `,
3253
+ },
3254
+ },
3255
+ },
3256
+ ],
3257
+ } as const;
3258
+
3259
+ export const LiveStreamUrlSchema = {
3260
+ type: "object",
3261
+ required: ["streamUrl"],
3262
+ description:
3263
+ "A run's new stream URL, as returned by `POST /live/{runId}/stream`.",
3264
+ properties: {
3265
+ streamUrl: {
3266
+ type: "string",
3267
+ format: "uri",
3268
+ description:
3269
+ "The run's new secret stream URL. The previous one has stopped working.",
3270
+ },
3271
+ },
3272
+ } as const;
3273
+
3274
+ export const LiveStreamRevokedSchema = {
3275
+ type: "object",
3276
+ required: ["runId", "revoked"],
3277
+ description: "What `DELETE /live/{runId}/stream` returns.",
3278
+ properties: {
3279
+ runId: {
3280
+ type: "string",
3281
+ },
3282
+ revoked: {
3283
+ type: "boolean",
3284
+ description: "Always `true`.",
3285
+ },
3060
3286
  },
3061
3287
  } as const;
3062
3288
 
@@ -3133,11 +3359,12 @@ export const LiveRunSummarySchema = {
3133
3359
  type: "string",
3134
3360
  enum: ["SANDBOX", "LIVE"],
3135
3361
  description:
3136
- "A new run always starts `SANDBOX` — a trial run compared against a second execution for agreement — and moves to `LIVE` once it passes.",
3362
+ "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.",
3137
3363
  },
3138
3364
  state: {
3139
3365
  type: "string",
3140
- description: `\`STARTING\` until first observed running; otherwise the runner's own reported state (e.g. \`RUNNING\`).`,
3366
+ description:
3367
+ "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.",
3141
3368
  },
3142
3369
  desired: {
3143
3370
  type: "string",
@@ -3145,6 +3372,20 @@ export const LiveRunSummarySchema = {
3145
3372
  description:
3146
3373
  "What you last asked for. `state` can lag this briefly after `DELETE`.",
3147
3374
  },
3375
+ reason: {
3376
+ type: "string",
3377
+ description: `Why the run stopped or failed, when there is something to say; absent otherwise. It is never a
3378
+ stack trace or an internal message. Either \`resource: ...\` (the platform stopped the run for
3379
+ exceeding its resource allowance; the text says which limit) or one of a fixed set of sentences for
3380
+ a \`FAILED\` run: the strategy cannot consume the source type the run was started with, the run's
3381
+ definition was refused, the run could not start after several attempts, the strategy failed while
3382
+ processing data, the run lost its data feed, or the generic \`The run failed.\`. The set may grow:
3383
+ read an unrecognised sentence as a failure and do not parse it. A \`FAILED\` run usually stays
3384
+ \`desired: RUNNING\` until you stop it, and counts as active (\`409\` on a new start, and toward your
3385
+ live-run limit) until then; one that can never run because its strategy cannot consume its source
3386
+ type is stopped by the platform itself (\`desired: STOPPED\`), so it holds no place.
3387
+ `,
3388
+ },
3148
3389
  sources: {
3149
3390
  type: "array",
3150
3391
  items: {
@@ -3554,7 +3795,8 @@ export const LiveSignalSchema = {
3554
3795
  data: {
3555
3796
  type: "object",
3556
3797
  additionalProperties: true,
3557
- description: "The signal's own free-form payload.",
3798
+ description:
3799
+ "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.",
3558
3800
  },
3559
3801
  regenerated: {
3560
3802
  type: "boolean",
@@ -3640,3 +3882,24 @@ export const LiveParamsUpdateResultSchema = {
3640
3882
  },
3641
3883
  },
3642
3884
  } as const;
3885
+
3886
+ export const LiveCommandResultSchema = {
3887
+ type: "object",
3888
+ required: ["runId", "commandId", "effectiveAtMs"],
3889
+ properties: {
3890
+ runId: {
3891
+ type: "string",
3892
+ },
3893
+ commandId: {
3894
+ type: "string",
3895
+ description:
3896
+ "This command's own id, generated fresh for this call. A retried request is a second, distinct command — this endpoint takes no idempotency key.",
3897
+ },
3898
+ effectiveAtMs: {
3899
+ type: "integer",
3900
+ format: "int64",
3901
+ description:
3902
+ "Epoch milliseconds — the market position every execution applies this command at.",
3903
+ },
3904
+ },
3905
+ } as const;