@qtsurfer/api-client 0.10.0 → 0.11.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/dist/index.d.ts +492 -20
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/generated/schemas.gen.ts +331 -15
- package/src/generated/sdk.gen.ts +197 -0
- package/src/generated/types.gen.ts +471 -19
|
@@ -269,10 +269,36 @@ export const DataSourceTypeSchema = {
|
|
|
269
269
|
|
|
270
270
|
export const PrepareRequestSchema = {
|
|
271
271
|
type: "object",
|
|
272
|
-
|
|
272
|
+
description: `Two shapes, chosen by the \`exchangeId\` path segment. Against a managed exchange,
|
|
273
|
+
\`instrument\` is required and \`datasetId\`/\`datasetVersionId\` are ignored. Against the
|
|
274
|
+
reserved \`exchangeId: user\`, send \`datasetId\` instead of \`instrument\` — \`instrument\` is
|
|
275
|
+
ignored there, since it comes from the dataset itself.
|
|
276
|
+
`,
|
|
277
|
+
required: ["from", "to"],
|
|
273
278
|
properties: {
|
|
274
279
|
instrument: {
|
|
275
|
-
|
|
280
|
+
allOf: [
|
|
281
|
+
{
|
|
282
|
+
$ref: "#/components/schemas/Instrument",
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
description: `Required unless \`exchangeId\` is the reserved value \`user\`, in which case send
|
|
286
|
+
\`datasetId\` instead.
|
|
287
|
+
`,
|
|
288
|
+
},
|
|
289
|
+
datasetId: {
|
|
290
|
+
type: "string",
|
|
291
|
+
description: `Only for \`exchangeId: user\`: the id of a dataset created via \`POST /datasets\`, in place
|
|
292
|
+
of \`instrument\`. Ignored against a managed exchange.
|
|
293
|
+
`,
|
|
294
|
+
example: "ds_3f9a1c2e7b0d4a5f",
|
|
295
|
+
},
|
|
296
|
+
datasetVersionId: {
|
|
297
|
+
type: "string",
|
|
298
|
+
description: `Only for \`exchangeId: user\`, and optional even then: pins a specific past version of
|
|
299
|
+
the dataset instead of its current one. Defaults to the dataset's current version.
|
|
300
|
+
`,
|
|
301
|
+
example: "dsv_8e2b4f19c6a03d7e",
|
|
276
302
|
},
|
|
277
303
|
from: {
|
|
278
304
|
type: "string",
|
|
@@ -300,7 +326,23 @@ resampling and stored alongside the native blob in cache. Coarser-than-
|
|
|
300
326
|
source values must be exact multiples of the source cadence — invalid
|
|
301
327
|
labels return \`400\`.
|
|
302
328
|
`,
|
|
303
|
-
enum: [
|
|
329
|
+
enum: [
|
|
330
|
+
"1s",
|
|
331
|
+
"5s",
|
|
332
|
+
"1m",
|
|
333
|
+
"3m",
|
|
334
|
+
"5m",
|
|
335
|
+
"15m",
|
|
336
|
+
"30m",
|
|
337
|
+
"1h",
|
|
338
|
+
"2h",
|
|
339
|
+
"4h",
|
|
340
|
+
"8h",
|
|
341
|
+
"12h",
|
|
342
|
+
"1d",
|
|
343
|
+
"1w",
|
|
344
|
+
"1q",
|
|
345
|
+
],
|
|
304
346
|
default: "1s",
|
|
305
347
|
},
|
|
306
348
|
},
|
|
@@ -363,12 +405,19 @@ is always terminal (\`Completed\`) — decide from
|
|
|
363
405
|
} as const;
|
|
364
406
|
|
|
365
407
|
export const PrepareJobStateSchema = {
|
|
366
|
-
description: `State of a single-instrument prepare job — the \`JobState\` shape plus a
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
408
|
+
description: `State of a single-instrument prepare job — the \`JobState\` shape plus a coverage summary.
|
|
409
|
+
A single-instrument prepare is always terminal (\`status: Completed\`): the client decides
|
|
410
|
+
what to do from \`coverageRatio\` (e.g. execute if it is at or above a chosen threshold)
|
|
411
|
+
rather than polling for missing hours that may never arrive — a missing hour for one
|
|
412
|
+
instrument usually means low activity, not missing data.
|
|
413
|
+
|
|
414
|
+
**Two coverage shapes, by exchange vs. dataset.** Against a managed exchange, coverage is
|
|
415
|
+
walked hour by hour: \`totalHours\`/\`hoursWithData\`/\`hoursWithoutData\`. Against a
|
|
416
|
+
dataset-backed prepare (\`exchangeId: user\`), coverage is reported on the dataset's own
|
|
417
|
+
cadence grid instead — hour-walking a daily dataset would report \`1/24\` and read as
|
|
418
|
+
broken — via \`cadence\`/\`gaps\`/\`largestGapSteps\`; \`totalHours\`/\`hoursWithData\`/
|
|
419
|
+
\`hoursWithoutData\` are absent in that case. \`dataFrom\`/\`dataTo\`/\`coverageRatio\` are present
|
|
420
|
+
either way, computed accordingly.
|
|
372
421
|
`,
|
|
373
422
|
allOf: [
|
|
374
423
|
{
|
|
@@ -396,25 +445,54 @@ activity, not missing data.
|
|
|
396
445
|
format: "double",
|
|
397
446
|
minimum: 0,
|
|
398
447
|
maximum: 1,
|
|
399
|
-
description:
|
|
400
|
-
fraction of hours in the requested range that have served
|
|
448
|
+
description: `Against a managed exchange: \`hoursWithData / totalHours\` in \`[0,1]\` (\`1.0\` when
|
|
449
|
+
\`totalHours\` is 0), the fraction of hours in the requested range that have served
|
|
450
|
+
data. Against a dataset (\`exchangeId: user\`): \`rows / expectedStepsAtCadence\`
|
|
451
|
+
over the dataset version's own range — echoing what ingest computed once, not
|
|
452
|
+
recomputed against a narrower prepare request.
|
|
401
453
|
`,
|
|
402
454
|
example: 0.994,
|
|
403
455
|
},
|
|
404
456
|
totalHours: {
|
|
405
457
|
type: "integer",
|
|
406
|
-
description:
|
|
458
|
+
description: `Number of whole hours in the requested prepare range. Managed exchanges only —
|
|
459
|
+
absent for a dataset-backed prepare.
|
|
460
|
+
`,
|
|
407
461
|
example: 168,
|
|
408
462
|
},
|
|
409
463
|
hoursWithData: {
|
|
410
464
|
type: "integer",
|
|
411
|
-
description:
|
|
465
|
+
description: `Number of hours in the range that have data. Managed exchanges only — absent for
|
|
466
|
+
a dataset-backed prepare.
|
|
467
|
+
`,
|
|
412
468
|
example: 167,
|
|
413
469
|
},
|
|
470
|
+
cadence: {
|
|
471
|
+
type: "string",
|
|
472
|
+
description: `The dataset version's own discovered cadence (e.g. \`1m\`, \`1h\`). Only present for a
|
|
473
|
+
dataset-backed prepare (\`exchangeId: user\`).
|
|
474
|
+
`,
|
|
475
|
+
example: "1m",
|
|
476
|
+
},
|
|
477
|
+
gaps: {
|
|
478
|
+
type: "integer",
|
|
479
|
+
description: `Number of gaps in the dataset version at its own cadence, as discovered at ingest
|
|
480
|
+
time. Only present for a dataset-backed prepare.
|
|
481
|
+
`,
|
|
482
|
+
example: 0,
|
|
483
|
+
},
|
|
484
|
+
largestGapSteps: {
|
|
485
|
+
type: "integer",
|
|
486
|
+
description: `The largest gap in the dataset version, in units of its own cadence step. Only
|
|
487
|
+
present for a dataset-backed prepare.
|
|
488
|
+
`,
|
|
489
|
+
example: 0,
|
|
490
|
+
},
|
|
414
491
|
hoursWithoutData: {
|
|
415
492
|
type: "array",
|
|
416
|
-
description:
|
|
417
|
-
|
|
493
|
+
description: `One entry per hour in the range that has no data, with a rationale. Managed
|
|
494
|
+
exchanges only — absent for a dataset-backed prepare.
|
|
495
|
+
`,
|
|
418
496
|
items: {
|
|
419
497
|
type: "object",
|
|
420
498
|
properties: {
|
|
@@ -1584,6 +1662,244 @@ the strategy — the check has not run. Stop waiting and re-request it later.
|
|
|
1584
1662
|
},
|
|
1585
1663
|
} as const;
|
|
1586
1664
|
|
|
1665
|
+
export const DatasetSchema = {
|
|
1666
|
+
type: "object",
|
|
1667
|
+
description: `A dataset's own metadata — not its data. \`currentVersionId\` is what a prepare against
|
|
1668
|
+
\`exchangeId: user\` reads by default; see \`DatasetVersion\` for what a version carries.
|
|
1669
|
+
|
|
1670
|
+
\`from\`/\`to\`/\`cadence\` mirror that current version's own discovered range and cadence, so
|
|
1671
|
+
you don't need a second call to \`GET /datasets/{datasetId}/uploads/{uploadId}\` just to see
|
|
1672
|
+
what a dataset covers. Absent until a version exists.
|
|
1673
|
+
`,
|
|
1674
|
+
required: ["datasetId", "name", "type", "instrument", "createdAt"],
|
|
1675
|
+
properties: {
|
|
1676
|
+
datasetId: {
|
|
1677
|
+
type: "string",
|
|
1678
|
+
description: "Opaque id, returned by `POST /datasets`.",
|
|
1679
|
+
example: "ds_3f9a1c2e7b0d4a5f",
|
|
1680
|
+
},
|
|
1681
|
+
name: {
|
|
1682
|
+
type: "string",
|
|
1683
|
+
description: "Unique among your datasets.",
|
|
1684
|
+
example: "My BTC ticks",
|
|
1685
|
+
},
|
|
1686
|
+
type: {
|
|
1687
|
+
type: "string",
|
|
1688
|
+
enum: ["ticker"],
|
|
1689
|
+
description: "Always `ticker` in v1.",
|
|
1690
|
+
example: "ticker",
|
|
1691
|
+
},
|
|
1692
|
+
instrument: {
|
|
1693
|
+
$ref: "#/components/schemas/Instrument",
|
|
1694
|
+
},
|
|
1695
|
+
createdAt: {
|
|
1696
|
+
type: "string",
|
|
1697
|
+
format: "date-time",
|
|
1698
|
+
description: "When the dataset was created.",
|
|
1699
|
+
example: "2026-08-20T09:00:00Z",
|
|
1700
|
+
},
|
|
1701
|
+
currentVersionId: {
|
|
1702
|
+
type: "string",
|
|
1703
|
+
description: `The id of the most recently finalized, successfully ingested version. Absent until at
|
|
1704
|
+
least one upload has finished ingesting.
|
|
1705
|
+
`,
|
|
1706
|
+
example: "dsv_8e2b4f19c6a03d7e",
|
|
1707
|
+
},
|
|
1708
|
+
updatedAt: {
|
|
1709
|
+
type: "string",
|
|
1710
|
+
format: "date-time",
|
|
1711
|
+
description:
|
|
1712
|
+
"When `currentVersionId` last changed. Absent until it has a value.",
|
|
1713
|
+
example: "2026-08-20T09:04:12Z",
|
|
1714
|
+
},
|
|
1715
|
+
from: {
|
|
1716
|
+
type: "string",
|
|
1717
|
+
format: "date-time",
|
|
1718
|
+
description: `Start of \`currentVersionId\`'s own data range, as discovered at ingest time. Absent
|
|
1719
|
+
until a version exists.
|
|
1720
|
+
`,
|
|
1721
|
+
example: "2026-03-01T00:00:00Z",
|
|
1722
|
+
},
|
|
1723
|
+
to: {
|
|
1724
|
+
type: "string",
|
|
1725
|
+
format: "date-time",
|
|
1726
|
+
description: `End of \`currentVersionId\`'s own data range, as discovered at ingest time. Absent until
|
|
1727
|
+
a version exists.
|
|
1728
|
+
`,
|
|
1729
|
+
example: "2026-03-08T00:00:00Z",
|
|
1730
|
+
},
|
|
1731
|
+
cadence: {
|
|
1732
|
+
type: "string",
|
|
1733
|
+
description: `\`currentVersionId\`'s own discovered bar cadence (e.g. \`1s\`, \`1m\`, \`1h\`). Absent until a
|
|
1734
|
+
version exists.
|
|
1735
|
+
`,
|
|
1736
|
+
example: "1m",
|
|
1737
|
+
},
|
|
1738
|
+
},
|
|
1739
|
+
} as const;
|
|
1740
|
+
|
|
1741
|
+
export const DatasetWithLinksSchema = {
|
|
1742
|
+
description:
|
|
1743
|
+
"A `Dataset` plus a self link. Returned by `GET /datasets/{datasetId}`.",
|
|
1744
|
+
allOf: [
|
|
1745
|
+
{
|
|
1746
|
+
$ref: "#/components/schemas/Dataset",
|
|
1747
|
+
},
|
|
1748
|
+
{
|
|
1749
|
+
type: "object",
|
|
1750
|
+
properties: {
|
|
1751
|
+
_links: {
|
|
1752
|
+
type: "object",
|
|
1753
|
+
properties: {
|
|
1754
|
+
self: {
|
|
1755
|
+
type: "object",
|
|
1756
|
+
properties: {
|
|
1757
|
+
href: {
|
|
1758
|
+
type: "string",
|
|
1759
|
+
example: "/v1/datasets/ds_3f9a1c2e7b0d4a5f",
|
|
1760
|
+
},
|
|
1761
|
+
},
|
|
1762
|
+
},
|
|
1763
|
+
},
|
|
1764
|
+
},
|
|
1765
|
+
},
|
|
1766
|
+
},
|
|
1767
|
+
],
|
|
1768
|
+
} as const;
|
|
1769
|
+
|
|
1770
|
+
export const DatasetCreatedSchema = {
|
|
1771
|
+
description: `A \`Dataset\` plus the first upload session — the presigned URL to PUT the file to.
|
|
1772
|
+
`,
|
|
1773
|
+
allOf: [
|
|
1774
|
+
{
|
|
1775
|
+
$ref: "#/components/schemas/Dataset",
|
|
1776
|
+
},
|
|
1777
|
+
{
|
|
1778
|
+
type: "object",
|
|
1779
|
+
required: ["uploadId", "upload"],
|
|
1780
|
+
properties: {
|
|
1781
|
+
uploadId: {
|
|
1782
|
+
type: "string",
|
|
1783
|
+
description: `Identifies this upload session. Pass to
|
|
1784
|
+
\`POST /datasets/{datasetId}/uploads/{uploadId}/finalize\` once the PUT completes.
|
|
1785
|
+
`,
|
|
1786
|
+
example: "up_1a2b3c4d5e6f7a8b",
|
|
1787
|
+
},
|
|
1788
|
+
upload: {
|
|
1789
|
+
type: "object",
|
|
1790
|
+
required: ["url", "expiresInMinutes"],
|
|
1791
|
+
properties: {
|
|
1792
|
+
url: {
|
|
1793
|
+
type: "string",
|
|
1794
|
+
description: `Presigned URL. \`PUT\` the raw CSV file here directly — no \`Authorization\`
|
|
1795
|
+
header, no other API credentials.
|
|
1796
|
+
`,
|
|
1797
|
+
example:
|
|
1798
|
+
"https://storage.qtsurfer.com/00000000-.../uploads/up_1a2b3c4d5e6f7a8b/raw.csv?X-Amz-...",
|
|
1799
|
+
},
|
|
1800
|
+
expiresInMinutes: {
|
|
1801
|
+
type: "integer",
|
|
1802
|
+
description: "How long `url` stays valid.",
|
|
1803
|
+
example: 15,
|
|
1804
|
+
},
|
|
1805
|
+
},
|
|
1806
|
+
},
|
|
1807
|
+
},
|
|
1808
|
+
},
|
|
1809
|
+
],
|
|
1810
|
+
} as const;
|
|
1811
|
+
|
|
1812
|
+
export const DatasetVersionSchema = {
|
|
1813
|
+
type: "object",
|
|
1814
|
+
description: `One successfully ingested upload. Cadence and timestamp unit are discovered from the file,
|
|
1815
|
+
not declared by the caller (D-11).
|
|
1816
|
+
`,
|
|
1817
|
+
required: ["datasetId"],
|
|
1818
|
+
properties: {
|
|
1819
|
+
datasetId: {
|
|
1820
|
+
type: "string",
|
|
1821
|
+
example: "ds_3f9a1c2e7b0d4a5f",
|
|
1822
|
+
},
|
|
1823
|
+
id: {
|
|
1824
|
+
type: "string",
|
|
1825
|
+
description:
|
|
1826
|
+
"The version id. Pass as `datasetVersionId` on `POST .../prepare` to pin it.",
|
|
1827
|
+
example: "dsv_8e2b4f19c6a03d7e",
|
|
1828
|
+
},
|
|
1829
|
+
bytes: {
|
|
1830
|
+
type: "integer",
|
|
1831
|
+
description: "Size of the uploaded file.",
|
|
1832
|
+
example: 4831022,
|
|
1833
|
+
},
|
|
1834
|
+
rows: {
|
|
1835
|
+
type: "integer",
|
|
1836
|
+
description: "Number of data rows.",
|
|
1837
|
+
example: 86400,
|
|
1838
|
+
},
|
|
1839
|
+
cadence: {
|
|
1840
|
+
type: "string",
|
|
1841
|
+
description: "The discovered bar cadence (e.g. `1s`, `1m`, `1h`).",
|
|
1842
|
+
example: "1s",
|
|
1843
|
+
},
|
|
1844
|
+
timestampUnit: {
|
|
1845
|
+
type: "string",
|
|
1846
|
+
enum: ["iso", "s", "ms", "us"],
|
|
1847
|
+
description: `The unit the \`timestamp\` column was uploaded in — ISO-8601, or the epoch band its
|
|
1848
|
+
numeric values fell in (seconds, millis, or micros).
|
|
1849
|
+
`,
|
|
1850
|
+
example: "iso",
|
|
1851
|
+
},
|
|
1852
|
+
gaps: {
|
|
1853
|
+
type: "integer",
|
|
1854
|
+
description: "Number of gaps at the discovered cadence.",
|
|
1855
|
+
example: 0,
|
|
1856
|
+
},
|
|
1857
|
+
largestGapSteps: {
|
|
1858
|
+
type: "integer",
|
|
1859
|
+
description: "The largest gap, in units of the discovered cadence step.",
|
|
1860
|
+
example: 0,
|
|
1861
|
+
},
|
|
1862
|
+
},
|
|
1863
|
+
} as const;
|
|
1864
|
+
|
|
1865
|
+
export const DatasetUploadStateSchema = {
|
|
1866
|
+
type: "object",
|
|
1867
|
+
description: `Progress of one upload, from staged through ingest. Postgres-backed once a version exists,
|
|
1868
|
+
so \`ready\`/\`failed\` are permanent answers; \`uploading\`/\`ingesting\` reflect in-flight state
|
|
1869
|
+
that can itself age out — see the \`404\` case on \`GET .../uploads/{uploadId}\`.
|
|
1870
|
+
`,
|
|
1871
|
+
required: ["uploadId", "status"],
|
|
1872
|
+
properties: {
|
|
1873
|
+
uploadId: {
|
|
1874
|
+
type: "string",
|
|
1875
|
+
example: "up_1a2b3c4d5e6f7a8b",
|
|
1876
|
+
},
|
|
1877
|
+
status: {
|
|
1878
|
+
type: "string",
|
|
1879
|
+
enum: ["uploading", "ingesting", "ready", "failed"],
|
|
1880
|
+
description: `* \`uploading\` — the file was PUT to the presigned URL, but \`finalize\` has not been
|
|
1881
|
+
called yet.
|
|
1882
|
+
* \`ingesting\` — \`finalize\` was called; the worker is parsing and validating the file.
|
|
1883
|
+
* \`ready\` — ingested successfully. \`version\` carries the result.
|
|
1884
|
+
* \`failed\` — ingest rejected the file (e.g. bad CSV contract, mixed timestamp units).
|
|
1885
|
+
`,
|
|
1886
|
+
example: "ready",
|
|
1887
|
+
},
|
|
1888
|
+
jobId: {
|
|
1889
|
+
type: "string",
|
|
1890
|
+
description: "The ingest job id, while `status` is `ingesting`.",
|
|
1891
|
+
},
|
|
1892
|
+
version: {
|
|
1893
|
+
allOf: [
|
|
1894
|
+
{
|
|
1895
|
+
$ref: "#/components/schemas/DatasetVersion",
|
|
1896
|
+
},
|
|
1897
|
+
],
|
|
1898
|
+
description: "Present when `status` is `ready` or `failed`.",
|
|
1899
|
+
},
|
|
1900
|
+
},
|
|
1901
|
+
} as const;
|
|
1902
|
+
|
|
1587
1903
|
export const AuthTokenResponseSchema = {
|
|
1588
1904
|
type: "object",
|
|
1589
1905
|
required: ["access_token", "token_type", "expires_in", "tier"],
|
package/src/generated/sdk.gen.ts
CHANGED
|
@@ -67,6 +67,23 @@ import type {
|
|
|
67
67
|
GetBacktestResultData,
|
|
68
68
|
GetBacktestResultResponse,
|
|
69
69
|
GetBacktestResultError,
|
|
70
|
+
ListDatasetsData,
|
|
71
|
+
ListDatasetsResponse,
|
|
72
|
+
CreateDatasetData,
|
|
73
|
+
CreateDatasetResponse,
|
|
74
|
+
CreateDatasetError,
|
|
75
|
+
DeleteDatasetData,
|
|
76
|
+
DeleteDatasetResponse,
|
|
77
|
+
DeleteDatasetError,
|
|
78
|
+
GetDatasetData,
|
|
79
|
+
GetDatasetResponse,
|
|
80
|
+
GetDatasetError,
|
|
81
|
+
FinalizeDatasetUploadData,
|
|
82
|
+
FinalizeDatasetUploadResponse,
|
|
83
|
+
FinalizeDatasetUploadError,
|
|
84
|
+
GetDatasetUploadData,
|
|
85
|
+
GetDatasetUploadResponse,
|
|
86
|
+
GetDatasetUploadError,
|
|
70
87
|
} from "./types.gen";
|
|
71
88
|
import { client as _heyApiClient } from "./client.gen";
|
|
72
89
|
|
|
@@ -456,6 +473,11 @@ export const getStrategyCode = <ThrowOnError extends boolean = false>(
|
|
|
456
473
|
* The same params always return the same `jobId` (idempotent). Repeated calls with identical
|
|
457
474
|
* params do not enqueue duplicate work — they reuse the existing job.
|
|
458
475
|
*
|
|
476
|
+
* **`exchangeId: user` is reserved for your own uploaded data.** Instead of a managed
|
|
477
|
+
* exchange, it prepares from a dataset you created via `POST /datasets` (see the **Dataset**
|
|
478
|
+
* endpoints) — send `datasetId` in place of `instrument`. See `PrepareRequest` below for the
|
|
479
|
+
* two request shapes.
|
|
480
|
+
*
|
|
459
481
|
*/
|
|
460
482
|
export const prepareBacktest = <ThrowOnError extends boolean = false>(
|
|
461
483
|
options: Options<PrepareBacktestData, ThrowOnError>
|
|
@@ -485,6 +507,9 @@ export const prepareBacktest = <ThrowOnError extends boolean = false>(
|
|
|
485
507
|
* Retrieves the current state of the prepare job identified by `jobId`.
|
|
486
508
|
* Poll until `status` is `Completed`, `Failed`, or `Aborted`.
|
|
487
509
|
*
|
|
510
|
+
* For a dataset prepare (`exchangeId: user`), coverage is reported against the dataset's own
|
|
511
|
+
* cadence grid instead of hours — see `cadence`/`gaps`/`largestGapSteps` on `PrepareJobState`.
|
|
512
|
+
*
|
|
488
513
|
*/
|
|
489
514
|
export const getPrepareStatus = <ThrowOnError extends boolean = false>(
|
|
490
515
|
options: Options<GetPrepareStatusData, ThrowOnError>
|
|
@@ -676,6 +701,9 @@ export const getSweepSensitivity = <ThrowOnError extends boolean = false>(
|
|
|
676
701
|
* The same params (same `prepareJobId`, `strategyId`, `storeSignals`) always return the same
|
|
677
702
|
* `jobId` (idempotent).
|
|
678
703
|
*
|
|
704
|
+
* Works unchanged for a dataset-backed prepare (`exchangeId: user`) — the request body is
|
|
705
|
+
* identical either way, since the instrument and range are recovered from `prepareJobId`.
|
|
706
|
+
*
|
|
679
707
|
*/
|
|
680
708
|
export const executeBacktest = <ThrowOnError extends boolean = false>(
|
|
681
709
|
options: Options<ExecuteBacktestData, ThrowOnError>
|
|
@@ -755,3 +783,172 @@ export const getBacktestResult = <ThrowOnError extends boolean = false>(
|
|
|
755
783
|
...options,
|
|
756
784
|
});
|
|
757
785
|
};
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* List your datasets
|
|
789
|
+
* Every dataset you have created and not deleted, most recently created first. Never a `404`
|
|
790
|
+
* — an empty array if you have none, same convention as `GET /strategies`.
|
|
791
|
+
*
|
|
792
|
+
*/
|
|
793
|
+
export const listDatasets = <ThrowOnError extends boolean = false>(
|
|
794
|
+
options?: Options<ListDatasetsData, ThrowOnError>
|
|
795
|
+
) => {
|
|
796
|
+
return (options?.client ?? _heyApiClient).get<
|
|
797
|
+
ListDatasetsResponse,
|
|
798
|
+
unknown,
|
|
799
|
+
ThrowOnError
|
|
800
|
+
>({
|
|
801
|
+
security: [
|
|
802
|
+
{
|
|
803
|
+
scheme: "bearer",
|
|
804
|
+
type: "http",
|
|
805
|
+
},
|
|
806
|
+
],
|
|
807
|
+
url: "/datasets",
|
|
808
|
+
...options,
|
|
809
|
+
});
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* Create a dataset and get a URL to upload it to
|
|
814
|
+
* Creates a dataset AND its first upload session in one call — a presigned URL your client
|
|
815
|
+
* PUTs the file to directly, no API credentials involved in that PUT. Call
|
|
816
|
+
* `POST /datasets/{datasetId}/uploads/{uploadId}/finalize` once the upload completes to kick
|
|
817
|
+
* off ingest.
|
|
818
|
+
*
|
|
819
|
+
* v1 is ticker data only — `type` is not a request field, it is always `"ticker"` in the
|
|
820
|
+
* response. `instrument` must be a plain spot pair (`BASE/QUOTE`, exactly one `/`); derivative
|
|
821
|
+
* forms (e.g. `BTC/USDT:USDT`) are rejected.
|
|
822
|
+
*
|
|
823
|
+
* **Upload format.** A CSV with a header row. Required columns: `timestamp` (ISO-8601, or
|
|
824
|
+
* numeric epoch seconds/millis/micros — detected from the first row, then enforced for every
|
|
825
|
+
* later row), `close`. Optional columns: `open`, `high`, `low`, `volume`, `quoteVolume`,
|
|
826
|
+
* `bid`, `bidSize`, `ask`, `askSize`. Cadence and timestamp unit are discovered from the data,
|
|
827
|
+
* not declared.
|
|
828
|
+
*
|
|
829
|
+
*/
|
|
830
|
+
export const createDataset = <ThrowOnError extends boolean = false>(
|
|
831
|
+
options: Options<CreateDatasetData, ThrowOnError>
|
|
832
|
+
) => {
|
|
833
|
+
return (options.client ?? _heyApiClient).post<
|
|
834
|
+
CreateDatasetResponse,
|
|
835
|
+
CreateDatasetError,
|
|
836
|
+
ThrowOnError
|
|
837
|
+
>({
|
|
838
|
+
security: [
|
|
839
|
+
{
|
|
840
|
+
scheme: "bearer",
|
|
841
|
+
type: "http",
|
|
842
|
+
},
|
|
843
|
+
],
|
|
844
|
+
url: "/datasets",
|
|
845
|
+
...options,
|
|
846
|
+
headers: {
|
|
847
|
+
"Content-Type": "application/json",
|
|
848
|
+
...options?.headers,
|
|
849
|
+
},
|
|
850
|
+
});
|
|
851
|
+
};
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Delete a dataset
|
|
855
|
+
* Soft-delete — the dataset stops appearing in `GET /datasets`/`GET /datasets/{datasetId}` and
|
|
856
|
+
* can no longer be prepared from, but its object data is reclaimed later rather than purged
|
|
857
|
+
* inline, so a backtest already running against one of its versions is not disrupted.
|
|
858
|
+
*
|
|
859
|
+
*/
|
|
860
|
+
export const deleteDataset = <ThrowOnError extends boolean = false>(
|
|
861
|
+
options: Options<DeleteDatasetData, ThrowOnError>
|
|
862
|
+
) => {
|
|
863
|
+
return (options.client ?? _heyApiClient).delete<
|
|
864
|
+
DeleteDatasetResponse,
|
|
865
|
+
DeleteDatasetError,
|
|
866
|
+
ThrowOnError
|
|
867
|
+
>({
|
|
868
|
+
security: [
|
|
869
|
+
{
|
|
870
|
+
scheme: "bearer",
|
|
871
|
+
type: "http",
|
|
872
|
+
},
|
|
873
|
+
],
|
|
874
|
+
url: "/datasets/{datasetId}",
|
|
875
|
+
...options,
|
|
876
|
+
});
|
|
877
|
+
};
|
|
878
|
+
|
|
879
|
+
/**
|
|
880
|
+
* Get a dataset by id
|
|
881
|
+
* Detail for one dataset, plus a self link.
|
|
882
|
+
*/
|
|
883
|
+
export const getDataset = <ThrowOnError extends boolean = false>(
|
|
884
|
+
options: Options<GetDatasetData, ThrowOnError>
|
|
885
|
+
) => {
|
|
886
|
+
return (options.client ?? _heyApiClient).get<
|
|
887
|
+
GetDatasetResponse,
|
|
888
|
+
GetDatasetError,
|
|
889
|
+
ThrowOnError
|
|
890
|
+
>({
|
|
891
|
+
security: [
|
|
892
|
+
{
|
|
893
|
+
scheme: "bearer",
|
|
894
|
+
type: "http",
|
|
895
|
+
},
|
|
896
|
+
],
|
|
897
|
+
url: "/datasets/{datasetId}",
|
|
898
|
+
...options,
|
|
899
|
+
});
|
|
900
|
+
};
|
|
901
|
+
|
|
902
|
+
/**
|
|
903
|
+
* Finalize an uploaded file and start ingest
|
|
904
|
+
* Call once the file has been PUT to the `upload.url` from `POST /datasets`. Enqueues ingest
|
|
905
|
+
* and returns immediately; poll
|
|
906
|
+
* `GET /datasets/{datasetId}/uploads/{uploadId}` for the result.
|
|
907
|
+
*
|
|
908
|
+
* Idempotent — a repeat finalize of the same upload returns the same `jobId` rather than
|
|
909
|
+
* enqueueing a second ingest.
|
|
910
|
+
*
|
|
911
|
+
*/
|
|
912
|
+
export const finalizeDatasetUpload = <ThrowOnError extends boolean = false>(
|
|
913
|
+
options: Options<FinalizeDatasetUploadData, ThrowOnError>
|
|
914
|
+
) => {
|
|
915
|
+
return (options.client ?? _heyApiClient).post<
|
|
916
|
+
FinalizeDatasetUploadResponse,
|
|
917
|
+
FinalizeDatasetUploadError,
|
|
918
|
+
ThrowOnError
|
|
919
|
+
>({
|
|
920
|
+
security: [
|
|
921
|
+
{
|
|
922
|
+
scheme: "bearer",
|
|
923
|
+
type: "http",
|
|
924
|
+
},
|
|
925
|
+
],
|
|
926
|
+
url: "/datasets/{datasetId}/uploads/{uploadId}/finalize",
|
|
927
|
+
...options,
|
|
928
|
+
});
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* Get the state of an upload/ingest
|
|
933
|
+
* Poll after `POST .../finalize` until `status` is `ready` or `failed`. Also reports
|
|
934
|
+
* `uploading` (finalize not called yet, but the file was PUT) before you finalize at all.
|
|
935
|
+
*
|
|
936
|
+
*/
|
|
937
|
+
export const getDatasetUpload = <ThrowOnError extends boolean = false>(
|
|
938
|
+
options: Options<GetDatasetUploadData, ThrowOnError>
|
|
939
|
+
) => {
|
|
940
|
+
return (options.client ?? _heyApiClient).get<
|
|
941
|
+
GetDatasetUploadResponse,
|
|
942
|
+
GetDatasetUploadError,
|
|
943
|
+
ThrowOnError
|
|
944
|
+
>({
|
|
945
|
+
security: [
|
|
946
|
+
{
|
|
947
|
+
scheme: "bearer",
|
|
948
|
+
type: "http",
|
|
949
|
+
},
|
|
950
|
+
],
|
|
951
|
+
url: "/datasets/{datasetId}/uploads/{uploadId}",
|
|
952
|
+
...options,
|
|
953
|
+
});
|
|
954
|
+
};
|