@qtsurfer/api-client 0.13.0 → 0.14.1
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 +1 -1
- package/dist/index.d.ts +139 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/generated/schemas.gen.ts +101 -15
- package/src/generated/sdk.gen.ts +31 -8
- package/src/generated/types.gen.ts +108 -12
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ pluggable token stores so callers don't reinvent that plumbing.
|
|
|
69
69
|
All operations are exported as standalone functions; every operation accepts an `Options` object and returns `{ data, error, response }`.
|
|
70
70
|
|
|
71
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.
|
|
72
|
+
the spec declares are exported. The rows below describe **spec version 0.115.1**, which is versioned
|
|
73
73
|
independently of this package.
|
|
74
74
|
|
|
75
75
|
| Function | Method | Path | Purpose |
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,10 @@ type ResponseError = {
|
|
|
14
14
|
*/
|
|
15
15
|
message: string;
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* A scalar strategy property value for one execution.
|
|
19
|
+
*/
|
|
20
|
+
type ScalarStrategyParamValue = number | string | boolean;
|
|
17
21
|
/**
|
|
18
22
|
* Exchange instrument identifier (e.g. a currency pair)
|
|
19
23
|
*/
|
|
@@ -226,7 +230,7 @@ type PrepareRequest = {
|
|
|
226
230
|
*/
|
|
227
231
|
type JobState = {
|
|
228
232
|
/**
|
|
229
|
-
*
|
|
233
|
+
* 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
234
|
*/
|
|
231
235
|
contextId: string;
|
|
232
236
|
/**
|
|
@@ -527,7 +531,7 @@ type SweepRunRow = {
|
|
|
527
531
|
*/
|
|
528
532
|
neighbourCount?: number;
|
|
529
533
|
/**
|
|
530
|
-
* Probability that this run's Sharpe reflects real edge rather than the best draw from however many parameter vectors were tried. Above ~0.95 the result survives the multiple-testing correction; near 0.5 or below it is indistinguishable from the best of a pile of coin flips. Absent on aborted runs,
|
|
534
|
+
* Probability that this run's Sharpe reflects real edge rather than the best draw from however many parameter vectors were tried. Above ~0.95 the result survives the multiple-testing correction; near 0.5 or below it is indistinguishable from the best of a pile of coin flips. Absent on aborted runs, on sweeps with too few trials to establish any dispersion to deflate against, on runs with fewer than 3 period returns, and on a degenerate (near-constant) return series — all cases where the underlying statistic isn't meaningfully computable, rather than genuinely zero. A present value is the computed probability, however small.
|
|
531
535
|
*/
|
|
532
536
|
deflatedSharpe?: number;
|
|
533
537
|
params: {
|
|
@@ -539,16 +543,31 @@ type SweepRunRow = {
|
|
|
539
543
|
* Absolute net PnL in the output currency.
|
|
540
544
|
*/
|
|
541
545
|
pnl: number;
|
|
546
|
+
/**
|
|
547
|
+
* Same units as `pnlTotalPercent` on the single-run result — percent (0-100 scale).
|
|
548
|
+
*/
|
|
542
549
|
pnlPct: number;
|
|
550
|
+
/**
|
|
551
|
+
* Same units as `cagr` on the single-run result — a ratio, not a percent.
|
|
552
|
+
*/
|
|
543
553
|
cagr: number;
|
|
554
|
+
/**
|
|
555
|
+
* Same units as `maxDrawdownPercent` on the single-run result — percent (0-100 scale).
|
|
556
|
+
*/
|
|
544
557
|
maxDdPct: number;
|
|
545
558
|
trades: number;
|
|
559
|
+
/**
|
|
560
|
+
* Same units as `winRate` on the single-run result — a fraction, 0.0-1.0 (a rate, not a percent).
|
|
561
|
+
*/
|
|
546
562
|
winRate: number;
|
|
547
563
|
belowTradeFloor: boolean;
|
|
548
564
|
aborted: boolean;
|
|
549
565
|
runtimeMs: number;
|
|
550
566
|
/**
|
|
551
|
-
* Present
|
|
567
|
+
* Present whenever this trial actually has a curve — which is any completed run of a sweep that requested curves at all (`equityCurve.mode` `topN`/`topPct`), not only the ranked winners. Absent, not null, when there is genuinely nothing: the run aborted, it made no trades, or the sweep never retained curves (`mode` `auto`/`none`).
|
|
568
|
+
* Selection decides how the curve travels, not whether it exists. A row may carry `url` alone, or `url` together with the points inline.
|
|
569
|
+
* **Read `points`/`equities` to tell whether the curve is inline — never the presence of this object, and never the absence of `url`.** Both mislead, and in opposite directions: this object is present on rows that carry only a pointer, and `url` stays present alongside an inline curve so a caller can still re-request a different transform. An inline curve is emitted on the materialisation view (`?order=natural`), where each row is read once; the ranked view keeps the pointer, being polled.
|
|
570
|
+
* When only a pointer is present, `GET` the `url` for the curve. Its own `meta` there is the real, possibly size-guarded outcome. This outer `meta` may be a declaration rather than a measurement — for a row whose curve was not promoted, the point count is derived from the trade count (one equity point per closed trade) instead of being read from the store, to keep a polled response from doing per-row work.
|
|
552
571
|
*/
|
|
553
572
|
equityCurve?: EquityCurveResult;
|
|
554
573
|
};
|
|
@@ -648,7 +667,8 @@ type ExecuteSweepResult = {
|
|
|
648
667
|
* The same `JobState` shape a single-execute `BacktestJobResult` carries — not a sweep-specific lookalike, the actual type, so field names and timestamp formatting match exactly.
|
|
649
668
|
* `state.status` uses `JobState`'s own vocabulary (`New`/`Started`/`Completed`/ `Aborted`/`Failed`), mapped from the sweep's `status` field above rather than copying it: `PARTIAL` and `CANCELLED` both map to `Aborted`, because a sweep's `PARTIAL` is already terminal (some shards finished, some failed, nothing more is coming) unlike a single job's non-terminal `Partial`, which has no equivalent here at all.
|
|
650
669
|
* `state.completed` is real ticks processed on a plain sweep. On a `walkForward` sweep it is currently always `0` — the walk-forward fold runner was not wired to count ticks when this shipped, unlike the plain shard path.
|
|
651
|
-
* `state.size` is
|
|
670
|
+
* `state.size` is an upfront estimate — range x the prepare's target cadence, set before any data is even loaded, not a query against loaded data — on a single execute and a plain sweep alike. A plain sweep's value is the sum of every shard's own `size` (each shard's per-run estimate x its own vector slice), the same additive shape `state.completed` already used above. `0` means the prepare context behind the job predates this field (a job whose prepare ran before the estimate existed) — never a guessed cadence standing in for a real one.
|
|
671
|
+
* On a `walkForward` sweep, `state.size` is still always `0`: fold runs were out of scope for the estimate the same way they are for `state.completed` above — a fold's `size` is simply never set, so the sum stays honest at `0` rather than needing a special case.
|
|
652
672
|
*/
|
|
653
673
|
state: JobState;
|
|
654
674
|
};
|
|
@@ -720,7 +740,7 @@ type WalkForwardFold = {
|
|
|
720
740
|
*/
|
|
721
741
|
type AcceptedJob = {
|
|
722
742
|
/**
|
|
723
|
-
* Unique job identifier; use this to poll for completion.
|
|
743
|
+
* 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
744
|
*/
|
|
725
745
|
jobId: string;
|
|
726
746
|
};
|
|
@@ -787,7 +807,7 @@ type ResultMap = {
|
|
|
787
807
|
*/
|
|
788
808
|
totalTrades?: number;
|
|
789
809
|
/**
|
|
790
|
-
*
|
|
810
|
+
* 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
811
|
*/
|
|
792
812
|
winRate?: number;
|
|
793
813
|
/**
|
|
@@ -799,7 +819,7 @@ type ResultMap = {
|
|
|
799
819
|
*/
|
|
800
820
|
sortinoRatio?: number;
|
|
801
821
|
/**
|
|
802
|
-
* Compound Annual Growth Rate
|
|
822
|
+
* Compound Annual Growth Rate (eg. 0.15 for 15%)
|
|
803
823
|
*/
|
|
804
824
|
cagr?: number;
|
|
805
825
|
/**
|
|
@@ -814,6 +834,12 @@ type ResultMap = {
|
|
|
814
834
|
* 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
835
|
*/
|
|
816
836
|
equityCurve?: EquityCurveResult;
|
|
837
|
+
/**
|
|
838
|
+
* 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.
|
|
839
|
+
*/
|
|
840
|
+
params?: {
|
|
841
|
+
[key: string]: ScalarStrategyParamValue;
|
|
842
|
+
};
|
|
817
843
|
/**
|
|
818
844
|
* Number of signals emitted during strategy execution
|
|
819
845
|
*/
|
|
@@ -1134,6 +1160,23 @@ type Dataset = {
|
|
|
1134
1160
|
* A `Dataset` plus a self link. Returned by `GET /datasets/{datasetId}`.
|
|
1135
1161
|
*/
|
|
1136
1162
|
type DatasetWithLinks = Dataset & {
|
|
1163
|
+
/**
|
|
1164
|
+
* Presigned GET URL to the current version's stored file — see `dataFormat` for
|
|
1165
|
+
* which format it's actually in. Present only once the current version's status is
|
|
1166
|
+
* `ready`. Long-lived (day-scale, not permanent): a DuckDB-WASM/`lastra-ts`-style
|
|
1167
|
+
* reader issues HTTP range requests against it lazily over an extended viewing
|
|
1168
|
+
* session, not in one shot like a browser upload.
|
|
1169
|
+
*
|
|
1170
|
+
*/
|
|
1171
|
+
dataUrl?: string;
|
|
1172
|
+
/**
|
|
1173
|
+
* Which format `dataUrl` is actually in — check this rather than assuming it
|
|
1174
|
+
* matches how you uploaded it. `lastra` — our native columnar format — for a CSV (or
|
|
1175
|
+
* gzip/zip of one) upload, always converted on ingest. `parquet` for a parquet
|
|
1176
|
+
* upload, stored as-is today.
|
|
1177
|
+
*
|
|
1178
|
+
*/
|
|
1179
|
+
dataFormat?: "lastra" | "parquet";
|
|
1137
1180
|
_links?: {
|
|
1138
1181
|
self?: {
|
|
1139
1182
|
href?: string;
|
|
@@ -1145,8 +1188,9 @@ type DatasetWithLinks = Dataset & {
|
|
|
1145
1188
|
*/
|
|
1146
1189
|
type DatasetUploadTarget = {
|
|
1147
1190
|
/**
|
|
1148
|
-
* Presigned URL. `PUT` the
|
|
1149
|
-
* no other API
|
|
1191
|
+
* Presigned URL. `PUT` the file here directly — the CSV or parquet itself, or a `.gz`/`.zip` of it
|
|
1192
|
+
* (see `createDataset`'s own description) — no `Authorization` header, no other API
|
|
1193
|
+
* credentials.
|
|
1150
1194
|
*
|
|
1151
1195
|
*/
|
|
1152
1196
|
url: string;
|
|
@@ -1204,7 +1248,7 @@ type DatasetVersion = {
|
|
|
1204
1248
|
*/
|
|
1205
1249
|
id?: string;
|
|
1206
1250
|
/**
|
|
1207
|
-
* Size of the
|
|
1251
|
+
* Size of the stored file `dataUrl` points at — a converted `lastra` for a CSV/gzip/zip upload, or the parquet file itself, unconverted, for a parquet upload. Not the size of the bytes originally PUT to storage; see `dataFormat`.
|
|
1208
1252
|
*/
|
|
1209
1253
|
bytes?: number;
|
|
1210
1254
|
/**
|
|
@@ -1229,9 +1273,25 @@ type DatasetVersion = {
|
|
|
1229
1273
|
* The largest gap, in units of the discovered cadence step.
|
|
1230
1274
|
*/
|
|
1231
1275
|
largestGapSteps?: number;
|
|
1276
|
+
/**
|
|
1277
|
+
* Presigned GET URL to the stored file — see `dataFormat` for which format it's in.
|
|
1278
|
+
* Present once the version is `ready`. Long-lived (day-scale, not permanent): a
|
|
1279
|
+
* DuckDB-WASM/`lastra-ts`-style reader issues HTTP range requests against it lazily over
|
|
1280
|
+
* an extended viewing session, not in one shot like a browser upload.
|
|
1281
|
+
*
|
|
1282
|
+
*/
|
|
1283
|
+
dataUrl?: string;
|
|
1284
|
+
/**
|
|
1285
|
+
* Which format `dataUrl` is actually in — check this rather than assuming it matches
|
|
1286
|
+
* how you uploaded it. `lastra` — our native columnar format — for a CSV (or gzip/zip
|
|
1287
|
+
* of one) upload, always converted on ingest. `parquet` for a parquet upload, stored
|
|
1288
|
+
* as-is today.
|
|
1289
|
+
*
|
|
1290
|
+
*/
|
|
1291
|
+
dataFormat?: "lastra" | "parquet";
|
|
1232
1292
|
};
|
|
1233
1293
|
/**
|
|
1234
|
-
* Progress of one upload, from staged through ingest.
|
|
1294
|
+
* Progress of one upload, from staged through ingest. Durably recorded once a version exists,
|
|
1235
1295
|
* so `ready`/`failed` are permanent answers; `uploading`/`ingesting` reflect in-flight state
|
|
1236
1296
|
* that can itself age out — see the `404` case on `GET .../uploads/{uploadId}`.
|
|
1237
1297
|
*
|
|
@@ -1243,7 +1303,8 @@ type DatasetUploadState = {
|
|
|
1243
1303
|
* called yet.
|
|
1244
1304
|
* * `ingesting` — `finalize` was called; the worker is parsing and validating the file.
|
|
1245
1305
|
* * `ready` — ingested successfully. `version` carries the result.
|
|
1246
|
-
* * `failed` — ingest rejected the file (e.g. bad CSV contract, mixed timestamp units
|
|
1306
|
+
* * `failed` — ingest rejected the file (e.g. bad CSV contract, mixed timestamp units, a
|
|
1307
|
+
* `.zip` with no file inside or more than one).
|
|
1247
1308
|
*
|
|
1248
1309
|
*/
|
|
1249
1310
|
status: "uploading" | "ingesting" | "ready" | "failed";
|
|
@@ -1803,6 +1864,9 @@ type CancelSweepData = {
|
|
|
1803
1864
|
path: {
|
|
1804
1865
|
exchangeId: string;
|
|
1805
1866
|
type: DataSourceType;
|
|
1867
|
+
/**
|
|
1868
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
1869
|
+
*/
|
|
1806
1870
|
requestId: string;
|
|
1807
1871
|
sweepId: string;
|
|
1808
1872
|
};
|
|
@@ -1831,6 +1895,9 @@ type GetSweepResultData = {
|
|
|
1831
1895
|
path: {
|
|
1832
1896
|
exchangeId: string;
|
|
1833
1897
|
type: DataSourceType;
|
|
1898
|
+
/**
|
|
1899
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
1900
|
+
*/
|
|
1834
1901
|
requestId: string;
|
|
1835
1902
|
sweepId: string;
|
|
1836
1903
|
};
|
|
@@ -1866,6 +1933,9 @@ type GetSweepSensitivityData = {
|
|
|
1866
1933
|
path: {
|
|
1867
1934
|
exchangeId: string;
|
|
1868
1935
|
type: DataSourceType;
|
|
1936
|
+
/**
|
|
1937
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
1938
|
+
*/
|
|
1869
1939
|
requestId: string;
|
|
1870
1940
|
sweepId: string;
|
|
1871
1941
|
};
|
|
@@ -1896,6 +1966,9 @@ type GetSweepRunEquityCurveData = {
|
|
|
1896
1966
|
path: {
|
|
1897
1967
|
exchangeId: string;
|
|
1898
1968
|
type: DataSourceType;
|
|
1969
|
+
/**
|
|
1970
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
1971
|
+
*/
|
|
1899
1972
|
requestId: string;
|
|
1900
1973
|
sweepId: string;
|
|
1901
1974
|
/**
|
|
@@ -1950,6 +2023,28 @@ type ExecuteBacktestData = {
|
|
|
1950
2023
|
*/
|
|
1951
2024
|
storeSignals?: boolean;
|
|
1952
2025
|
equityCurve?: EquityCurveOptions;
|
|
2026
|
+
/**
|
|
2027
|
+
* Strategy properties to apply to this run. Omit to run the strategy's declared
|
|
2028
|
+
* defaults, which is exactly what a request without this field has always done.
|
|
2029
|
+
*
|
|
2030
|
+
* Each key is the `name` declared on the strategy's `@StrategyProperty`, which
|
|
2031
|
+
* need NOT match the Java field it annotates — `GET`/`POST /strategy` returns
|
|
2032
|
+
* `declaredProperties` for precisely this. A key naming no declared property is
|
|
2033
|
+
* rejected: the job fails with the list of names the strategy does declare,
|
|
2034
|
+
* rather than completing at the defaults and handing back a plausible result for
|
|
2035
|
+
* parameters nobody chose.
|
|
2036
|
+
*
|
|
2037
|
+
* Scalars only — number, string or boolean. Ranges and lists belong to
|
|
2038
|
+
* `executeSweep`; one request here is one run. `null` is not a value: leave the
|
|
2039
|
+
* key out to keep a property at its default. Keys are made of letters, digits,
|
|
2040
|
+
* `_`, `-` and dots, and may not be `strategyId`, `storeSignals`, `equityCurve`,
|
|
2041
|
+
* `backtestEnabled` or `backtestFakeExecution` — those configure the job rather
|
|
2042
|
+
* than the strategy.
|
|
2043
|
+
*
|
|
2044
|
+
*/
|
|
2045
|
+
params?: {
|
|
2046
|
+
[key: string]: ScalarStrategyParamValue;
|
|
2047
|
+
};
|
|
1953
2048
|
};
|
|
1954
2049
|
path: {
|
|
1955
2050
|
/**
|
|
@@ -2614,9 +2709,21 @@ declare const getSweepRunEquityCurve: <ThrowOnError extends boolean = false>(opt
|
|
|
2614
2709
|
* Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`
|
|
2615
2710
|
* for the result.
|
|
2616
2711
|
*
|
|
2617
|
-
*
|
|
2618
|
-
*
|
|
2619
|
-
*
|
|
2712
|
+
* Optionally takes `params`: strategy properties for this one run, applied without
|
|
2713
|
+
* recompiling. This is how a sweep leaderboard winner gets re-run for its `equityCurve` —
|
|
2714
|
+
* a sweep row carries the ten ranking metrics but never a curve, whatever its size. Compile
|
|
2715
|
+
* once, call this endpoint N times with different `params`, and each response is an ordinary
|
|
2716
|
+
* backtest result with the curve included.
|
|
2717
|
+
*
|
|
2718
|
+
* The same request (same `prepareJobId`, `strategyId`, `storeSignals`, `equityCurve`,
|
|
2719
|
+
* `params`) always returns the same `jobId` (idempotent) — a request that omits `equityCurve`
|
|
2720
|
+
* or `params` dedupes exactly as it did before those fields existed. Two different `params`
|
|
2721
|
+
* vectors over one prepare are two different jobs, and `9` and `9.0` are the same one.
|
|
2722
|
+
*
|
|
2723
|
+
* The re-run is an independent execution rather than a replay of the sweep trial — the two
|
|
2724
|
+
* paths do not share a simulator — but they are pinned to agree: one vector run both ways
|
|
2725
|
+
* matches on every leaderboard metric, asserted as a regression test. Treat a difference as a
|
|
2726
|
+
* bug worth reporting, not as expected behaviour.
|
|
2620
2727
|
*
|
|
2621
2728
|
* Works unchanged for a dataset-backed prepare (`exchangeId: user`) — the request body is
|
|
2622
2729
|
* identical either way, since the instrument and range are recovered from `prepareJobId`.
|
|
@@ -2670,11 +2777,22 @@ declare const listDatasets: <ThrowOnError extends boolean = false>(options?: Opt
|
|
|
2670
2777
|
* response. `instrument` must be a plain spot pair (`BASE/QUOTE`, exactly one `/`); derivative
|
|
2671
2778
|
* forms (e.g. `BTC/USDT:USDT`) are rejected.
|
|
2672
2779
|
*
|
|
2673
|
-
* **Upload format.** A CSV with a header row
|
|
2674
|
-
* numeric epoch seconds/millis/micros — detected
|
|
2675
|
-
* later row), `close`. Optional
|
|
2676
|
-
* `bid`, `bidSize`, `ask`, `askSize`. Cadence and timestamp
|
|
2677
|
-
* not declared.
|
|
2780
|
+
* **Upload format.** A CSV with a header row, or a parquet file with the same columns by
|
|
2781
|
+
* name. Required: `timestamp` (ISO-8601, or numeric epoch seconds/millis/micros — detected
|
|
2782
|
+
* from the first row, then enforced for every later row), `close`. Optional: `open`, `high`,
|
|
2783
|
+
* `low`, `volume`, `quoteVolume`, `bid`, `bidSize`, `ask`, `askSize`. Cadence and timestamp
|
|
2784
|
+
* unit are discovered from the data, not declared.
|
|
2785
|
+
*
|
|
2786
|
+
* A CSV upload is converted to our native columnar format (`lastra`) for storage. A parquet
|
|
2787
|
+
* upload is stored as-is today. Either way, always check `dataFormat` on
|
|
2788
|
+
* `GET /datasets/{datasetId}` and `GET /datasets/{datasetId}/uploads/{uploadId}` for which
|
|
2789
|
+
* one `dataUrl` actually is, rather than assuming from how you uploaded it.
|
|
2790
|
+
*
|
|
2791
|
+
* The bytes PUT to `upload.url` may be that file directly, gzipped (`.gz`), or zipped
|
|
2792
|
+
* (`.zip`, exactly one file inside — a dataset is one file regardless of how it travels).
|
|
2793
|
+
* Format is detected from the decompressed content itself: there is no filename or
|
|
2794
|
+
* `Content-Type` anywhere in this flow for a client to declare it with, so nothing needs to
|
|
2795
|
+
* be sent besides the bytes.
|
|
2678
2796
|
*
|
|
2679
2797
|
*/
|
|
2680
2798
|
declare const createDataset: <ThrowOnError extends boolean = false>(options: Options<CreateDatasetData, ThrowOnError>) => _hey_api_client_fetch.RequestResult<DatasetCreated, ResponseError, ThrowOnError>;
|
|
@@ -2733,4 +2851,4 @@ declare const getDatasetUpload: <ThrowOnError extends boolean = false>(options:
|
|
|
2733
2851
|
|
|
2734
2852
|
declare const client: _hey_api_client_fetch.Client;
|
|
2735
2853
|
|
|
2736
|
-
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 };
|
|
2854
|
+
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 ScalarStrategyParamValue, 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.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 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 * 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 * 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":[]}
|
|
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, or a parquet file with the same columns by\n * name. Required: `timestamp` (ISO-8601, or numeric epoch seconds/millis/micros — detected\n * from the first row, then enforced for every later row), `close`. Optional: `open`, `high`,\n * `low`, `volume`, `quoteVolume`, `bid`, `bidSize`, `ask`, `askSize`. Cadence and timestamp\n * unit are discovered from the data, not declared.\n *\n * A CSV upload is converted to our native columnar format (`lastra`) for storage. A parquet\n * upload is stored as-is today. Either way, always check `dataFormat` on\n * `GET /datasets/{datasetId}` and `GET /datasets/{datasetId}/uploads/{uploadId}` for which\n * one `dataUrl` actually is, rather than assuming from how you uploaded it.\n *\n * The bytes PUT to `upload.url` may be that file directly, gzipped (`.gz`), or zipped\n * (`.zip`, exactly one file inside — a dataset is one file regardless of how it travels).\n * Format is detected from the decompressed content itself: there is no filename or\n * `Content-Type` anywhere in this flow for a client to declare it with, so nothing needs to\n * be sent besides the bytes.\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
|
@@ -18,6 +18,21 @@ export const ResponseErrorSchema = {
|
|
|
18
18
|
},
|
|
19
19
|
} as const;
|
|
20
20
|
|
|
21
|
+
export const ScalarStrategyParamValueSchema = {
|
|
22
|
+
description: "A scalar strategy property value for one execution.",
|
|
23
|
+
oneOf: [
|
|
24
|
+
{
|
|
25
|
+
type: "number",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: "string",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: "boolean",
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
} as const;
|
|
35
|
+
|
|
21
36
|
export const InstrumentSchema = {
|
|
22
37
|
description: "Exchange instrument identifier (e.g. a currency pair)",
|
|
23
38
|
type: "string",
|
|
@@ -361,8 +376,10 @@ export const JobStateSchema = {
|
|
|
361
376
|
properties: {
|
|
362
377
|
contextId: {
|
|
363
378
|
type: "string",
|
|
364
|
-
description:
|
|
365
|
-
|
|
379
|
+
description:
|
|
380
|
+
"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.",
|
|
381
|
+
example:
|
|
382
|
+
"jctx:ticker:76b90203-03c2-46f6-b366-9944f167e818:binance:5ikyamio8b3v9wcnfxztzg:btc/usdt:0vicnz3thzhrqvfczks1pu",
|
|
366
383
|
},
|
|
367
384
|
status: {
|
|
368
385
|
type: "string",
|
|
@@ -967,7 +984,7 @@ export const SweepRunRowSchema = {
|
|
|
967
984
|
minimum: 0,
|
|
968
985
|
maximum: 1,
|
|
969
986
|
description:
|
|
970
|
-
"Probability that this run's Sharpe reflects real edge rather than the best draw from however many parameter vectors were tried. Above ~0.95 the result survives the multiple-testing correction; near 0.5 or below it is indistinguishable from the best of a pile of coin flips. Absent on aborted runs,
|
|
987
|
+
"Probability that this run's Sharpe reflects real edge rather than the best draw from however many parameter vectors were tried. Above ~0.95 the result survives the multiple-testing correction; near 0.5 or below it is indistinguishable from the best of a pile of coin flips. Absent on aborted runs, on sweeps with too few trials to establish any dispersion to deflate against, on runs with fewer than 3 period returns, and on a degenerate (near-constant) return series — all cases where the underlying statistic isn't meaningfully computable, rather than genuinely zero. A present value is the computed probability, however small.",
|
|
971
988
|
},
|
|
972
989
|
params: {
|
|
973
990
|
type: "object",
|
|
@@ -989,14 +1006,20 @@ export const SweepRunRowSchema = {
|
|
|
989
1006
|
pnlPct: {
|
|
990
1007
|
type: "number",
|
|
991
1008
|
format: "double",
|
|
1009
|
+
description:
|
|
1010
|
+
"Same units as `pnlTotalPercent` on the single-run result — percent (0-100 scale).",
|
|
992
1011
|
},
|
|
993
1012
|
cagr: {
|
|
994
1013
|
type: "number",
|
|
995
1014
|
format: "double",
|
|
1015
|
+
description:
|
|
1016
|
+
"Same units as `cagr` on the single-run result — a ratio, not a percent.",
|
|
996
1017
|
},
|
|
997
1018
|
maxDdPct: {
|
|
998
1019
|
type: "number",
|
|
999
1020
|
format: "double",
|
|
1021
|
+
description:
|
|
1022
|
+
"Same units as `maxDrawdownPercent` on the single-run result — percent (0-100 scale).",
|
|
1000
1023
|
},
|
|
1001
1024
|
trades: {
|
|
1002
1025
|
type: "integer",
|
|
@@ -1005,6 +1028,8 @@ export const SweepRunRowSchema = {
|
|
|
1005
1028
|
winRate: {
|
|
1006
1029
|
type: "number",
|
|
1007
1030
|
format: "double",
|
|
1031
|
+
description:
|
|
1032
|
+
"Same units as `winRate` on the single-run result — a fraction, 0.0-1.0 (a rate, not a percent).",
|
|
1008
1033
|
},
|
|
1009
1034
|
belowTradeFloor: {
|
|
1010
1035
|
type: "boolean",
|
|
@@ -1022,8 +1047,10 @@ export const SweepRunRowSchema = {
|
|
|
1022
1047
|
$ref: "#/components/schemas/EquityCurveResult",
|
|
1023
1048
|
},
|
|
1024
1049
|
],
|
|
1025
|
-
description:
|
|
1026
|
-
|
|
1050
|
+
description: `Present whenever this trial actually has a curve — which is any completed run of a sweep that requested curves at all (\`equityCurve.mode\` \`topN\`/\`topPct\`), not only the ranked winners. Absent, not null, when there is genuinely nothing: the run aborted, it made no trades, or the sweep never retained curves (\`mode\` \`auto\`/\`none\`).
|
|
1051
|
+
Selection decides how the curve travels, not whether it exists. A row may carry \`url\` alone, or \`url\` together with the points inline.
|
|
1052
|
+
**Read \`points\`/\`equities\` to tell whether the curve is inline — never the presence of this object, and never the absence of \`url\`.** Both mislead, and in opposite directions: this object is present on rows that carry only a pointer, and \`url\` stays present alongside an inline curve so a caller can still re-request a different transform. An inline curve is emitted on the materialisation view (\`?order=natural\`), where each row is read once; the ranked view keeps the pointer, being polled.
|
|
1053
|
+
When only a pointer is present, \`GET\` the \`url\` for the curve. Its own \`meta\` there is the real, possibly size-guarded outcome. This outer \`meta\` may be a declaration rather than a measurement — for a row whose curve was not promoted, the point count is derived from the trade count (one equity point per closed trade) instead of being read from the store, to keep a polled response from doing per-row work.`,
|
|
1027
1054
|
},
|
|
1028
1055
|
},
|
|
1029
1056
|
} as const;
|
|
@@ -1236,7 +1263,8 @@ First failure wins and later ones are not recorded, so on a sweep where several
|
|
|
1236
1263
|
description: `The same \`JobState\` shape a single-execute \`BacktestJobResult\` carries — not a sweep-specific lookalike, the actual type, so field names and timestamp formatting match exactly.
|
|
1237
1264
|
\`state.status\` uses \`JobState\`'s own vocabulary (\`New\`/\`Started\`/\`Completed\`/ \`Aborted\`/\`Failed\`), mapped from the sweep's \`status\` field above rather than copying it: \`PARTIAL\` and \`CANCELLED\` both map to \`Aborted\`, because a sweep's \`PARTIAL\` is already terminal (some shards finished, some failed, nothing more is coming) unlike a single job's non-terminal \`Partial\`, which has no equivalent here at all.
|
|
1238
1265
|
\`state.completed\` is real ticks processed on a plain sweep. On a \`walkForward\` sweep it is currently always \`0\` — the walk-forward fold runner was not wired to count ticks when this shipped, unlike the plain shard path.
|
|
1239
|
-
\`state.size\` is
|
|
1266
|
+
\`state.size\` is an upfront estimate — range x the prepare's target cadence, set before any data is even loaded, not a query against loaded data — on a single execute and a plain sweep alike. A plain sweep's value is the sum of every shard's own \`size\` (each shard's per-run estimate x its own vector slice), the same additive shape \`state.completed\` already used above. \`0\` means the prepare context behind the job predates this field (a job whose prepare ran before the estimate existed) — never a guessed cadence standing in for a real one.
|
|
1267
|
+
On a \`walkForward\` sweep, \`state.size\` is still always \`0\`: fold runs were out of scope for the estimate the same way they are for \`state.completed\` above — a fold's \`size\` is simply never set, so the sum stays honest at \`0\` rather than needing a special case.`,
|
|
1240
1268
|
},
|
|
1241
1269
|
},
|
|
1242
1270
|
} as const;
|
|
@@ -1340,7 +1368,8 @@ same input parameters — repeated calls with identical params return the same i
|
|
|
1340
1368
|
properties: {
|
|
1341
1369
|
jobId: {
|
|
1342
1370
|
type: "string",
|
|
1343
|
-
description:
|
|
1371
|
+
description:
|
|
1372
|
+
"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
1373
|
example: "13RBLGQlPnfDjO6wyKSX8i",
|
|
1345
1374
|
},
|
|
1346
1375
|
},
|
|
@@ -1443,8 +1472,9 @@ reading: a run that produced no trades often did so for a reason stated here.
|
|
|
1443
1472
|
winRate: {
|
|
1444
1473
|
type: "number",
|
|
1445
1474
|
format: "double",
|
|
1446
|
-
description:
|
|
1447
|
-
|
|
1475
|
+
description:
|
|
1476
|
+
"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.",
|
|
1477
|
+
example: 0.5833,
|
|
1448
1478
|
},
|
|
1449
1479
|
sharpeRatio: {
|
|
1450
1480
|
type: "number",
|
|
@@ -1463,7 +1493,7 @@ reading: a run that produced no trades often did so for a reason stated here.
|
|
|
1463
1493
|
cagr: {
|
|
1464
1494
|
type: "number",
|
|
1465
1495
|
format: "double",
|
|
1466
|
-
description: "Compound Annual Growth Rate",
|
|
1496
|
+
description: "Compound Annual Growth Rate (eg. 0.15 for 15%)",
|
|
1467
1497
|
example: 0.1534,
|
|
1468
1498
|
},
|
|
1469
1499
|
maxDrawdown: {
|
|
@@ -1510,6 +1540,18 @@ reading: a run that produced no trades often did so for a reason stated here.
|
|
|
1510
1540
|
},
|
|
1511
1541
|
},
|
|
1512
1542
|
},
|
|
1543
|
+
params: {
|
|
1544
|
+
type: "object",
|
|
1545
|
+
additionalProperties: {
|
|
1546
|
+
$ref: "#/components/schemas/ScalarStrategyParamValue",
|
|
1547
|
+
},
|
|
1548
|
+
description:
|
|
1549
|
+
"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.",
|
|
1550
|
+
example: {
|
|
1551
|
+
"ema.fast.period": 9,
|
|
1552
|
+
"ema.slow.period": 21,
|
|
1553
|
+
},
|
|
1554
|
+
},
|
|
1513
1555
|
signalCount: {
|
|
1514
1556
|
type: "integer",
|
|
1515
1557
|
description: "Number of signals emitted during strategy execution",
|
|
@@ -2008,6 +2050,27 @@ export const DatasetWithLinksSchema = {
|
|
|
2008
2050
|
{
|
|
2009
2051
|
type: "object",
|
|
2010
2052
|
properties: {
|
|
2053
|
+
dataUrl: {
|
|
2054
|
+
type: "string",
|
|
2055
|
+
description: `Presigned GET URL to the current version's stored file — see \`dataFormat\` for
|
|
2056
|
+
which format it's actually in. Present only once the current version's status is
|
|
2057
|
+
\`ready\`. Long-lived (day-scale, not permanent): a DuckDB-WASM/\`lastra-ts\`-style
|
|
2058
|
+
reader issues HTTP range requests against it lazily over an extended viewing
|
|
2059
|
+
session, not in one shot like a browser upload.
|
|
2060
|
+
`,
|
|
2061
|
+
example:
|
|
2062
|
+
"https://storage.qtsurfer.com/00000000-.../ds_3f9a1c2e7b0d4a5f/dsv_8e2b4f19c6a03d7e/ticker_BTC_USDT_1700000000000_1700086400000_1m.lastra?X-Amz-...",
|
|
2063
|
+
},
|
|
2064
|
+
dataFormat: {
|
|
2065
|
+
type: "string",
|
|
2066
|
+
enum: ["lastra", "parquet"],
|
|
2067
|
+
description: `Which format \`dataUrl\` is actually in — check this rather than assuming it
|
|
2068
|
+
matches how you uploaded it. \`lastra\` — our native columnar format — for a CSV (or
|
|
2069
|
+
gzip/zip of one) upload, always converted on ingest. \`parquet\` for a parquet
|
|
2070
|
+
upload, stored as-is today.
|
|
2071
|
+
`,
|
|
2072
|
+
example: "lastra",
|
|
2073
|
+
},
|
|
2011
2074
|
_links: {
|
|
2012
2075
|
type: "object",
|
|
2013
2076
|
properties: {
|
|
@@ -2035,8 +2098,9 @@ export const DatasetUploadTargetSchema = {
|
|
|
2035
2098
|
properties: {
|
|
2036
2099
|
url: {
|
|
2037
2100
|
type: "string",
|
|
2038
|
-
description: `Presigned URL. \`PUT\` the
|
|
2039
|
-
no other API
|
|
2101
|
+
description: `Presigned URL. \`PUT\` the file here directly — the CSV or parquet itself, or a \`.gz\`/\`.zip\` of it
|
|
2102
|
+
(see \`createDataset\`'s own description) — no \`Authorization\` header, no other API
|
|
2103
|
+
credentials.
|
|
2040
2104
|
`,
|
|
2041
2105
|
example:
|
|
2042
2106
|
"https://storage.qtsurfer.com/uploads/00000000-.../up_1a2b3c4d5e6f7a8b/raw.csv?X-Amz-...",
|
|
@@ -2127,7 +2191,8 @@ not declared by the caller.
|
|
|
2127
2191
|
},
|
|
2128
2192
|
bytes: {
|
|
2129
2193
|
type: "integer",
|
|
2130
|
-
description:
|
|
2194
|
+
description:
|
|
2195
|
+
"Size of the stored file `dataUrl` points at — a converted `lastra` for a CSV/gzip/zip upload, or the parquet file itself, unconverted, for a parquet upload. Not the size of the bytes originally PUT to storage; see `dataFormat`.",
|
|
2131
2196
|
example: 4831022,
|
|
2132
2197
|
},
|
|
2133
2198
|
rows: {
|
|
@@ -2158,12 +2223,32 @@ numeric values fell in (seconds, millis, or micros).
|
|
|
2158
2223
|
description: "The largest gap, in units of the discovered cadence step.",
|
|
2159
2224
|
example: 0,
|
|
2160
2225
|
},
|
|
2226
|
+
dataUrl: {
|
|
2227
|
+
type: "string",
|
|
2228
|
+
description: `Presigned GET URL to the stored file — see \`dataFormat\` for which format it's in.
|
|
2229
|
+
Present once the version is \`ready\`. Long-lived (day-scale, not permanent): a
|
|
2230
|
+
DuckDB-WASM/\`lastra-ts\`-style reader issues HTTP range requests against it lazily over
|
|
2231
|
+
an extended viewing session, not in one shot like a browser upload.
|
|
2232
|
+
`,
|
|
2233
|
+
example:
|
|
2234
|
+
"https://storage.qtsurfer.com/00000000-.../ds_3f9a1c2e7b0d4a5f/dsv_8e2b4f19c6a03d7e/ticker_BTC_USDT_1700000000000_1700086400000_1m.lastra?X-Amz-...",
|
|
2235
|
+
},
|
|
2236
|
+
dataFormat: {
|
|
2237
|
+
type: "string",
|
|
2238
|
+
enum: ["lastra", "parquet"],
|
|
2239
|
+
description: `Which format \`dataUrl\` is actually in — check this rather than assuming it matches
|
|
2240
|
+
how you uploaded it. \`lastra\` — our native columnar format — for a CSV (or gzip/zip
|
|
2241
|
+
of one) upload, always converted on ingest. \`parquet\` for a parquet upload, stored
|
|
2242
|
+
as-is today.
|
|
2243
|
+
`,
|
|
2244
|
+
example: "lastra",
|
|
2245
|
+
},
|
|
2161
2246
|
},
|
|
2162
2247
|
} as const;
|
|
2163
2248
|
|
|
2164
2249
|
export const DatasetUploadStateSchema = {
|
|
2165
2250
|
type: "object",
|
|
2166
|
-
description: `Progress of one upload, from staged through ingest.
|
|
2251
|
+
description: `Progress of one upload, from staged through ingest. Durably recorded once a version exists,
|
|
2167
2252
|
so \`ready\`/\`failed\` are permanent answers; \`uploading\`/\`ingesting\` reflect in-flight state
|
|
2168
2253
|
that can itself age out — see the \`404\` case on \`GET .../uploads/{uploadId}\`.
|
|
2169
2254
|
`,
|
|
@@ -2180,7 +2265,8 @@ that can itself age out — see the \`404\` case on \`GET .../uploads/{uploadId}
|
|
|
2180
2265
|
called yet.
|
|
2181
2266
|
* \`ingesting\` — \`finalize\` was called; the worker is parsing and validating the file.
|
|
2182
2267
|
* \`ready\` — ingested successfully. \`version\` carries the result.
|
|
2183
|
-
* \`failed\` — ingest rejected the file (e.g. bad CSV contract, mixed timestamp units
|
|
2268
|
+
* \`failed\` — ingest rejected the file (e.g. bad CSV contract, mixed timestamp units, a
|
|
2269
|
+
\`.zip\` with no file inside or more than one).
|
|
2184
2270
|
`,
|
|
2185
2271
|
example: "ready",
|
|
2186
2272
|
},
|
package/src/generated/sdk.gen.ts
CHANGED
|
@@ -743,9 +743,21 @@ export const getSweepRunEquityCurve = <ThrowOnError extends boolean = false>(
|
|
|
743
743
|
* Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`
|
|
744
744
|
* for the result.
|
|
745
745
|
*
|
|
746
|
-
*
|
|
747
|
-
*
|
|
748
|
-
*
|
|
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.
|
|
749
761
|
*
|
|
750
762
|
* Works unchanged for a dataset-backed prepare (`exchangeId: user`) — the request body is
|
|
751
763
|
* identical either way, since the instrument and range are recovered from `prepareJobId`.
|
|
@@ -870,11 +882,22 @@ export const listDatasets = <ThrowOnError extends boolean = false>(
|
|
|
870
882
|
* response. `instrument` must be a plain spot pair (`BASE/QUOTE`, exactly one `/`); derivative
|
|
871
883
|
* forms (e.g. `BTC/USDT:USDT`) are rejected.
|
|
872
884
|
*
|
|
873
|
-
* **Upload format.** A CSV with a header row
|
|
874
|
-
* numeric epoch seconds/millis/micros — detected
|
|
875
|
-
* later row), `close`. Optional
|
|
876
|
-
* `bid`, `bidSize`, `ask`, `askSize`. Cadence and timestamp
|
|
877
|
-
* not declared.
|
|
885
|
+
* **Upload format.** A CSV with a header row, or a parquet file with the same columns by
|
|
886
|
+
* name. Required: `timestamp` (ISO-8601, or numeric epoch seconds/millis/micros — detected
|
|
887
|
+
* from the first row, then enforced for every later row), `close`. Optional: `open`, `high`,
|
|
888
|
+
* `low`, `volume`, `quoteVolume`, `bid`, `bidSize`, `ask`, `askSize`. Cadence and timestamp
|
|
889
|
+
* unit are discovered from the data, not declared.
|
|
890
|
+
*
|
|
891
|
+
* A CSV upload is converted to our native columnar format (`lastra`) for storage. A parquet
|
|
892
|
+
* upload is stored as-is today. Either way, always check `dataFormat` on
|
|
893
|
+
* `GET /datasets/{datasetId}` and `GET /datasets/{datasetId}/uploads/{uploadId}` for which
|
|
894
|
+
* one `dataUrl` actually is, rather than assuming from how you uploaded it.
|
|
895
|
+
*
|
|
896
|
+
* The bytes PUT to `upload.url` may be that file directly, gzipped (`.gz`), or zipped
|
|
897
|
+
* (`.zip`, exactly one file inside — a dataset is one file regardless of how it travels).
|
|
898
|
+
* Format is detected from the decompressed content itself: there is no filename or
|
|
899
|
+
* `Content-Type` anywhere in this flow for a client to declare it with, so nothing needs to
|
|
900
|
+
* be sent besides the bytes.
|
|
878
901
|
*
|
|
879
902
|
*/
|
|
880
903
|
export const createDataset = <ThrowOnError extends boolean = false>(
|
|
@@ -14,6 +14,11 @@ export type ResponseError = {
|
|
|
14
14
|
message: string;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* A scalar strategy property value for one execution.
|
|
19
|
+
*/
|
|
20
|
+
export type ScalarStrategyParamValue = number | string | boolean;
|
|
21
|
+
|
|
17
22
|
/**
|
|
18
23
|
* Exchange instrument identifier (e.g. a currency pair)
|
|
19
24
|
*/
|
|
@@ -253,7 +258,7 @@ export type PrepareRequest = {
|
|
|
253
258
|
*/
|
|
254
259
|
export type JobState = {
|
|
255
260
|
/**
|
|
256
|
-
*
|
|
261
|
+
* 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
262
|
*/
|
|
258
263
|
contextId: string;
|
|
259
264
|
/**
|
|
@@ -568,7 +573,7 @@ export type SweepRunRow = {
|
|
|
568
573
|
*/
|
|
569
574
|
neighbourCount?: number;
|
|
570
575
|
/**
|
|
571
|
-
* Probability that this run's Sharpe reflects real edge rather than the best draw from however many parameter vectors were tried. Above ~0.95 the result survives the multiple-testing correction; near 0.5 or below it is indistinguishable from the best of a pile of coin flips. Absent on aborted runs,
|
|
576
|
+
* Probability that this run's Sharpe reflects real edge rather than the best draw from however many parameter vectors were tried. Above ~0.95 the result survives the multiple-testing correction; near 0.5 or below it is indistinguishable from the best of a pile of coin flips. Absent on aborted runs, on sweeps with too few trials to establish any dispersion to deflate against, on runs with fewer than 3 period returns, and on a degenerate (near-constant) return series — all cases where the underlying statistic isn't meaningfully computable, rather than genuinely zero. A present value is the computed probability, however small.
|
|
572
577
|
*/
|
|
573
578
|
deflatedSharpe?: number;
|
|
574
579
|
params: {
|
|
@@ -580,16 +585,31 @@ export type SweepRunRow = {
|
|
|
580
585
|
* Absolute net PnL in the output currency.
|
|
581
586
|
*/
|
|
582
587
|
pnl: number;
|
|
588
|
+
/**
|
|
589
|
+
* Same units as `pnlTotalPercent` on the single-run result — percent (0-100 scale).
|
|
590
|
+
*/
|
|
583
591
|
pnlPct: number;
|
|
592
|
+
/**
|
|
593
|
+
* Same units as `cagr` on the single-run result — a ratio, not a percent.
|
|
594
|
+
*/
|
|
584
595
|
cagr: number;
|
|
596
|
+
/**
|
|
597
|
+
* Same units as `maxDrawdownPercent` on the single-run result — percent (0-100 scale).
|
|
598
|
+
*/
|
|
585
599
|
maxDdPct: number;
|
|
586
600
|
trades: number;
|
|
601
|
+
/**
|
|
602
|
+
* Same units as `winRate` on the single-run result — a fraction, 0.0-1.0 (a rate, not a percent).
|
|
603
|
+
*/
|
|
587
604
|
winRate: number;
|
|
588
605
|
belowTradeFloor: boolean;
|
|
589
606
|
aborted: boolean;
|
|
590
607
|
runtimeMs: number;
|
|
591
608
|
/**
|
|
592
|
-
* Present
|
|
609
|
+
* Present whenever this trial actually has a curve — which is any completed run of a sweep that requested curves at all (`equityCurve.mode` `topN`/`topPct`), not only the ranked winners. Absent, not null, when there is genuinely nothing: the run aborted, it made no trades, or the sweep never retained curves (`mode` `auto`/`none`).
|
|
610
|
+
* Selection decides how the curve travels, not whether it exists. A row may carry `url` alone, or `url` together with the points inline.
|
|
611
|
+
* **Read `points`/`equities` to tell whether the curve is inline — never the presence of this object, and never the absence of `url`.** Both mislead, and in opposite directions: this object is present on rows that carry only a pointer, and `url` stays present alongside an inline curve so a caller can still re-request a different transform. An inline curve is emitted on the materialisation view (`?order=natural`), where each row is read once; the ranked view keeps the pointer, being polled.
|
|
612
|
+
* When only a pointer is present, `GET` the `url` for the curve. Its own `meta` there is the real, possibly size-guarded outcome. This outer `meta` may be a declaration rather than a measurement — for a row whose curve was not promoted, the point count is derived from the trade count (one equity point per closed trade) instead of being read from the store, to keep a polled response from doing per-row work.
|
|
593
613
|
*/
|
|
594
614
|
equityCurve?: EquityCurveResult;
|
|
595
615
|
};
|
|
@@ -695,7 +715,8 @@ export type ExecuteSweepResult = {
|
|
|
695
715
|
* The same `JobState` shape a single-execute `BacktestJobResult` carries — not a sweep-specific lookalike, the actual type, so field names and timestamp formatting match exactly.
|
|
696
716
|
* `state.status` uses `JobState`'s own vocabulary (`New`/`Started`/`Completed`/ `Aborted`/`Failed`), mapped from the sweep's `status` field above rather than copying it: `PARTIAL` and `CANCELLED` both map to `Aborted`, because a sweep's `PARTIAL` is already terminal (some shards finished, some failed, nothing more is coming) unlike a single job's non-terminal `Partial`, which has no equivalent here at all.
|
|
697
717
|
* `state.completed` is real ticks processed on a plain sweep. On a `walkForward` sweep it is currently always `0` — the walk-forward fold runner was not wired to count ticks when this shipped, unlike the plain shard path.
|
|
698
|
-
* `state.size` is
|
|
718
|
+
* `state.size` is an upfront estimate — range x the prepare's target cadence, set before any data is even loaded, not a query against loaded data — on a single execute and a plain sweep alike. A plain sweep's value is the sum of every shard's own `size` (each shard's per-run estimate x its own vector slice), the same additive shape `state.completed` already used above. `0` means the prepare context behind the job predates this field (a job whose prepare ran before the estimate existed) — never a guessed cadence standing in for a real one.
|
|
719
|
+
* On a `walkForward` sweep, `state.size` is still always `0`: fold runs were out of scope for the estimate the same way they are for `state.completed` above — a fold's `size` is simply never set, so the sum stays honest at `0` rather than needing a special case.
|
|
699
720
|
*/
|
|
700
721
|
state: JobState;
|
|
701
722
|
};
|
|
@@ -770,7 +791,7 @@ export type WalkForwardFold = {
|
|
|
770
791
|
*/
|
|
771
792
|
export type AcceptedJob = {
|
|
772
793
|
/**
|
|
773
|
-
* Unique job identifier; use this to poll for completion.
|
|
794
|
+
* 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
795
|
*/
|
|
775
796
|
jobId: string;
|
|
776
797
|
};
|
|
@@ -839,7 +860,7 @@ export type ResultMap = {
|
|
|
839
860
|
*/
|
|
840
861
|
totalTrades?: number;
|
|
841
862
|
/**
|
|
842
|
-
*
|
|
863
|
+
* 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
864
|
*/
|
|
844
865
|
winRate?: number;
|
|
845
866
|
/**
|
|
@@ -851,7 +872,7 @@ export type ResultMap = {
|
|
|
851
872
|
*/
|
|
852
873
|
sortinoRatio?: number;
|
|
853
874
|
/**
|
|
854
|
-
* Compound Annual Growth Rate
|
|
875
|
+
* Compound Annual Growth Rate (eg. 0.15 for 15%)
|
|
855
876
|
*/
|
|
856
877
|
cagr?: number;
|
|
857
878
|
/**
|
|
@@ -866,6 +887,12 @@ export type ResultMap = {
|
|
|
866
887
|
* 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
888
|
*/
|
|
868
889
|
equityCurve?: EquityCurveResult;
|
|
890
|
+
/**
|
|
891
|
+
* 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.
|
|
892
|
+
*/
|
|
893
|
+
params?: {
|
|
894
|
+
[key: string]: ScalarStrategyParamValue;
|
|
895
|
+
};
|
|
869
896
|
/**
|
|
870
897
|
* Number of signals emitted during strategy execution
|
|
871
898
|
*/
|
|
@@ -1197,6 +1224,23 @@ export type Dataset = {
|
|
|
1197
1224
|
* A `Dataset` plus a self link. Returned by `GET /datasets/{datasetId}`.
|
|
1198
1225
|
*/
|
|
1199
1226
|
export type DatasetWithLinks = Dataset & {
|
|
1227
|
+
/**
|
|
1228
|
+
* Presigned GET URL to the current version's stored file — see `dataFormat` for
|
|
1229
|
+
* which format it's actually in. Present only once the current version's status is
|
|
1230
|
+
* `ready`. Long-lived (day-scale, not permanent): a DuckDB-WASM/`lastra-ts`-style
|
|
1231
|
+
* reader issues HTTP range requests against it lazily over an extended viewing
|
|
1232
|
+
* session, not in one shot like a browser upload.
|
|
1233
|
+
*
|
|
1234
|
+
*/
|
|
1235
|
+
dataUrl?: string;
|
|
1236
|
+
/**
|
|
1237
|
+
* Which format `dataUrl` is actually in — check this rather than assuming it
|
|
1238
|
+
* matches how you uploaded it. `lastra` — our native columnar format — for a CSV (or
|
|
1239
|
+
* gzip/zip of one) upload, always converted on ingest. `parquet` for a parquet
|
|
1240
|
+
* upload, stored as-is today.
|
|
1241
|
+
*
|
|
1242
|
+
*/
|
|
1243
|
+
dataFormat?: "lastra" | "parquet";
|
|
1200
1244
|
_links?: {
|
|
1201
1245
|
self?: {
|
|
1202
1246
|
href?: string;
|
|
@@ -1209,8 +1253,9 @@ export type DatasetWithLinks = Dataset & {
|
|
|
1209
1253
|
*/
|
|
1210
1254
|
export type DatasetUploadTarget = {
|
|
1211
1255
|
/**
|
|
1212
|
-
* Presigned URL. `PUT` the
|
|
1213
|
-
* no other API
|
|
1256
|
+
* Presigned URL. `PUT` the file here directly — the CSV or parquet itself, or a `.gz`/`.zip` of it
|
|
1257
|
+
* (see `createDataset`'s own description) — no `Authorization` header, no other API
|
|
1258
|
+
* credentials.
|
|
1214
1259
|
*
|
|
1215
1260
|
*/
|
|
1216
1261
|
url: string;
|
|
@@ -1271,7 +1316,7 @@ export type DatasetVersion = {
|
|
|
1271
1316
|
*/
|
|
1272
1317
|
id?: string;
|
|
1273
1318
|
/**
|
|
1274
|
-
* Size of the
|
|
1319
|
+
* Size of the stored file `dataUrl` points at — a converted `lastra` for a CSV/gzip/zip upload, or the parquet file itself, unconverted, for a parquet upload. Not the size of the bytes originally PUT to storage; see `dataFormat`.
|
|
1275
1320
|
*/
|
|
1276
1321
|
bytes?: number;
|
|
1277
1322
|
/**
|
|
@@ -1296,10 +1341,26 @@ export type DatasetVersion = {
|
|
|
1296
1341
|
* The largest gap, in units of the discovered cadence step.
|
|
1297
1342
|
*/
|
|
1298
1343
|
largestGapSteps?: number;
|
|
1344
|
+
/**
|
|
1345
|
+
* Presigned GET URL to the stored file — see `dataFormat` for which format it's in.
|
|
1346
|
+
* Present once the version is `ready`. Long-lived (day-scale, not permanent): a
|
|
1347
|
+
* DuckDB-WASM/`lastra-ts`-style reader issues HTTP range requests against it lazily over
|
|
1348
|
+
* an extended viewing session, not in one shot like a browser upload.
|
|
1349
|
+
*
|
|
1350
|
+
*/
|
|
1351
|
+
dataUrl?: string;
|
|
1352
|
+
/**
|
|
1353
|
+
* Which format `dataUrl` is actually in — check this rather than assuming it matches
|
|
1354
|
+
* how you uploaded it. `lastra` — our native columnar format — for a CSV (or gzip/zip
|
|
1355
|
+
* of one) upload, always converted on ingest. `parquet` for a parquet upload, stored
|
|
1356
|
+
* as-is today.
|
|
1357
|
+
*
|
|
1358
|
+
*/
|
|
1359
|
+
dataFormat?: "lastra" | "parquet";
|
|
1299
1360
|
};
|
|
1300
1361
|
|
|
1301
1362
|
/**
|
|
1302
|
-
* Progress of one upload, from staged through ingest.
|
|
1363
|
+
* Progress of one upload, from staged through ingest. Durably recorded once a version exists,
|
|
1303
1364
|
* so `ready`/`failed` are permanent answers; `uploading`/`ingesting` reflect in-flight state
|
|
1304
1365
|
* that can itself age out — see the `404` case on `GET .../uploads/{uploadId}`.
|
|
1305
1366
|
*
|
|
@@ -1311,7 +1372,8 @@ export type DatasetUploadState = {
|
|
|
1311
1372
|
* called yet.
|
|
1312
1373
|
* * `ingesting` — `finalize` was called; the worker is parsing and validating the file.
|
|
1313
1374
|
* * `ready` — ingested successfully. `version` carries the result.
|
|
1314
|
-
* * `failed` — ingest rejected the file (e.g. bad CSV contract, mixed timestamp units
|
|
1375
|
+
* * `failed` — ingest rejected the file (e.g. bad CSV contract, mixed timestamp units, a
|
|
1376
|
+
* `.zip` with no file inside or more than one).
|
|
1315
1377
|
*
|
|
1316
1378
|
*/
|
|
1317
1379
|
status: "uploading" | "ingesting" | "ready" | "failed";
|
|
@@ -1970,6 +2032,9 @@ export type CancelSweepData = {
|
|
|
1970
2032
|
path: {
|
|
1971
2033
|
exchangeId: string;
|
|
1972
2034
|
type: DataSourceType;
|
|
2035
|
+
/**
|
|
2036
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
2037
|
+
*/
|
|
1973
2038
|
requestId: string;
|
|
1974
2039
|
sweepId: string;
|
|
1975
2040
|
};
|
|
@@ -2004,6 +2069,9 @@ export type GetSweepResultData = {
|
|
|
2004
2069
|
path: {
|
|
2005
2070
|
exchangeId: string;
|
|
2006
2071
|
type: DataSourceType;
|
|
2072
|
+
/**
|
|
2073
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
2074
|
+
*/
|
|
2007
2075
|
requestId: string;
|
|
2008
2076
|
sweepId: string;
|
|
2009
2077
|
};
|
|
@@ -2046,6 +2114,9 @@ export type GetSweepSensitivityData = {
|
|
|
2046
2114
|
path: {
|
|
2047
2115
|
exchangeId: string;
|
|
2048
2116
|
type: DataSourceType;
|
|
2117
|
+
/**
|
|
2118
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
2119
|
+
*/
|
|
2049
2120
|
requestId: string;
|
|
2050
2121
|
sweepId: string;
|
|
2051
2122
|
};
|
|
@@ -2083,6 +2154,9 @@ export type GetSweepRunEquityCurveData = {
|
|
|
2083
2154
|
path: {
|
|
2084
2155
|
exchangeId: string;
|
|
2085
2156
|
type: DataSourceType;
|
|
2157
|
+
/**
|
|
2158
|
+
* The `jobId` returned by `POST /backtest/{exchangeId}/{type}/prepare`.
|
|
2159
|
+
*/
|
|
2086
2160
|
requestId: string;
|
|
2087
2161
|
sweepId: string;
|
|
2088
2162
|
/**
|
|
@@ -2144,6 +2218,28 @@ export type ExecuteBacktestData = {
|
|
|
2144
2218
|
*/
|
|
2145
2219
|
storeSignals?: boolean;
|
|
2146
2220
|
equityCurve?: EquityCurveOptions;
|
|
2221
|
+
/**
|
|
2222
|
+
* Strategy properties to apply to this run. Omit to run the strategy's declared
|
|
2223
|
+
* defaults, which is exactly what a request without this field has always done.
|
|
2224
|
+
*
|
|
2225
|
+
* Each key is the `name` declared on the strategy's `@StrategyProperty`, which
|
|
2226
|
+
* need NOT match the Java field it annotates — `GET`/`POST /strategy` returns
|
|
2227
|
+
* `declaredProperties` for precisely this. A key naming no declared property is
|
|
2228
|
+
* rejected: the job fails with the list of names the strategy does declare,
|
|
2229
|
+
* rather than completing at the defaults and handing back a plausible result for
|
|
2230
|
+
* parameters nobody chose.
|
|
2231
|
+
*
|
|
2232
|
+
* Scalars only — number, string or boolean. Ranges and lists belong to
|
|
2233
|
+
* `executeSweep`; one request here is one run. `null` is not a value: leave the
|
|
2234
|
+
* key out to keep a property at its default. Keys are made of letters, digits,
|
|
2235
|
+
* `_`, `-` and dots, and may not be `strategyId`, `storeSignals`, `equityCurve`,
|
|
2236
|
+
* `backtestEnabled` or `backtestFakeExecution` — those configure the job rather
|
|
2237
|
+
* than the strategy.
|
|
2238
|
+
*
|
|
2239
|
+
*/
|
|
2240
|
+
params?: {
|
|
2241
|
+
[key: string]: ScalarStrategyParamValue;
|
|
2242
|
+
};
|
|
2147
2243
|
};
|
|
2148
2244
|
path: {
|
|
2149
2245
|
/**
|