@qtsurfer/api-client 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.d.ts +550 -87
- package/dist/index.js +30 -5
- package/dist/index.js.map +1 -1
- package/package.json +9 -2
- package/src/generated/client.gen.ts +16 -6
- package/src/generated/index.ts +2 -2
- package/src/generated/schemas.gen.ts +1444 -867
- package/src/generated/sdk.gen.ts +470 -189
- package/src/generated/types.gen.ts +1326 -897
package/src/generated/sdk.gen.ts
CHANGED
|
@@ -1,21 +1,82 @@
|
|
|
1
1
|
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import type {
|
|
4
|
+
Options as ClientOptions,
|
|
5
|
+
TDataShape,
|
|
6
|
+
Client,
|
|
7
|
+
} from "@hey-api/client-fetch";
|
|
8
|
+
import type {
|
|
9
|
+
AuthenticateData,
|
|
10
|
+
AuthenticateResponse,
|
|
11
|
+
AuthenticateError,
|
|
12
|
+
ListExchangesData,
|
|
13
|
+
ListExchangesResponse,
|
|
14
|
+
ListInstrumentsData,
|
|
15
|
+
ListInstrumentsResponse,
|
|
16
|
+
ListInstrumentsError,
|
|
17
|
+
ListSegmentInstrumentsData,
|
|
18
|
+
ListSegmentInstrumentsResponse,
|
|
19
|
+
ListSegmentInstrumentsError,
|
|
20
|
+
DownloadTickersData,
|
|
21
|
+
DownloadTickersResponse,
|
|
22
|
+
DownloadTickersError,
|
|
23
|
+
DownloadKlinesData,
|
|
24
|
+
DownloadKlinesResponse,
|
|
25
|
+
DownloadKlinesError,
|
|
26
|
+
CompileStrategyData,
|
|
27
|
+
CompileStrategyResponse,
|
|
28
|
+
CompileStrategyError,
|
|
29
|
+
ValidateStrategyData,
|
|
30
|
+
ValidateStrategyResponse,
|
|
31
|
+
ValidateStrategyError,
|
|
32
|
+
GetStrategyData,
|
|
33
|
+
GetStrategyResponse,
|
|
34
|
+
GetStrategyError,
|
|
35
|
+
PrepareBacktestData,
|
|
36
|
+
PrepareBacktestResponse,
|
|
37
|
+
PrepareBacktestError,
|
|
38
|
+
GetPrepareStatusData,
|
|
39
|
+
GetPrepareStatusResponse,
|
|
40
|
+
GetPrepareStatusError,
|
|
41
|
+
ExecuteSweepData,
|
|
42
|
+
ExecuteSweepResponse,
|
|
43
|
+
ExecuteSweepError,
|
|
44
|
+
CancelSweepData,
|
|
45
|
+
CancelSweepResponse,
|
|
46
|
+
CancelSweepError,
|
|
47
|
+
GetSweepResultData,
|
|
48
|
+
GetSweepResultResponse,
|
|
49
|
+
GetSweepResultError,
|
|
50
|
+
GetSweepSensitivityData,
|
|
51
|
+
GetSweepSensitivityResponse,
|
|
52
|
+
GetSweepSensitivityError,
|
|
53
|
+
ExecuteBacktestData,
|
|
54
|
+
ExecuteBacktestResponse,
|
|
55
|
+
ExecuteBacktestError,
|
|
56
|
+
CancelBacktestData,
|
|
57
|
+
CancelBacktestResponse,
|
|
58
|
+
CancelBacktestError,
|
|
59
|
+
GetBacktestResultData,
|
|
60
|
+
GetBacktestResultResponse,
|
|
61
|
+
GetBacktestResultError,
|
|
62
|
+
} from "./types.gen";
|
|
63
|
+
import { client as _heyApiClient } from "./client.gen";
|
|
6
64
|
|
|
7
|
-
export type Options<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
65
|
+
export type Options<
|
|
66
|
+
TData extends TDataShape = TDataShape,
|
|
67
|
+
ThrowOnError extends boolean = boolean
|
|
68
|
+
> = ClientOptions<TData, ThrowOnError> & {
|
|
69
|
+
/**
|
|
70
|
+
* You can provide a client instance returned by `createClient()` instead of
|
|
71
|
+
* individual options. This might be also useful if you want to implement a
|
|
72
|
+
* custom client.
|
|
73
|
+
*/
|
|
74
|
+
client?: Client;
|
|
75
|
+
/**
|
|
76
|
+
* You can pass arbitrary values through the `meta` object. This can be
|
|
77
|
+
* used to access values that aren't defined as part of the SDK function.
|
|
78
|
+
*/
|
|
79
|
+
meta?: Record<string, unknown>;
|
|
19
80
|
};
|
|
20
81
|
|
|
21
82
|
/**
|
|
@@ -30,27 +91,39 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
|
|
|
30
91
|
* before expiry (or on a `401` response) by calling this endpoint again.
|
|
31
92
|
*
|
|
32
93
|
*/
|
|
33
|
-
export const authenticate = <ThrowOnError extends boolean = false>(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
94
|
+
export const authenticate = <ThrowOnError extends boolean = false>(
|
|
95
|
+
options?: Options<AuthenticateData, ThrowOnError>
|
|
96
|
+
) => {
|
|
97
|
+
return (options?.client ?? _heyApiClient).post<
|
|
98
|
+
AuthenticateResponse,
|
|
99
|
+
AuthenticateError,
|
|
100
|
+
ThrowOnError
|
|
101
|
+
>({
|
|
102
|
+
security: [
|
|
103
|
+
{
|
|
104
|
+
name: "X-API-Key",
|
|
105
|
+
type: "apiKey",
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
url: "/auth/token",
|
|
109
|
+
...options,
|
|
110
|
+
});
|
|
44
111
|
};
|
|
45
112
|
|
|
46
113
|
/**
|
|
47
114
|
* List the available exchanges
|
|
48
115
|
*/
|
|
49
|
-
export const listExchanges = <ThrowOnError extends boolean = false>(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
116
|
+
export const listExchanges = <ThrowOnError extends boolean = false>(
|
|
117
|
+
options?: Options<ListExchangesData, ThrowOnError>
|
|
118
|
+
) => {
|
|
119
|
+
return (options?.client ?? _heyApiClient).get<
|
|
120
|
+
ListExchangesResponse,
|
|
121
|
+
unknown,
|
|
122
|
+
ThrowOnError
|
|
123
|
+
>({
|
|
124
|
+
url: "/exchanges",
|
|
125
|
+
...options,
|
|
126
|
+
});
|
|
54
127
|
};
|
|
55
128
|
|
|
56
129
|
/**
|
|
@@ -61,11 +134,17 @@ export const listExchanges = <ThrowOnError extends boolean = false>(options?: Op
|
|
|
61
134
|
* `spot` / `futures` segment-discovery links.
|
|
62
135
|
*
|
|
63
136
|
*/
|
|
64
|
-
export const listInstruments = <ThrowOnError extends boolean = false>(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
137
|
+
export const listInstruments = <ThrowOnError extends boolean = false>(
|
|
138
|
+
options: Options<ListInstrumentsData, ThrowOnError>
|
|
139
|
+
) => {
|
|
140
|
+
return (options.client ?? _heyApiClient).get<
|
|
141
|
+
ListInstrumentsResponse,
|
|
142
|
+
ListInstrumentsError,
|
|
143
|
+
ThrowOnError
|
|
144
|
+
>({
|
|
145
|
+
url: "/exchange/{exchangeId}/instruments",
|
|
146
|
+
...options,
|
|
147
|
+
});
|
|
69
148
|
};
|
|
70
149
|
|
|
71
150
|
/**
|
|
@@ -76,11 +155,17 @@ export const listInstruments = <ThrowOnError extends boolean = false>(options: O
|
|
|
76
155
|
* `GET /exchange/{exchangeId}/instruments` (spot).
|
|
77
156
|
*
|
|
78
157
|
*/
|
|
79
|
-
export const listSegmentInstruments = <ThrowOnError extends boolean = false>(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
158
|
+
export const listSegmentInstruments = <ThrowOnError extends boolean = false>(
|
|
159
|
+
options: Options<ListSegmentInstrumentsData, ThrowOnError>
|
|
160
|
+
) => {
|
|
161
|
+
return (options.client ?? _heyApiClient).get<
|
|
162
|
+
ListSegmentInstrumentsResponse,
|
|
163
|
+
ListSegmentInstrumentsError,
|
|
164
|
+
ThrowOnError
|
|
165
|
+
>({
|
|
166
|
+
url: "/exchange/{exchangeId}/{segment}/instruments",
|
|
167
|
+
...options,
|
|
168
|
+
});
|
|
84
169
|
};
|
|
85
170
|
|
|
86
171
|
/**
|
|
@@ -115,11 +200,17 @@ export const listSegmentInstruments = <ThrowOnError extends boolean = false>(opt
|
|
|
115
200
|
* descriptive filename).
|
|
116
201
|
*
|
|
117
202
|
*/
|
|
118
|
-
export const downloadTickers = <ThrowOnError extends boolean = false>(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
203
|
+
export const downloadTickers = <ThrowOnError extends boolean = false>(
|
|
204
|
+
options: Options<DownloadTickersData, ThrowOnError>
|
|
205
|
+
) => {
|
|
206
|
+
return (options.client ?? _heyApiClient).get<
|
|
207
|
+
DownloadTickersResponse,
|
|
208
|
+
DownloadTickersError,
|
|
209
|
+
ThrowOnError
|
|
210
|
+
>({
|
|
211
|
+
url: "/exchange/{exchangeId}/tickers/{base}/{quote}",
|
|
212
|
+
...options,
|
|
213
|
+
});
|
|
123
214
|
};
|
|
124
215
|
|
|
125
216
|
/**
|
|
@@ -134,59 +225,127 @@ export const downloadTickers = <ThrowOnError extends boolean = false>(options: O
|
|
|
134
225
|
* per-tick payload would be too large for the window of interest.
|
|
135
226
|
*
|
|
136
227
|
*/
|
|
137
|
-
export const downloadKlines = <ThrowOnError extends boolean = false>(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
228
|
+
export const downloadKlines = <ThrowOnError extends boolean = false>(
|
|
229
|
+
options: Options<DownloadKlinesData, ThrowOnError>
|
|
230
|
+
) => {
|
|
231
|
+
return (options.client ?? _heyApiClient).get<
|
|
232
|
+
DownloadKlinesResponse,
|
|
233
|
+
DownloadKlinesError,
|
|
234
|
+
ThrowOnError
|
|
235
|
+
>({
|
|
236
|
+
url: "/exchange/{exchangeId}/klines/{base}/{quote}",
|
|
237
|
+
...options,
|
|
238
|
+
});
|
|
142
239
|
};
|
|
143
240
|
|
|
144
241
|
/**
|
|
145
|
-
* Compile a strategy
|
|
146
|
-
*
|
|
147
|
-
* the `strategyId` once compilation succeeds. Set the header `X-Compile-Async: true` to enqueue
|
|
148
|
-
* the compile task and return immediately with a `jobId` — poll
|
|
149
|
-
* `GET /strategy/{strategyId}` to check status.
|
|
242
|
+
* Compile and register a strategy
|
|
243
|
+
* Compiles raw strategy source and registers it, returning its `strategyId`.
|
|
150
244
|
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
245
|
+
* **This answers one question: is the source valid Java.** It compiles, registers, and hands
|
|
246
|
+
* back the id — nothing more. Whether the class can actually run is
|
|
247
|
+
* `POST /strategy/{strategyId}/validate`, and everything known about a strategy, validation
|
|
248
|
+
* included, is read from `GET /strategy/{strategyId}`. One place to ask, so there is no second
|
|
249
|
+
* answer to keep in step.
|
|
250
|
+
*
|
|
251
|
+
* The `strategyId` is derived from what the code *means*, not from how it is written. Adding a
|
|
252
|
+
* comment, inserting a blank line, re-indenting, reordering imports, or moving a method around
|
|
253
|
+
* all return the **same** id — you have not created a second strategy. Renaming a variable,
|
|
254
|
+
* changing an identifier's case, reordering fields, or reordering statements inside a method
|
|
255
|
+
* return a **different** one.
|
|
256
|
+
*
|
|
257
|
+
* Two rules follow, and they are worth designing around:
|
|
258
|
+
*
|
|
259
|
+
* - re-submitting a strategy you have only reformatted is free, and gives you back the id you
|
|
260
|
+
* already had, along with any validation already recorded against it;
|
|
261
|
+
* - the id says nothing about *behaviour*. Two sources that compute the same thing by
|
|
262
|
+
* different means are two strategies, because deciding otherwise would mean deciding program
|
|
263
|
+
* equivalence.
|
|
153
264
|
*
|
|
154
265
|
*/
|
|
155
|
-
export const compileStrategy = <ThrowOnError extends boolean = false>(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
266
|
+
export const compileStrategy = <ThrowOnError extends boolean = false>(
|
|
267
|
+
options: Options<CompileStrategyData, ThrowOnError>
|
|
268
|
+
) => {
|
|
269
|
+
return (options.client ?? _heyApiClient).post<
|
|
270
|
+
CompileStrategyResponse,
|
|
271
|
+
CompileStrategyError,
|
|
272
|
+
ThrowOnError
|
|
273
|
+
>({
|
|
274
|
+
bodySerializer: null,
|
|
275
|
+
security: [
|
|
276
|
+
{
|
|
277
|
+
scheme: "bearer",
|
|
278
|
+
type: "http",
|
|
279
|
+
},
|
|
280
|
+
],
|
|
281
|
+
url: "/strategy",
|
|
282
|
+
...options,
|
|
283
|
+
headers: {
|
|
284
|
+
"Content-Type": "text/plain",
|
|
285
|
+
...options?.headers,
|
|
286
|
+
},
|
|
287
|
+
});
|
|
171
288
|
};
|
|
172
289
|
|
|
173
290
|
/**
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
291
|
+
* Check that a registered strategy can actually run
|
|
292
|
+
* Instantiates the compiled class and drives it through a bounded synthetic series, so a wiring
|
|
293
|
+
* fault surfaces here instead of at your first backtest. The verdict — pass or fail, plus any
|
|
294
|
+
* engine notices — is recorded and served from `GET /strategy/{strategyId}`.
|
|
295
|
+
*
|
|
296
|
+
* **Idempotent.** If a verdict already exists for the current compilation it comes straight
|
|
297
|
+
* back with `200` and nothing is queued. Otherwise the check is queued and this returns `202`;
|
|
298
|
+
* poll `GET /strategy/{strategyId}` until `validation` is `passed` or `failed`.
|
|
299
|
+
*
|
|
300
|
+
* Recompiling supersedes a verdict, which makes this callable again — the old answer described
|
|
301
|
+
* bytecode that is no longer what would run.
|
|
177
302
|
*
|
|
178
303
|
*/
|
|
179
|
-
export const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
304
|
+
export const validateStrategy = <ThrowOnError extends boolean = false>(
|
|
305
|
+
options: Options<ValidateStrategyData, ThrowOnError>
|
|
306
|
+
) => {
|
|
307
|
+
return (options.client ?? _heyApiClient).post<
|
|
308
|
+
ValidateStrategyResponse,
|
|
309
|
+
ValidateStrategyError,
|
|
310
|
+
ThrowOnError
|
|
311
|
+
>({
|
|
312
|
+
security: [
|
|
313
|
+
{
|
|
314
|
+
scheme: "bearer",
|
|
315
|
+
type: "http",
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
url: "/strategy/{strategyId}/validate",
|
|
319
|
+
...options,
|
|
320
|
+
});
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Get a strategy by id, including its validation state
|
|
325
|
+
* Reports that the strategy is registered — implied by a `200` at all — and what validating it
|
|
326
|
+
* found.
|
|
327
|
+
*
|
|
328
|
+
* A `404` means one thing: no such registered strategy for this user. It is never a stale or
|
|
329
|
+
* expired answer; registration and verdict are stored durably, not cached.
|
|
330
|
+
*
|
|
331
|
+
*/
|
|
332
|
+
export const getStrategy = <ThrowOnError extends boolean = false>(
|
|
333
|
+
options: Options<GetStrategyData, ThrowOnError>
|
|
334
|
+
) => {
|
|
335
|
+
return (options.client ?? _heyApiClient).get<
|
|
336
|
+
GetStrategyResponse,
|
|
337
|
+
GetStrategyError,
|
|
338
|
+
ThrowOnError
|
|
339
|
+
>({
|
|
340
|
+
security: [
|
|
341
|
+
{
|
|
342
|
+
scheme: "bearer",
|
|
343
|
+
type: "http",
|
|
344
|
+
},
|
|
345
|
+
],
|
|
346
|
+
url: "/strategy/{strategyId}",
|
|
347
|
+
...options,
|
|
348
|
+
});
|
|
190
349
|
};
|
|
191
350
|
|
|
192
351
|
/**
|
|
@@ -198,21 +357,27 @@ export const getStrategy = <ThrowOnError extends boolean = false>(options: Optio
|
|
|
198
357
|
* params do not enqueue duplicate work — they reuse the existing job.
|
|
199
358
|
*
|
|
200
359
|
*/
|
|
201
|
-
export const prepareBacktest = <ThrowOnError extends boolean = false>(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
360
|
+
export const prepareBacktest = <ThrowOnError extends boolean = false>(
|
|
361
|
+
options: Options<PrepareBacktestData, ThrowOnError>
|
|
362
|
+
) => {
|
|
363
|
+
return (options.client ?? _heyApiClient).post<
|
|
364
|
+
PrepareBacktestResponse,
|
|
365
|
+
PrepareBacktestError,
|
|
366
|
+
ThrowOnError
|
|
367
|
+
>({
|
|
368
|
+
security: [
|
|
369
|
+
{
|
|
370
|
+
scheme: "bearer",
|
|
371
|
+
type: "http",
|
|
372
|
+
},
|
|
373
|
+
],
|
|
374
|
+
url: "/backtest/{exchangeId}/{type}/prepare",
|
|
375
|
+
...options,
|
|
376
|
+
headers: {
|
|
377
|
+
"Content-Type": "application/json",
|
|
378
|
+
...options?.headers,
|
|
379
|
+
},
|
|
380
|
+
});
|
|
216
381
|
};
|
|
217
382
|
|
|
218
383
|
/**
|
|
@@ -221,17 +386,23 @@ export const prepareBacktest = <ThrowOnError extends boolean = false>(options: O
|
|
|
221
386
|
* Poll until `status` is `Completed`, `Failed`, or `Aborted`.
|
|
222
387
|
*
|
|
223
388
|
*/
|
|
224
|
-
export const getPrepareStatus = <ThrowOnError extends boolean = false>(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
389
|
+
export const getPrepareStatus = <ThrowOnError extends boolean = false>(
|
|
390
|
+
options: Options<GetPrepareStatusData, ThrowOnError>
|
|
391
|
+
) => {
|
|
392
|
+
return (options.client ?? _heyApiClient).get<
|
|
393
|
+
GetPrepareStatusResponse,
|
|
394
|
+
GetPrepareStatusError,
|
|
395
|
+
ThrowOnError
|
|
396
|
+
>({
|
|
397
|
+
security: [
|
|
398
|
+
{
|
|
399
|
+
scheme: "bearer",
|
|
400
|
+
type: "http",
|
|
401
|
+
},
|
|
402
|
+
],
|
|
403
|
+
url: "/backtest/{exchangeId}/{type}/prepare/{jobId}",
|
|
404
|
+
...options,
|
|
405
|
+
});
|
|
235
406
|
};
|
|
236
407
|
|
|
237
408
|
/**
|
|
@@ -240,39 +411,62 @@ export const getPrepareStatus = <ThrowOnError extends boolean = false>(options:
|
|
|
240
411
|
* The backend expands and executes the matrix internally; clients poll the returned
|
|
241
412
|
* `sweepId` for incremental results.
|
|
242
413
|
*
|
|
414
|
+
* Supplying `walkForward` runs the sweep in a different mode entirely. Instead of scoring
|
|
415
|
+
* every parameter vector once over the whole range, the data is split into F sequential
|
|
416
|
+
* folds; each fold optimizes the full grid on its own window and then scores only its winner
|
|
417
|
+
* on the window immediately after — data that winner was not chosen on. It answers a harder
|
|
418
|
+
* question than a leaderboard: not "which parameters won", but "does re-optimizing this
|
|
419
|
+
* periodically actually work". Omit the block and nothing changes, including the response.
|
|
420
|
+
*
|
|
421
|
+
* The cost is the reason it is opt-in rather than always on: F folds × N vectors, so a
|
|
422
|
+
* 4-fold run over a 500-point grid is 2004 backtests where the plain sweep is 500. The
|
|
423
|
+
* request is rejected when `folds × totalRuns` exceeds the server's sweep budget.
|
|
424
|
+
*
|
|
243
425
|
*/
|
|
244
|
-
export const executeSweep = <ThrowOnError extends boolean = false>(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
426
|
+
export const executeSweep = <ThrowOnError extends boolean = false>(
|
|
427
|
+
options: Options<ExecuteSweepData, ThrowOnError>
|
|
428
|
+
) => {
|
|
429
|
+
return (options.client ?? _heyApiClient).post<
|
|
430
|
+
ExecuteSweepResponse,
|
|
431
|
+
ExecuteSweepError,
|
|
432
|
+
ThrowOnError
|
|
433
|
+
>({
|
|
434
|
+
security: [
|
|
435
|
+
{
|
|
436
|
+
scheme: "bearer",
|
|
437
|
+
type: "http",
|
|
438
|
+
},
|
|
439
|
+
],
|
|
440
|
+
url: "/backtest/{exchangeId}/{type}/executeSweep/{requestId}",
|
|
441
|
+
...options,
|
|
442
|
+
headers: {
|
|
443
|
+
"Content-Type": "application/json",
|
|
444
|
+
...options?.headers,
|
|
445
|
+
},
|
|
446
|
+
});
|
|
259
447
|
};
|
|
260
448
|
|
|
261
449
|
/**
|
|
262
450
|
* Cancel a running parameter sweep
|
|
263
451
|
* Requests cancellation between parameter vectors. Completed rows remain readable.
|
|
264
452
|
*/
|
|
265
|
-
export const cancelSweep = <ThrowOnError extends boolean = false>(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
453
|
+
export const cancelSweep = <ThrowOnError extends boolean = false>(
|
|
454
|
+
options: Options<CancelSweepData, ThrowOnError>
|
|
455
|
+
) => {
|
|
456
|
+
return (options.client ?? _heyApiClient).delete<
|
|
457
|
+
CancelSweepResponse,
|
|
458
|
+
CancelSweepError,
|
|
459
|
+
ThrowOnError
|
|
460
|
+
>({
|
|
461
|
+
security: [
|
|
462
|
+
{
|
|
463
|
+
scheme: "bearer",
|
|
464
|
+
type: "http",
|
|
465
|
+
},
|
|
466
|
+
],
|
|
467
|
+
url: "/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}",
|
|
468
|
+
...options,
|
|
469
|
+
});
|
|
276
470
|
};
|
|
277
471
|
|
|
278
472
|
/**
|
|
@@ -281,18 +475,87 @@ export const cancelSweep = <ThrowOnError extends boolean = false>(options: Optio
|
|
|
281
475
|
* display leaderboard. `order=natural` returns every available row, untruncated, ordered by
|
|
282
476
|
* deterministic `runIx`; use that view when materialising durable trial rows.
|
|
283
477
|
*
|
|
478
|
+
* The `ranked` view is ordered by **plateau score** by default, not by the raw objective. A
|
|
479
|
+
* plateau score is the objective of the worst run in a parameter point's immediate
|
|
480
|
+
* neighbourhood, so a point scores well only if the region around it also does — the highest
|
|
481
|
+
* raw score is frequently a spike that does not survive the parameters moving slightly. Pass
|
|
482
|
+
* `ranking=raw` for the unadjusted objective order.
|
|
483
|
+
*
|
|
484
|
+
* Rows in the `ranked` view carry `plateauScore` and `neighbourCount` when plateau ranking
|
|
485
|
+
* applied. Read them together: `neighbourCount: 0` means the point had no neighbours to
|
|
486
|
+
* compare against, so its plateau score is unevidenced rather than confirmed. Sweeps
|
|
487
|
+
* submitted before plateau ranking existed have no stored parameter grid to rebuild a
|
|
488
|
+
* neighbourhood from and are always ranked raw; the response's `ranking` field says which
|
|
489
|
+
* ordering was actually used.
|
|
490
|
+
*
|
|
491
|
+
* A sweep submitted with `walkForward` answers in a different shape, and the `walkForward`
|
|
492
|
+
* field on the response is what tells the two apart — it appears as soon as the sweep is
|
|
493
|
+
* accepted, before any fold has finished, so it is safe to branch on while polling. There
|
|
494
|
+
* the leaderboard is one row per completed fold: that fold's winner as it scored
|
|
495
|
+
* **out-of-sample**, with `runIx` carrying the fold index rather than a grid position. The
|
|
496
|
+
* in-sample runs behind those winners are not retained — they are an optimization's working
|
|
497
|
+
* set, and only the winner survives its fold. `ranking` is always `raw` and no plateau, DSR
|
|
498
|
+
* or PBO figure is reported: the out-of-sample scores are already the honest number, and
|
|
499
|
+
* layering a certification computed over F observations on top of them would overstate what
|
|
500
|
+
* was measured.
|
|
501
|
+
*
|
|
284
502
|
*/
|
|
285
|
-
export const getSweepResult = <ThrowOnError extends boolean = false>(
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
503
|
+
export const getSweepResult = <ThrowOnError extends boolean = false>(
|
|
504
|
+
options: Options<GetSweepResultData, ThrowOnError>
|
|
505
|
+
) => {
|
|
506
|
+
return (options.client ?? _heyApiClient).get<
|
|
507
|
+
GetSweepResultResponse,
|
|
508
|
+
GetSweepResultError,
|
|
509
|
+
ThrowOnError
|
|
510
|
+
>({
|
|
511
|
+
security: [
|
|
512
|
+
{
|
|
513
|
+
scheme: "bearer",
|
|
514
|
+
type: "http",
|
|
515
|
+
},
|
|
516
|
+
],
|
|
517
|
+
url: "/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}",
|
|
518
|
+
...options,
|
|
519
|
+
});
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Get sweep sensitivity surfaces
|
|
524
|
+
* How the objective moves as each parameter moves — the question a leaderboard cannot answer.
|
|
525
|
+
* A leaderboard says which point won; a sweep can spend its entire budget on an axis that
|
|
526
|
+
* never moved the objective at all, and showing only the top rows hides that completely.
|
|
527
|
+
*
|
|
528
|
+
* A **marginal** takes one axis and collapses every other one: for each value of that axis,
|
|
529
|
+
* it aggregates every run that used it, whatever the rest of the parameters were. A flat
|
|
530
|
+
* marginal means the axis is irrelevant over the range swept. `best`, `mean` and `worst` are
|
|
531
|
+
* all reported because them disagreeing is itself the signal — a value with a high `best` and
|
|
532
|
+
* a poor `mean` works only in specific company, which is an interaction between parameters
|
|
533
|
+
* and would be invisible behind a single number.
|
|
534
|
+
*
|
|
535
|
+
* A **heatmap** does the same over a pair of axes, where that interaction becomes visible
|
|
536
|
+
* directly.
|
|
537
|
+
*
|
|
538
|
+
* Served from the sweep's stored rows: no re-run, no engine call, and it works on a sweep
|
|
539
|
+
* still in flight — the aggregates then describe the runs finished so far. Aborted runs are
|
|
540
|
+
* excluded throughout, since a run that threw measured nothing and counting it as a bad
|
|
541
|
+
* outcome would invent evidence against a parameter value that was never really tested.
|
|
542
|
+
*
|
|
543
|
+
* This is a separate endpoint rather than extra fields on the result view because the
|
|
544
|
+
* two-dimensional half is quadratic in the axis count (N axes give N(N-1)/2 surfaces, each
|
|
545
|
+
* the product of two axes' value counts) and is not wanted on the poll that drives progress.
|
|
546
|
+
*
|
|
547
|
+
*/
|
|
548
|
+
export const getSweepSensitivity = <ThrowOnError extends boolean = false>(
|
|
549
|
+
options: Options<GetSweepSensitivityData, ThrowOnError>
|
|
550
|
+
) => {
|
|
551
|
+
return (options.client ?? _heyApiClient).get<
|
|
552
|
+
GetSweepSensitivityResponse,
|
|
553
|
+
GetSweepSensitivityError,
|
|
554
|
+
ThrowOnError
|
|
555
|
+
>({
|
|
556
|
+
url: "/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}/sensitivity",
|
|
557
|
+
...options,
|
|
558
|
+
});
|
|
296
559
|
};
|
|
297
560
|
|
|
298
561
|
/**
|
|
@@ -308,21 +571,27 @@ export const getSweepResult = <ThrowOnError extends boolean = false>(options: Op
|
|
|
308
571
|
* `jobId` (idempotent).
|
|
309
572
|
*
|
|
310
573
|
*/
|
|
311
|
-
export const executeBacktest = <ThrowOnError extends boolean = false>(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
}
|
|
574
|
+
export const executeBacktest = <ThrowOnError extends boolean = false>(
|
|
575
|
+
options: Options<ExecuteBacktestData, ThrowOnError>
|
|
576
|
+
) => {
|
|
577
|
+
return (options.client ?? _heyApiClient).post<
|
|
578
|
+
ExecuteBacktestResponse,
|
|
579
|
+
ExecuteBacktestError,
|
|
580
|
+
ThrowOnError
|
|
581
|
+
>({
|
|
582
|
+
security: [
|
|
583
|
+
{
|
|
584
|
+
scheme: "bearer",
|
|
585
|
+
type: "http",
|
|
586
|
+
},
|
|
587
|
+
],
|
|
588
|
+
url: "/backtest/{exchangeId}/{type}/execute",
|
|
589
|
+
...options,
|
|
590
|
+
headers: {
|
|
591
|
+
"Content-Type": "application/json",
|
|
592
|
+
...options?.headers,
|
|
593
|
+
},
|
|
594
|
+
});
|
|
326
595
|
};
|
|
327
596
|
|
|
328
597
|
/**
|
|
@@ -333,17 +602,23 @@ export const executeBacktest = <ThrowOnError extends boolean = false>(options: O
|
|
|
333
602
|
* to confirm the final status.
|
|
334
603
|
*
|
|
335
604
|
*/
|
|
336
|
-
export const cancelBacktest = <ThrowOnError extends boolean = false>(
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
605
|
+
export const cancelBacktest = <ThrowOnError extends boolean = false>(
|
|
606
|
+
options: Options<CancelBacktestData, ThrowOnError>
|
|
607
|
+
) => {
|
|
608
|
+
return (options.client ?? _heyApiClient).delete<
|
|
609
|
+
CancelBacktestResponse,
|
|
610
|
+
CancelBacktestError,
|
|
611
|
+
ThrowOnError
|
|
612
|
+
>({
|
|
613
|
+
security: [
|
|
614
|
+
{
|
|
615
|
+
scheme: "bearer",
|
|
616
|
+
type: "http",
|
|
617
|
+
},
|
|
618
|
+
],
|
|
619
|
+
url: "/backtest/{exchangeId}/{type}/execute/{jobId}",
|
|
620
|
+
...options,
|
|
621
|
+
});
|
|
347
622
|
};
|
|
348
623
|
|
|
349
624
|
/**
|
|
@@ -356,15 +631,21 @@ export const cancelBacktest = <ThrowOnError extends boolean = false>(options: Op
|
|
|
356
631
|
* not stop on it.
|
|
357
632
|
*
|
|
358
633
|
*/
|
|
359
|
-
export const getBacktestResult = <ThrowOnError extends boolean = false>(
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
634
|
+
export const getBacktestResult = <ThrowOnError extends boolean = false>(
|
|
635
|
+
options: Options<GetBacktestResultData, ThrowOnError>
|
|
636
|
+
) => {
|
|
637
|
+
return (options.client ?? _heyApiClient).get<
|
|
638
|
+
GetBacktestResultResponse,
|
|
639
|
+
GetBacktestResultError,
|
|
640
|
+
ThrowOnError
|
|
641
|
+
>({
|
|
642
|
+
security: [
|
|
643
|
+
{
|
|
644
|
+
scheme: "bearer",
|
|
645
|
+
type: "http",
|
|
646
|
+
},
|
|
647
|
+
],
|
|
648
|
+
url: "/backtest/{exchangeId}/{type}/execute/{jobId}",
|
|
649
|
+
...options,
|
|
650
|
+
});
|
|
651
|
+
};
|