@qtsurfer/api-client 0.12.0 → 0.14.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 +3 -2
- package/dist/index.d.ts +172 -28
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/generated/schemas.gen.ts +107 -34
- package/src/generated/sdk.gen.ts +60 -7
- package/src/generated/types.gen.ts +141 -20
package/README.md
CHANGED
|
@@ -68,8 +68,8 @@ pluggable token stores so callers don't reinvent that plumbing.
|
|
|
68
68
|
|
|
69
69
|
All operations are exported as standalone functions; every operation accepts an `Options` object and returns `{ data, error, response }`.
|
|
70
70
|
|
|
71
|
-
The table is exhaustive: `src/generated/` is produced from the OpenAPI spec, so **all
|
|
72
|
-
the spec declares are exported. The rows below describe **spec version 0.
|
|
71
|
+
The table is exhaustive: `src/generated/` is produced from the OpenAPI spec, so **all 29 operations**
|
|
72
|
+
the spec declares are exported. The rows below describe **spec version 0.112.0**, which is versioned
|
|
73
73
|
independently of this package.
|
|
74
74
|
|
|
75
75
|
| Function | Method | Path | Purpose |
|
|
@@ -100,6 +100,7 @@ independently of this package.
|
|
|
100
100
|
| `createDataset` | POST | `/datasets` | Create a dataset and obtain its first upload session |
|
|
101
101
|
| `deleteDataset` | DELETE | `/datasets/{datasetId}` | Soft-delete a dataset |
|
|
102
102
|
| `getDataset` | GET | `/datasets/{datasetId}` | Get dataset metadata |
|
|
103
|
+
| `openDatasetUpload` | POST | `/datasets/{datasetId}/uploads` | Open an upload session for a later dataset version |
|
|
103
104
|
| `finalizeDatasetUpload` | POST | `/datasets/{datasetId}/uploads/{uploadId}/finalize` | Queue ingest after uploading a file |
|
|
104
105
|
| `getDatasetUpload` | GET | `/datasets/{datasetId}/uploads/{uploadId}` | Get an upload's ingestion state |
|
|
105
106
|
|
package/dist/index.d.ts
CHANGED
|
@@ -226,7 +226,7 @@ type PrepareRequest = {
|
|
|
226
226
|
*/
|
|
227
227
|
type JobState = {
|
|
228
228
|
/**
|
|
229
|
-
*
|
|
229
|
+
* Identifier for the job's execution context. Its current shape is a colon-delimited string encoding the data source type, an internal user id, the exchange, the job id, and the instrument — but that structure is not a committed contract and may change without notice. Treat it as an opaque token: store and pass it back, don't parse it.
|
|
230
230
|
*/
|
|
231
231
|
contextId: string;
|
|
232
232
|
/**
|
|
@@ -539,10 +539,22 @@ type SweepRunRow = {
|
|
|
539
539
|
* Absolute net PnL in the output currency.
|
|
540
540
|
*/
|
|
541
541
|
pnl: number;
|
|
542
|
+
/**
|
|
543
|
+
* Same units as `pnlTotalPercent` on the single-run result — percent (0-100 scale).
|
|
544
|
+
*/
|
|
542
545
|
pnlPct: number;
|
|
546
|
+
/**
|
|
547
|
+
* Same units as `cagr` on the single-run result — a ratio, not a percent.
|
|
548
|
+
*/
|
|
543
549
|
cagr: number;
|
|
550
|
+
/**
|
|
551
|
+
* Same units as `maxDrawdownPercent` on the single-run result — percent (0-100 scale).
|
|
552
|
+
*/
|
|
544
553
|
maxDdPct: number;
|
|
545
554
|
trades: number;
|
|
555
|
+
/**
|
|
556
|
+
* Same units as `winRate` on the single-run result — a fraction, 0.0-1.0 (a rate, not a percent).
|
|
557
|
+
*/
|
|
546
558
|
winRate: number;
|
|
547
559
|
belowTradeFloor: boolean;
|
|
548
560
|
aborted: boolean;
|
|
@@ -720,7 +732,7 @@ type WalkForwardFold = {
|
|
|
720
732
|
*/
|
|
721
733
|
type AcceptedJob = {
|
|
722
734
|
/**
|
|
723
|
-
* Unique job identifier; use this to poll for completion.
|
|
735
|
+
* Unique job identifier; use this to poll for completion. For a sweep, pass this same value as the `requestId` path parameter to `executeSweep` — same identifier, different name at that call site.
|
|
724
736
|
*/
|
|
725
737
|
jobId: string;
|
|
726
738
|
};
|
|
@@ -787,7 +799,7 @@ type ResultMap = {
|
|
|
787
799
|
*/
|
|
788
800
|
totalTrades?: number;
|
|
789
801
|
/**
|
|
790
|
-
*
|
|
802
|
+
* Fraction of profitable trades, 0.0-1.0 (a rate, not a percent — multiply by 100 to display as one). Zero when `totalTrades` is 0.
|
|
791
803
|
*/
|
|
792
804
|
winRate?: number;
|
|
793
805
|
/**
|
|
@@ -799,7 +811,7 @@ type ResultMap = {
|
|
|
799
811
|
*/
|
|
800
812
|
sortinoRatio?: number;
|
|
801
813
|
/**
|
|
802
|
-
* Compound Annual Growth Rate
|
|
814
|
+
* Compound Annual Growth Rate (eg. 0.15 for 15%)
|
|
803
815
|
*/
|
|
804
816
|
cagr?: number;
|
|
805
817
|
/**
|
|
@@ -814,6 +826,12 @@ type ResultMap = {
|
|
|
814
826
|
* Equity curve over the backtest. `points[0]` (or `timestamps[0]`/`equities[0]` in `SHORT` mode) is an anchor at the backtest `from` with `initialCapital`; the remaining points are one sample per emitted yield, in order. Use it to plot the strategy's running equity without re-deriving it from the yield history. Always inline for a plain backtest today — never a pointer (`url`); that shape exists only for a sweep row's top-N winners.
|
|
815
827
|
*/
|
|
816
828
|
equityCurve?: EquityCurveResult;
|
|
829
|
+
/**
|
|
830
|
+
* 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.
|
|
831
|
+
*/
|
|
832
|
+
params?: {
|
|
833
|
+
[key: string]: number | string | boolean;
|
|
834
|
+
};
|
|
817
835
|
/**
|
|
818
836
|
* Number of signals emitted during strategy execution
|
|
819
837
|
*/
|
|
@@ -1141,29 +1159,57 @@ type DatasetWithLinks = Dataset & {
|
|
|
1141
1159
|
};
|
|
1142
1160
|
};
|
|
1143
1161
|
/**
|
|
1144
|
-
* A
|
|
1162
|
+
* A presigned destination for uploading a raw dataset file directly to storage.
|
|
1163
|
+
*/
|
|
1164
|
+
type DatasetUploadTarget = {
|
|
1165
|
+
/**
|
|
1166
|
+
* Presigned URL. `PUT` the raw CSV file here directly — no `Authorization` header,
|
|
1167
|
+
* no other API credentials.
|
|
1168
|
+
*
|
|
1169
|
+
*/
|
|
1170
|
+
url: string;
|
|
1171
|
+
/**
|
|
1172
|
+
* How long `url` stays valid.
|
|
1173
|
+
*/
|
|
1174
|
+
expiresInMinutes: number;
|
|
1175
|
+
};
|
|
1176
|
+
/**
|
|
1177
|
+
* An upload session — an id plus the presigned URL to PUT the raw file to. Returned both by
|
|
1178
|
+
* `POST /datasets` (as part of the new dataset) and by `POST /datasets/{datasetId}/uploads`
|
|
1179
|
+
* (on its own, for an existing one).
|
|
1145
1180
|
*
|
|
1146
1181
|
*/
|
|
1147
|
-
type
|
|
1182
|
+
type DatasetUploadSession = {
|
|
1148
1183
|
/**
|
|
1149
1184
|
* Identifies this upload session. Pass to
|
|
1150
1185
|
* `POST /datasets/{datasetId}/uploads/{uploadId}/finalize` once the PUT completes.
|
|
1151
1186
|
*
|
|
1152
1187
|
*/
|
|
1153
1188
|
uploadId: string;
|
|
1154
|
-
upload:
|
|
1155
|
-
/**
|
|
1156
|
-
* Presigned URL. `PUT` the raw CSV file here directly — no `Authorization`
|
|
1157
|
-
* header, no other API credentials.
|
|
1158
|
-
*
|
|
1159
|
-
*/
|
|
1160
|
-
url: string;
|
|
1161
|
-
/**
|
|
1162
|
-
* How long `url` stays valid.
|
|
1163
|
-
*/
|
|
1164
|
-
expiresInMinutes: number;
|
|
1165
|
-
};
|
|
1189
|
+
upload: DatasetUploadTarget;
|
|
1166
1190
|
};
|
|
1191
|
+
/**
|
|
1192
|
+
* The metadata available immediately after creating a dataset, plus its first upload
|
|
1193
|
+
* session — the presigned URL to PUT the file to. Version-derived fields such as
|
|
1194
|
+
* `createdAt`, `currentVersionId`, range, and cadence are available from `GET /datasets/{datasetId}`
|
|
1195
|
+
* after the relevant lifecycle stages, not in this creation response.
|
|
1196
|
+
*
|
|
1197
|
+
*/
|
|
1198
|
+
type DatasetCreated = {
|
|
1199
|
+
/**
|
|
1200
|
+
* Opaque id of the newly created dataset.
|
|
1201
|
+
*/
|
|
1202
|
+
datasetId: string;
|
|
1203
|
+
/**
|
|
1204
|
+
* Unique name of the newly created dataset.
|
|
1205
|
+
*/
|
|
1206
|
+
name: string;
|
|
1207
|
+
/**
|
|
1208
|
+
* Always `ticker` in v1.
|
|
1209
|
+
*/
|
|
1210
|
+
type: "ticker";
|
|
1211
|
+
instrument: Instrument;
|
|
1212
|
+
} & DatasetUploadSession;
|
|
1167
1213
|
/**
|
|
1168
1214
|
* One successfully ingested upload. Cadence and timestamp unit are discovered from the file,
|
|
1169
1215
|
* not declared by the caller.
|
|
@@ -1775,6 +1821,9 @@ type CancelSweepData = {
|
|
|
1775
1821
|
path: {
|
|
1776
1822
|
exchangeId: string;
|
|
1777
1823
|
type: DataSourceType;
|
|
1824
|
+
/**
|
|
1825
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
1826
|
+
*/
|
|
1778
1827
|
requestId: string;
|
|
1779
1828
|
sweepId: string;
|
|
1780
1829
|
};
|
|
@@ -1803,6 +1852,9 @@ type GetSweepResultData = {
|
|
|
1803
1852
|
path: {
|
|
1804
1853
|
exchangeId: string;
|
|
1805
1854
|
type: DataSourceType;
|
|
1855
|
+
/**
|
|
1856
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
1857
|
+
*/
|
|
1806
1858
|
requestId: string;
|
|
1807
1859
|
sweepId: string;
|
|
1808
1860
|
};
|
|
@@ -1838,6 +1890,9 @@ type GetSweepSensitivityData = {
|
|
|
1838
1890
|
path: {
|
|
1839
1891
|
exchangeId: string;
|
|
1840
1892
|
type: DataSourceType;
|
|
1893
|
+
/**
|
|
1894
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
1895
|
+
*/
|
|
1841
1896
|
requestId: string;
|
|
1842
1897
|
sweepId: string;
|
|
1843
1898
|
};
|
|
@@ -1868,6 +1923,9 @@ type GetSweepRunEquityCurveData = {
|
|
|
1868
1923
|
path: {
|
|
1869
1924
|
exchangeId: string;
|
|
1870
1925
|
type: DataSourceType;
|
|
1926
|
+
/**
|
|
1927
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
1928
|
+
*/
|
|
1871
1929
|
requestId: string;
|
|
1872
1930
|
sweepId: string;
|
|
1873
1931
|
/**
|
|
@@ -1922,6 +1980,28 @@ type ExecuteBacktestData = {
|
|
|
1922
1980
|
*/
|
|
1923
1981
|
storeSignals?: boolean;
|
|
1924
1982
|
equityCurve?: EquityCurveOptions;
|
|
1983
|
+
/**
|
|
1984
|
+
* Strategy properties to apply to this run. Omit to run the strategy's declared
|
|
1985
|
+
* defaults, which is exactly what a request without this field has always done.
|
|
1986
|
+
*
|
|
1987
|
+
* Each key is the `name` declared on the strategy's `@StrategyProperty`, which
|
|
1988
|
+
* need NOT match the Java field it annotates — `GET`/`POST /strategy` returns
|
|
1989
|
+
* `declaredProperties` for precisely this. A key naming no declared property is
|
|
1990
|
+
* rejected: the job fails with the list of names the strategy does declare,
|
|
1991
|
+
* rather than completing at the defaults and handing back a plausible result for
|
|
1992
|
+
* parameters nobody chose.
|
|
1993
|
+
*
|
|
1994
|
+
* Scalars only — number, string or boolean. Ranges and lists belong to
|
|
1995
|
+
* `executeSweep`; one request here is one run. `null` is not a value: leave the
|
|
1996
|
+
* key out to keep a property at its default. Keys are made of letters, digits,
|
|
1997
|
+
* `_`, `-` and dots, and may not be `strategyId`, `storeSignals`, `equityCurve`,
|
|
1998
|
+
* `backtestEnabled` or `backtestFakeExecution` — those configure the job rather
|
|
1999
|
+
* than the strategy.
|
|
2000
|
+
*
|
|
2001
|
+
*/
|
|
2002
|
+
params?: {
|
|
2003
|
+
[key: string]: number | string | boolean;
|
|
2004
|
+
};
|
|
1925
2005
|
};
|
|
1926
2006
|
path: {
|
|
1927
2007
|
/**
|
|
@@ -2147,6 +2227,31 @@ type GetDatasetResponses = {
|
|
|
2147
2227
|
200: DatasetWithLinks;
|
|
2148
2228
|
};
|
|
2149
2229
|
type GetDatasetResponse = GetDatasetResponses[keyof GetDatasetResponses];
|
|
2230
|
+
type OpenDatasetUploadData = {
|
|
2231
|
+
body?: never;
|
|
2232
|
+
path: {
|
|
2233
|
+
/**
|
|
2234
|
+
* The id returned by `POST /datasets`
|
|
2235
|
+
*/
|
|
2236
|
+
datasetId: string;
|
|
2237
|
+
};
|
|
2238
|
+
query?: never;
|
|
2239
|
+
url: "/datasets/{datasetId}/uploads";
|
|
2240
|
+
};
|
|
2241
|
+
type OpenDatasetUploadErrors = {
|
|
2242
|
+
/**
|
|
2243
|
+
* No such dataset for this user
|
|
2244
|
+
*/
|
|
2245
|
+
404: ResponseError;
|
|
2246
|
+
};
|
|
2247
|
+
type OpenDatasetUploadError = OpenDatasetUploadErrors[keyof OpenDatasetUploadErrors];
|
|
2248
|
+
type OpenDatasetUploadResponses = {
|
|
2249
|
+
/**
|
|
2250
|
+
* An upload session — new, or the one already open for this dataset
|
|
2251
|
+
*/
|
|
2252
|
+
201: DatasetUploadSession;
|
|
2253
|
+
};
|
|
2254
|
+
type OpenDatasetUploadResponse = OpenDatasetUploadResponses[keyof OpenDatasetUploadResponses];
|
|
2150
2255
|
type FinalizeDatasetUploadData = {
|
|
2151
2256
|
body?: never;
|
|
2152
2257
|
path: {
|
|
@@ -2164,11 +2269,18 @@ type FinalizeDatasetUploadData = {
|
|
|
2164
2269
|
};
|
|
2165
2270
|
type FinalizeDatasetUploadErrors = {
|
|
2166
2271
|
/**
|
|
2167
|
-
* No such dataset for this user
|
|
2168
|
-
* nothing to
|
|
2272
|
+
* No such dataset for this user; `uploadId` was not issued for this dataset (never
|
|
2273
|
+
* minted, or minted for a different one); or nothing was PUT to `upload.url` yet — a
|
|
2274
|
+
* finalize with nothing to finalize.
|
|
2169
2275
|
*
|
|
2170
2276
|
*/
|
|
2171
2277
|
404: ResponseError;
|
|
2278
|
+
/**
|
|
2279
|
+
* `uploadId` already produced a version. The error message names it. Open a new upload
|
|
2280
|
+
* session (`POST /datasets/{datasetId}/uploads`) for anything new.
|
|
2281
|
+
*
|
|
2282
|
+
*/
|
|
2283
|
+
409: ResponseError;
|
|
2172
2284
|
/**
|
|
2173
2285
|
* The uploaded file exceeds your tier's size limit for a dataset.
|
|
2174
2286
|
*/
|
|
@@ -2554,9 +2666,21 @@ declare const getSweepRunEquityCurve: <ThrowOnError extends boolean = false>(opt
|
|
|
2554
2666
|
* Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`
|
|
2555
2667
|
* for the result.
|
|
2556
2668
|
*
|
|
2557
|
-
*
|
|
2558
|
-
*
|
|
2559
|
-
*
|
|
2669
|
+
* Optionally takes `params`: strategy properties for this one run, applied without
|
|
2670
|
+
* recompiling. This is how a sweep leaderboard winner gets re-run for its `equityCurve` —
|
|
2671
|
+
* a sweep row carries the ten ranking metrics but never a curve, whatever its size. Compile
|
|
2672
|
+
* once, call this endpoint N times with different `params`, and each response is an ordinary
|
|
2673
|
+
* backtest result with the curve included.
|
|
2674
|
+
*
|
|
2675
|
+
* The same request (same `prepareJobId`, `strategyId`, `storeSignals`, `equityCurve`,
|
|
2676
|
+
* `params`) always returns the same `jobId` (idempotent) — a request that omits `equityCurve`
|
|
2677
|
+
* or `params` dedupes exactly as it did before those fields existed. Two different `params`
|
|
2678
|
+
* vectors over one prepare are two different jobs, and `9` and `9.0` are the same one.
|
|
2679
|
+
*
|
|
2680
|
+
* The re-run is an independent execution rather than a replay of the sweep trial — the two
|
|
2681
|
+
* paths do not share a simulator — but they are pinned to agree: one vector run both ways
|
|
2682
|
+
* matches on every leaderboard metric, asserted as a regression test. Treat a difference as a
|
|
2683
|
+
* bug worth reporting, not as expected behaviour.
|
|
2560
2684
|
*
|
|
2561
2685
|
* Works unchanged for a dataset-backed prepare (`exchangeId: user`) — the request body is
|
|
2562
2686
|
* identical either way, since the instrument and range are recovered from `prepareJobId`.
|
|
@@ -2602,6 +2726,10 @@ declare const listDatasets: <ThrowOnError extends boolean = false>(options?: Opt
|
|
|
2602
2726
|
* `POST /datasets/{datasetId}/uploads/{uploadId}/finalize` once the upload completes to kick
|
|
2603
2727
|
* off ingest.
|
|
2604
2728
|
*
|
|
2729
|
+
* Losing this response loses nothing: calling this dataset's
|
|
2730
|
+
* `POST /datasets/{datasetId}/uploads` returns the very same upload session again rather than
|
|
2731
|
+
* opening a new one, as long as nothing has been finalized against it yet.
|
|
2732
|
+
*
|
|
2605
2733
|
* v1 is ticker data only — `type` is not a request field, it is always `"ticker"` in the
|
|
2606
2734
|
* response. `instrument` must be a plain spot pair (`BASE/QUOTE`, exactly one `/`); derivative
|
|
2607
2735
|
* forms (e.g. `BTC/USDT:USDT`) are rejected.
|
|
@@ -2630,14 +2758,30 @@ declare const deleteDataset: <ThrowOnError extends boolean = false>(options: Opt
|
|
|
2630
2758
|
* Detail for one dataset, plus a self link.
|
|
2631
2759
|
*/
|
|
2632
2760
|
declare const getDataset: <ThrowOnError extends boolean = false>(options: Options<GetDatasetData, ThrowOnError>) => _hey_api_client_fetch.RequestResult<DatasetWithLinks, ResponseError, ThrowOnError>;
|
|
2761
|
+
/**
|
|
2762
|
+
* Open a new upload session for an existing dataset
|
|
2763
|
+
* Get a fresh presigned URL to upload a new version into a dataset you already have — a
|
|
2764
|
+
* corrected file, or the next chunk of history. Behaves the same way `POST /datasets` does
|
|
2765
|
+
* for a brand-new dataset's own upload: at most one upload session is open per dataset at a
|
|
2766
|
+
* time, so calling this again before finalizing just hands back that same session rather
|
|
2767
|
+
* than opening a second one — safe to call repeatedly if a response gets lost.
|
|
2768
|
+
*
|
|
2769
|
+
* Once a session has been finalized (successfully or not), the next call here opens a
|
|
2770
|
+
* genuinely new one for that dataset's next version.
|
|
2771
|
+
*
|
|
2772
|
+
*/
|
|
2773
|
+
declare const openDatasetUpload: <ThrowOnError extends boolean = false>(options: Options<OpenDatasetUploadData, ThrowOnError>) => _hey_api_client_fetch.RequestResult<DatasetUploadSession, ResponseError, ThrowOnError>;
|
|
2633
2774
|
/**
|
|
2634
2775
|
* Finalize an uploaded file and start ingest
|
|
2635
|
-
* Call once the file has been PUT to the `upload.url` from `POST /datasets
|
|
2636
|
-
* and returns immediately; poll
|
|
2776
|
+
* Call once the file has been PUT to the `upload.url` from `POST /datasets` (or from
|
|
2777
|
+
* `POST /datasets/{datasetId}/uploads`). Enqueues ingest and returns immediately; poll
|
|
2637
2778
|
* `GET /datasets/{datasetId}/uploads/{uploadId}` for the result.
|
|
2638
2779
|
*
|
|
2639
|
-
* Idempotent
|
|
2640
|
-
* enqueueing a second ingest.
|
|
2780
|
+
* Idempotent while the upload is still open — a repeat finalize before it has produced a
|
|
2781
|
+
* version returns the same `jobId` rather than enqueueing a second ingest. Once it HAS
|
|
2782
|
+
* produced a version, `uploadId` is spent: finalizing it again is a `409`, even with
|
|
2783
|
+
* different bytes freshly PUT to the same URL — open a new upload session instead
|
|
2784
|
+
* (`POST /datasets/{datasetId}/uploads`) rather than reusing a spent one.
|
|
2641
2785
|
*
|
|
2642
2786
|
*/
|
|
2643
2787
|
declare const finalizeDatasetUpload: <ThrowOnError extends boolean = false>(options: Options<FinalizeDatasetUploadData, ThrowOnError>) => _hey_api_client_fetch.RequestResult<{
|
|
@@ -2653,4 +2797,4 @@ declare const getDatasetUpload: <ThrowOnError extends boolean = false>(options:
|
|
|
2653
2797
|
|
|
2654
2798
|
declare const client: _hey_api_client_fetch.Client;
|
|
2655
2799
|
|
|
2656
|
-
export { type AcceptedJob, type AuthTokenError, type AuthTokenResponse, type AuthenticateData, type AuthenticateError, type AuthenticateErrors, type AuthenticateResponse, type AuthenticateResponses, type BacktestJobResult, type CancelBacktestData, type CancelBacktestError, type CancelBacktestErrors, type CancelBacktestResponse, type CancelBacktestResponses, type CancelSweepData, type CancelSweepError, type CancelSweepErrors, type CancelSweepResponse, type CancelSweepResponses, type ClientOptions, type CompileStrategyData, type CompileStrategyError, type CompileStrategyErrors, type CompileStrategyResponse, type CompileStrategyResponses, type CoverageWindow, type CreateDatasetData, type CreateDatasetError, type CreateDatasetErrors, type CreateDatasetResponse, type CreateDatasetResponses, type DataSourceType, type Dataset, type DatasetCreated, type DatasetUploadState, type DatasetVersion, type DatasetWithLinks, type DeclaredProperty, type DeleteDatasetData, type DeleteDatasetError, type DeleteDatasetErrors, type DeleteDatasetResponse, type DeleteDatasetResponses, type DeleteStrategyData, type DeleteStrategyError, type DeleteStrategyErrors, type DeleteStrategyResponse, type DeleteStrategyResponses, type DownloadKlinesData, type DownloadKlinesError, type DownloadKlinesErrors, type DownloadKlinesResponse, type DownloadKlinesResponses, type DownloadTickersData, type DownloadTickersError, type DownloadTickersErrors, type DownloadTickersResponse, type DownloadTickersResponses, type EquityCurveMeta, type EquityCurveOptions, type EquityCurveOutMode, type EquityCurveRequest, type EquityCurveResult, type EquityPoint, type Exchange, type ExecuteBacktestData, type ExecuteBacktestError, type ExecuteBacktestErrors, type ExecuteBacktestResponse, type ExecuteBacktestResponses, type ExecuteSweepAccepted, type ExecuteSweepData, type ExecuteSweepError, type ExecuteSweepErrors, type ExecuteSweepRequest, type ExecuteSweepResponse, type ExecuteSweepResponses, type ExecuteSweepResult, type FinalizeDatasetUploadData, type FinalizeDatasetUploadError, type FinalizeDatasetUploadErrors, type FinalizeDatasetUploadResponse, type FinalizeDatasetUploadResponses, type GetBacktestResultData, type GetBacktestResultError, type GetBacktestResultErrors, type GetBacktestResultResponse, type GetBacktestResultResponses, type GetDatasetData, type GetDatasetError, type GetDatasetErrors, type GetDatasetResponse, type GetDatasetResponses, type GetDatasetUploadData, type GetDatasetUploadError, type GetDatasetUploadErrors, type GetDatasetUploadResponse, type GetDatasetUploadResponses, type GetPrepareStatusData, type GetPrepareStatusError, type GetPrepareStatusErrors, type GetPrepareStatusResponse, type GetPrepareStatusResponses, type GetStrategyCodeData, type GetStrategyCodeError, type GetStrategyCodeErrors, type GetStrategyCodeResponse, type GetStrategyCodeResponses, type GetStrategyData, type GetStrategyError, type GetStrategyErrors, type GetStrategyResponse, type GetStrategyResponses, type GetSweepResultData, type GetSweepResultError, type GetSweepResultErrors, type GetSweepResultResponse, type GetSweepResultResponses, type GetSweepRunEquityCurveData, type GetSweepRunEquityCurveError, type GetSweepRunEquityCurveErrors, type GetSweepRunEquityCurveResponse, type GetSweepRunEquityCurveResponses, type GetSweepSensitivityData, type GetSweepSensitivityError, type GetSweepSensitivityErrors, type GetSweepSensitivityResponse, type GetSweepSensitivityResponses, type HalLink, type Instrument, type InstrumentCoverage, type InstrumentDetail, type InstrumentLinks, type InstrumentListMeta, type InstrumentListResponse, type JobState, type ListDatasetsData, type ListDatasetsResponse, type ListDatasetsResponses, type ListExchangesData, type ListExchangesResponse, type ListExchangesResponses, type ListInstrumentsData, type ListInstrumentsError, type ListInstrumentsErrors, type ListInstrumentsResponse, type ListInstrumentsResponses, type ListSegmentInstrumentsData, type ListSegmentInstrumentsError, type ListSegmentInstrumentsErrors, type ListSegmentInstrumentsResponse, type ListSegmentInstrumentsResponses, type ListStrategiesData, type ListStrategiesResponse, type ListStrategiesResponses, type Notice, type Options, type PrepareBacktestData, type PrepareBacktestError, type PrepareBacktestErrors, type PrepareBacktestResponse, type PrepareBacktestResponses, type PrepareJobState, type PrepareRequest, type ResponseError, type ResultMap, type StrategyId, type StrategyLinks, type StrategyState, type StrategySummary, type SweepAxis, type SweepBaseConfig, type SweepHeatmap, type SweepHeatmapCell, type SweepMarginal, type SweepMarginalPoint, type SweepProgress, type SweepRunRow, type SweepSensitivity, type SweepSpecRequest, type ValidateStrategyData, type ValidateStrategyError, type ValidateStrategyErrors, type ValidateStrategyResponse, type ValidateStrategyResponses, type WalkForwardAccepted, type WalkForwardFold, type WalkForwardRequest, type WalkForwardResult, authenticate, cancelBacktest, cancelSweep, client, compileStrategy, createDataset, deleteDataset, deleteStrategy, downloadKlines, downloadTickers, executeBacktest, executeSweep, finalizeDatasetUpload, getBacktestResult, getDataset, getDatasetUpload, getPrepareStatus, getStrategy, getStrategyCode, getSweepResult, getSweepRunEquityCurve, getSweepSensitivity, listDatasets, listExchanges, listInstruments, listSegmentInstruments, listStrategies, prepareBacktest, validateStrategy };
|
|
2800
|
+
export { type AcceptedJob, type AuthTokenError, type AuthTokenResponse, type AuthenticateData, type AuthenticateError, type AuthenticateErrors, type AuthenticateResponse, type AuthenticateResponses, type BacktestJobResult, type CancelBacktestData, type CancelBacktestError, type CancelBacktestErrors, type CancelBacktestResponse, type CancelBacktestResponses, type CancelSweepData, type CancelSweepError, type CancelSweepErrors, type CancelSweepResponse, type CancelSweepResponses, type ClientOptions, type CompileStrategyData, type CompileStrategyError, type CompileStrategyErrors, type CompileStrategyResponse, type CompileStrategyResponses, type CoverageWindow, type CreateDatasetData, type CreateDatasetError, type CreateDatasetErrors, type CreateDatasetResponse, type CreateDatasetResponses, type DataSourceType, type Dataset, type DatasetCreated, type DatasetUploadSession, type DatasetUploadState, type DatasetUploadTarget, type DatasetVersion, type DatasetWithLinks, type DeclaredProperty, type DeleteDatasetData, type DeleteDatasetError, type DeleteDatasetErrors, type DeleteDatasetResponse, type DeleteDatasetResponses, type DeleteStrategyData, type DeleteStrategyError, type DeleteStrategyErrors, type DeleteStrategyResponse, type DeleteStrategyResponses, type DownloadKlinesData, type DownloadKlinesError, type DownloadKlinesErrors, type DownloadKlinesResponse, type DownloadKlinesResponses, type DownloadTickersData, type DownloadTickersError, type DownloadTickersErrors, type DownloadTickersResponse, type DownloadTickersResponses, type EquityCurveMeta, type EquityCurveOptions, type EquityCurveOutMode, type EquityCurveRequest, type EquityCurveResult, type EquityPoint, type Exchange, type ExecuteBacktestData, type ExecuteBacktestError, type ExecuteBacktestErrors, type ExecuteBacktestResponse, type ExecuteBacktestResponses, type ExecuteSweepAccepted, type ExecuteSweepData, type ExecuteSweepError, type ExecuteSweepErrors, type ExecuteSweepRequest, type ExecuteSweepResponse, type ExecuteSweepResponses, type ExecuteSweepResult, type FinalizeDatasetUploadData, type FinalizeDatasetUploadError, type FinalizeDatasetUploadErrors, type FinalizeDatasetUploadResponse, type FinalizeDatasetUploadResponses, type GetBacktestResultData, type GetBacktestResultError, type GetBacktestResultErrors, type GetBacktestResultResponse, type GetBacktestResultResponses, type GetDatasetData, type GetDatasetError, type GetDatasetErrors, type GetDatasetResponse, type GetDatasetResponses, type GetDatasetUploadData, type GetDatasetUploadError, type GetDatasetUploadErrors, type GetDatasetUploadResponse, type GetDatasetUploadResponses, type GetPrepareStatusData, type GetPrepareStatusError, type GetPrepareStatusErrors, type GetPrepareStatusResponse, type GetPrepareStatusResponses, type GetStrategyCodeData, type GetStrategyCodeError, type GetStrategyCodeErrors, type GetStrategyCodeResponse, type GetStrategyCodeResponses, type GetStrategyData, type GetStrategyError, type GetStrategyErrors, type GetStrategyResponse, type GetStrategyResponses, type GetSweepResultData, type GetSweepResultError, type GetSweepResultErrors, type GetSweepResultResponse, type GetSweepResultResponses, type GetSweepRunEquityCurveData, type GetSweepRunEquityCurveError, type GetSweepRunEquityCurveErrors, type GetSweepRunEquityCurveResponse, type GetSweepRunEquityCurveResponses, type GetSweepSensitivityData, type GetSweepSensitivityError, type GetSweepSensitivityErrors, type GetSweepSensitivityResponse, type GetSweepSensitivityResponses, type HalLink, type Instrument, type InstrumentCoverage, type InstrumentDetail, type InstrumentLinks, type InstrumentListMeta, type InstrumentListResponse, type JobState, type ListDatasetsData, type ListDatasetsResponse, type ListDatasetsResponses, type ListExchangesData, type ListExchangesResponse, type ListExchangesResponses, type ListInstrumentsData, type ListInstrumentsError, type ListInstrumentsErrors, type ListInstrumentsResponse, type ListInstrumentsResponses, type ListSegmentInstrumentsData, type ListSegmentInstrumentsError, type ListSegmentInstrumentsErrors, type ListSegmentInstrumentsResponse, type ListSegmentInstrumentsResponses, type ListStrategiesData, type ListStrategiesResponse, type ListStrategiesResponses, type Notice, type OpenDatasetUploadData, type OpenDatasetUploadError, type OpenDatasetUploadErrors, type OpenDatasetUploadResponse, type OpenDatasetUploadResponses, type Options, type PrepareBacktestData, type PrepareBacktestError, type PrepareBacktestErrors, type PrepareBacktestResponse, type PrepareBacktestResponses, type PrepareJobState, type PrepareRequest, type ResponseError, type ResultMap, type StrategyId, type StrategyLinks, type StrategyState, type StrategySummary, type SweepAxis, type SweepBaseConfig, type SweepHeatmap, type SweepHeatmapCell, type SweepMarginal, type SweepMarginalPoint, type SweepProgress, type SweepRunRow, type SweepSensitivity, type SweepSpecRequest, type ValidateStrategyData, type ValidateStrategyError, type ValidateStrategyErrors, type ValidateStrategyResponse, type ValidateStrategyResponses, type WalkForwardAccepted, type WalkForwardFold, type WalkForwardRequest, type WalkForwardResult, authenticate, cancelBacktest, cancelSweep, client, compileStrategy, createDataset, deleteDataset, deleteStrategy, downloadKlines, downloadTickers, executeBacktest, executeSweep, finalizeDatasetUpload, getBacktestResult, getDataset, getDatasetUpload, getPrepareStatus, getStrategy, getStrategyCode, getSweepResult, getSweepRunEquityCurve, getSweepSensitivity, listDatasets, listExchanges, listInstruments, listSegmentInstruments, listStrategies, openDatasetUpload, prepareBacktest, validateStrategy };
|
package/dist/index.js
CHANGED
|
@@ -313,6 +313,18 @@ var getDataset = (options) => {
|
|
|
313
313
|
...options
|
|
314
314
|
});
|
|
315
315
|
};
|
|
316
|
+
var openDatasetUpload = (options) => {
|
|
317
|
+
return (options.client ?? client).post({
|
|
318
|
+
security: [
|
|
319
|
+
{
|
|
320
|
+
scheme: "bearer",
|
|
321
|
+
type: "http"
|
|
322
|
+
}
|
|
323
|
+
],
|
|
324
|
+
url: "/datasets/{datasetId}/uploads",
|
|
325
|
+
...options
|
|
326
|
+
});
|
|
327
|
+
};
|
|
316
328
|
var finalizeDatasetUpload = (options) => {
|
|
317
329
|
return (options.client ?? client).post({
|
|
318
330
|
security: [
|
|
@@ -365,6 +377,7 @@ export {
|
|
|
365
377
|
listInstruments,
|
|
366
378
|
listSegmentInstruments,
|
|
367
379
|
listStrategies,
|
|
380
|
+
openDatasetUpload,
|
|
368
381
|
prepareBacktest,
|
|
369
382
|
validateStrategy
|
|
370
383
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/generated/client.gen.ts","../src/generated/sdk.gen.ts"],"sourcesContent":["// This file is auto-generated by @hey-api/openapi-ts\n\nimport type { ClientOptions } from \"./types.gen\";\nimport {\n type Config,\n type ClientOptions as DefaultClientOptions,\n createClient,\n createConfig,\n} from \"@hey-api/client-fetch\";\n\n/**\n * The `createClientConfig()` function will be called on client initialization\n * and the returned object will become the client's initial configuration.\n *\n * You may want to initialize your client this way instead of calling\n * `setConfig()`. This is useful for example if you're using Next.js\n * to ensure your client always has the correct values.\n */\nexport type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> =\n (\n override?: Config<DefaultClientOptions & T>\n ) => Config<Required<DefaultClientOptions> & T>;\n\nexport const client = createClient(\n createConfig<ClientOptions>({\n baseUrl: \"https://api.qtsurfer.net/v1\",\n })\n);\n","// This file is auto-generated by @hey-api/openapi-ts\n\nimport type {\n Options as ClientOptions,\n TDataShape,\n Client,\n} from \"@hey-api/client-fetch\";\nimport type {\n AuthenticateData,\n AuthenticateResponse,\n AuthenticateError,\n ListExchangesData,\n ListExchangesResponse,\n ListInstrumentsData,\n ListInstrumentsResponse,\n ListInstrumentsError,\n ListSegmentInstrumentsData,\n ListSegmentInstrumentsResponse,\n ListSegmentInstrumentsError,\n DownloadTickersData,\n DownloadTickersResponse,\n DownloadTickersError,\n DownloadKlinesData,\n DownloadKlinesResponse,\n DownloadKlinesError,\n ListStrategiesData,\n ListStrategiesResponse,\n CompileStrategyData,\n CompileStrategyResponse,\n CompileStrategyError,\n ValidateStrategyData,\n ValidateStrategyResponse,\n ValidateStrategyError,\n DeleteStrategyData,\n DeleteStrategyResponse,\n DeleteStrategyError,\n GetStrategyData,\n GetStrategyResponse,\n GetStrategyError,\n GetStrategyCodeData,\n GetStrategyCodeResponse,\n GetStrategyCodeError,\n PrepareBacktestData,\n PrepareBacktestResponse,\n PrepareBacktestError,\n GetPrepareStatusData,\n GetPrepareStatusResponse,\n GetPrepareStatusError,\n ExecuteSweepData,\n ExecuteSweepResponse,\n ExecuteSweepError,\n CancelSweepData,\n CancelSweepResponse,\n CancelSweepError,\n GetSweepResultData,\n GetSweepResultResponse,\n GetSweepResultError,\n GetSweepSensitivityData,\n GetSweepSensitivityResponse,\n GetSweepSensitivityError,\n GetSweepRunEquityCurveData,\n GetSweepRunEquityCurveResponse,\n GetSweepRunEquityCurveError,\n ExecuteBacktestData,\n ExecuteBacktestResponse,\n ExecuteBacktestError,\n CancelBacktestData,\n CancelBacktestResponse,\n CancelBacktestError,\n GetBacktestResultData,\n GetBacktestResultResponse,\n GetBacktestResultError,\n ListDatasetsData,\n ListDatasetsResponse,\n CreateDatasetData,\n CreateDatasetResponse,\n CreateDatasetError,\n DeleteDatasetData,\n DeleteDatasetResponse,\n DeleteDatasetError,\n GetDatasetData,\n GetDatasetResponse,\n GetDatasetError,\n FinalizeDatasetUploadData,\n FinalizeDatasetUploadResponse,\n FinalizeDatasetUploadError,\n GetDatasetUploadData,\n GetDatasetUploadResponse,\n GetDatasetUploadError,\n} from \"./types.gen\";\nimport { client as _heyApiClient } from \"./client.gen\";\n\nexport type Options<\n TData extends TDataShape = TDataShape,\n ThrowOnError extends boolean = boolean\n> = ClientOptions<TData, ThrowOnError> & {\n /**\n * You can provide a client instance returned by `createClient()` instead of\n * individual options. This might be also useful if you want to implement a\n * custom client.\n */\n client?: Client;\n /**\n * You can pass arbitrary values through the `meta` object. This can be\n * used to access values that aren't defined as part of the SDK function.\n */\n meta?: Record<string, unknown>;\n};\n\n/**\n * Exchange API key for a short-lived JWT\n * Exchanges a long-lived API key for a short-lived JWT used by every other\n * endpoint. This is the only endpoint that accepts an API key directly —\n * callers should obtain a JWT here, then send it as `Authorization: Bearer\n * <token>` to all other operations.\n *\n * The returned JWT carries the caller's subscription `tier` as a claim and\n * expires after `expires_in` seconds. Callers should refresh the token\n * before expiry (or on a `401` response) by calling this endpoint again.\n *\n */\nexport const authenticate = <ThrowOnError extends boolean = false>(\n options?: Options<AuthenticateData, ThrowOnError>\n) => {\n return (options?.client ?? _heyApiClient).post<\n AuthenticateResponse,\n AuthenticateError,\n ThrowOnError\n >({\n security: [\n {\n name: \"X-API-Key\",\n type: \"apiKey\",\n },\n ],\n url: \"/auth/token\",\n ...options,\n });\n};\n\n/**\n * List the available exchanges\n */\nexport const listExchanges = <ThrowOnError extends boolean = false>(\n options?: Options<ListExchangesData, ThrowOnError>\n) => {\n return (options?.client ?? _heyApiClient).get<\n ListExchangesResponse,\n unknown,\n ThrowOnError\n >({\n url: \"/exchanges\",\n ...options,\n });\n};\n\n/**\n * List an exchange's instruments (default spot segment)\n * \"Give me binance instruments\" — returns the exchange's DEFAULT segment (`spot`)\n * in `data`, each instrument with per-data-type coverage and market info. `meta`\n * confirms the served `segment` (`spot`); HAL `_links` carry `self` plus the\n * `spot` / `futures` segment-discovery links.\n *\n */\nexport const listInstruments = <ThrowOnError extends boolean = false>(\n options: Options<ListInstrumentsData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n ListInstrumentsResponse,\n ListInstrumentsError,\n ThrowOnError\n >({\n url: \"/exchange/{exchangeId}/instruments\",\n ...options,\n });\n};\n\n/**\n * List an exchange segment's instruments\n * Returns the instruments for one market segment of the exchange, each with\n * per-data-type coverage and market info. HAL `_links` carry `self` plus the\n * `spot` / `futures` segment-discovery links; the default-segment shortcut is\n * `GET /exchange/{exchangeId}/instruments` (spot).\n *\n */\nexport const listSegmentInstruments = <ThrowOnError extends boolean = false>(\n options: Options<ListSegmentInstrumentsData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n ListSegmentInstrumentsResponse,\n ListSegmentInstrumentsError,\n ThrowOnError\n >({\n url: \"/exchange/{exchangeId}/{segment}/instruments\",\n ...options,\n });\n};\n\n/**\n * Download one hour of tickers for an instrument as a Lastra segment\n * Serves exactly one hour of raw ticker data for the given instrument on the\n * requested exchange. The payload is a native [Lastra](https://github.com/QTSurfer/lastra-java)\n * file — QTSurfer's columnar format for tick-precision timeseries — with\n * no JSON envelope.\n *\n * One segment = one hour, aligned to UTC. The `hour` query parameter selects\n * the segment and must match `YYYY-MM-DDTHH` (no minutes/seconds, no timezone\n * suffix). Example: `hour=2026-01-15T10` returns `h10.lastra` for\n * 2026-01-15, covering `[10:00:00Z, 11:00:00Z)`. Hours not yet available\n * return `404`.\n *\n * A `format=parquet` query parameter switches the response to on-the-fly\n * Parquet conversion via [lastra-convert](https://github.com/QTSurfer/lastra-convert)\n * for clients that don't yet read Lastra. Lastra is the primary format\n * and cheaper when the client can consume it.\n *\n * Clients:\n * - [lastra-java](https://github.com/QTSurfer/lastra-java) — reference\n * Java reader/writer with per-column codecs (ALP, Gorilla, delta-varint,\n * ZSTD) and CRC32 integrity.\n * - [lastra-ts](https://github.com/QTSurfer/lastra-ts) — TypeScript reader\n * (~4 kB bundle, browser + Node.js).\n * - [duckdb-lastra](https://github.com/QTSurfer/duckdb-lastra) — DuckDB\n * extension for ad-hoc SQL over Lastra files.\n * - [lastra-convert](https://github.com/QTSurfer/lastra-convert) — CLI + Java\n * API for converting to/from Parquet, Reef, and CSV.\n * - `curl -OJ` for offline dumps (the `Content-Disposition` header sets a\n * descriptive filename).\n *\n */\nexport const downloadTickers = <ThrowOnError extends boolean = false>(\n options: Options<DownloadTickersData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n DownloadTickersResponse,\n DownloadTickersError,\n ThrowOnError\n >({\n url: \"/exchange/{exchangeId}/tickers/{base}/{quote}\",\n ...options,\n });\n};\n\n/**\n * Download one hour of klines for an instrument as a Lastra segment\n * Same shape and semantics as `/exchange/{exchangeId}/tickers/{base}/{quote}`,\n * but serves klines (aggregated bars) instead of raw ticks. One\n * [Lastra](https://github.com/QTSurfer/lastra-java) segment = one hour of\n * klines at the exchange's native kline cadence, aligned to UTC.\n *\n * Klines use the same columnar layout as tickers — readers that handle one\n * format read the other with the same code. Use this endpoint when a\n * per-tick payload would be too large for the window of interest.\n *\n */\nexport const downloadKlines = <ThrowOnError extends boolean = false>(\n options: Options<DownloadKlinesData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n DownloadKlinesResponse,\n DownloadKlinesError,\n ThrowOnError\n >({\n url: \"/exchange/{exchangeId}/klines/{base}/{quote}\",\n ...options,\n });\n};\n\n/**\n * List your registered strategies\n * Every strategy you have registered and not deleted, most recently compiled first.\n *\n * Each entry carries the same provenance `GET /strategy/{strategyId}` does — `compiledAt`,\n * `requiredSources` — but not its validation state, so listing stays cheap regardless of how\n * many strategies you have. Check a specific strategy's validation with `GET\n * /strategy/{strategyId}`.\n *\n */\nexport const listStrategies = <ThrowOnError extends boolean = false>(\n options?: Options<ListStrategiesData, ThrowOnError>\n) => {\n return (options?.client ?? _heyApiClient).get<\n ListStrategiesResponse,\n unknown,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategies\",\n ...options,\n });\n};\n\n/**\n * Compile and register a strategy\n * Compiles raw strategy source and registers it, returning its `strategyId`.\n *\n * **This answers one question: is the source valid Java.** It compiles, registers, and hands\n * back the id — nothing more. Whether the class can actually run is\n * `POST /strategy/{strategyId}/validate`, and everything known about a strategy, validation\n * included, is read from `GET /strategy/{strategyId}`. One place to ask, so there is no second\n * answer to keep in step.\n *\n * The `strategyId` is derived from what the code *means*, not from how it is written. Adding a\n * comment, inserting a blank line, re-indenting, reordering imports, or moving a method around\n * all return the **same** id — you have not created a second strategy. Renaming a variable,\n * changing an identifier's case, reordering fields, or reordering statements inside a method\n * return a **different** one.\n *\n * Two rules follow, and they are worth designing around:\n *\n * - re-submitting a strategy you have only reformatted is free, and gives you back the id you\n * already had, along with any validation already recorded against it;\n * - the id says nothing about *behaviour*. Two sources that compute the same thing by\n * different means are two strategies, because deciding otherwise would mean deciding program\n * equivalence.\n *\n * The response also lists `declaredProperties` — the sweep/execute param keys this strategy\n * is known to accept, so a caller can catch a typo'd key before submitting a sweep instead of\n * only learning it from a rejected one. See `DeclaredProperty`: best-effort, not exhaustive.\n *\n */\nexport const compileStrategy = <ThrowOnError extends boolean = false>(\n options: Options<CompileStrategyData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n CompileStrategyResponse,\n CompileStrategyError,\n ThrowOnError\n >({\n bodySerializer: null,\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategy\",\n ...options,\n headers: {\n \"Content-Type\": \"text/plain\",\n ...options?.headers,\n },\n });\n};\n\n/**\n * Check that a registered strategy can actually run\n * Instantiates the compiled class and drives it through a bounded synthetic series, so a wiring\n * fault surfaces here instead of at your first backtest. The verdict — pass or fail, plus any\n * engine notices — is recorded and served from `GET /strategy/{strategyId}`.\n *\n * **Idempotent.** If a verdict already exists for the current compilation it comes straight\n * back with `200` and nothing is queued. Otherwise the check is queued and this returns `202`;\n * poll `GET /strategy/{strategyId}` until `validation` is `passed` or `failed`.\n *\n * Recompiling supersedes a verdict, which makes this callable again — the old answer described\n * bytecode that is no longer what would run.\n *\n */\nexport const validateStrategy = <ThrowOnError extends boolean = false>(\n options: Options<ValidateStrategyData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n ValidateStrategyResponse,\n ValidateStrategyError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategy/{strategyId}/validate\",\n ...options,\n });\n};\n\n/**\n * Release a registered strategy\n * Removes a strategy from `GET /strategy/{strategyId}` and `GET /strategies`. This is not\n * undone by re-submitting the same source to `POST /strategy` — that registers a new\n * strategy, with a new id.\n *\n * **Backtests you already ran against this strategy are unaffected.** Deleting it stops it\n * from counting against your account and stops you from validating or re-running it under\n * this id — it does not erase what already happened.\n *\n * Only removes a strategy you registered yourself. If you copied someone else's strategy\n * (a shared/marketplace listing), deleting your copy never affects theirs, or anyone else's.\n *\n */\nexport const deleteStrategy = <ThrowOnError extends boolean = false>(\n options: Options<DeleteStrategyData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).delete<\n DeleteStrategyResponse,\n DeleteStrategyError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategy/{strategyId}\",\n ...options,\n });\n};\n\n/**\n * Get a strategy by id, including its validation state\n * Reports that the strategy is registered — implied by a `200` at all — and what validating it\n * found.\n *\n * A `404` means one thing: no such registered strategy for this user. It is never a stale or\n * expired answer; registration and verdict are stored durably, not cached.\n *\n */\nexport const getStrategy = <ThrowOnError extends boolean = false>(\n options: Options<GetStrategyData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetStrategyResponse,\n GetStrategyError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategy/{strategyId}\",\n ...options,\n });\n};\n\n/**\n * Get a registered strategy's source, if you still have one to read\n * The exact source you last submitted for this id — the same text `POST /strategy` derives\n * `strategyId` from, whitespace and comments included.\n *\n * **\"If available\", not \"always\".** A strategy you resolve only through a shared/marketplace\n * listing you copied by reference carries no source of its own, and reads as a `404` here the\n * same as a `strategyId` you never registered — that is the honest answer either way, since\n * from this endpoint's point of view nothing is there to return.\n *\n */\nexport const getStrategyCode = <ThrowOnError extends boolean = false>(\n options: Options<GetStrategyCodeData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetStrategyCodeResponse,\n GetStrategyCodeError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategy/{strategyId}/code\",\n ...options,\n });\n};\n\n/**\n * Prepare backtest data\n * Enqueues a prepare task over the requested date range. Returns immediately with a `jobId`;\n * poll `GET /backtest/{exchangeId}/{type}/prepare/{jobId}` for completion.\n *\n * The same params always return the same `jobId` (idempotent). Repeated calls with identical\n * params do not enqueue duplicate work — they reuse the existing job.\n *\n * **`exchangeId: user` is reserved for your own uploaded data.** Instead of a managed\n * exchange, it prepares from a dataset you created via `POST /datasets` (see the **Dataset**\n * endpoints) — send `datasetId` in place of `instrument`. See `PrepareRequest` below for the\n * two request shapes.\n *\n */\nexport const prepareBacktest = <ThrowOnError extends boolean = false>(\n options: Options<PrepareBacktestData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n PrepareBacktestResponse,\n PrepareBacktestError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/prepare\",\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n};\n\n/**\n * Get the status of a prepare job\n * Retrieves the current state of the prepare job identified by `jobId`.\n * Poll until `status` is `Completed`, `Failed`, or `Aborted`.\n *\n * For a dataset prepare (`exchangeId: user`), coverage is reported against the dataset's own\n * cadence grid instead of hours — see `cadence`/`gaps`/`largestGapSteps` on `PrepareJobState`.\n *\n */\nexport const getPrepareStatus = <ThrowOnError extends boolean = false>(\n options: Options<GetPrepareStatusData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetPrepareStatusResponse,\n GetPrepareStatusError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/prepare/{jobId}\",\n ...options,\n });\n};\n\n/**\n * Execute a parameter sweep over prepared data\n * Runs a parameter matrix over the single immutable dataset identified by `requestId`.\n * The backend expands and executes the matrix internally; clients poll the returned\n * `sweepId` for incremental results.\n *\n * Supplying `walkForward` runs the sweep in a different mode entirely. Instead of scoring\n * every parameter vector once over the whole range, the data is split into F sequential\n * folds; each fold optimizes the full grid on its own window and then scores only its winner\n * on the window immediately after — data that winner was not chosen on. It answers a harder\n * question than a leaderboard: not \"which parameters won\", but \"does re-optimizing this\n * periodically actually work\". Omit the block and nothing changes, including the response.\n *\n * The cost is the reason it is opt-in rather than always on: F folds × N vectors, so a\n * 4-fold run over a 500-point grid is 2004 backtests where the plain sweep is 500. The\n * request is rejected when `folds × totalRuns` exceeds the server's sweep budget.\n *\n */\nexport const executeSweep = <ThrowOnError extends boolean = false>(\n options: Options<ExecuteSweepData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n ExecuteSweepResponse,\n ExecuteSweepError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/executeSweep/{requestId}\",\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n};\n\n/**\n * Cancel a running parameter sweep\n * Requests cancellation between parameter vectors. Completed rows remain readable.\n */\nexport const cancelSweep = <ThrowOnError extends boolean = false>(\n options: Options<CancelSweepData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).delete<\n CancelSweepResponse,\n CancelSweepError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}\",\n ...options,\n });\n};\n\n/**\n * Get sweep progress and results\n * Returns incremental sweep progress. The default `ranked` view sorts and may truncate the\n * display leaderboard. `order=natural` returns every available row, untruncated, ordered by\n * deterministic `runIx`; use that view when materialising durable trial rows.\n *\n * The `ranked` view is ordered by **plateau score** by default, not by the raw objective. A\n * plateau score is the objective of the worst run in a parameter point's immediate\n * neighbourhood, so a point scores well only if the region around it also does — the highest\n * raw score is frequently a spike that does not survive the parameters moving slightly. Pass\n * `ranking=raw` for the unadjusted objective order.\n *\n * Rows in the `ranked` view carry `plateauScore` and `neighbourCount` when plateau ranking\n * applied. Read them together: `neighbourCount: 0` means the point had no neighbours to\n * compare against, so its plateau score is unevidenced rather than confirmed. Sweeps\n * submitted before plateau ranking existed have no stored parameter grid to rebuild a\n * neighbourhood from and are always ranked raw; the response's `ranking` field says which\n * ordering was actually used.\n *\n * A sweep submitted with `walkForward` answers in a different shape, and the `walkForward`\n * field on the response is what tells the two apart — it appears as soon as the sweep is\n * accepted, before any fold has finished, so it is safe to branch on while polling. There\n * the leaderboard is one row per completed fold: that fold's winner as it scored\n * **out-of-sample**, with `runIx` carrying the fold index rather than a grid position. The\n * in-sample runs behind those winners are not retained — they are an optimization's working\n * set, and only the winner survives its fold. `ranking` is always `raw` and no plateau, DSR\n * or PBO figure is reported: the out-of-sample scores are already the honest number, and\n * layering a certification computed over F observations on top of them would overstate what\n * was measured.\n *\n */\nexport const getSweepResult = <ThrowOnError extends boolean = false>(\n options: Options<GetSweepResultData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetSweepResultResponse,\n GetSweepResultError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}\",\n ...options,\n });\n};\n\n/**\n * Get sweep sensitivity surfaces\n * How the objective moves as each parameter moves — the question a leaderboard cannot answer.\n * A leaderboard says which point won; a sweep can spend its entire budget on an axis that\n * never moved the objective at all, and showing only the top rows hides that completely.\n *\n * A **marginal** takes one axis and collapses every other one: for each value of that axis,\n * it aggregates every run that used it, whatever the rest of the parameters were. A flat\n * marginal means the axis is irrelevant over the range swept. `best`, `mean` and `worst` are\n * all reported because them disagreeing is itself the signal — a value with a high `best` and\n * a poor `mean` works only in specific company, which is an interaction between parameters\n * and would be invisible behind a single number.\n *\n * A **heatmap** does the same over a pair of axes, where that interaction becomes visible\n * directly.\n *\n * Served from the sweep's stored rows: no re-run, no engine call, and it works on a sweep\n * still in flight — the aggregates then describe the runs finished so far. Aborted runs are\n * excluded throughout, since a run that threw measured nothing and counting it as a bad\n * outcome would invent evidence against a parameter value that was never really tested.\n *\n * This is a separate endpoint rather than extra fields on the result view because the\n * two-dimensional half is quadratic in the axis count (N axes give N(N-1)/2 surfaces, each\n * the product of two axes' value counts) and is not wanted on the poll that drives progress.\n *\n */\nexport const getSweepSensitivity = <ThrowOnError extends boolean = false>(\n options: Options<GetSweepSensitivityData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetSweepSensitivityResponse,\n GetSweepSensitivityError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}/sensitivity\",\n ...options,\n });\n};\n\n/**\n * Get one sweep trial's equity curve\n * The resource a leaderboard row's `equityCurve.url` points at — only reachable when that\n * trial's curve was actually selected (`equityCurve.mode: topN` or `topPct` on the sweep\n * submission, and this trial ranked among the winners). Returns the exact same\n * `{points|timestamps+equities, meta}` shape a plain backtest's inline `equityCurve` carries.\n *\n * Query params reshape the response the same way a plain backtest's `equityCurve` options do.\n * A param genuinely absent from the query string falls back to the `equityCurve` transform\n * preference the sweep was submitted with — a param\n * present but malformed does not fall back, it degrades the same way it always has. Above a\n * server-side size threshold, the shape is forced regardless of either — `meta.outMode` in\n * the response, not the query string or the submitted default, is the source of truth for\n * what shape actually came back.\n *\n */\nexport const getSweepRunEquityCurve = <ThrowOnError extends boolean = false>(\n options: Options<GetSweepRunEquityCurveData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetSweepRunEquityCurveResponse,\n GetSweepRunEquityCurveError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}/runs/{runIx}/equityCurve\",\n ...options,\n });\n};\n\n/**\n * Execute a compiled strategy against a prepared dataset\n * Enqueues an execute task that runs the strategy identified by `strategyId` over the data\n * prepared by the prepare job identified by `prepareJobId`. The instrument and date range are\n * recovered from the prepare job — they do not need to be sent again.\n *\n * Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`\n * for the result.\n *\n * The same params (same `prepareJobId`, `strategyId`, `storeSignals`, `equityCurve`) always\n * return the same `jobId` (idempotent) — a request that omits `equityCurve` dedupes exactly\n * as it did before that field existed.\n *\n * Works unchanged for a dataset-backed prepare (`exchangeId: user`) — the request body is\n * identical either way, since the instrument and range are recovered from `prepareJobId`.\n *\n */\nexport const executeBacktest = <ThrowOnError extends boolean = false>(\n options: Options<ExecuteBacktestData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n ExecuteBacktestResponse,\n ExecuteBacktestError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/execute\",\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n};\n\n/**\n * Cancel a running backtest execution\n * Requests cancellation of the specified execution. The execution\n * status will transition to `Aborted` once the cancellation is\n * processed. Cancellation is asynchronous — poll the GET endpoint\n * to confirm the final status.\n *\n */\nexport const cancelBacktest = <ThrowOnError extends boolean = false>(\n options: Options<CancelBacktestData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).delete<\n CancelBacktestResponse,\n CancelBacktestError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/execute/{jobId}\",\n ...options,\n });\n};\n\n/**\n * Get the result of a backtest execution job\n * Retrieves the current state and results of the execute job identified by `jobId`.\n * Poll until `state.status` is `Completed`, `Failed`, or `Aborted`.\n *\n * A `202` means the result is not readable yet — keep polling. It is never a terminal\n * outcome, and it carries no `state`, so a poll loop that stops on a terminal status will\n * not stop on it.\n *\n */\nexport const getBacktestResult = <ThrowOnError extends boolean = false>(\n options: Options<GetBacktestResultData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetBacktestResultResponse,\n GetBacktestResultError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/execute/{jobId}\",\n ...options,\n });\n};\n\n/**\n * List your datasets\n * Every dataset you have created and not deleted, most recently created first. Never a `404`\n * — an empty array if you have none, same convention as `GET /strategies`.\n *\n */\nexport const listDatasets = <ThrowOnError extends boolean = false>(\n options?: Options<ListDatasetsData, ThrowOnError>\n) => {\n return (options?.client ?? _heyApiClient).get<\n ListDatasetsResponse,\n unknown,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets\",\n ...options,\n });\n};\n\n/**\n * Create a dataset and get a URL to upload it to\n * Creates a dataset AND its first upload session in one call — a presigned URL your client\n * PUTs the file to directly, no API credentials involved in that PUT. Call\n * `POST /datasets/{datasetId}/uploads/{uploadId}/finalize` once the upload completes to kick\n * off ingest.\n *\n * v1 is ticker data only — `type` is not a request field, it is always `\"ticker\"` in the\n * response. `instrument` must be a plain spot pair (`BASE/QUOTE`, exactly one `/`); derivative\n * forms (e.g. `BTC/USDT:USDT`) are rejected.\n *\n * **Upload format.** A CSV with a header row. Required columns: `timestamp` (ISO-8601, or\n * numeric epoch seconds/millis/micros — detected from the first row, then enforced for every\n * later row), `close`. Optional columns: `open`, `high`, `low`, `volume`, `quoteVolume`,\n * `bid`, `bidSize`, `ask`, `askSize`. Cadence and timestamp unit are discovered from the data,\n * not declared.\n *\n */\nexport const createDataset = <ThrowOnError extends boolean = false>(\n options: Options<CreateDatasetData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n CreateDatasetResponse,\n CreateDatasetError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets\",\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n};\n\n/**\n * Delete a dataset\n * Soft-delete — the dataset stops appearing in `GET /datasets`/`GET /datasets/{datasetId}` and\n * can no longer be prepared from, but its object data is reclaimed later rather than purged\n * inline, so a backtest already running against one of its versions is not disrupted.\n *\n */\nexport const deleteDataset = <ThrowOnError extends boolean = false>(\n options: Options<DeleteDatasetData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).delete<\n DeleteDatasetResponse,\n DeleteDatasetError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets/{datasetId}\",\n ...options,\n });\n};\n\n/**\n * Get a dataset by id\n * Detail for one dataset, plus a self link.\n */\nexport const getDataset = <ThrowOnError extends boolean = false>(\n options: Options<GetDatasetData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetDatasetResponse,\n GetDatasetError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets/{datasetId}\",\n ...options,\n });\n};\n\n/**\n * Finalize an uploaded file and start ingest\n * Call once the file has been PUT to the `upload.url` from `POST /datasets`. Enqueues ingest\n * and returns immediately; poll\n * `GET /datasets/{datasetId}/uploads/{uploadId}` for the result.\n *\n * Idempotent — a repeat finalize of the same upload returns the same `jobId` rather than\n * enqueueing a second ingest.\n *\n */\nexport const finalizeDatasetUpload = <ThrowOnError extends boolean = false>(\n options: Options<FinalizeDatasetUploadData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n FinalizeDatasetUploadResponse,\n FinalizeDatasetUploadError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets/{datasetId}/uploads/{uploadId}/finalize\",\n ...options,\n });\n};\n\n/**\n * Get the state of an upload/ingest\n * Poll after `POST .../finalize` until `status` is `ready` or `failed`. Also reports\n * `uploading` (finalize not called yet, but the file was PUT) before you finalize at all.\n *\n */\nexport const getDatasetUpload = <ThrowOnError extends boolean = false>(\n options: Options<GetDatasetUploadData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetDatasetUploadResponse,\n GetDatasetUploadError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets/{datasetId}/uploads/{uploadId}\",\n ...options,\n });\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/generated/client.gen.ts","../src/generated/sdk.gen.ts"],"sourcesContent":["// This file is auto-generated by @hey-api/openapi-ts\n\nimport type { ClientOptions } from \"./types.gen\";\nimport {\n type Config,\n type ClientOptions as DefaultClientOptions,\n createClient,\n createConfig,\n} from \"@hey-api/client-fetch\";\n\n/**\n * The `createClientConfig()` function will be called on client initialization\n * and the returned object will become the client's initial configuration.\n *\n * You may want to initialize your client this way instead of calling\n * `setConfig()`. This is useful for example if you're using Next.js\n * to ensure your client always has the correct values.\n */\nexport type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> =\n (\n override?: Config<DefaultClientOptions & T>\n ) => Config<Required<DefaultClientOptions> & T>;\n\nexport const client = createClient(\n createConfig<ClientOptions>({\n baseUrl: \"https://api.qtsurfer.net/v1\",\n })\n);\n","// This file is auto-generated by @hey-api/openapi-ts\n\nimport type {\n Options as ClientOptions,\n TDataShape,\n Client,\n} from \"@hey-api/client-fetch\";\nimport type {\n AuthenticateData,\n AuthenticateResponse,\n AuthenticateError,\n ListExchangesData,\n ListExchangesResponse,\n ListInstrumentsData,\n ListInstrumentsResponse,\n ListInstrumentsError,\n ListSegmentInstrumentsData,\n ListSegmentInstrumentsResponse,\n ListSegmentInstrumentsError,\n DownloadTickersData,\n DownloadTickersResponse,\n DownloadTickersError,\n DownloadKlinesData,\n DownloadKlinesResponse,\n DownloadKlinesError,\n ListStrategiesData,\n ListStrategiesResponse,\n CompileStrategyData,\n CompileStrategyResponse,\n CompileStrategyError,\n ValidateStrategyData,\n ValidateStrategyResponse,\n ValidateStrategyError,\n DeleteStrategyData,\n DeleteStrategyResponse,\n DeleteStrategyError,\n GetStrategyData,\n GetStrategyResponse,\n GetStrategyError,\n GetStrategyCodeData,\n GetStrategyCodeResponse,\n GetStrategyCodeError,\n PrepareBacktestData,\n PrepareBacktestResponse,\n PrepareBacktestError,\n GetPrepareStatusData,\n GetPrepareStatusResponse,\n GetPrepareStatusError,\n ExecuteSweepData,\n ExecuteSweepResponse,\n ExecuteSweepError,\n CancelSweepData,\n CancelSweepResponse,\n CancelSweepError,\n GetSweepResultData,\n GetSweepResultResponse,\n GetSweepResultError,\n GetSweepSensitivityData,\n GetSweepSensitivityResponse,\n GetSweepSensitivityError,\n GetSweepRunEquityCurveData,\n GetSweepRunEquityCurveResponse,\n GetSweepRunEquityCurveError,\n ExecuteBacktestData,\n ExecuteBacktestResponse,\n ExecuteBacktestError,\n CancelBacktestData,\n CancelBacktestResponse,\n CancelBacktestError,\n GetBacktestResultData,\n GetBacktestResultResponse,\n GetBacktestResultError,\n ListDatasetsData,\n ListDatasetsResponse,\n CreateDatasetData,\n CreateDatasetResponse,\n CreateDatasetError,\n DeleteDatasetData,\n DeleteDatasetResponse,\n DeleteDatasetError,\n GetDatasetData,\n GetDatasetResponse,\n GetDatasetError,\n OpenDatasetUploadData,\n OpenDatasetUploadResponse,\n OpenDatasetUploadError,\n FinalizeDatasetUploadData,\n FinalizeDatasetUploadResponse,\n FinalizeDatasetUploadError,\n GetDatasetUploadData,\n GetDatasetUploadResponse,\n GetDatasetUploadError,\n} from \"./types.gen\";\nimport { client as _heyApiClient } from \"./client.gen\";\n\nexport type Options<\n TData extends TDataShape = TDataShape,\n ThrowOnError extends boolean = boolean\n> = ClientOptions<TData, ThrowOnError> & {\n /**\n * You can provide a client instance returned by `createClient()` instead of\n * individual options. This might be also useful if you want to implement a\n * custom client.\n */\n client?: Client;\n /**\n * You can pass arbitrary values through the `meta` object. This can be\n * used to access values that aren't defined as part of the SDK function.\n */\n meta?: Record<string, unknown>;\n};\n\n/**\n * Exchange API key for a short-lived JWT\n * Exchanges a long-lived API key for a short-lived JWT used by every other\n * endpoint. This is the only endpoint that accepts an API key directly —\n * callers should obtain a JWT here, then send it as `Authorization: Bearer\n * <token>` to all other operations.\n *\n * The returned JWT carries the caller's subscription `tier` as a claim and\n * expires after `expires_in` seconds. Callers should refresh the token\n * before expiry (or on a `401` response) by calling this endpoint again.\n *\n */\nexport const authenticate = <ThrowOnError extends boolean = false>(\n options?: Options<AuthenticateData, ThrowOnError>\n) => {\n return (options?.client ?? _heyApiClient).post<\n AuthenticateResponse,\n AuthenticateError,\n ThrowOnError\n >({\n security: [\n {\n name: \"X-API-Key\",\n type: \"apiKey\",\n },\n ],\n url: \"/auth/token\",\n ...options,\n });\n};\n\n/**\n * List the available exchanges\n */\nexport const listExchanges = <ThrowOnError extends boolean = false>(\n options?: Options<ListExchangesData, ThrowOnError>\n) => {\n return (options?.client ?? _heyApiClient).get<\n ListExchangesResponse,\n unknown,\n ThrowOnError\n >({\n url: \"/exchanges\",\n ...options,\n });\n};\n\n/**\n * List an exchange's instruments (default spot segment)\n * \"Give me binance instruments\" — returns the exchange's DEFAULT segment (`spot`)\n * in `data`, each instrument with per-data-type coverage and market info. `meta`\n * confirms the served `segment` (`spot`); HAL `_links` carry `self` plus the\n * `spot` / `futures` segment-discovery links.\n *\n */\nexport const listInstruments = <ThrowOnError extends boolean = false>(\n options: Options<ListInstrumentsData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n ListInstrumentsResponse,\n ListInstrumentsError,\n ThrowOnError\n >({\n url: \"/exchange/{exchangeId}/instruments\",\n ...options,\n });\n};\n\n/**\n * List an exchange segment's instruments\n * Returns the instruments for one market segment of the exchange, each with\n * per-data-type coverage and market info. HAL `_links` carry `self` plus the\n * `spot` / `futures` segment-discovery links; the default-segment shortcut is\n * `GET /exchange/{exchangeId}/instruments` (spot).\n *\n */\nexport const listSegmentInstruments = <ThrowOnError extends boolean = false>(\n options: Options<ListSegmentInstrumentsData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n ListSegmentInstrumentsResponse,\n ListSegmentInstrumentsError,\n ThrowOnError\n >({\n url: \"/exchange/{exchangeId}/{segment}/instruments\",\n ...options,\n });\n};\n\n/**\n * Download one hour of tickers for an instrument as a Lastra segment\n * Serves exactly one hour of raw ticker data for the given instrument on the\n * requested exchange. The payload is a native [Lastra](https://github.com/QTSurfer/lastra-java)\n * file — QTSurfer's columnar format for tick-precision timeseries — with\n * no JSON envelope.\n *\n * One segment = one hour, aligned to UTC. The `hour` query parameter selects\n * the segment and must match `YYYY-MM-DDTHH` (no minutes/seconds, no timezone\n * suffix). Example: `hour=2026-01-15T10` returns `h10.lastra` for\n * 2026-01-15, covering `[10:00:00Z, 11:00:00Z)`. Hours not yet available\n * return `404`.\n *\n * A `format=parquet` query parameter switches the response to on-the-fly\n * Parquet conversion via [lastra-convert](https://github.com/QTSurfer/lastra-convert)\n * for clients that don't yet read Lastra. Lastra is the primary format\n * and cheaper when the client can consume it.\n *\n * Clients:\n * - [lastra-java](https://github.com/QTSurfer/lastra-java) — reference\n * Java reader/writer with per-column codecs (ALP, Gorilla, delta-varint,\n * ZSTD) and CRC32 integrity.\n * - [lastra-ts](https://github.com/QTSurfer/lastra-ts) — TypeScript reader\n * (~4 kB bundle, browser + Node.js).\n * - [duckdb-lastra](https://github.com/QTSurfer/duckdb-lastra) — DuckDB\n * extension for ad-hoc SQL over Lastra files.\n * - [lastra-convert](https://github.com/QTSurfer/lastra-convert) — CLI + Java\n * API for converting to/from Parquet, Reef, and CSV.\n * - `curl -OJ` for offline dumps (the `Content-Disposition` header sets a\n * descriptive filename).\n *\n */\nexport const downloadTickers = <ThrowOnError extends boolean = false>(\n options: Options<DownloadTickersData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n DownloadTickersResponse,\n DownloadTickersError,\n ThrowOnError\n >({\n url: \"/exchange/{exchangeId}/tickers/{base}/{quote}\",\n ...options,\n });\n};\n\n/**\n * Download one hour of klines for an instrument as a Lastra segment\n * Same shape and semantics as `/exchange/{exchangeId}/tickers/{base}/{quote}`,\n * but serves klines (aggregated bars) instead of raw ticks. One\n * [Lastra](https://github.com/QTSurfer/lastra-java) segment = one hour of\n * klines at the exchange's native kline cadence, aligned to UTC.\n *\n * Klines use the same columnar layout as tickers — readers that handle one\n * format read the other with the same code. Use this endpoint when a\n * per-tick payload would be too large for the window of interest.\n *\n */\nexport const downloadKlines = <ThrowOnError extends boolean = false>(\n options: Options<DownloadKlinesData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n DownloadKlinesResponse,\n DownloadKlinesError,\n ThrowOnError\n >({\n url: \"/exchange/{exchangeId}/klines/{base}/{quote}\",\n ...options,\n });\n};\n\n/**\n * List your registered strategies\n * Every strategy you have registered and not deleted, most recently compiled first.\n *\n * Each entry carries the same provenance `GET /strategy/{strategyId}` does — `compiledAt`,\n * `requiredSources` — but not its validation state, so listing stays cheap regardless of how\n * many strategies you have. Check a specific strategy's validation with `GET\n * /strategy/{strategyId}`.\n *\n */\nexport const listStrategies = <ThrowOnError extends boolean = false>(\n options?: Options<ListStrategiesData, ThrowOnError>\n) => {\n return (options?.client ?? _heyApiClient).get<\n ListStrategiesResponse,\n unknown,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategies\",\n ...options,\n });\n};\n\n/**\n * Compile and register a strategy\n * Compiles raw strategy source and registers it, returning its `strategyId`.\n *\n * **This answers one question: is the source valid Java.** It compiles, registers, and hands\n * back the id — nothing more. Whether the class can actually run is\n * `POST /strategy/{strategyId}/validate`, and everything known about a strategy, validation\n * included, is read from `GET /strategy/{strategyId}`. One place to ask, so there is no second\n * answer to keep in step.\n *\n * The `strategyId` is derived from what the code *means*, not from how it is written. Adding a\n * comment, inserting a blank line, re-indenting, reordering imports, or moving a method around\n * all return the **same** id — you have not created a second strategy. Renaming a variable,\n * changing an identifier's case, reordering fields, or reordering statements inside a method\n * return a **different** one.\n *\n * Two rules follow, and they are worth designing around:\n *\n * - re-submitting a strategy you have only reformatted is free, and gives you back the id you\n * already had, along with any validation already recorded against it;\n * - the id says nothing about *behaviour*. Two sources that compute the same thing by\n * different means are two strategies, because deciding otherwise would mean deciding program\n * equivalence.\n *\n * The response also lists `declaredProperties` — the sweep/execute param keys this strategy\n * is known to accept, so a caller can catch a typo'd key before submitting a sweep instead of\n * only learning it from a rejected one. See `DeclaredProperty`: best-effort, not exhaustive.\n *\n */\nexport const compileStrategy = <ThrowOnError extends boolean = false>(\n options: Options<CompileStrategyData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n CompileStrategyResponse,\n CompileStrategyError,\n ThrowOnError\n >({\n bodySerializer: null,\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategy\",\n ...options,\n headers: {\n \"Content-Type\": \"text/plain\",\n ...options?.headers,\n },\n });\n};\n\n/**\n * Check that a registered strategy can actually run\n * Instantiates the compiled class and drives it through a bounded synthetic series, so a wiring\n * fault surfaces here instead of at your first backtest. The verdict — pass or fail, plus any\n * engine notices — is recorded and served from `GET /strategy/{strategyId}`.\n *\n * **Idempotent.** If a verdict already exists for the current compilation it comes straight\n * back with `200` and nothing is queued. Otherwise the check is queued and this returns `202`;\n * poll `GET /strategy/{strategyId}` until `validation` is `passed` or `failed`.\n *\n * Recompiling supersedes a verdict, which makes this callable again — the old answer described\n * bytecode that is no longer what would run.\n *\n */\nexport const validateStrategy = <ThrowOnError extends boolean = false>(\n options: Options<ValidateStrategyData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n ValidateStrategyResponse,\n ValidateStrategyError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategy/{strategyId}/validate\",\n ...options,\n });\n};\n\n/**\n * Release a registered strategy\n * Removes a strategy from `GET /strategy/{strategyId}` and `GET /strategies`. This is not\n * undone by re-submitting the same source to `POST /strategy` — that registers a new\n * strategy, with a new id.\n *\n * **Backtests you already ran against this strategy are unaffected.** Deleting it stops it\n * from counting against your account and stops you from validating or re-running it under\n * this id — it does not erase what already happened.\n *\n * Only removes a strategy you registered yourself. If you copied someone else's strategy\n * (a shared/marketplace listing), deleting your copy never affects theirs, or anyone else's.\n *\n */\nexport const deleteStrategy = <ThrowOnError extends boolean = false>(\n options: Options<DeleteStrategyData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).delete<\n DeleteStrategyResponse,\n DeleteStrategyError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategy/{strategyId}\",\n ...options,\n });\n};\n\n/**\n * Get a strategy by id, including its validation state\n * Reports that the strategy is registered — implied by a `200` at all — and what validating it\n * found.\n *\n * A `404` means one thing: no such registered strategy for this user. It is never a stale or\n * expired answer; registration and verdict are stored durably, not cached.\n *\n */\nexport const getStrategy = <ThrowOnError extends boolean = false>(\n options: Options<GetStrategyData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetStrategyResponse,\n GetStrategyError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategy/{strategyId}\",\n ...options,\n });\n};\n\n/**\n * Get a registered strategy's source, if you still have one to read\n * The exact source you last submitted for this id — the same text `POST /strategy` derives\n * `strategyId` from, whitespace and comments included.\n *\n * **\"If available\", not \"always\".** A strategy you resolve only through a shared/marketplace\n * listing you copied by reference carries no source of its own, and reads as a `404` here the\n * same as a `strategyId` you never registered — that is the honest answer either way, since\n * from this endpoint's point of view nothing is there to return.\n *\n */\nexport const getStrategyCode = <ThrowOnError extends boolean = false>(\n options: Options<GetStrategyCodeData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetStrategyCodeResponse,\n GetStrategyCodeError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/strategy/{strategyId}/code\",\n ...options,\n });\n};\n\n/**\n * Prepare backtest data\n * Enqueues a prepare task over the requested date range. Returns immediately with a `jobId`;\n * poll `GET /backtest/{exchangeId}/{type}/prepare/{jobId}` for completion.\n *\n * The same params always return the same `jobId` (idempotent). Repeated calls with identical\n * params do not enqueue duplicate work — they reuse the existing job.\n *\n * **`exchangeId: user` is reserved for your own uploaded data.** Instead of a managed\n * exchange, it prepares from a dataset you created via `POST /datasets` (see the **Dataset**\n * endpoints) — send `datasetId` in place of `instrument`. See `PrepareRequest` below for the\n * two request shapes.\n *\n */\nexport const prepareBacktest = <ThrowOnError extends boolean = false>(\n options: Options<PrepareBacktestData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n PrepareBacktestResponse,\n PrepareBacktestError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/prepare\",\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n};\n\n/**\n * Get the status of a prepare job\n * Retrieves the current state of the prepare job identified by `jobId`.\n * Poll until `status` is `Completed`, `Failed`, or `Aborted`.\n *\n * For a dataset prepare (`exchangeId: user`), coverage is reported against the dataset's own\n * cadence grid instead of hours — see `cadence`/`gaps`/`largestGapSteps` on `PrepareJobState`.\n *\n */\nexport const getPrepareStatus = <ThrowOnError extends boolean = false>(\n options: Options<GetPrepareStatusData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetPrepareStatusResponse,\n GetPrepareStatusError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/prepare/{jobId}\",\n ...options,\n });\n};\n\n/**\n * Execute a parameter sweep over prepared data\n * Runs a parameter matrix over the single immutable dataset identified by `requestId`.\n * The backend expands and executes the matrix internally; clients poll the returned\n * `sweepId` for incremental results.\n *\n * Supplying `walkForward` runs the sweep in a different mode entirely. Instead of scoring\n * every parameter vector once over the whole range, the data is split into F sequential\n * folds; each fold optimizes the full grid on its own window and then scores only its winner\n * on the window immediately after — data that winner was not chosen on. It answers a harder\n * question than a leaderboard: not \"which parameters won\", but \"does re-optimizing this\n * periodically actually work\". Omit the block and nothing changes, including the response.\n *\n * The cost is the reason it is opt-in rather than always on: F folds × N vectors, so a\n * 4-fold run over a 500-point grid is 2004 backtests where the plain sweep is 500. The\n * request is rejected when `folds × totalRuns` exceeds the server's sweep budget.\n *\n */\nexport const executeSweep = <ThrowOnError extends boolean = false>(\n options: Options<ExecuteSweepData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n ExecuteSweepResponse,\n ExecuteSweepError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/executeSweep/{requestId}\",\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n};\n\n/**\n * Cancel a running parameter sweep\n * Requests cancellation between parameter vectors. Completed rows remain readable.\n */\nexport const cancelSweep = <ThrowOnError extends boolean = false>(\n options: Options<CancelSweepData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).delete<\n CancelSweepResponse,\n CancelSweepError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}\",\n ...options,\n });\n};\n\n/**\n * Get sweep progress and results\n * Returns incremental sweep progress. The default `ranked` view sorts and may truncate the\n * display leaderboard. `order=natural` returns every available row, untruncated, ordered by\n * deterministic `runIx`; use that view when materialising durable trial rows.\n *\n * The `ranked` view is ordered by **plateau score** by default, not by the raw objective. A\n * plateau score is the objective of the worst run in a parameter point's immediate\n * neighbourhood, so a point scores well only if the region around it also does — the highest\n * raw score is frequently a spike that does not survive the parameters moving slightly. Pass\n * `ranking=raw` for the unadjusted objective order.\n *\n * Rows in the `ranked` view carry `plateauScore` and `neighbourCount` when plateau ranking\n * applied. Read them together: `neighbourCount: 0` means the point had no neighbours to\n * compare against, so its plateau score is unevidenced rather than confirmed. Sweeps\n * submitted before plateau ranking existed have no stored parameter grid to rebuild a\n * neighbourhood from and are always ranked raw; the response's `ranking` field says which\n * ordering was actually used.\n *\n * A sweep submitted with `walkForward` answers in a different shape, and the `walkForward`\n * field on the response is what tells the two apart — it appears as soon as the sweep is\n * accepted, before any fold has finished, so it is safe to branch on while polling. There\n * the leaderboard is one row per completed fold: that fold's winner as it scored\n * **out-of-sample**, with `runIx` carrying the fold index rather than a grid position. The\n * in-sample runs behind those winners are not retained — they are an optimization's working\n * set, and only the winner survives its fold. `ranking` is always `raw` and no plateau, DSR\n * or PBO figure is reported: the out-of-sample scores are already the honest number, and\n * layering a certification computed over F observations on top of them would overstate what\n * was measured.\n *\n */\nexport const getSweepResult = <ThrowOnError extends boolean = false>(\n options: Options<GetSweepResultData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetSweepResultResponse,\n GetSweepResultError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}\",\n ...options,\n });\n};\n\n/**\n * Get sweep sensitivity surfaces\n * How the objective moves as each parameter moves — the question a leaderboard cannot answer.\n * A leaderboard says which point won; a sweep can spend its entire budget on an axis that\n * never moved the objective at all, and showing only the top rows hides that completely.\n *\n * A **marginal** takes one axis and collapses every other one: for each value of that axis,\n * it aggregates every run that used it, whatever the rest of the parameters were. A flat\n * marginal means the axis is irrelevant over the range swept. `best`, `mean` and `worst` are\n * all reported because them disagreeing is itself the signal — a value with a high `best` and\n * a poor `mean` works only in specific company, which is an interaction between parameters\n * and would be invisible behind a single number.\n *\n * A **heatmap** does the same over a pair of axes, where that interaction becomes visible\n * directly.\n *\n * Served from the sweep's stored rows: no re-run, no engine call, and it works on a sweep\n * still in flight — the aggregates then describe the runs finished so far. Aborted runs are\n * excluded throughout, since a run that threw measured nothing and counting it as a bad\n * outcome would invent evidence against a parameter value that was never really tested.\n *\n * This is a separate endpoint rather than extra fields on the result view because the\n * two-dimensional half is quadratic in the axis count (N axes give N(N-1)/2 surfaces, each\n * the product of two axes' value counts) and is not wanted on the poll that drives progress.\n *\n */\nexport const getSweepSensitivity = <ThrowOnError extends boolean = false>(\n options: Options<GetSweepSensitivityData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetSweepSensitivityResponse,\n GetSweepSensitivityError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}/sensitivity\",\n ...options,\n });\n};\n\n/**\n * Get one sweep trial's equity curve\n * The resource a leaderboard row's `equityCurve.url` points at — only reachable when that\n * trial's curve was actually selected (`equityCurve.mode: topN` or `topPct` on the sweep\n * submission, and this trial ranked among the winners). Returns the exact same\n * `{points|timestamps+equities, meta}` shape a plain backtest's inline `equityCurve` carries.\n *\n * Query params reshape the response the same way a plain backtest's `equityCurve` options do.\n * A param genuinely absent from the query string falls back to the `equityCurve` transform\n * preference the sweep was submitted with — a param\n * present but malformed does not fall back, it degrades the same way it always has. Above a\n * server-side size threshold, the shape is forced regardless of either — `meta.outMode` in\n * the response, not the query string or the submitted default, is the source of truth for\n * what shape actually came back.\n *\n */\nexport const getSweepRunEquityCurve = <ThrowOnError extends boolean = false>(\n options: Options<GetSweepRunEquityCurveData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetSweepRunEquityCurveResponse,\n GetSweepRunEquityCurveError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}/runs/{runIx}/equityCurve\",\n ...options,\n });\n};\n\n/**\n * Execute a compiled strategy against a prepared dataset\n * Enqueues an execute task that runs the strategy identified by `strategyId` over the data\n * prepared by the prepare job identified by `prepareJobId`. The instrument and date range are\n * recovered from the prepare job — they do not need to be sent again.\n *\n * Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`\n * for the result.\n *\n * Optionally takes `params`: strategy properties for this one run, applied without\n * recompiling. This is how a sweep leaderboard winner gets re-run for its `equityCurve` —\n * a sweep row carries the ten ranking metrics but never a curve, whatever its size. Compile\n * once, call this endpoint N times with different `params`, and each response is an ordinary\n * backtest result with the curve included.\n *\n * The same request (same `prepareJobId`, `strategyId`, `storeSignals`, `equityCurve`,\n * `params`) always returns the same `jobId` (idempotent) — a request that omits `equityCurve`\n * or `params` dedupes exactly as it did before those fields existed. Two different `params`\n * vectors over one prepare are two different jobs, and `9` and `9.0` are the same one.\n *\n * The re-run is an independent execution rather than a replay of the sweep trial — the two\n * paths do not share a simulator — but they are pinned to agree: one vector run both ways\n * matches on every leaderboard metric, asserted as a regression test. Treat a difference as a\n * bug worth reporting, not as expected behaviour.\n *\n * Works unchanged for a dataset-backed prepare (`exchangeId: user`) — the request body is\n * identical either way, since the instrument and range are recovered from `prepareJobId`.\n *\n */\nexport const executeBacktest = <ThrowOnError extends boolean = false>(\n options: Options<ExecuteBacktestData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n ExecuteBacktestResponse,\n ExecuteBacktestError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/execute\",\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n};\n\n/**\n * Cancel a running backtest execution\n * Requests cancellation of the specified execution. The execution\n * status will transition to `Aborted` once the cancellation is\n * processed. Cancellation is asynchronous — poll the GET endpoint\n * to confirm the final status.\n *\n */\nexport const cancelBacktest = <ThrowOnError extends boolean = false>(\n options: Options<CancelBacktestData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).delete<\n CancelBacktestResponse,\n CancelBacktestError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/execute/{jobId}\",\n ...options,\n });\n};\n\n/**\n * Get the result of a backtest execution job\n * Retrieves the current state and results of the execute job identified by `jobId`.\n * Poll until `state.status` is `Completed`, `Failed`, or `Aborted`.\n *\n * A `202` means the result is not readable yet — keep polling. It is never a terminal\n * outcome, and it carries no `state`, so a poll loop that stops on a terminal status will\n * not stop on it.\n *\n */\nexport const getBacktestResult = <ThrowOnError extends boolean = false>(\n options: Options<GetBacktestResultData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetBacktestResultResponse,\n GetBacktestResultError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/backtest/{exchangeId}/{type}/execute/{jobId}\",\n ...options,\n });\n};\n\n/**\n * List your datasets\n * Every dataset you have created and not deleted, most recently created first. Never a `404`\n * — an empty array if you have none, same convention as `GET /strategies`.\n *\n */\nexport const listDatasets = <ThrowOnError extends boolean = false>(\n options?: Options<ListDatasetsData, ThrowOnError>\n) => {\n return (options?.client ?? _heyApiClient).get<\n ListDatasetsResponse,\n unknown,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets\",\n ...options,\n });\n};\n\n/**\n * Create a dataset and get a URL to upload it to\n * Creates a dataset AND its first upload session in one call — a presigned URL your client\n * PUTs the file to directly, no API credentials involved in that PUT. Call\n * `POST /datasets/{datasetId}/uploads/{uploadId}/finalize` once the upload completes to kick\n * off ingest.\n *\n * Losing this response loses nothing: calling this dataset's\n * `POST /datasets/{datasetId}/uploads` returns the very same upload session again rather than\n * opening a new one, as long as nothing has been finalized against it yet.\n *\n * v1 is ticker data only — `type` is not a request field, it is always `\"ticker\"` in the\n * response. `instrument` must be a plain spot pair (`BASE/QUOTE`, exactly one `/`); derivative\n * forms (e.g. `BTC/USDT:USDT`) are rejected.\n *\n * **Upload format.** A CSV with a header row. Required columns: `timestamp` (ISO-8601, or\n * numeric epoch seconds/millis/micros — detected from the first row, then enforced for every\n * later row), `close`. Optional columns: `open`, `high`, `low`, `volume`, `quoteVolume`,\n * `bid`, `bidSize`, `ask`, `askSize`. Cadence and timestamp unit are discovered from the data,\n * not declared.\n *\n */\nexport const createDataset = <ThrowOnError extends boolean = false>(\n options: Options<CreateDatasetData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n CreateDatasetResponse,\n CreateDatasetError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets\",\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n};\n\n/**\n * Delete a dataset\n * Soft-delete — the dataset stops appearing in `GET /datasets`/`GET /datasets/{datasetId}` and\n * can no longer be prepared from, but its object data is reclaimed later rather than purged\n * inline, so a backtest already running against one of its versions is not disrupted.\n *\n */\nexport const deleteDataset = <ThrowOnError extends boolean = false>(\n options: Options<DeleteDatasetData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).delete<\n DeleteDatasetResponse,\n DeleteDatasetError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets/{datasetId}\",\n ...options,\n });\n};\n\n/**\n * Get a dataset by id\n * Detail for one dataset, plus a self link.\n */\nexport const getDataset = <ThrowOnError extends boolean = false>(\n options: Options<GetDatasetData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetDatasetResponse,\n GetDatasetError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets/{datasetId}\",\n ...options,\n });\n};\n\n/**\n * Open a new upload session for an existing dataset\n * Get a fresh presigned URL to upload a new version into a dataset you already have — a\n * corrected file, or the next chunk of history. Behaves the same way `POST /datasets` does\n * for a brand-new dataset's own upload: at most one upload session is open per dataset at a\n * time, so calling this again before finalizing just hands back that same session rather\n * than opening a second one — safe to call repeatedly if a response gets lost.\n *\n * Once a session has been finalized (successfully or not), the next call here opens a\n * genuinely new one for that dataset's next version.\n *\n */\nexport const openDatasetUpload = <ThrowOnError extends boolean = false>(\n options: Options<OpenDatasetUploadData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n OpenDatasetUploadResponse,\n OpenDatasetUploadError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets/{datasetId}/uploads\",\n ...options,\n });\n};\n\n/**\n * Finalize an uploaded file and start ingest\n * Call once the file has been PUT to the `upload.url` from `POST /datasets` (or from\n * `POST /datasets/{datasetId}/uploads`). Enqueues ingest and returns immediately; poll\n * `GET /datasets/{datasetId}/uploads/{uploadId}` for the result.\n *\n * Idempotent while the upload is still open — a repeat finalize before it has produced a\n * version returns the same `jobId` rather than enqueueing a second ingest. Once it HAS\n * produced a version, `uploadId` is spent: finalizing it again is a `409`, even with\n * different bytes freshly PUT to the same URL — open a new upload session instead\n * (`POST /datasets/{datasetId}/uploads`) rather than reusing a spent one.\n *\n */\nexport const finalizeDatasetUpload = <ThrowOnError extends boolean = false>(\n options: Options<FinalizeDatasetUploadData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).post<\n FinalizeDatasetUploadResponse,\n FinalizeDatasetUploadError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets/{datasetId}/uploads/{uploadId}/finalize\",\n ...options,\n });\n};\n\n/**\n * Get the state of an upload/ingest\n * Poll after `POST .../finalize` until `status` is `ready` or `failed`. Also reports\n * `uploading` (finalize not called yet, but the file was PUT) before you finalize at all.\n *\n */\nexport const getDatasetUpload = <ThrowOnError extends boolean = false>(\n options: Options<GetDatasetUploadData, ThrowOnError>\n) => {\n return (options.client ?? _heyApiClient).get<\n GetDatasetUploadResponse,\n GetDatasetUploadError,\n ThrowOnError\n >({\n security: [\n {\n scheme: \"bearer\",\n type: \"http\",\n },\n ],\n url: \"/datasets/{datasetId}/uploads/{uploadId}\",\n ...options,\n });\n};\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -361,8 +361,10 @@ export const JobStateSchema = {
|
|
|
361
361
|
properties: {
|
|
362
362
|
contextId: {
|
|
363
363
|
type: "string",
|
|
364
|
-
description:
|
|
365
|
-
|
|
364
|
+
description:
|
|
365
|
+
"Identifier for the job's execution context. Its current shape is a colon-delimited string encoding the data source type, an internal user id, the exchange, the job id, and the instrument — but that structure is not a committed contract and may change without notice. Treat it as an opaque token: store and pass it back, don't parse it.",
|
|
366
|
+
example:
|
|
367
|
+
"jctx:ticker:76b90203-03c2-46f6-b366-9944f167e818:binance:5ikyamio8b3v9wcnfxztzg:btc/usdt:0vicnz3thzhrqvfczks1pu",
|
|
366
368
|
},
|
|
367
369
|
status: {
|
|
368
370
|
type: "string",
|
|
@@ -989,14 +991,20 @@ export const SweepRunRowSchema = {
|
|
|
989
991
|
pnlPct: {
|
|
990
992
|
type: "number",
|
|
991
993
|
format: "double",
|
|
994
|
+
description:
|
|
995
|
+
"Same units as `pnlTotalPercent` on the single-run result — percent (0-100 scale).",
|
|
992
996
|
},
|
|
993
997
|
cagr: {
|
|
994
998
|
type: "number",
|
|
995
999
|
format: "double",
|
|
1000
|
+
description:
|
|
1001
|
+
"Same units as `cagr` on the single-run result — a ratio, not a percent.",
|
|
996
1002
|
},
|
|
997
1003
|
maxDdPct: {
|
|
998
1004
|
type: "number",
|
|
999
1005
|
format: "double",
|
|
1006
|
+
description:
|
|
1007
|
+
"Same units as `maxDrawdownPercent` on the single-run result — percent (0-100 scale).",
|
|
1000
1008
|
},
|
|
1001
1009
|
trades: {
|
|
1002
1010
|
type: "integer",
|
|
@@ -1005,6 +1013,8 @@ export const SweepRunRowSchema = {
|
|
|
1005
1013
|
winRate: {
|
|
1006
1014
|
type: "number",
|
|
1007
1015
|
format: "double",
|
|
1016
|
+
description:
|
|
1017
|
+
"Same units as `winRate` on the single-run result — a fraction, 0.0-1.0 (a rate, not a percent).",
|
|
1008
1018
|
},
|
|
1009
1019
|
belowTradeFloor: {
|
|
1010
1020
|
type: "boolean",
|
|
@@ -1340,7 +1350,8 @@ same input parameters — repeated calls with identical params return the same i
|
|
|
1340
1350
|
properties: {
|
|
1341
1351
|
jobId: {
|
|
1342
1352
|
type: "string",
|
|
1343
|
-
description:
|
|
1353
|
+
description:
|
|
1354
|
+
"Unique job identifier; use this to poll for completion. For a sweep, pass this same value as the `requestId` path parameter to `executeSweep` — same identifier, different name at that call site.",
|
|
1344
1355
|
example: "13RBLGQlPnfDjO6wyKSX8i",
|
|
1345
1356
|
},
|
|
1346
1357
|
},
|
|
@@ -1443,8 +1454,9 @@ reading: a run that produced no trades often did so for a reason stated here.
|
|
|
1443
1454
|
winRate: {
|
|
1444
1455
|
type: "number",
|
|
1445
1456
|
format: "double",
|
|
1446
|
-
description:
|
|
1447
|
-
|
|
1457
|
+
description:
|
|
1458
|
+
"Fraction of profitable trades, 0.0-1.0 (a rate, not a percent — multiply by 100 to display as one). Zero when `totalTrades` is 0.",
|
|
1459
|
+
example: 0.5833,
|
|
1448
1460
|
},
|
|
1449
1461
|
sharpeRatio: {
|
|
1450
1462
|
type: "number",
|
|
@@ -1463,7 +1475,7 @@ reading: a run that produced no trades often did so for a reason stated here.
|
|
|
1463
1475
|
cagr: {
|
|
1464
1476
|
type: "number",
|
|
1465
1477
|
format: "double",
|
|
1466
|
-
description: "Compound Annual Growth Rate",
|
|
1478
|
+
description: "Compound Annual Growth Rate (eg. 0.15 for 15%)",
|
|
1467
1479
|
example: 0.1534,
|
|
1468
1480
|
},
|
|
1469
1481
|
maxDrawdown: {
|
|
@@ -1510,6 +1522,28 @@ reading: a run that produced no trades often did so for a reason stated here.
|
|
|
1510
1522
|
},
|
|
1511
1523
|
},
|
|
1512
1524
|
},
|
|
1525
|
+
params: {
|
|
1526
|
+
type: "object",
|
|
1527
|
+
additionalProperties: {
|
|
1528
|
+
oneOf: [
|
|
1529
|
+
{
|
|
1530
|
+
type: "number",
|
|
1531
|
+
},
|
|
1532
|
+
{
|
|
1533
|
+
type: "string",
|
|
1534
|
+
},
|
|
1535
|
+
{
|
|
1536
|
+
type: "boolean",
|
|
1537
|
+
},
|
|
1538
|
+
],
|
|
1539
|
+
},
|
|
1540
|
+
description:
|
|
1541
|
+
"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.",
|
|
1542
|
+
example: {
|
|
1543
|
+
"ema.fast.period": 9,
|
|
1544
|
+
"ema.slow.period": 21,
|
|
1545
|
+
},
|
|
1546
|
+
},
|
|
1513
1547
|
signalCount: {
|
|
1514
1548
|
type: "integer",
|
|
1515
1549
|
description: "Number of signals emitted during strategy execution",
|
|
@@ -2027,45 +2061,84 @@ export const DatasetWithLinksSchema = {
|
|
|
2027
2061
|
],
|
|
2028
2062
|
} as const;
|
|
2029
2063
|
|
|
2064
|
+
export const DatasetUploadTargetSchema = {
|
|
2065
|
+
description:
|
|
2066
|
+
"A presigned destination for uploading a raw dataset file directly to storage.",
|
|
2067
|
+
type: "object",
|
|
2068
|
+
required: ["url", "expiresInMinutes"],
|
|
2069
|
+
properties: {
|
|
2070
|
+
url: {
|
|
2071
|
+
type: "string",
|
|
2072
|
+
description: `Presigned URL. \`PUT\` the raw CSV file here directly — no \`Authorization\` header,
|
|
2073
|
+
no other API credentials.
|
|
2074
|
+
`,
|
|
2075
|
+
example:
|
|
2076
|
+
"https://storage.qtsurfer.com/uploads/00000000-.../up_1a2b3c4d5e6f7a8b/raw.csv?X-Amz-...",
|
|
2077
|
+
},
|
|
2078
|
+
expiresInMinutes: {
|
|
2079
|
+
type: "integer",
|
|
2080
|
+
description: "How long `url` stays valid.",
|
|
2081
|
+
example: 15,
|
|
2082
|
+
},
|
|
2083
|
+
},
|
|
2084
|
+
} as const;
|
|
2085
|
+
|
|
2086
|
+
export const DatasetUploadSessionSchema = {
|
|
2087
|
+
description: `An upload session — an id plus the presigned URL to PUT the raw file to. Returned both by
|
|
2088
|
+
\`POST /datasets\` (as part of the new dataset) and by \`POST /datasets/{datasetId}/uploads\`
|
|
2089
|
+
(on its own, for an existing one).
|
|
2090
|
+
`,
|
|
2091
|
+
type: "object",
|
|
2092
|
+
required: ["uploadId", "upload"],
|
|
2093
|
+
properties: {
|
|
2094
|
+
uploadId: {
|
|
2095
|
+
type: "string",
|
|
2096
|
+
description: `Identifies this upload session. Pass to
|
|
2097
|
+
\`POST /datasets/{datasetId}/uploads/{uploadId}/finalize\` once the PUT completes.
|
|
2098
|
+
`,
|
|
2099
|
+
example: "up_1a2b3c4d5e6f7a8b",
|
|
2100
|
+
},
|
|
2101
|
+
upload: {
|
|
2102
|
+
$ref: "#/components/schemas/DatasetUploadTarget",
|
|
2103
|
+
},
|
|
2104
|
+
},
|
|
2105
|
+
} as const;
|
|
2106
|
+
|
|
2030
2107
|
export const DatasetCreatedSchema = {
|
|
2031
|
-
description: `
|
|
2108
|
+
description: `The metadata available immediately after creating a dataset, plus its first upload
|
|
2109
|
+
session — the presigned URL to PUT the file to. Version-derived fields such as
|
|
2110
|
+
\`createdAt\`, \`currentVersionId\`, range, and cadence are available from \`GET /datasets/{datasetId}\`
|
|
2111
|
+
after the relevant lifecycle stages, not in this creation response.
|
|
2032
2112
|
`,
|
|
2033
2113
|
allOf: [
|
|
2034
|
-
{
|
|
2035
|
-
$ref: "#/components/schemas/Dataset",
|
|
2036
|
-
},
|
|
2037
2114
|
{
|
|
2038
2115
|
type: "object",
|
|
2039
|
-
required: ["
|
|
2116
|
+
required: ["datasetId", "name", "type", "instrument"],
|
|
2040
2117
|
properties: {
|
|
2041
|
-
|
|
2118
|
+
datasetId: {
|
|
2042
2119
|
type: "string",
|
|
2043
|
-
description:
|
|
2044
|
-
|
|
2045
|
-
`,
|
|
2046
|
-
example: "up_1a2b3c4d5e6f7a8b",
|
|
2120
|
+
description: "Opaque id of the newly created dataset.",
|
|
2121
|
+
example: "ds_3f9a1c2e7b0d4a5f",
|
|
2047
2122
|
},
|
|
2048
|
-
|
|
2049
|
-
type: "
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
type: "integer",
|
|
2062
|
-
description: "How long `url` stays valid.",
|
|
2063
|
-
example: 15,
|
|
2064
|
-
},
|
|
2065
|
-
},
|
|
2123
|
+
name: {
|
|
2124
|
+
type: "string",
|
|
2125
|
+
description: "Unique name of the newly created dataset.",
|
|
2126
|
+
example: "My BTC ticks",
|
|
2127
|
+
},
|
|
2128
|
+
type: {
|
|
2129
|
+
type: "string",
|
|
2130
|
+
enum: ["ticker"],
|
|
2131
|
+
description: "Always `ticker` in v1.",
|
|
2132
|
+
example: "ticker",
|
|
2133
|
+
},
|
|
2134
|
+
instrument: {
|
|
2135
|
+
$ref: "#/components/schemas/Instrument",
|
|
2066
2136
|
},
|
|
2067
2137
|
},
|
|
2068
2138
|
},
|
|
2139
|
+
{
|
|
2140
|
+
$ref: "#/components/schemas/DatasetUploadSession",
|
|
2141
|
+
},
|
|
2069
2142
|
],
|
|
2070
2143
|
} as const;
|
|
2071
2144
|
|
package/src/generated/sdk.gen.ts
CHANGED
|
@@ -81,6 +81,9 @@ import type {
|
|
|
81
81
|
GetDatasetData,
|
|
82
82
|
GetDatasetResponse,
|
|
83
83
|
GetDatasetError,
|
|
84
|
+
OpenDatasetUploadData,
|
|
85
|
+
OpenDatasetUploadResponse,
|
|
86
|
+
OpenDatasetUploadError,
|
|
84
87
|
FinalizeDatasetUploadData,
|
|
85
88
|
FinalizeDatasetUploadResponse,
|
|
86
89
|
FinalizeDatasetUploadError,
|
|
@@ -740,9 +743,21 @@ export const getSweepRunEquityCurve = <ThrowOnError extends boolean = false>(
|
|
|
740
743
|
* Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`
|
|
741
744
|
* for the result.
|
|
742
745
|
*
|
|
743
|
-
*
|
|
744
|
-
*
|
|
745
|
-
*
|
|
746
|
+
* Optionally takes `params`: strategy properties for this one run, applied without
|
|
747
|
+
* recompiling. This is how a sweep leaderboard winner gets re-run for its `equityCurve` —
|
|
748
|
+
* a sweep row carries the ten ranking metrics but never a curve, whatever its size. Compile
|
|
749
|
+
* once, call this endpoint N times with different `params`, and each response is an ordinary
|
|
750
|
+
* backtest result with the curve included.
|
|
751
|
+
*
|
|
752
|
+
* The same request (same `prepareJobId`, `strategyId`, `storeSignals`, `equityCurve`,
|
|
753
|
+
* `params`) always returns the same `jobId` (idempotent) — a request that omits `equityCurve`
|
|
754
|
+
* or `params` dedupes exactly as it did before those fields existed. Two different `params`
|
|
755
|
+
* vectors over one prepare are two different jobs, and `9` and `9.0` are the same one.
|
|
756
|
+
*
|
|
757
|
+
* The re-run is an independent execution rather than a replay of the sweep trial — the two
|
|
758
|
+
* paths do not share a simulator — but they are pinned to agree: one vector run both ways
|
|
759
|
+
* matches on every leaderboard metric, asserted as a regression test. Treat a difference as a
|
|
760
|
+
* bug worth reporting, not as expected behaviour.
|
|
746
761
|
*
|
|
747
762
|
* Works unchanged for a dataset-backed prepare (`exchangeId: user`) — the request body is
|
|
748
763
|
* identical either way, since the instrument and range are recovered from `prepareJobId`.
|
|
@@ -859,6 +874,10 @@ export const listDatasets = <ThrowOnError extends boolean = false>(
|
|
|
859
874
|
* `POST /datasets/{datasetId}/uploads/{uploadId}/finalize` once the upload completes to kick
|
|
860
875
|
* off ingest.
|
|
861
876
|
*
|
|
877
|
+
* Losing this response loses nothing: calling this dataset's
|
|
878
|
+
* `POST /datasets/{datasetId}/uploads` returns the very same upload session again rather than
|
|
879
|
+
* opening a new one, as long as nothing has been finalized against it yet.
|
|
880
|
+
*
|
|
862
881
|
* v1 is ticker data only — `type` is not a request field, it is always `"ticker"` in the
|
|
863
882
|
* response. `instrument` must be a plain spot pair (`BASE/QUOTE`, exactly one `/`); derivative
|
|
864
883
|
* forms (e.g. `BTC/USDT:USDT`) are rejected.
|
|
@@ -942,14 +961,48 @@ export const getDataset = <ThrowOnError extends boolean = false>(
|
|
|
942
961
|
});
|
|
943
962
|
};
|
|
944
963
|
|
|
964
|
+
/**
|
|
965
|
+
* Open a new upload session for an existing dataset
|
|
966
|
+
* Get a fresh presigned URL to upload a new version into a dataset you already have — a
|
|
967
|
+
* corrected file, or the next chunk of history. Behaves the same way `POST /datasets` does
|
|
968
|
+
* for a brand-new dataset's own upload: at most one upload session is open per dataset at a
|
|
969
|
+
* time, so calling this again before finalizing just hands back that same session rather
|
|
970
|
+
* than opening a second one — safe to call repeatedly if a response gets lost.
|
|
971
|
+
*
|
|
972
|
+
* Once a session has been finalized (successfully or not), the next call here opens a
|
|
973
|
+
* genuinely new one for that dataset's next version.
|
|
974
|
+
*
|
|
975
|
+
*/
|
|
976
|
+
export const openDatasetUpload = <ThrowOnError extends boolean = false>(
|
|
977
|
+
options: Options<OpenDatasetUploadData, ThrowOnError>
|
|
978
|
+
) => {
|
|
979
|
+
return (options.client ?? _heyApiClient).post<
|
|
980
|
+
OpenDatasetUploadResponse,
|
|
981
|
+
OpenDatasetUploadError,
|
|
982
|
+
ThrowOnError
|
|
983
|
+
>({
|
|
984
|
+
security: [
|
|
985
|
+
{
|
|
986
|
+
scheme: "bearer",
|
|
987
|
+
type: "http",
|
|
988
|
+
},
|
|
989
|
+
],
|
|
990
|
+
url: "/datasets/{datasetId}/uploads",
|
|
991
|
+
...options,
|
|
992
|
+
});
|
|
993
|
+
};
|
|
994
|
+
|
|
945
995
|
/**
|
|
946
996
|
* Finalize an uploaded file and start ingest
|
|
947
|
-
* Call once the file has been PUT to the `upload.url` from `POST /datasets
|
|
948
|
-
* and returns immediately; poll
|
|
997
|
+
* Call once the file has been PUT to the `upload.url` from `POST /datasets` (or from
|
|
998
|
+
* `POST /datasets/{datasetId}/uploads`). Enqueues ingest and returns immediately; poll
|
|
949
999
|
* `GET /datasets/{datasetId}/uploads/{uploadId}` for the result.
|
|
950
1000
|
*
|
|
951
|
-
* Idempotent
|
|
952
|
-
* enqueueing a second ingest.
|
|
1001
|
+
* Idempotent while the upload is still open — a repeat finalize before it has produced a
|
|
1002
|
+
* version returns the same `jobId` rather than enqueueing a second ingest. Once it HAS
|
|
1003
|
+
* produced a version, `uploadId` is spent: finalizing it again is a `409`, even with
|
|
1004
|
+
* different bytes freshly PUT to the same URL — open a new upload session instead
|
|
1005
|
+
* (`POST /datasets/{datasetId}/uploads`) rather than reusing a spent one.
|
|
953
1006
|
*
|
|
954
1007
|
*/
|
|
955
1008
|
export const finalizeDatasetUpload = <ThrowOnError extends boolean = false>(
|
|
@@ -253,7 +253,7 @@ export type PrepareRequest = {
|
|
|
253
253
|
*/
|
|
254
254
|
export type JobState = {
|
|
255
255
|
/**
|
|
256
|
-
*
|
|
256
|
+
* Identifier for the job's execution context. Its current shape is a colon-delimited string encoding the data source type, an internal user id, the exchange, the job id, and the instrument — but that structure is not a committed contract and may change without notice. Treat it as an opaque token: store and pass it back, don't parse it.
|
|
257
257
|
*/
|
|
258
258
|
contextId: string;
|
|
259
259
|
/**
|
|
@@ -580,10 +580,22 @@ export type SweepRunRow = {
|
|
|
580
580
|
* Absolute net PnL in the output currency.
|
|
581
581
|
*/
|
|
582
582
|
pnl: number;
|
|
583
|
+
/**
|
|
584
|
+
* Same units as `pnlTotalPercent` on the single-run result — percent (0-100 scale).
|
|
585
|
+
*/
|
|
583
586
|
pnlPct: number;
|
|
587
|
+
/**
|
|
588
|
+
* Same units as `cagr` on the single-run result — a ratio, not a percent.
|
|
589
|
+
*/
|
|
584
590
|
cagr: number;
|
|
591
|
+
/**
|
|
592
|
+
* Same units as `maxDrawdownPercent` on the single-run result — percent (0-100 scale).
|
|
593
|
+
*/
|
|
585
594
|
maxDdPct: number;
|
|
586
595
|
trades: number;
|
|
596
|
+
/**
|
|
597
|
+
* Same units as `winRate` on the single-run result — a fraction, 0.0-1.0 (a rate, not a percent).
|
|
598
|
+
*/
|
|
587
599
|
winRate: number;
|
|
588
600
|
belowTradeFloor: boolean;
|
|
589
601
|
aborted: boolean;
|
|
@@ -770,7 +782,7 @@ export type WalkForwardFold = {
|
|
|
770
782
|
*/
|
|
771
783
|
export type AcceptedJob = {
|
|
772
784
|
/**
|
|
773
|
-
* Unique job identifier; use this to poll for completion.
|
|
785
|
+
* Unique job identifier; use this to poll for completion. For a sweep, pass this same value as the `requestId` path parameter to `executeSweep` — same identifier, different name at that call site.
|
|
774
786
|
*/
|
|
775
787
|
jobId: string;
|
|
776
788
|
};
|
|
@@ -839,7 +851,7 @@ export type ResultMap = {
|
|
|
839
851
|
*/
|
|
840
852
|
totalTrades?: number;
|
|
841
853
|
/**
|
|
842
|
-
*
|
|
854
|
+
* Fraction of profitable trades, 0.0-1.0 (a rate, not a percent — multiply by 100 to display as one). Zero when `totalTrades` is 0.
|
|
843
855
|
*/
|
|
844
856
|
winRate?: number;
|
|
845
857
|
/**
|
|
@@ -851,7 +863,7 @@ export type ResultMap = {
|
|
|
851
863
|
*/
|
|
852
864
|
sortinoRatio?: number;
|
|
853
865
|
/**
|
|
854
|
-
* Compound Annual Growth Rate
|
|
866
|
+
* Compound Annual Growth Rate (eg. 0.15 for 15%)
|
|
855
867
|
*/
|
|
856
868
|
cagr?: number;
|
|
857
869
|
/**
|
|
@@ -866,6 +878,12 @@ export type ResultMap = {
|
|
|
866
878
|
* Equity curve over the backtest. `points[0]` (or `timestamps[0]`/`equities[0]` in `SHORT` mode) is an anchor at the backtest `from` with `initialCapital`; the remaining points are one sample per emitted yield, in order. Use it to plot the strategy's running equity without re-deriving it from the yield history. Always inline for a plain backtest today — never a pointer (`url`); that shape exists only for a sweep row's top-N winners.
|
|
867
879
|
*/
|
|
868
880
|
equityCurve?: EquityCurveResult;
|
|
881
|
+
/**
|
|
882
|
+
* 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.
|
|
883
|
+
*/
|
|
884
|
+
params?: {
|
|
885
|
+
[key: string]: number | string | boolean;
|
|
886
|
+
};
|
|
869
887
|
/**
|
|
870
888
|
* Number of signals emitted during strategy execution
|
|
871
889
|
*/
|
|
@@ -1205,30 +1223,60 @@ export type DatasetWithLinks = Dataset & {
|
|
|
1205
1223
|
};
|
|
1206
1224
|
|
|
1207
1225
|
/**
|
|
1208
|
-
* A
|
|
1226
|
+
* A presigned destination for uploading a raw dataset file directly to storage.
|
|
1227
|
+
*/
|
|
1228
|
+
export type DatasetUploadTarget = {
|
|
1229
|
+
/**
|
|
1230
|
+
* Presigned URL. `PUT` the raw CSV file here directly — no `Authorization` header,
|
|
1231
|
+
* no other API credentials.
|
|
1232
|
+
*
|
|
1233
|
+
*/
|
|
1234
|
+
url: string;
|
|
1235
|
+
/**
|
|
1236
|
+
* How long `url` stays valid.
|
|
1237
|
+
*/
|
|
1238
|
+
expiresInMinutes: number;
|
|
1239
|
+
};
|
|
1240
|
+
|
|
1241
|
+
/**
|
|
1242
|
+
* An upload session — an id plus the presigned URL to PUT the raw file to. Returned both by
|
|
1243
|
+
* `POST /datasets` (as part of the new dataset) and by `POST /datasets/{datasetId}/uploads`
|
|
1244
|
+
* (on its own, for an existing one).
|
|
1209
1245
|
*
|
|
1210
1246
|
*/
|
|
1211
|
-
export type
|
|
1247
|
+
export type DatasetUploadSession = {
|
|
1212
1248
|
/**
|
|
1213
1249
|
* Identifies this upload session. Pass to
|
|
1214
1250
|
* `POST /datasets/{datasetId}/uploads/{uploadId}/finalize` once the PUT completes.
|
|
1215
1251
|
*
|
|
1216
1252
|
*/
|
|
1217
1253
|
uploadId: string;
|
|
1218
|
-
upload:
|
|
1219
|
-
/**
|
|
1220
|
-
* Presigned URL. `PUT` the raw CSV file here directly — no `Authorization`
|
|
1221
|
-
* header, no other API credentials.
|
|
1222
|
-
*
|
|
1223
|
-
*/
|
|
1224
|
-
url: string;
|
|
1225
|
-
/**
|
|
1226
|
-
* How long `url` stays valid.
|
|
1227
|
-
*/
|
|
1228
|
-
expiresInMinutes: number;
|
|
1229
|
-
};
|
|
1254
|
+
upload: DatasetUploadTarget;
|
|
1230
1255
|
};
|
|
1231
1256
|
|
|
1257
|
+
/**
|
|
1258
|
+
* The metadata available immediately after creating a dataset, plus its first upload
|
|
1259
|
+
* session — the presigned URL to PUT the file to. Version-derived fields such as
|
|
1260
|
+
* `createdAt`, `currentVersionId`, range, and cadence are available from `GET /datasets/{datasetId}`
|
|
1261
|
+
* after the relevant lifecycle stages, not in this creation response.
|
|
1262
|
+
*
|
|
1263
|
+
*/
|
|
1264
|
+
export type DatasetCreated = {
|
|
1265
|
+
/**
|
|
1266
|
+
* Opaque id of the newly created dataset.
|
|
1267
|
+
*/
|
|
1268
|
+
datasetId: string;
|
|
1269
|
+
/**
|
|
1270
|
+
* Unique name of the newly created dataset.
|
|
1271
|
+
*/
|
|
1272
|
+
name: string;
|
|
1273
|
+
/**
|
|
1274
|
+
* Always `ticker` in v1.
|
|
1275
|
+
*/
|
|
1276
|
+
type: "ticker";
|
|
1277
|
+
instrument: Instrument;
|
|
1278
|
+
} & DatasetUploadSession;
|
|
1279
|
+
|
|
1232
1280
|
/**
|
|
1233
1281
|
* One successfully ingested upload. Cadence and timestamp unit are discovered from the file,
|
|
1234
1282
|
* not declared by the caller.
|
|
@@ -1940,6 +1988,9 @@ export type CancelSweepData = {
|
|
|
1940
1988
|
path: {
|
|
1941
1989
|
exchangeId: string;
|
|
1942
1990
|
type: DataSourceType;
|
|
1991
|
+
/**
|
|
1992
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
1993
|
+
*/
|
|
1943
1994
|
requestId: string;
|
|
1944
1995
|
sweepId: string;
|
|
1945
1996
|
};
|
|
@@ -1974,6 +2025,9 @@ export type GetSweepResultData = {
|
|
|
1974
2025
|
path: {
|
|
1975
2026
|
exchangeId: string;
|
|
1976
2027
|
type: DataSourceType;
|
|
2028
|
+
/**
|
|
2029
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
2030
|
+
*/
|
|
1977
2031
|
requestId: string;
|
|
1978
2032
|
sweepId: string;
|
|
1979
2033
|
};
|
|
@@ -2016,6 +2070,9 @@ export type GetSweepSensitivityData = {
|
|
|
2016
2070
|
path: {
|
|
2017
2071
|
exchangeId: string;
|
|
2018
2072
|
type: DataSourceType;
|
|
2073
|
+
/**
|
|
2074
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
2075
|
+
*/
|
|
2019
2076
|
requestId: string;
|
|
2020
2077
|
sweepId: string;
|
|
2021
2078
|
};
|
|
@@ -2053,6 +2110,9 @@ export type GetSweepRunEquityCurveData = {
|
|
|
2053
2110
|
path: {
|
|
2054
2111
|
exchangeId: string;
|
|
2055
2112
|
type: DataSourceType;
|
|
2113
|
+
/**
|
|
2114
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
2115
|
+
*/
|
|
2056
2116
|
requestId: string;
|
|
2057
2117
|
sweepId: string;
|
|
2058
2118
|
/**
|
|
@@ -2114,6 +2174,28 @@ export type ExecuteBacktestData = {
|
|
|
2114
2174
|
*/
|
|
2115
2175
|
storeSignals?: boolean;
|
|
2116
2176
|
equityCurve?: EquityCurveOptions;
|
|
2177
|
+
/**
|
|
2178
|
+
* Strategy properties to apply to this run. Omit to run the strategy's declared
|
|
2179
|
+
* defaults, which is exactly what a request without this field has always done.
|
|
2180
|
+
*
|
|
2181
|
+
* Each key is the `name` declared on the strategy's `@StrategyProperty`, which
|
|
2182
|
+
* need NOT match the Java field it annotates — `GET`/`POST /strategy` returns
|
|
2183
|
+
* `declaredProperties` for precisely this. A key naming no declared property is
|
|
2184
|
+
* rejected: the job fails with the list of names the strategy does declare,
|
|
2185
|
+
* rather than completing at the defaults and handing back a plausible result for
|
|
2186
|
+
* parameters nobody chose.
|
|
2187
|
+
*
|
|
2188
|
+
* Scalars only — number, string or boolean. Ranges and lists belong to
|
|
2189
|
+
* `executeSweep`; one request here is one run. `null` is not a value: leave the
|
|
2190
|
+
* key out to keep a property at its default. Keys are made of letters, digits,
|
|
2191
|
+
* `_`, `-` and dots, and may not be `strategyId`, `storeSignals`, `equityCurve`,
|
|
2192
|
+
* `backtestEnabled` or `backtestFakeExecution` — those configure the job rather
|
|
2193
|
+
* than the strategy.
|
|
2194
|
+
*
|
|
2195
|
+
*/
|
|
2196
|
+
params?: {
|
|
2197
|
+
[key: string]: number | string | boolean;
|
|
2198
|
+
};
|
|
2117
2199
|
};
|
|
2118
2200
|
path: {
|
|
2119
2201
|
/**
|
|
@@ -2381,6 +2463,38 @@ export type GetDatasetResponses = {
|
|
|
2381
2463
|
|
|
2382
2464
|
export type GetDatasetResponse = GetDatasetResponses[keyof GetDatasetResponses];
|
|
2383
2465
|
|
|
2466
|
+
export type OpenDatasetUploadData = {
|
|
2467
|
+
body?: never;
|
|
2468
|
+
path: {
|
|
2469
|
+
/**
|
|
2470
|
+
* The id returned by `POST /datasets`
|
|
2471
|
+
*/
|
|
2472
|
+
datasetId: string;
|
|
2473
|
+
};
|
|
2474
|
+
query?: never;
|
|
2475
|
+
url: "/datasets/{datasetId}/uploads";
|
|
2476
|
+
};
|
|
2477
|
+
|
|
2478
|
+
export type OpenDatasetUploadErrors = {
|
|
2479
|
+
/**
|
|
2480
|
+
* No such dataset for this user
|
|
2481
|
+
*/
|
|
2482
|
+
404: ResponseError;
|
|
2483
|
+
};
|
|
2484
|
+
|
|
2485
|
+
export type OpenDatasetUploadError =
|
|
2486
|
+
OpenDatasetUploadErrors[keyof OpenDatasetUploadErrors];
|
|
2487
|
+
|
|
2488
|
+
export type OpenDatasetUploadResponses = {
|
|
2489
|
+
/**
|
|
2490
|
+
* An upload session — new, or the one already open for this dataset
|
|
2491
|
+
*/
|
|
2492
|
+
201: DatasetUploadSession;
|
|
2493
|
+
};
|
|
2494
|
+
|
|
2495
|
+
export type OpenDatasetUploadResponse =
|
|
2496
|
+
OpenDatasetUploadResponses[keyof OpenDatasetUploadResponses];
|
|
2497
|
+
|
|
2384
2498
|
export type FinalizeDatasetUploadData = {
|
|
2385
2499
|
body?: never;
|
|
2386
2500
|
path: {
|
|
@@ -2399,11 +2513,18 @@ export type FinalizeDatasetUploadData = {
|
|
|
2399
2513
|
|
|
2400
2514
|
export type FinalizeDatasetUploadErrors = {
|
|
2401
2515
|
/**
|
|
2402
|
-
* No such dataset for this user
|
|
2403
|
-
* nothing to
|
|
2516
|
+
* No such dataset for this user; `uploadId` was not issued for this dataset (never
|
|
2517
|
+
* minted, or minted for a different one); or nothing was PUT to `upload.url` yet — a
|
|
2518
|
+
* finalize with nothing to finalize.
|
|
2404
2519
|
*
|
|
2405
2520
|
*/
|
|
2406
2521
|
404: ResponseError;
|
|
2522
|
+
/**
|
|
2523
|
+
* `uploadId` already produced a version. The error message names it. Open a new upload
|
|
2524
|
+
* session (`POST /datasets/{datasetId}/uploads`) for anything new.
|
|
2525
|
+
*
|
|
2526
|
+
*/
|
|
2527
|
+
409: ResponseError;
|
|
2407
2528
|
/**
|
|
2408
2529
|
* The uploaded file exceeds your tier's size limit for a dataset.
|
|
2409
2530
|
*/
|