@qtsurfer/api-client 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +667 -21
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/generated/schemas.gen.ts +493 -7
- package/src/generated/sdk.gen.ts +326 -8
- package/src/generated/types.gen.ts +574 -12
package/src/generated/sdk.gen.ts
CHANGED
|
@@ -100,6 +100,29 @@ import type {
|
|
|
100
100
|
GetDatasetImportData,
|
|
101
101
|
GetDatasetImportResponse,
|
|
102
102
|
GetDatasetImportError,
|
|
103
|
+
StopLiveData,
|
|
104
|
+
StopLiveResponse,
|
|
105
|
+
StopLiveError,
|
|
106
|
+
GetLiveData,
|
|
107
|
+
GetLiveResponse,
|
|
108
|
+
GetLiveError,
|
|
109
|
+
StartLiveData,
|
|
110
|
+
StartLiveResponse,
|
|
111
|
+
StartLiveError,
|
|
112
|
+
ListPublicLiveData,
|
|
113
|
+
ListPublicLiveResponse,
|
|
114
|
+
ListPublicLiveError,
|
|
115
|
+
UpdateLiveData,
|
|
116
|
+
UpdateLiveResponse,
|
|
117
|
+
UpdateLiveError,
|
|
118
|
+
UpdateLiveParamsData,
|
|
119
|
+
UpdateLiveParamsResponse,
|
|
120
|
+
UpdateLiveParamsError,
|
|
121
|
+
GetLiveRunSignalsData,
|
|
122
|
+
GetLiveRunSignalsResponse,
|
|
123
|
+
GetLiveRunSignalsError,
|
|
124
|
+
MintLiveConnectionTokenData,
|
|
125
|
+
MintLiveConnectionTokenResponse,
|
|
103
126
|
} from "./types.gen";
|
|
104
127
|
import { client as _heyApiClient } from "./client.gen";
|
|
105
128
|
|
|
@@ -366,22 +389,35 @@ export const listStrategies = <ThrowOnError extends boolean = false>(
|
|
|
366
389
|
* Compile and register a strategy
|
|
367
390
|
* Compiles raw strategy source and registers it, returning its `strategyId`.
|
|
368
391
|
*
|
|
369
|
-
*
|
|
392
|
+
* The source is either **Java** — a class extending a strategy base class — or **QTScript**
|
|
393
|
+
* (beta), a compact strategy language whose braced bodies are plain Java. QTScript source
|
|
394
|
+
* begins with the `strategy` keyword — whitespace and comments (`//` or `* *`) before it
|
|
395
|
+
* are ignored — and that is how the two are told apart: there is no separate endpoint and
|
|
396
|
+
* no header to set. Once registered, a strategy is used the same way
|
|
397
|
+
* whichever language it was written in.
|
|
398
|
+
*
|
|
399
|
+
* **This answers one question: is the source valid.** It compiles, registers, and hands
|
|
370
400
|
* back the id — nothing more. Whether the class can actually run is
|
|
371
401
|
* `POST /strategy/{strategyId}/validate`, and everything known about a strategy, validation
|
|
372
402
|
* included, is read from `GET /strategy/{strategyId}`. One place to ask, so there is no second
|
|
373
403
|
* answer to keep in step.
|
|
374
404
|
*
|
|
375
|
-
*
|
|
376
|
-
* comment, inserting a blank line, re-indenting, reordering imports, or
|
|
377
|
-
* all return the **same** id — you have not created a second strategy.
|
|
378
|
-
* changing an identifier's case, reordering fields, or reordering
|
|
379
|
-
* return a **different** one.
|
|
405
|
+
* For **Java**, the `strategyId` is derived from what the code *means*, not from how it is
|
|
406
|
+
* written. Adding a comment, inserting a blank line, re-indenting, reordering imports, or
|
|
407
|
+
* moving a method around all return the **same** id — you have not created a second strategy.
|
|
408
|
+
* Renaming a variable, changing an identifier's case, reordering fields, or reordering
|
|
409
|
+
* statements inside a method return a **different** one.
|
|
410
|
+
*
|
|
411
|
+
* For **QTScript**, the id is derived from the text, because indentation is part of its
|
|
412
|
+
* grammar. Only differences that cannot change the strategy are ignored: a byte-order mark, the
|
|
413
|
+
* style of line endings, whitespace at the end of a line, and blank lines before the first and
|
|
414
|
+
* after the last line. Anything else — a comment, the indentation, a blank line in between —
|
|
415
|
+
* returns a **different** id.
|
|
380
416
|
*
|
|
381
417
|
* Two rules follow, and they are worth designing around:
|
|
382
418
|
*
|
|
383
|
-
* - re-submitting a strategy you have only reformatted is free, and gives you back the id
|
|
384
|
-
* already had, along with any validation already recorded against it;
|
|
419
|
+
* - re-submitting a Java strategy you have only reformatted is free, and gives you back the id
|
|
420
|
+
* you already had, along with any validation already recorded against it;
|
|
385
421
|
* - the id says nothing about *behaviour*. Two sources that compute the same thing by
|
|
386
422
|
* different means are two strategies, because deciding otherwise would mean deciding program
|
|
387
423
|
* equivalence.
|
|
@@ -547,6 +583,10 @@ export const getStrategyCode = <ThrowOnError extends boolean = false>(
|
|
|
547
583
|
* The same params always return the same `jobId` (idempotent). Repeated calls with identical
|
|
548
584
|
* params do not enqueue duplicate work — they reuse the existing job.
|
|
549
585
|
*
|
|
586
|
+
* Every source in `DataSourceType` can be prepared, but not every one can then be run: `funding`
|
|
587
|
+
* data can be prepared and is rejected by `execute` and `executeSweep`. A `kline` prepare takes
|
|
588
|
+
* the bar width from `cadence` — see `PrepareRequest`.
|
|
589
|
+
*
|
|
550
590
|
* **`exchangeId: user` is reserved for your own uploaded data.** Instead of a managed
|
|
551
591
|
* exchange, it prepares from a dataset you created via `POST /datasets` (see the **Dataset**
|
|
552
592
|
* endpoints) — send `datasetId` in place of `instrument`. See `PrepareRequest` below for the
|
|
@@ -610,6 +650,10 @@ export const getPrepareStatus = <ThrowOnError extends boolean = false>(
|
|
|
610
650
|
* The backend expands and executes the matrix internally; clients poll the returned
|
|
611
651
|
* `sweepId` for incremental results.
|
|
612
652
|
*
|
|
653
|
+
* `type` must be `ticker` or `kline`; a `kline` sweep, walk-forward included, runs over bars of
|
|
654
|
+
* the cadence the request was prepared at. `funding` can be prepared but not swept yet: it is
|
|
655
|
+
* rejected with `400` before anything is queued.
|
|
656
|
+
*
|
|
613
657
|
* Supplying `walkForward` runs the sweep in a different mode entirely. Instead of scoring
|
|
614
658
|
* every parameter vector once over the whole range, the data is split into F sequential
|
|
615
659
|
* folds; each fold optimizes the full grid on its own window and then scores only its winner
|
|
@@ -807,6 +851,11 @@ export const getSweepRunEquityCurve = <ThrowOnError extends boolean = false>(
|
|
|
807
851
|
* Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`
|
|
808
852
|
* for the result.
|
|
809
853
|
*
|
|
854
|
+
* `type` must be a source that can be executed: `ticker` or `kline`. A `kline` strategy is fed
|
|
855
|
+
* bars of the cadence its `prepareJobId` was prepared at — chosen by you when preparing, not by
|
|
856
|
+
* the strategy. `funding` can be prepared but not executed yet: it is rejected with `400`
|
|
857
|
+
* before anything is queued.
|
|
858
|
+
*
|
|
810
859
|
* Optionally takes `params`: strategy properties for this one run, applied without
|
|
811
860
|
* recompiling. This is how a sweep leaderboard winner gets re-run for its `equityCurve` —
|
|
812
861
|
* a sweep row carries the ten ranking metrics but never a curve, whatever its size. Compile
|
|
@@ -1209,3 +1258,272 @@ export const getDatasetImport = <ThrowOnError extends boolean = false>(
|
|
|
1209
1258
|
...options,
|
|
1210
1259
|
});
|
|
1211
1260
|
};
|
|
1261
|
+
|
|
1262
|
+
/**
|
|
1263
|
+
* Stop this strategy's live run
|
|
1264
|
+
* Requests a stop. The run winds down at its own next check-in rather than instantly —
|
|
1265
|
+
* poll `GET`/`PATCH` `.../live` and expect `state` to remain `RUNNING` for a short window
|
|
1266
|
+
* after `desired` flips to `STOPPED`. Calling this again on an already-stopped run is not an
|
|
1267
|
+
* error; it returns the same (unchanged) state.
|
|
1268
|
+
*
|
|
1269
|
+
*/
|
|
1270
|
+
export const stopLive = <ThrowOnError extends boolean = false>(
|
|
1271
|
+
options: Options<StopLiveData, ThrowOnError>
|
|
1272
|
+
) => {
|
|
1273
|
+
return (options.client ?? _heyApiClient).delete<
|
|
1274
|
+
StopLiveResponse,
|
|
1275
|
+
StopLiveError,
|
|
1276
|
+
ThrowOnError
|
|
1277
|
+
>({
|
|
1278
|
+
security: [
|
|
1279
|
+
{
|
|
1280
|
+
scheme: "bearer",
|
|
1281
|
+
type: "http",
|
|
1282
|
+
},
|
|
1283
|
+
],
|
|
1284
|
+
url: "/strategy/{strategyId}/live",
|
|
1285
|
+
...options,
|
|
1286
|
+
});
|
|
1287
|
+
};
|
|
1288
|
+
|
|
1289
|
+
/**
|
|
1290
|
+
* Get this strategy's current (or most recent) live run
|
|
1291
|
+
* The run you last started for this strategy — its most complete state, including `params`
|
|
1292
|
+
* and the promotion `gate` once the sandbox trial has one to report. Returns the run's last
|
|
1293
|
+
* known state even after it has stopped; this endpoint never disappears history.
|
|
1294
|
+
*
|
|
1295
|
+
*/
|
|
1296
|
+
export const getLive = <ThrowOnError extends boolean = false>(
|
|
1297
|
+
options: Options<GetLiveData, ThrowOnError>
|
|
1298
|
+
) => {
|
|
1299
|
+
return (options.client ?? _heyApiClient).get<
|
|
1300
|
+
GetLiveResponse,
|
|
1301
|
+
GetLiveError,
|
|
1302
|
+
ThrowOnError
|
|
1303
|
+
>({
|
|
1304
|
+
security: [
|
|
1305
|
+
{
|
|
1306
|
+
scheme: "bearer",
|
|
1307
|
+
type: "http",
|
|
1308
|
+
},
|
|
1309
|
+
],
|
|
1310
|
+
url: "/strategy/{strategyId}/live",
|
|
1311
|
+
...options,
|
|
1312
|
+
});
|
|
1313
|
+
};
|
|
1314
|
+
|
|
1315
|
+
/**
|
|
1316
|
+
* Start a strategy on a live market feed
|
|
1317
|
+
* Starts your strategy against a live market feed. A new run always begins in the **sandbox**
|
|
1318
|
+
* stage — a short trial that compares an independent second execution against the first for
|
|
1319
|
+
* agreement — before it is eligible for promotion to the live stage where it actually
|
|
1320
|
+
* publishes signals other systems can act on. Poll `GET /strategy/{strategyId}/live` (or
|
|
1321
|
+
* `PATCH`/`DELETE` `/live/{runId}` once you have the `runId`) to watch `stage` move from
|
|
1322
|
+
* `SANDBOX` to `LIVE`.
|
|
1323
|
+
*
|
|
1324
|
+
* Only one run per strategy at a time — starting again while one is already running is `409`;
|
|
1325
|
+
* stop the current one first.
|
|
1326
|
+
*
|
|
1327
|
+
* `sources` takes exactly one entry today (multi-source strategies are not supported yet).
|
|
1328
|
+
* `type` is `ticker` or `kline`; anything else is rejected. Both connect to the lightest
|
|
1329
|
+
* (fastest) cadence available for the exchange — today that is 1 tick/second on every
|
|
1330
|
+
* supported exchange; choosing among several cadences is not offered yet.
|
|
1331
|
+
*
|
|
1332
|
+
* `params` is passed straight through to the strategy at start — the same free-form object
|
|
1333
|
+
* `POST /strategy/{strategyId}/validate` and the backtest endpoints already accept. To change
|
|
1334
|
+
* a parameter **while the run is live**, use `PUT /live/{runId}/params` instead; this endpoint
|
|
1335
|
+
* only sets the values a run starts with.
|
|
1336
|
+
*
|
|
1337
|
+
* Consuming a run's own output — its signals, and updating its parameters over a live
|
|
1338
|
+
* connection instead of polling — is a WebSocket protocol on top of these REST endpoints; see
|
|
1339
|
+
* the "Live execution" guide linked from this tag's description for the full flow (minting a
|
|
1340
|
+
* connection token, the channel and RPC method).
|
|
1341
|
+
*
|
|
1342
|
+
*/
|
|
1343
|
+
export const startLive = <ThrowOnError extends boolean = false>(
|
|
1344
|
+
options: Options<StartLiveData, ThrowOnError>
|
|
1345
|
+
) => {
|
|
1346
|
+
return (options.client ?? _heyApiClient).post<
|
|
1347
|
+
StartLiveResponse,
|
|
1348
|
+
StartLiveError,
|
|
1349
|
+
ThrowOnError
|
|
1350
|
+
>({
|
|
1351
|
+
security: [
|
|
1352
|
+
{
|
|
1353
|
+
scheme: "bearer",
|
|
1354
|
+
type: "http",
|
|
1355
|
+
},
|
|
1356
|
+
],
|
|
1357
|
+
url: "/strategy/{strategyId}/live",
|
|
1358
|
+
...options,
|
|
1359
|
+
headers: {
|
|
1360
|
+
"Content-Type": "application/json",
|
|
1361
|
+
...options?.headers,
|
|
1362
|
+
},
|
|
1363
|
+
});
|
|
1364
|
+
};
|
|
1365
|
+
|
|
1366
|
+
/**
|
|
1367
|
+
* Browse public live runs
|
|
1368
|
+
* Every run whose owner marked it `public` and is currently live and running — anyone's,
|
|
1369
|
+
* yours included, and listed without revealing who owns it. Most recently started first.
|
|
1370
|
+
*
|
|
1371
|
+
* This is the only `Live Execution` endpoint that needs no `Authorization` header.
|
|
1372
|
+
*
|
|
1373
|
+
*/
|
|
1374
|
+
export const listPublicLive = <ThrowOnError extends boolean = false>(
|
|
1375
|
+
options?: Options<ListPublicLiveData, ThrowOnError>
|
|
1376
|
+
) => {
|
|
1377
|
+
return (options?.client ?? _heyApiClient).get<
|
|
1378
|
+
ListPublicLiveResponse,
|
|
1379
|
+
ListPublicLiveError,
|
|
1380
|
+
ThrowOnError
|
|
1381
|
+
>({
|
|
1382
|
+
url: "/live/public",
|
|
1383
|
+
...options,
|
|
1384
|
+
});
|
|
1385
|
+
};
|
|
1386
|
+
|
|
1387
|
+
/**
|
|
1388
|
+
* Change a run's visibility, name, or description
|
|
1389
|
+
* Owner only, addressed by `runId` directly rather than through its strategy — this is a
|
|
1390
|
+
* run's own canonical identity, independent of which strategy started it.
|
|
1391
|
+
*
|
|
1392
|
+
* Setting `visibility` from `public` back to `private` also evicts anyone currently connected
|
|
1393
|
+
* to the run's live signal channel who is not its owner — best-effort; the change to this
|
|
1394
|
+
* record is not rolled back if that eviction fails.
|
|
1395
|
+
*
|
|
1396
|
+
*/
|
|
1397
|
+
export const updateLive = <ThrowOnError extends boolean = false>(
|
|
1398
|
+
options: Options<UpdateLiveData, ThrowOnError>
|
|
1399
|
+
) => {
|
|
1400
|
+
return (options.client ?? _heyApiClient).patch<
|
|
1401
|
+
UpdateLiveResponse,
|
|
1402
|
+
UpdateLiveError,
|
|
1403
|
+
ThrowOnError
|
|
1404
|
+
>({
|
|
1405
|
+
security: [
|
|
1406
|
+
{
|
|
1407
|
+
scheme: "bearer",
|
|
1408
|
+
type: "http",
|
|
1409
|
+
},
|
|
1410
|
+
],
|
|
1411
|
+
url: "/live/{runId}",
|
|
1412
|
+
...options,
|
|
1413
|
+
headers: {
|
|
1414
|
+
"Content-Type": "application/json",
|
|
1415
|
+
...options?.headers,
|
|
1416
|
+
},
|
|
1417
|
+
});
|
|
1418
|
+
};
|
|
1419
|
+
|
|
1420
|
+
/**
|
|
1421
|
+
* Change a running strategy's parameters
|
|
1422
|
+
* Updates one or more parameters of a run **while it stays live** — unlike `params` on
|
|
1423
|
+
* `POST /strategy/{strategyId}/live`, which only sets the starting values. Owner only.
|
|
1424
|
+
*
|
|
1425
|
+
* Every key in `params` must be one your strategy declares (see `declaredProperties` on
|
|
1426
|
+
* `POST /strategy`) as of the compilation this run is executing — recompiling the strategy
|
|
1427
|
+
* later never changes what an already-running instance accepts; start a new run for that.
|
|
1428
|
+
*
|
|
1429
|
+
* The change does not take effect the instant this call returns: `effectiveAtMs` is the
|
|
1430
|
+
* earliest moment it is guaranteed to apply, a few seconds out, so both the REST and
|
|
1431
|
+
* WebSocket paths to this same update (see the "Live execution" guide) land on the exact same
|
|
1432
|
+
* value at the exact same moment.
|
|
1433
|
+
*
|
|
1434
|
+
*/
|
|
1435
|
+
export const updateLiveParams = <ThrowOnError extends boolean = false>(
|
|
1436
|
+
options: Options<UpdateLiveParamsData, ThrowOnError>
|
|
1437
|
+
) => {
|
|
1438
|
+
return (options.client ?? _heyApiClient).put<
|
|
1439
|
+
UpdateLiveParamsResponse,
|
|
1440
|
+
UpdateLiveParamsError,
|
|
1441
|
+
ThrowOnError
|
|
1442
|
+
>({
|
|
1443
|
+
security: [
|
|
1444
|
+
{
|
|
1445
|
+
scheme: "bearer",
|
|
1446
|
+
type: "http",
|
|
1447
|
+
},
|
|
1448
|
+
],
|
|
1449
|
+
url: "/live/{runId}/params",
|
|
1450
|
+
...options,
|
|
1451
|
+
headers: {
|
|
1452
|
+
"Content-Type": "application/json",
|
|
1453
|
+
...options?.headers,
|
|
1454
|
+
},
|
|
1455
|
+
});
|
|
1456
|
+
};
|
|
1457
|
+
|
|
1458
|
+
/**
|
|
1459
|
+
* Read a run's signals
|
|
1460
|
+
* Returns one page of the signals a run has already produced, newest-last, optionally from a
|
|
1461
|
+
* given time and narrowed to one or more instruments.
|
|
1462
|
+
*
|
|
1463
|
+
* This is the counterpart to the real-time WebSocket channel: that channel only carries what
|
|
1464
|
+
* happens while you are connected, and only for a run that asked for `relay`. A run's signals
|
|
1465
|
+
* are recorded either way, so this endpoint serves them whether or not `relay` was ever on,
|
|
1466
|
+
* in both the `sandbox` and `live` stages — use it to catch up after a disconnect, to read a
|
|
1467
|
+
* run you never relayed, or to page back over what has already happened.
|
|
1468
|
+
*
|
|
1469
|
+
* **The available window moves.** Signals are kept for a limited span, and the oldest are
|
|
1470
|
+
* continuously discarded as new ones arrive, so how far back you can read is not a fixed
|
|
1471
|
+
* number of hours: on a busy run it can be a good deal shorter. Every response carries
|
|
1472
|
+
* `availableSinceMs`, the oldest moment that can still be answered for. Asking for a
|
|
1473
|
+
* `sinceMs` older than that is not an error — you get everything from `availableSinceMs`
|
|
1474
|
+
* onwards, and that field tells you it happened.
|
|
1475
|
+
*
|
|
1476
|
+
* **A cursor can expire, and on a busy run it expires quickly.** If the position a cursor
|
|
1477
|
+
* points at has since been discarded, the next page answers `410` rather than silently
|
|
1478
|
+
* serving a shortened page that looks complete. Treat that as a normal outcome: read
|
|
1479
|
+
* `availableSinceMs` from the error and start again from there.
|
|
1480
|
+
*
|
|
1481
|
+
* Readable by the run's owner, and by anyone if the run is `public` — the same rule the
|
|
1482
|
+
* signal channel applies to a subscription.
|
|
1483
|
+
*
|
|
1484
|
+
*/
|
|
1485
|
+
export const getLiveRunSignals = <ThrowOnError extends boolean = false>(
|
|
1486
|
+
options: Options<GetLiveRunSignalsData, ThrowOnError>
|
|
1487
|
+
) => {
|
|
1488
|
+
return (options.client ?? _heyApiClient).get<
|
|
1489
|
+
GetLiveRunSignalsResponse,
|
|
1490
|
+
GetLiveRunSignalsError,
|
|
1491
|
+
ThrowOnError
|
|
1492
|
+
>({
|
|
1493
|
+
security: [
|
|
1494
|
+
{
|
|
1495
|
+
scheme: "bearer",
|
|
1496
|
+
type: "http",
|
|
1497
|
+
},
|
|
1498
|
+
],
|
|
1499
|
+
url: "/live/{runId}/signals",
|
|
1500
|
+
...options,
|
|
1501
|
+
});
|
|
1502
|
+
};
|
|
1503
|
+
|
|
1504
|
+
/**
|
|
1505
|
+
* Mint a WebSocket connection token
|
|
1506
|
+
* Mints a short-lived token for the WebSocket connection used to receive a run's signals in
|
|
1507
|
+
* real time and to call `live.params` (the WebSocket form of `PUT /live/{runId}/params`) —
|
|
1508
|
+
* see the "Live execution" guide linked from this tag's description for the full protocol.
|
|
1509
|
+
* Carries no request body.
|
|
1510
|
+
*
|
|
1511
|
+
*/
|
|
1512
|
+
export const mintLiveConnectionToken = <ThrowOnError extends boolean = false>(
|
|
1513
|
+
options?: Options<MintLiveConnectionTokenData, ThrowOnError>
|
|
1514
|
+
) => {
|
|
1515
|
+
return (options?.client ?? _heyApiClient).post<
|
|
1516
|
+
MintLiveConnectionTokenResponse,
|
|
1517
|
+
unknown,
|
|
1518
|
+
ThrowOnError
|
|
1519
|
+
>({
|
|
1520
|
+
security: [
|
|
1521
|
+
{
|
|
1522
|
+
scheme: "bearer",
|
|
1523
|
+
type: "http",
|
|
1524
|
+
},
|
|
1525
|
+
],
|
|
1526
|
+
url: "/live/token",
|
|
1527
|
+
...options,
|
|
1528
|
+
});
|
|
1529
|
+
};
|