@qtsurfer/api-client 0.14.0 → 0.15.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.
- package/README.md +4 -2
- package/dist/index.d.ts +383 -43
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/generated/schemas.gen.ts +322 -61
- package/src/generated/sdk.gen.ts +106 -8
- package/src/generated/types.gen.ts +342 -51
|
@@ -18,6 +18,21 @@ export const ResponseErrorSchema = {
|
|
|
18
18
|
},
|
|
19
19
|
} as const;
|
|
20
20
|
|
|
21
|
+
export const ScalarStrategyParamValueSchema = {
|
|
22
|
+
description: "A scalar strategy property value for one execution.",
|
|
23
|
+
oneOf: [
|
|
24
|
+
{
|
|
25
|
+
type: "number",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: "string",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: "boolean",
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
} as const;
|
|
35
|
+
|
|
21
36
|
export const InstrumentSchema = {
|
|
22
37
|
description: "Exchange instrument identifier (e.g. a currency pair)",
|
|
23
38
|
type: "string",
|
|
@@ -320,30 +335,20 @@ the dataset instead of its current one. Defaults to the dataset's current versio
|
|
|
320
335
|
},
|
|
321
336
|
cadence: {
|
|
322
337
|
type: "string",
|
|
323
|
-
description: `Output bar cadence for the prepared range.
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
"1h",
|
|
338
|
-
"2h",
|
|
339
|
-
"4h",
|
|
340
|
-
"8h",
|
|
341
|
-
"12h",
|
|
342
|
-
"1d",
|
|
343
|
-
"1w",
|
|
344
|
-
"1q",
|
|
345
|
-
],
|
|
346
|
-
default: "1s",
|
|
338
|
+
description: `Output bar cadence for the prepared range. Coarser cadences are produced on demand by
|
|
339
|
+
resampling the source and stored alongside the native blob in cache. A target finer
|
|
340
|
+
than the source, or not an exact multiple of it, returns \`400\`. What's accepted, and
|
|
341
|
+
what omitting it means, depends on the source:
|
|
342
|
+
|
|
343
|
+
* Managed exchange — one of \`1s\`, \`5s\`, \`1m\`, \`3m\`, \`5m\`, \`15m\`, \`30m\`, \`1h\`, \`2h\`,
|
|
344
|
+
\`4h\`, \`8h\`, \`12h\`, \`1d\`, \`1w\`, \`1q\`; any other label returns \`400\`. Omitted = \`1s\`,
|
|
345
|
+
the publisher's native cadence.
|
|
346
|
+
* Dataset (\`exchangeId: user\`) — omitted = the dataset version's own discovered
|
|
347
|
+
\`cadence\` (see \`DatasetVersion.cadence\`), served as-is. Any cadence equal to or
|
|
348
|
+
coarser than it and an exact multiple of it is accepted, including ones outside the
|
|
349
|
+
managed-exchange list (e.g. \`15s\`); an \`rt\` dataset can be resampled to any fixed
|
|
350
|
+
cadence.
|
|
351
|
+
`,
|
|
347
352
|
},
|
|
348
353
|
},
|
|
349
354
|
example: {
|
|
@@ -371,7 +376,8 @@ export const JobStateSchema = {
|
|
|
371
376
|
description: `Current status of the job. Treat \`Completed | Aborted | Failed\` as
|
|
372
377
|
terminal; \`New | Started\` mean keep polling. A single-instrument prepare
|
|
373
378
|
is always terminal (\`Completed\`) — decide from
|
|
374
|
-
\`PrepareJobState.coverageRatio
|
|
379
|
+
\`PrepareJobState.coverageRatio\` (or \`dataFrom\`/\`dataTo\` against an \`rt\` dataset,
|
|
380
|
+
which has no ratio), not by polling.
|
|
375
381
|
`,
|
|
376
382
|
enum: ["New", "Started", "Completed", "Aborted", "Failed"],
|
|
377
383
|
example: "Completed",
|
|
@@ -418,8 +424,10 @@ walked hour by hour: \`totalHours\`/\`hoursWithData\`/\`hoursWithoutData\`. Agai
|
|
|
418
424
|
dataset-backed prepare (\`exchangeId: user\`), coverage is reported on the dataset's own
|
|
419
425
|
cadence grid instead — hour-walking a daily dataset would report \`1/24\` and read as
|
|
420
426
|
broken — via \`cadence\`/\`gaps\`/\`largestGapSteps\`; \`totalHours\`/\`hoursWithData\`/
|
|
421
|
-
\`hoursWithoutData\` are absent in that case. \`dataFrom\`/\`dataTo
|
|
422
|
-
|
|
427
|
+
\`hoursWithoutData\` are absent in that case. \`dataFrom\`/\`dataTo\` are present either way, and
|
|
428
|
+
\`coverageRatio\` too, computed accordingly — except against a dataset whose \`cadence\` is \`rt\`:
|
|
429
|
+
with no fixed step there is no expected row count to measure against, so \`coverageRatio\`
|
|
430
|
+
is absent and \`gaps\`/\`largestGapSteps\` are \`0\`.
|
|
423
431
|
`,
|
|
424
432
|
allOf: [
|
|
425
433
|
{
|
|
@@ -451,7 +459,8 @@ either way, computed accordingly.
|
|
|
451
459
|
\`totalHours\` is 0), the fraction of hours in the requested range that have served
|
|
452
460
|
data. Against a dataset (\`exchangeId: user\`): \`rows / expectedStepsAtCadence\`
|
|
453
461
|
over the dataset version's own range — echoing what ingest computed once, not
|
|
454
|
-
recomputed against a narrower prepare request.
|
|
462
|
+
recomputed against a narrower prepare request. Absent for an \`rt\` dataset (no
|
|
463
|
+
fixed step, so no expected row count).
|
|
455
464
|
`,
|
|
456
465
|
example: 0.994,
|
|
457
466
|
},
|
|
@@ -471,22 +480,23 @@ a dataset-backed prepare.
|
|
|
471
480
|
},
|
|
472
481
|
cadence: {
|
|
473
482
|
type: "string",
|
|
474
|
-
description: `The dataset version's own discovered cadence (e.g. \`1m\`, \`1h\`)
|
|
475
|
-
|
|
483
|
+
description: `The dataset version's own discovered cadence — a fixed grid (e.g. \`1m\`, \`1h\`) or
|
|
484
|
+
\`rt\` (see \`DatasetVersion.cadence\`). Only present for a dataset-backed prepare
|
|
485
|
+
(\`exchangeId: user\`).
|
|
476
486
|
`,
|
|
477
487
|
example: "1m",
|
|
478
488
|
},
|
|
479
489
|
gaps: {
|
|
480
490
|
type: "integer",
|
|
481
491
|
description: `Number of gaps in the dataset version at its own cadence, as discovered at ingest
|
|
482
|
-
time. Only present for a dataset-backed prepare.
|
|
492
|
+
time. \`0\` for \`rt\`. Only present for a dataset-backed prepare.
|
|
483
493
|
`,
|
|
484
494
|
example: 0,
|
|
485
495
|
},
|
|
486
496
|
largestGapSteps: {
|
|
487
497
|
type: "integer",
|
|
488
|
-
description: `The largest gap in the dataset version, in units of its own cadence step.
|
|
489
|
-
present for a dataset-backed prepare.
|
|
498
|
+
description: `The largest gap in the dataset version, in units of its own cadence step. \`0\` for
|
|
499
|
+
\`rt\`. Only present for a dataset-backed prepare.
|
|
490
500
|
`,
|
|
491
501
|
example: 0,
|
|
492
502
|
},
|
|
@@ -639,7 +649,7 @@ export const SweepBaseConfigSchema = {
|
|
|
639
649
|
type: "number",
|
|
640
650
|
format: "double",
|
|
641
651
|
exclusiveMinimum: 0,
|
|
642
|
-
default:
|
|
652
|
+
default: 100,
|
|
643
653
|
},
|
|
644
654
|
feeRate: {
|
|
645
655
|
type: "number",
|
|
@@ -969,7 +979,7 @@ export const SweepRunRowSchema = {
|
|
|
969
979
|
minimum: 0,
|
|
970
980
|
maximum: 1,
|
|
971
981
|
description:
|
|
972
|
-
"Probability that this run's Sharpe reflects real edge rather than the best draw from however many parameter vectors were tried. Above ~0.95 the result survives the multiple-testing correction; near 0.5 or below it is indistinguishable from the best of a pile of coin flips. Absent on aborted runs,
|
|
982
|
+
"Probability that this run's Sharpe reflects real edge rather than the best draw from however many parameter vectors were tried. Above ~0.95 the result survives the multiple-testing correction; near 0.5 or below it is indistinguishable from the best of a pile of coin flips. Absent on aborted runs, on sweeps with too few trials to establish any dispersion to deflate against, on runs with fewer than 3 period returns, and on a degenerate (near-constant) return series — all cases where the underlying statistic isn't meaningfully computable, rather than genuinely zero. A present value is the computed probability, however small.",
|
|
973
983
|
},
|
|
974
984
|
params: {
|
|
975
985
|
type: "object",
|
|
@@ -1032,8 +1042,10 @@ export const SweepRunRowSchema = {
|
|
|
1032
1042
|
$ref: "#/components/schemas/EquityCurveResult",
|
|
1033
1043
|
},
|
|
1034
1044
|
],
|
|
1035
|
-
description:
|
|
1036
|
-
|
|
1045
|
+
description: `Present whenever this trial actually has a curve — which is any completed run of a sweep that requested curves at all (\`equityCurve.mode\` \`topN\`/\`topPct\`), not only the ranked winners. Absent, not null, when there is genuinely nothing: the run aborted, it made no trades, or the sweep never retained curves (\`mode\` \`auto\`/\`none\`).
|
|
1046
|
+
Selection decides how the curve travels, not whether it exists. A row may carry \`url\` alone, or \`url\` together with the points inline.
|
|
1047
|
+
**Read \`points\`/\`equities\` to tell whether the curve is inline — never the presence of this object, and never the absence of \`url\`.** Both mislead, and in opposite directions: this object is present on rows that carry only a pointer, and \`url\` stays present alongside an inline curve so a caller can still re-request a different transform. An inline curve is emitted on the materialisation view (\`?order=natural\`), where each row is read once; the ranked view keeps the pointer, being polled.
|
|
1048
|
+
When only a pointer is present, \`GET\` the \`url\` for the curve. Its own \`meta\` there is the real, possibly size-guarded outcome. This outer \`meta\` may be a declaration rather than a measurement — for a row whose curve was not promoted, the point count is derived from the trade count (one equity point per closed trade) instead of being read from the store, to keep a polled response from doing per-row work.`,
|
|
1037
1049
|
},
|
|
1038
1050
|
},
|
|
1039
1051
|
} as const;
|
|
@@ -1246,7 +1258,8 @@ First failure wins and later ones are not recorded, so on a sweep where several
|
|
|
1246
1258
|
description: `The same \`JobState\` shape a single-execute \`BacktestJobResult\` carries — not a sweep-specific lookalike, the actual type, so field names and timestamp formatting match exactly.
|
|
1247
1259
|
\`state.status\` uses \`JobState\`'s own vocabulary (\`New\`/\`Started\`/\`Completed\`/ \`Aborted\`/\`Failed\`), mapped from the sweep's \`status\` field above rather than copying it: \`PARTIAL\` and \`CANCELLED\` both map to \`Aborted\`, because a sweep's \`PARTIAL\` is already terminal (some shards finished, some failed, nothing more is coming) unlike a single job's non-terminal \`Partial\`, which has no equivalent here at all.
|
|
1248
1260
|
\`state.completed\` is real ticks processed on a plain sweep. On a \`walkForward\` sweep it is currently always \`0\` — the walk-forward fold runner was not wired to count ticks when this shipped, unlike the plain shard path.
|
|
1249
|
-
\`state.size\` is
|
|
1261
|
+
\`state.size\` is an upfront estimate — range x the prepare's target cadence, set before any data is even loaded, not a query against loaded data — on a single execute and a plain sweep alike. A plain sweep's value is the sum of every shard's own \`size\` (each shard's per-run estimate x its own vector slice), the same additive shape \`state.completed\` already used above. \`0\` means the prepare context behind the job predates this field (a job whose prepare ran before the estimate existed) — never a guessed cadence standing in for a real one.
|
|
1262
|
+
On a \`walkForward\` sweep, \`state.size\` is still always \`0\`: fold runs were out of scope for the estimate the same way they are for \`state.completed\` above — a fold's \`size\` is simply never set, so the sum stays honest at \`0\` rather than needing a special case.`,
|
|
1250
1263
|
},
|
|
1251
1264
|
},
|
|
1252
1265
|
} as const;
|
|
@@ -1525,17 +1538,7 @@ reading: a run that produced no trades often did so for a reason stated here.
|
|
|
1525
1538
|
params: {
|
|
1526
1539
|
type: "object",
|
|
1527
1540
|
additionalProperties: {
|
|
1528
|
-
|
|
1529
|
-
{
|
|
1530
|
-
type: "number",
|
|
1531
|
-
},
|
|
1532
|
-
{
|
|
1533
|
-
type: "string",
|
|
1534
|
-
},
|
|
1535
|
-
{
|
|
1536
|
-
type: "boolean",
|
|
1537
|
-
},
|
|
1538
|
-
],
|
|
1541
|
+
$ref: "#/components/schemas/ScalarStrategyParamValue",
|
|
1539
1542
|
},
|
|
1540
1543
|
description:
|
|
1541
1544
|
"The strategy properties this run was given, echoed back as sent. Absent when the request carried none, so its presence is what distinguishes a parameterised run from one at the declared defaults — a stored result cannot otherwise say which vector produced it, and this endpoint is meant to be called repeatedly over one prepare.",
|
|
@@ -1979,8 +1982,11 @@ what a dataset covers. Absent until a version exists.
|
|
|
1979
1982
|
},
|
|
1980
1983
|
type: {
|
|
1981
1984
|
type: "string",
|
|
1982
|
-
enum: ["ticker"],
|
|
1983
|
-
description:
|
|
1985
|
+
enum: ["ticker", "klines"],
|
|
1986
|
+
description: `\`ticker\` for an upload or a \`dex\` import with no \`cadence\` requested (native per-trade
|
|
1987
|
+
data). \`klines\` for a \`dex\` import that requested a candle \`cadence\` — pre-aggregated
|
|
1988
|
+
bars rather than raw ticks. Purely informational; both shapes are read the same way.
|
|
1989
|
+
`,
|
|
1984
1990
|
example: "ticker",
|
|
1985
1991
|
},
|
|
1986
1992
|
instrument: {
|
|
@@ -2024,8 +2030,8 @@ a version exists.
|
|
|
2024
2030
|
},
|
|
2025
2031
|
cadence: {
|
|
2026
2032
|
type: "string",
|
|
2027
|
-
description: `\`currentVersionId\`'s own discovered
|
|
2028
|
-
version exists.
|
|
2033
|
+
description: `\`currentVersionId\`'s own discovered cadence — a fixed grid (e.g. \`1s\`, \`1m\`, \`1h\`) or
|
|
2034
|
+
\`rt\` (see \`DatasetVersion.cadence\`). Absent until a version exists.
|
|
2029
2035
|
`,
|
|
2030
2036
|
example: "1m",
|
|
2031
2037
|
},
|
|
@@ -2042,6 +2048,27 @@ export const DatasetWithLinksSchema = {
|
|
|
2042
2048
|
{
|
|
2043
2049
|
type: "object",
|
|
2044
2050
|
properties: {
|
|
2051
|
+
dataUrl: {
|
|
2052
|
+
type: "string",
|
|
2053
|
+
description: `Presigned GET URL to the current version's stored file — see \`dataFormat\` for
|
|
2054
|
+
which format it's actually in. Present only once the current version's status is
|
|
2055
|
+
\`ready\`. Long-lived (day-scale, not permanent): a DuckDB-WASM/\`lastra-ts\`-style
|
|
2056
|
+
reader issues HTTP range requests against it lazily over an extended viewing
|
|
2057
|
+
session, not in one shot like a browser upload.
|
|
2058
|
+
`,
|
|
2059
|
+
example:
|
|
2060
|
+
"https://storage.qtsurfer.com/00000000-.../ds_3f9a1c2e7b0d4a5f/dsv_8e2b4f19c6a03d7e/ticker_BTC_USDT_1700000000000_1700086400000_1m.lastra?X-Amz-...",
|
|
2061
|
+
},
|
|
2062
|
+
dataFormat: {
|
|
2063
|
+
type: "string",
|
|
2064
|
+
enum: ["lastra", "parquet"],
|
|
2065
|
+
description: `Which format \`dataUrl\` is actually in — check this rather than assuming it
|
|
2066
|
+
matches how you uploaded it. \`lastra\` — our native columnar format — for a CSV (or
|
|
2067
|
+
gzip/zip of one) upload, always converted on ingest. \`parquet\` for a parquet
|
|
2068
|
+
upload, stored as-is today.
|
|
2069
|
+
`,
|
|
2070
|
+
example: "lastra",
|
|
2071
|
+
},
|
|
2045
2072
|
_links: {
|
|
2046
2073
|
type: "object",
|
|
2047
2074
|
properties: {
|
|
@@ -2069,8 +2096,9 @@ export const DatasetUploadTargetSchema = {
|
|
|
2069
2096
|
properties: {
|
|
2070
2097
|
url: {
|
|
2071
2098
|
type: "string",
|
|
2072
|
-
description: `Presigned URL. \`PUT\` the
|
|
2073
|
-
no other API
|
|
2099
|
+
description: `Presigned URL. \`PUT\` the file here directly — the CSV or parquet itself, or a \`.gz\`/\`.zip\` of it
|
|
2100
|
+
(see \`createDataset\`'s own description) — no \`Authorization\` header, no other API
|
|
2101
|
+
credentials.
|
|
2074
2102
|
`,
|
|
2075
2103
|
example:
|
|
2076
2104
|
"https://storage.qtsurfer.com/uploads/00000000-.../up_1a2b3c4d5e6f7a8b/raw.csv?X-Amz-...",
|
|
@@ -2161,7 +2189,8 @@ not declared by the caller.
|
|
|
2161
2189
|
},
|
|
2162
2190
|
bytes: {
|
|
2163
2191
|
type: "integer",
|
|
2164
|
-
description:
|
|
2192
|
+
description:
|
|
2193
|
+
"Size of the stored file `dataUrl` points at — a converted `lastra` for a CSV/gzip/zip upload, or the parquet file itself, unconverted, for a parquet upload. Not the size of the bytes originally PUT to storage; see `dataFormat`.",
|
|
2165
2194
|
example: 4831022,
|
|
2166
2195
|
},
|
|
2167
2196
|
rows: {
|
|
@@ -2171,7 +2200,13 @@ not declared by the caller.
|
|
|
2171
2200
|
},
|
|
2172
2201
|
cadence: {
|
|
2173
2202
|
type: "string",
|
|
2174
|
-
description:
|
|
2203
|
+
description: `The cadence discovered from the data's own timestamps. Either a fixed grid — \`1s\`,
|
|
2204
|
+
\`5s\`, \`15s\`, \`1m\`, \`5m\`, \`15m\`, \`30m\`, \`1h\`, \`4h\`, \`1d\` — when at least half the
|
|
2205
|
+
intervals between consecutive rows fall on that step (small clock jitter tolerated), or
|
|
2206
|
+
\`rt\`: native data at the rate it was captured, each row at its own timestamp with no
|
|
2207
|
+
fixed step — per-trade on-chain swaps, block-spaced or sub-second ticks, irregular
|
|
2208
|
+
intervals. An \`rt\` dataset can be resampled to any fixed cadence at prepare time.
|
|
2209
|
+
`,
|
|
2175
2210
|
example: "1s",
|
|
2176
2211
|
},
|
|
2177
2212
|
timestampUnit: {
|
|
@@ -2184,20 +2219,42 @@ numeric values fell in (seconds, millis, or micros).
|
|
|
2184
2219
|
},
|
|
2185
2220
|
gaps: {
|
|
2186
2221
|
type: "integer",
|
|
2187
|
-
description:
|
|
2222
|
+
description:
|
|
2223
|
+
"Number of gaps at the discovered cadence. Always `0` for `rt`.",
|
|
2188
2224
|
example: 0,
|
|
2189
2225
|
},
|
|
2190
2226
|
largestGapSteps: {
|
|
2191
2227
|
type: "integer",
|
|
2192
|
-
description:
|
|
2228
|
+
description:
|
|
2229
|
+
"The largest gap, in units of the discovered cadence step. Always `0` for `rt`.",
|
|
2193
2230
|
example: 0,
|
|
2194
2231
|
},
|
|
2232
|
+
dataUrl: {
|
|
2233
|
+
type: "string",
|
|
2234
|
+
description: `Presigned GET URL to the stored file — see \`dataFormat\` for which format it's in.
|
|
2235
|
+
Present once the version is \`ready\`. Long-lived (day-scale, not permanent): a
|
|
2236
|
+
DuckDB-WASM/\`lastra-ts\`-style reader issues HTTP range requests against it lazily over
|
|
2237
|
+
an extended viewing session, not in one shot like a browser upload.
|
|
2238
|
+
`,
|
|
2239
|
+
example:
|
|
2240
|
+
"https://storage.qtsurfer.com/00000000-.../ds_3f9a1c2e7b0d4a5f/dsv_8e2b4f19c6a03d7e/ticker_BTC_USDT_1700000000000_1700086400000_1m.lastra?X-Amz-...",
|
|
2241
|
+
},
|
|
2242
|
+
dataFormat: {
|
|
2243
|
+
type: "string",
|
|
2244
|
+
enum: ["lastra", "parquet"],
|
|
2245
|
+
description: `Which format \`dataUrl\` is actually in — check this rather than assuming it matches
|
|
2246
|
+
how you uploaded it. \`lastra\` — our native columnar format — for a CSV (or gzip/zip
|
|
2247
|
+
of one) upload, always converted on ingest. \`parquet\` for a parquet upload, stored
|
|
2248
|
+
as-is today.
|
|
2249
|
+
`,
|
|
2250
|
+
example: "lastra",
|
|
2251
|
+
},
|
|
2195
2252
|
},
|
|
2196
2253
|
} as const;
|
|
2197
2254
|
|
|
2198
2255
|
export const DatasetUploadStateSchema = {
|
|
2199
2256
|
type: "object",
|
|
2200
|
-
description: `Progress of one upload, from staged through ingest.
|
|
2257
|
+
description: `Progress of one upload, from staged through ingest. Durably recorded once a version exists,
|
|
2201
2258
|
so \`ready\`/\`failed\` are permanent answers; \`uploading\`/\`ingesting\` reflect in-flight state
|
|
2202
2259
|
that can itself age out — see the \`404\` case on \`GET .../uploads/{uploadId}\`.
|
|
2203
2260
|
`,
|
|
@@ -2214,7 +2271,8 @@ that can itself age out — see the \`404\` case on \`GET .../uploads/{uploadId}
|
|
|
2214
2271
|
called yet.
|
|
2215
2272
|
* \`ingesting\` — \`finalize\` was called; the worker is parsing and validating the file.
|
|
2216
2273
|
* \`ready\` — ingested successfully. \`version\` carries the result.
|
|
2217
|
-
* \`failed\` — ingest rejected the file (e.g. bad CSV contract, mixed timestamp units
|
|
2274
|
+
* \`failed\` — ingest rejected the file (e.g. bad CSV contract, mixed timestamp units, a
|
|
2275
|
+
\`.zip\` with no file inside or more than one).
|
|
2218
2276
|
`,
|
|
2219
2277
|
example: "ready",
|
|
2220
2278
|
},
|
|
@@ -2222,6 +2280,209 @@ that can itself age out — see the \`404\` case on \`GET .../uploads/{uploadId}
|
|
|
2222
2280
|
type: "string",
|
|
2223
2281
|
description: "The ingest job id, while `status` is `ingesting`.",
|
|
2224
2282
|
},
|
|
2283
|
+
error: {
|
|
2284
|
+
type: "string",
|
|
2285
|
+
description: `A human-readable reason, present when \`status\` is \`failed\` (e.g. bad CSV contract,
|
|
2286
|
+
mixed timestamp units, a \`.zip\` with no file inside or more than one). Durably
|
|
2287
|
+
recorded alongside the failure itself, so it stays available however long after the
|
|
2288
|
+
fact you poll — not tied to how recently the failure happened.
|
|
2289
|
+
`,
|
|
2290
|
+
example: "line 3: column 'close' is not a number: not-a-number",
|
|
2291
|
+
},
|
|
2292
|
+
version: {
|
|
2293
|
+
allOf: [
|
|
2294
|
+
{
|
|
2295
|
+
$ref: "#/components/schemas/DatasetVersion",
|
|
2296
|
+
},
|
|
2297
|
+
],
|
|
2298
|
+
description: "Present when `status` is `ready` or `failed`.",
|
|
2299
|
+
},
|
|
2300
|
+
},
|
|
2301
|
+
} as const;
|
|
2302
|
+
|
|
2303
|
+
export const DatasetImportRequestSchema = {
|
|
2304
|
+
type: "object",
|
|
2305
|
+
description: `\`POST /datasets/imports\`'s request body. A common block plus one type-specific block,
|
|
2306
|
+
selected by \`type\` — \`dex\` is the only value today.
|
|
2307
|
+
`,
|
|
2308
|
+
required: ["name", "instrument", "from", "to", "type"],
|
|
2309
|
+
properties: {
|
|
2310
|
+
name: {
|
|
2311
|
+
type: "string",
|
|
2312
|
+
description: "A name unique among your datasets. `409` if already taken.",
|
|
2313
|
+
example: "weth-usdc-week",
|
|
2314
|
+
},
|
|
2315
|
+
instrument: {
|
|
2316
|
+
$ref: "#/components/schemas/Instrument",
|
|
2317
|
+
},
|
|
2318
|
+
from: {
|
|
2319
|
+
type: "string",
|
|
2320
|
+
format: "date-time",
|
|
2321
|
+
description:
|
|
2322
|
+
"Start of the range to fetch, inclusive. Must be before `to`.",
|
|
2323
|
+
example: "2026-08-01T00:00:00Z",
|
|
2324
|
+
},
|
|
2325
|
+
to: {
|
|
2326
|
+
type: "string",
|
|
2327
|
+
format: "date-time",
|
|
2328
|
+
description: `End of the range to fetch, exclusive. The total span is capped by your tier — a
|
|
2329
|
+
request wider than that ceiling is \`400\`, regardless of source type.
|
|
2330
|
+
`,
|
|
2331
|
+
example: "2026-08-08T00:00:00Z",
|
|
2332
|
+
},
|
|
2333
|
+
cadence: {
|
|
2334
|
+
type: "string",
|
|
2335
|
+
enum: ["1s", "1m", "5m"],
|
|
2336
|
+
description: `Optional. Omitted/blank keeps native per-trade event cadence — each swap at its own
|
|
2337
|
+
timestamp, so the resulting version's \`cadence\` is \`rt\` unless the swaps happen to sit
|
|
2338
|
+
on a fixed grid (see \`DatasetVersion.cadence\`). Set to \`1s\`, \`1m\` or
|
|
2339
|
+
\`5m\` instead to get pre-aggregated candles at that width rather than raw trades (the
|
|
2340
|
+
resulting dataset's \`type\` becomes \`klines\`); any other value is \`400\`. Not every
|
|
2341
|
+
network supports every cadence — an unsupported combination fails asynchronously, not
|
|
2342
|
+
at request time (see \`DatasetImportState.error\`).
|
|
2343
|
+
`,
|
|
2344
|
+
},
|
|
2345
|
+
type: {
|
|
2346
|
+
type: "string",
|
|
2347
|
+
enum: ["dex"],
|
|
2348
|
+
description: "The source to fetch from. `dex` is the only value today.",
|
|
2349
|
+
example: "dex",
|
|
2350
|
+
},
|
|
2351
|
+
dex: {
|
|
2352
|
+
$ref: "#/components/schemas/DatasetImportDexRequest",
|
|
2353
|
+
},
|
|
2354
|
+
},
|
|
2355
|
+
} as const;
|
|
2356
|
+
|
|
2357
|
+
export const DatasetImportDexRequestSchema = {
|
|
2358
|
+
type: "object",
|
|
2359
|
+
description: `The \`dex\` source's own fields — required when \`type\` is \`dex\`. \`id\`/\`version\` are required
|
|
2360
|
+
for a plain (native-cadence) import; both are ignored if the top-level \`cadence\` requested
|
|
2361
|
+
pre-aggregated candles instead, since that path needs neither a protocol nor a version
|
|
2362
|
+
distinction.
|
|
2363
|
+
`,
|
|
2364
|
+
required: ["network", "contract"],
|
|
2365
|
+
properties: {
|
|
2366
|
+
network: {
|
|
2367
|
+
type: "string",
|
|
2368
|
+
enum: ["ethereum", "robinhood"],
|
|
2369
|
+
description: "Which chain the pool/pair lives on.",
|
|
2370
|
+
example: "ethereum",
|
|
2371
|
+
},
|
|
2372
|
+
id: {
|
|
2373
|
+
type: "string",
|
|
2374
|
+
enum: ["uniswap"],
|
|
2375
|
+
description: `Which on-chain DEX protocol \`contract\` implements. Required unless the top-level
|
|
2376
|
+
\`cadence\` requested pre-aggregated candles, in which case it's ignored.
|
|
2377
|
+
`,
|
|
2378
|
+
example: "uniswap",
|
|
2379
|
+
},
|
|
2380
|
+
version: {
|
|
2381
|
+
type: "string",
|
|
2382
|
+
enum: ["v2", "v3"],
|
|
2383
|
+
description: `Uniswap version the pool/pair contract implements. Required unless the top-level
|
|
2384
|
+
\`cadence\` requested pre-aggregated candles, in which case it's ignored.
|
|
2385
|
+
`,
|
|
2386
|
+
example: "v3",
|
|
2387
|
+
},
|
|
2388
|
+
contract: {
|
|
2389
|
+
type: "string",
|
|
2390
|
+
description: "The pool (v3) or pair (v2) contract address.",
|
|
2391
|
+
example: "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
|
|
2392
|
+
},
|
|
2393
|
+
factory: {
|
|
2394
|
+
type: "string",
|
|
2395
|
+
description: `The factory that deployed \`contract\`. Optional — when omitted, it is discovered
|
|
2396
|
+
on-chain from \`contract\` itself at fetch time. Supply it explicitly only if you
|
|
2397
|
+
already know it, or the pool/pair belongs to a factory other than the canonical one
|
|
2398
|
+
for \`network\`/\`version\`. Either way, the pool/pair is validated against whichever
|
|
2399
|
+
factory is used before anything is fetched — a wrong or unrelated factory fails the
|
|
2400
|
+
import rather than silently fetching from the wrong pool. Ignored if the top-level
|
|
2401
|
+
\`cadence\` requested pre-aggregated candles.
|
|
2402
|
+
`,
|
|
2403
|
+
},
|
|
2404
|
+
},
|
|
2405
|
+
example: {
|
|
2406
|
+
network: "ethereum",
|
|
2407
|
+
id: "uniswap",
|
|
2408
|
+
version: "v3",
|
|
2409
|
+
contract: "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
|
|
2410
|
+
},
|
|
2411
|
+
} as const;
|
|
2412
|
+
|
|
2413
|
+
export const DatasetImportCreatedSchema = {
|
|
2414
|
+
type: "object",
|
|
2415
|
+
description:
|
|
2416
|
+
"The response to `POST /datasets/imports` — the dataset now exists, and its fetch has started.",
|
|
2417
|
+
required: ["datasetId", "importId", "jobId", "status"],
|
|
2418
|
+
properties: {
|
|
2419
|
+
datasetId: {
|
|
2420
|
+
type: "string",
|
|
2421
|
+
description:
|
|
2422
|
+
"Opaque id of the newly created dataset — same id space as `POST /datasets`.",
|
|
2423
|
+
example: "ds_3f9a1c2e7b0d4a5f",
|
|
2424
|
+
},
|
|
2425
|
+
importId: {
|
|
2426
|
+
type: "string",
|
|
2427
|
+
description: `Identifies this import. Pass to \`GET /datasets/{datasetId}/imports/{importId}\` to poll
|
|
2428
|
+
it — there is no separate "finalize" step the way an upload has.
|
|
2429
|
+
`,
|
|
2430
|
+
example: "imp_01j9z1x2y3z4a5b6c7d8e9f0g1",
|
|
2431
|
+
},
|
|
2432
|
+
jobId: {
|
|
2433
|
+
type: "string",
|
|
2434
|
+
description: "The fetch/ingest job id.",
|
|
2435
|
+
example:
|
|
2436
|
+
"dataset-import:00000000-.../ds_3f9a1c2e7b0d4a5f:imp_01j9z1x2y3z4a5b6c7d8e9f0g1",
|
|
2437
|
+
},
|
|
2438
|
+
status: {
|
|
2439
|
+
type: "string",
|
|
2440
|
+
enum: ["fetching"],
|
|
2441
|
+
description:
|
|
2442
|
+
"Always `fetching` in this response — the fetch has only just started.",
|
|
2443
|
+
example: "fetching",
|
|
2444
|
+
},
|
|
2445
|
+
},
|
|
2446
|
+
} as const;
|
|
2447
|
+
|
|
2448
|
+
export const DatasetImportStateSchema = {
|
|
2449
|
+
type: "object",
|
|
2450
|
+
description: `Progress of one import, from fetching through ingest. \`fetching\` is the one status only an
|
|
2451
|
+
import ever reports — an upload's file already exists by the time you can poll it; an
|
|
2452
|
+
import's doesn't, until this source finishes fetching it.
|
|
2453
|
+
`,
|
|
2454
|
+
required: ["importId", "status"],
|
|
2455
|
+
properties: {
|
|
2456
|
+
importId: {
|
|
2457
|
+
type: "string",
|
|
2458
|
+
example: "imp_01j9z1x2y3z4a5b6c7d8e9f0g1",
|
|
2459
|
+
},
|
|
2460
|
+
status: {
|
|
2461
|
+
type: "string",
|
|
2462
|
+
enum: ["fetching", "ingesting", "ready", "failed"],
|
|
2463
|
+
description: `* \`fetching\` — reading from the source; nothing staged yet.
|
|
2464
|
+
* \`ingesting\` — fetch complete, staged, and re-entered the same ingest chain an
|
|
2465
|
+
upload uses; the worker is parsing and validating it.
|
|
2466
|
+
* \`ready\` — ingested successfully. \`version\` carries the result.
|
|
2467
|
+
* \`failed\` — the fetch or the ingest that followed it was rejected. \`error\` names why.
|
|
2468
|
+
`,
|
|
2469
|
+
example: "ready",
|
|
2470
|
+
},
|
|
2471
|
+
jobId: {
|
|
2472
|
+
type: "string",
|
|
2473
|
+
description:
|
|
2474
|
+
"The fetch/ingest job id, while `status` is `fetching` or `ingesting`.",
|
|
2475
|
+
},
|
|
2476
|
+
error: {
|
|
2477
|
+
type: "string",
|
|
2478
|
+
description: `A human-readable reason, present when \`status\` is \`failed\` — an unresolvable
|
|
2479
|
+
pool/pair, no data in the requested range, a range older than the configured source
|
|
2480
|
+
retains, the fetch exceeding your tier's time ceiling, or any of
|
|
2481
|
+
\`DatasetUploadState.error\`'s own ingest-side reasons once fetching hands off to it.
|
|
2482
|
+
Durably recorded, same as on the upload path.
|
|
2483
|
+
`,
|
|
2484
|
+
example: "Import exceeded the tier's 12 minute ceiling",
|
|
2485
|
+
},
|
|
2225
2486
|
version: {
|
|
2226
2487
|
allOf: [
|
|
2227
2488
|
{
|