@qtsurfer/api-client 0.11.0 → 0.13.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 +10 -2
- package/dist/index.d.ts +323 -26
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/generated/schemas.gen.ts +345 -46
- package/src/generated/sdk.gen.ts +90 -6
- package/src/generated/types.gen.ts +295 -19
|
@@ -705,9 +705,76 @@ export const ExecuteSweepRequestSchema = {
|
|
|
705
705
|
walkForward: {
|
|
706
706
|
$ref: "#/components/schemas/WalkForwardRequest",
|
|
707
707
|
},
|
|
708
|
+
equityCurve: {
|
|
709
|
+
$ref: "#/components/schemas/EquityCurveRequest",
|
|
710
|
+
},
|
|
708
711
|
},
|
|
709
712
|
} as const;
|
|
710
713
|
|
|
714
|
+
export const EquityCurveOptionsSchema = {
|
|
715
|
+
type: "object",
|
|
716
|
+
description:
|
|
717
|
+
"Requested equity-curve transform, applied server-side in a fixed pipeline order: `resample` (point count) then `differential` (encoding) then `outMode` (JSON shape) — each stage assumes the previous one already ran. A server-side size guard can still force a smaller/deflated shape above its thresholds regardless of what is requested here — see `EquityCurveMeta` for what actually happened.",
|
|
718
|
+
properties: {
|
|
719
|
+
resample: {
|
|
720
|
+
type: "integer",
|
|
721
|
+
minimum: 2,
|
|
722
|
+
description:
|
|
723
|
+
"Downsample to at most this many points (extrema-preserving — the global max/min and the exact first/last point are always kept). Omit for no downsampling.",
|
|
724
|
+
},
|
|
725
|
+
differential: {
|
|
726
|
+
type: "boolean",
|
|
727
|
+
default: false,
|
|
728
|
+
description:
|
|
729
|
+
"Delta-encode both fields from the second (post-resample) point onward.",
|
|
730
|
+
},
|
|
731
|
+
outMode: {
|
|
732
|
+
allOf: [
|
|
733
|
+
{
|
|
734
|
+
$ref: "#/components/schemas/EquityCurveOutMode",
|
|
735
|
+
},
|
|
736
|
+
],
|
|
737
|
+
default: "ARRAY",
|
|
738
|
+
description: "Requested JSON shape.",
|
|
739
|
+
},
|
|
740
|
+
},
|
|
741
|
+
} as const;
|
|
742
|
+
|
|
743
|
+
export const EquityCurveRequestSchema = {
|
|
744
|
+
allOf: [
|
|
745
|
+
{
|
|
746
|
+
$ref: "#/components/schemas/EquityCurveOptions",
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
type: "object",
|
|
750
|
+
properties: {
|
|
751
|
+
mode: {
|
|
752
|
+
type: "string",
|
|
753
|
+
enum: ["auto", "topN", "topPct", "none"],
|
|
754
|
+
default: "auto",
|
|
755
|
+
description:
|
|
756
|
+
"Which trials keep their per-point equity curve. `auto` retains curves only while the accumulated size stays within server limits; `topN`/`topPct` retain curves for the best-ranked trials explicitly; `none` retains no curves.",
|
|
757
|
+
},
|
|
758
|
+
n: {
|
|
759
|
+
type: "integer",
|
|
760
|
+
minimum: 1,
|
|
761
|
+
description: "Trial count to retain when mode is topN.",
|
|
762
|
+
},
|
|
763
|
+
maxPct: {
|
|
764
|
+
type: "number",
|
|
765
|
+
format: "double",
|
|
766
|
+
exclusiveMinimum: 0,
|
|
767
|
+
maximum: 100,
|
|
768
|
+
description:
|
|
769
|
+
"Top percentage of trials to retain when mode is topPct.",
|
|
770
|
+
},
|
|
771
|
+
},
|
|
772
|
+
},
|
|
773
|
+
],
|
|
774
|
+
description:
|
|
775
|
+
"Selection (`mode`/`n`/`maxPct`) plus the transform preference (`resample`/`differential`/`outMode`) applied by `GET .../equityCurve` whenever ITS OWN query params are absent, for a curve this sweep retained. The transform half never affects retention or `sweepId` — a caller can always override it per-request at read time regardless of what was submitted here.",
|
|
776
|
+
} as const;
|
|
777
|
+
|
|
711
778
|
export const WalkForwardRequestSchema = {
|
|
712
779
|
type: "object",
|
|
713
780
|
description:
|
|
@@ -949,6 +1016,15 @@ export const SweepRunRowSchema = {
|
|
|
949
1016
|
type: "integer",
|
|
950
1017
|
format: "int64",
|
|
951
1018
|
},
|
|
1019
|
+
equityCurve: {
|
|
1020
|
+
allOf: [
|
|
1021
|
+
{
|
|
1022
|
+
$ref: "#/components/schemas/EquityCurveResult",
|
|
1023
|
+
},
|
|
1024
|
+
],
|
|
1025
|
+
description:
|
|
1026
|
+
"Present only when this trial's curve was selected (`equityCurve.mode` was `topN`/`topPct` on the request, and this row ranked among the winners) — absent, not null, otherwise; a run that was never spilled and one that was spilled but not selected look identical here. Always a pointer today (`url` present, no inline points): a sweep's curves live in a spill store, not the response, until fetched separately. `GET` the `url` to fetch the curve itself; its own `meta` there is the real, possibly size-guarded outcome, while this outer `meta` is a raw, untransformed preview from selection time and can differ.",
|
|
1027
|
+
},
|
|
952
1028
|
},
|
|
953
1029
|
} as const;
|
|
954
1030
|
|
|
@@ -1086,6 +1162,7 @@ export const ExecuteSweepResultSchema = {
|
|
|
1086
1162
|
"leaderboardSize",
|
|
1087
1163
|
"truncated",
|
|
1088
1164
|
"leaderboard",
|
|
1165
|
+
"state",
|
|
1089
1166
|
],
|
|
1090
1167
|
properties: {
|
|
1091
1168
|
sweepId: {
|
|
@@ -1094,6 +1171,8 @@ export const ExecuteSweepResultSchema = {
|
|
|
1094
1171
|
status: {
|
|
1095
1172
|
type: "string",
|
|
1096
1173
|
enum: ["RUNNING", "COMPLETED", "PARTIAL", "CANCELLED"],
|
|
1174
|
+
description:
|
|
1175
|
+
"The sweep's own status vocabulary — not the same set `state.status` below uses. See `state` for why.",
|
|
1097
1176
|
},
|
|
1098
1177
|
objective: {
|
|
1099
1178
|
type: "string",
|
|
@@ -1148,6 +1227,17 @@ First failure wins and later ones are not recorded, so on a sweep where several
|
|
|
1148
1227
|
walkForward: {
|
|
1149
1228
|
$ref: "#/components/schemas/WalkForwardResult",
|
|
1150
1229
|
},
|
|
1230
|
+
state: {
|
|
1231
|
+
allOf: [
|
|
1232
|
+
{
|
|
1233
|
+
$ref: "#/components/schemas/JobState",
|
|
1234
|
+
},
|
|
1235
|
+
],
|
|
1236
|
+
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
|
+
\`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
|
+
\`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 always \`0\` on every path (single execute, plain sweep, walk-forward alike) — nothing populates it anywhere yet. That is a known gap across the whole API, not a sweep-specific omission.`,
|
|
1240
|
+
},
|
|
1151
1241
|
},
|
|
1152
1242
|
} as const;
|
|
1153
1243
|
|
|
@@ -1389,26 +1479,36 @@ reading: a run that produced no trades often did so for a reason stated here.
|
|
|
1389
1479
|
example: 8.75,
|
|
1390
1480
|
},
|
|
1391
1481
|
equityCurve: {
|
|
1392
|
-
|
|
1393
|
-
description:
|
|
1394
|
-
"Equity curve over the backtest. Element 0 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.",
|
|
1395
|
-
items: {
|
|
1396
|
-
$ref: "#/components/schemas/EquityPoint",
|
|
1397
|
-
},
|
|
1398
|
-
example: [
|
|
1399
|
-
{
|
|
1400
|
-
timestamp: 1700000000000,
|
|
1401
|
-
equity: 100,
|
|
1402
|
-
},
|
|
1403
|
-
{
|
|
1404
|
-
timestamp: 1700000060000,
|
|
1405
|
-
equity: 110.5,
|
|
1406
|
-
},
|
|
1482
|
+
allOf: [
|
|
1407
1483
|
{
|
|
1408
|
-
|
|
1409
|
-
equity: 90.25,
|
|
1484
|
+
$ref: "#/components/schemas/EquityCurveResult",
|
|
1410
1485
|
},
|
|
1411
1486
|
],
|
|
1487
|
+
description:
|
|
1488
|
+
"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.",
|
|
1489
|
+
example: {
|
|
1490
|
+
points: [
|
|
1491
|
+
{
|
|
1492
|
+
timestamp: 1700000000000,
|
|
1493
|
+
equity: 100,
|
|
1494
|
+
},
|
|
1495
|
+
{
|
|
1496
|
+
timestamp: 1700000060000,
|
|
1497
|
+
equity: 110.5,
|
|
1498
|
+
},
|
|
1499
|
+
{
|
|
1500
|
+
timestamp: 1700000120000,
|
|
1501
|
+
equity: 90.25,
|
|
1502
|
+
},
|
|
1503
|
+
],
|
|
1504
|
+
meta: {
|
|
1505
|
+
inputPointCount: 3,
|
|
1506
|
+
outputPointCount: 3,
|
|
1507
|
+
resampled: false,
|
|
1508
|
+
differential: false,
|
|
1509
|
+
outMode: "ARRAY",
|
|
1510
|
+
},
|
|
1511
|
+
},
|
|
1412
1512
|
},
|
|
1413
1513
|
signalCount: {
|
|
1414
1514
|
type: "integer",
|
|
@@ -1475,6 +1575,104 @@ export const EquityPointSchema = {
|
|
|
1475
1575
|
},
|
|
1476
1576
|
} as const;
|
|
1477
1577
|
|
|
1578
|
+
export const EquityCurveOutModeSchema = {
|
|
1579
|
+
type: "string",
|
|
1580
|
+
enum: ["ARRAY", "SHORT"],
|
|
1581
|
+
description:
|
|
1582
|
+
"JSON shape for an equity curve's points. `ARRAY` is `[{timestamp, equity}, ...]`; `SHORT` is `{timestamps: [...], equities: [...]}` (parallel arrays, no repeated key text). The one schema shared by every place `outMode` appears, request or response, so the two cannot drift to different value sets.",
|
|
1583
|
+
} as const;
|
|
1584
|
+
|
|
1585
|
+
export const EquityCurveMetaSchema = {
|
|
1586
|
+
type: "object",
|
|
1587
|
+
description:
|
|
1588
|
+
"What the transform pipeline actually did, computed from the observed outcome — never a copy of what was requested. Lets a caller detect a forced or no-op transform (e.g. a `resample` ceiling already above the curve's size is a legal no-op, reported honestly as `resampled: false`).",
|
|
1589
|
+
required: [
|
|
1590
|
+
"inputPointCount",
|
|
1591
|
+
"outputPointCount",
|
|
1592
|
+
"resampled",
|
|
1593
|
+
"differential",
|
|
1594
|
+
"outMode",
|
|
1595
|
+
],
|
|
1596
|
+
properties: {
|
|
1597
|
+
inputPointCount: {
|
|
1598
|
+
type: "integer",
|
|
1599
|
+
description: "Size of the curve the transform pipeline received.",
|
|
1600
|
+
example: 100000,
|
|
1601
|
+
},
|
|
1602
|
+
outputPointCount: {
|
|
1603
|
+
type: "integer",
|
|
1604
|
+
description:
|
|
1605
|
+
"Size after the full pipeline (resample, then differential, then outMode).",
|
|
1606
|
+
example: 100,
|
|
1607
|
+
},
|
|
1608
|
+
resampled: {
|
|
1609
|
+
type: "boolean",
|
|
1610
|
+
description:
|
|
1611
|
+
"True only if the resample stage actually changed the point count.",
|
|
1612
|
+
},
|
|
1613
|
+
differential: {
|
|
1614
|
+
type: "boolean",
|
|
1615
|
+
description:
|
|
1616
|
+
"True only if delta-encoding actually ran. Requesting it on a curve of 0 or 1 points has nothing to encode, so it does not run even if asked.",
|
|
1617
|
+
},
|
|
1618
|
+
outMode: {
|
|
1619
|
+
allOf: [
|
|
1620
|
+
{
|
|
1621
|
+
$ref: "#/components/schemas/EquityCurveOutMode",
|
|
1622
|
+
},
|
|
1623
|
+
],
|
|
1624
|
+
description:
|
|
1625
|
+
"The actual JSON shape served. Present even when the points themselves are not (a pointer curve, `EquityCurveResult.url`) — a caller resolving that URL separately still needs to know how to parse what it gets back before fetching it. May override an explicit request above a server-side size threshold; this field, not the request, is the source of truth for what shape actually came back.",
|
|
1626
|
+
example: "ARRAY",
|
|
1627
|
+
},
|
|
1628
|
+
},
|
|
1629
|
+
} as const;
|
|
1630
|
+
|
|
1631
|
+
export const EquityCurveResultSchema = {
|
|
1632
|
+
type: "object",
|
|
1633
|
+
description:
|
|
1634
|
+
"An equity curve, shaped per `meta.outMode`: `points` when `ARRAY`, `timestamps` + `equities` (parallel arrays) when `SHORT`. Used identically wherever a curve is returned — a plain backtest's inline `equityCurve` and a sweep row's `equityCurve` are the same type. `url` is present *instead of* any points when the curve is served by pointer rather than inline (a sweep row's top-N winners only): `GET` it separately to fetch this exact same shape with the points populated.",
|
|
1635
|
+
required: ["meta"],
|
|
1636
|
+
properties: {
|
|
1637
|
+
meta: {
|
|
1638
|
+
$ref: "#/components/schemas/EquityCurveMeta",
|
|
1639
|
+
},
|
|
1640
|
+
points: {
|
|
1641
|
+
type: "array",
|
|
1642
|
+
description:
|
|
1643
|
+
"Present when `meta.outMode` is `ARRAY` and the curve is inline (not a pointer).",
|
|
1644
|
+
items: {
|
|
1645
|
+
$ref: "#/components/schemas/EquityPoint",
|
|
1646
|
+
},
|
|
1647
|
+
},
|
|
1648
|
+
timestamps: {
|
|
1649
|
+
type: "array",
|
|
1650
|
+
description:
|
|
1651
|
+
"Present when `meta.outMode` is `SHORT` and the curve is inline (not a pointer).",
|
|
1652
|
+
items: {
|
|
1653
|
+
type: "integer",
|
|
1654
|
+
format: "int64",
|
|
1655
|
+
},
|
|
1656
|
+
},
|
|
1657
|
+
equities: {
|
|
1658
|
+
type: "array",
|
|
1659
|
+
description:
|
|
1660
|
+
"Present when `meta.outMode` is `SHORT` and the curve is inline (not a pointer), parallel to `timestamps` (same index, same point).",
|
|
1661
|
+
items: {
|
|
1662
|
+
type: "number",
|
|
1663
|
+
format: "double",
|
|
1664
|
+
},
|
|
1665
|
+
},
|
|
1666
|
+
url: {
|
|
1667
|
+
type: "string",
|
|
1668
|
+
description:
|
|
1669
|
+
"Present only for a sweep row's pointer curve. `GET` this to fetch the curve itself, in this exact `{points|timestamps+equities, meta}` shape — `meta` there is the real, possibly size-guarded outcome; this outer `meta` is a raw, untransformed preview from the moment the sweep selected this trial's curve, and the two can legitimately differ.",
|
|
1670
|
+
example:
|
|
1671
|
+
"/v1/backtest/binance/ticker/executeSweep/req-1/swp_test/runs/3/equityCurve",
|
|
1672
|
+
},
|
|
1673
|
+
},
|
|
1674
|
+
} as const;
|
|
1675
|
+
|
|
1478
1676
|
export const strategyIdSchema = {
|
|
1479
1677
|
description: `Unique identifier for a compiled strategy, derived from the source itself: the same code
|
|
1480
1678
|
always yields the same id, for every caller, whatever its formatting. See
|
|
@@ -1484,6 +1682,68 @@ always yields the same id, for every caller, whatever its formatting. See
|
|
|
1484
1682
|
example: "6bsh31ikwkuivhtgcoa6s4",
|
|
1485
1683
|
} as const;
|
|
1486
1684
|
|
|
1685
|
+
export const DeclaredPropertySchema = {
|
|
1686
|
+
type: "object",
|
|
1687
|
+
description: `One property name \`POST /strategy\` could establish without constructing the strategy —
|
|
1688
|
+
either declared with \`@StrategyProperty\` on the compiled source, or one of the small set of
|
|
1689
|
+
base properties every strategy carries (\`amnt\`, \`enabled\`, \`multiEntry\`, ...).
|
|
1690
|
+
|
|
1691
|
+
**Best-effort, not exhaustive.** A property registered through an attached risk/backtest
|
|
1692
|
+
config needs a live instance to discover and is not listed here. Use this to catch a typo'd
|
|
1693
|
+
sweep key before submitting, not as the definitive list of what a sweep will accept — a
|
|
1694
|
+
name absent from this list may still be valid.
|
|
1695
|
+
`,
|
|
1696
|
+
required: ["name"],
|
|
1697
|
+
properties: {
|
|
1698
|
+
name: {
|
|
1699
|
+
type: "string",
|
|
1700
|
+
description:
|
|
1701
|
+
"The key a sweep or execute param map uses for this property.",
|
|
1702
|
+
example: "rsi.period",
|
|
1703
|
+
},
|
|
1704
|
+
description: {
|
|
1705
|
+
type: "string",
|
|
1706
|
+
description: "Human-readable label, as declared.",
|
|
1707
|
+
example: "RSI period",
|
|
1708
|
+
},
|
|
1709
|
+
defaultValue: {
|
|
1710
|
+
type: "string",
|
|
1711
|
+
description: `The declared default, as a string, if one was given. Absent, not null, when none was
|
|
1712
|
+
declared.
|
|
1713
|
+
`,
|
|
1714
|
+
example: "14",
|
|
1715
|
+
},
|
|
1716
|
+
reflected: {
|
|
1717
|
+
type: "boolean",
|
|
1718
|
+
description: `Whether a value for this key is injected into the strategy's field (\`true\`) or only
|
|
1719
|
+
available through the property map (\`false\`).
|
|
1720
|
+
`,
|
|
1721
|
+
example: true,
|
|
1722
|
+
},
|
|
1723
|
+
min: {
|
|
1724
|
+
type: "number",
|
|
1725
|
+
format: "double",
|
|
1726
|
+
description:
|
|
1727
|
+
"Suggested sweep/range minimum, if declared. Advisory only, never validated.",
|
|
1728
|
+
example: 2,
|
|
1729
|
+
},
|
|
1730
|
+
max: {
|
|
1731
|
+
type: "number",
|
|
1732
|
+
format: "double",
|
|
1733
|
+
description:
|
|
1734
|
+
"Suggested sweep/range maximum, if declared. Advisory only, never validated.",
|
|
1735
|
+
example: 50,
|
|
1736
|
+
},
|
|
1737
|
+
step: {
|
|
1738
|
+
type: "number",
|
|
1739
|
+
format: "double",
|
|
1740
|
+
description:
|
|
1741
|
+
"Suggested sweep/range step, if declared. Advisory only, never validated.",
|
|
1742
|
+
example: 1,
|
|
1743
|
+
},
|
|
1744
|
+
},
|
|
1745
|
+
} as const;
|
|
1746
|
+
|
|
1487
1747
|
export const NoticeSchema = {
|
|
1488
1748
|
type: "object",
|
|
1489
1749
|
description: `A diagnostic the engine raised while the strategy ran. Advisory: it describes something worth
|
|
@@ -1767,52 +2027,91 @@ export const DatasetWithLinksSchema = {
|
|
|
1767
2027
|
],
|
|
1768
2028
|
} as const;
|
|
1769
2029
|
|
|
2030
|
+
export const DatasetUploadTargetSchema = {
|
|
2031
|
+
description:
|
|
2032
|
+
"A presigned destination for uploading a raw dataset file directly to storage.",
|
|
2033
|
+
type: "object",
|
|
2034
|
+
required: ["url", "expiresInMinutes"],
|
|
2035
|
+
properties: {
|
|
2036
|
+
url: {
|
|
2037
|
+
type: "string",
|
|
2038
|
+
description: `Presigned URL. \`PUT\` the raw CSV file here directly — no \`Authorization\` header,
|
|
2039
|
+
no other API credentials.
|
|
2040
|
+
`,
|
|
2041
|
+
example:
|
|
2042
|
+
"https://storage.qtsurfer.com/uploads/00000000-.../up_1a2b3c4d5e6f7a8b/raw.csv?X-Amz-...",
|
|
2043
|
+
},
|
|
2044
|
+
expiresInMinutes: {
|
|
2045
|
+
type: "integer",
|
|
2046
|
+
description: "How long `url` stays valid.",
|
|
2047
|
+
example: 15,
|
|
2048
|
+
},
|
|
2049
|
+
},
|
|
2050
|
+
} as const;
|
|
2051
|
+
|
|
2052
|
+
export const DatasetUploadSessionSchema = {
|
|
2053
|
+
description: `An upload session — an id plus the presigned URL to PUT the raw file to. Returned both by
|
|
2054
|
+
\`POST /datasets\` (as part of the new dataset) and by \`POST /datasets/{datasetId}/uploads\`
|
|
2055
|
+
(on its own, for an existing one).
|
|
2056
|
+
`,
|
|
2057
|
+
type: "object",
|
|
2058
|
+
required: ["uploadId", "upload"],
|
|
2059
|
+
properties: {
|
|
2060
|
+
uploadId: {
|
|
2061
|
+
type: "string",
|
|
2062
|
+
description: `Identifies this upload session. Pass to
|
|
2063
|
+
\`POST /datasets/{datasetId}/uploads/{uploadId}/finalize\` once the PUT completes.
|
|
2064
|
+
`,
|
|
2065
|
+
example: "up_1a2b3c4d5e6f7a8b",
|
|
2066
|
+
},
|
|
2067
|
+
upload: {
|
|
2068
|
+
$ref: "#/components/schemas/DatasetUploadTarget",
|
|
2069
|
+
},
|
|
2070
|
+
},
|
|
2071
|
+
} as const;
|
|
2072
|
+
|
|
1770
2073
|
export const DatasetCreatedSchema = {
|
|
1771
|
-
description: `
|
|
2074
|
+
description: `The metadata available immediately after creating a dataset, plus its first upload
|
|
2075
|
+
session — the presigned URL to PUT the file to. Version-derived fields such as
|
|
2076
|
+
\`createdAt\`, \`currentVersionId\`, range, and cadence are available from \`GET /datasets/{datasetId}\`
|
|
2077
|
+
after the relevant lifecycle stages, not in this creation response.
|
|
1772
2078
|
`,
|
|
1773
2079
|
allOf: [
|
|
1774
|
-
{
|
|
1775
|
-
$ref: "#/components/schemas/Dataset",
|
|
1776
|
-
},
|
|
1777
2080
|
{
|
|
1778
2081
|
type: "object",
|
|
1779
|
-
required: ["
|
|
2082
|
+
required: ["datasetId", "name", "type", "instrument"],
|
|
1780
2083
|
properties: {
|
|
1781
|
-
|
|
2084
|
+
datasetId: {
|
|
1782
2085
|
type: "string",
|
|
1783
|
-
description:
|
|
1784
|
-
|
|
1785
|
-
`,
|
|
1786
|
-
example: "up_1a2b3c4d5e6f7a8b",
|
|
2086
|
+
description: "Opaque id of the newly created dataset.",
|
|
2087
|
+
example: "ds_3f9a1c2e7b0d4a5f",
|
|
1787
2088
|
},
|
|
1788
|
-
|
|
1789
|
-
type: "
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
type: "integer",
|
|
1802
|
-
description: "How long `url` stays valid.",
|
|
1803
|
-
example: 15,
|
|
1804
|
-
},
|
|
1805
|
-
},
|
|
2089
|
+
name: {
|
|
2090
|
+
type: "string",
|
|
2091
|
+
description: "Unique name of the newly created dataset.",
|
|
2092
|
+
example: "My BTC ticks",
|
|
2093
|
+
},
|
|
2094
|
+
type: {
|
|
2095
|
+
type: "string",
|
|
2096
|
+
enum: ["ticker"],
|
|
2097
|
+
description: "Always `ticker` in v1.",
|
|
2098
|
+
example: "ticker",
|
|
2099
|
+
},
|
|
2100
|
+
instrument: {
|
|
2101
|
+
$ref: "#/components/schemas/Instrument",
|
|
1806
2102
|
},
|
|
1807
2103
|
},
|
|
1808
2104
|
},
|
|
2105
|
+
{
|
|
2106
|
+
$ref: "#/components/schemas/DatasetUploadSession",
|
|
2107
|
+
},
|
|
1809
2108
|
],
|
|
1810
2109
|
} as const;
|
|
1811
2110
|
|
|
1812
2111
|
export const DatasetVersionSchema = {
|
|
1813
2112
|
type: "object",
|
|
1814
2113
|
description: `One successfully ingested upload. Cadence and timestamp unit are discovered from the file,
|
|
1815
|
-
not declared by the caller
|
|
2114
|
+
not declared by the caller.
|
|
1816
2115
|
`,
|
|
1817
2116
|
required: ["datasetId"],
|
|
1818
2117
|
properties: {
|
package/src/generated/sdk.gen.ts
CHANGED
|
@@ -58,6 +58,9 @@ import type {
|
|
|
58
58
|
GetSweepSensitivityData,
|
|
59
59
|
GetSweepSensitivityResponse,
|
|
60
60
|
GetSweepSensitivityError,
|
|
61
|
+
GetSweepRunEquityCurveData,
|
|
62
|
+
GetSweepRunEquityCurveResponse,
|
|
63
|
+
GetSweepRunEquityCurveError,
|
|
61
64
|
ExecuteBacktestData,
|
|
62
65
|
ExecuteBacktestResponse,
|
|
63
66
|
ExecuteBacktestError,
|
|
@@ -78,6 +81,9 @@ import type {
|
|
|
78
81
|
GetDatasetData,
|
|
79
82
|
GetDatasetResponse,
|
|
80
83
|
GetDatasetError,
|
|
84
|
+
OpenDatasetUploadData,
|
|
85
|
+
OpenDatasetUploadResponse,
|
|
86
|
+
OpenDatasetUploadError,
|
|
81
87
|
FinalizeDatasetUploadData,
|
|
82
88
|
FinalizeDatasetUploadResponse,
|
|
83
89
|
FinalizeDatasetUploadError,
|
|
@@ -316,6 +322,10 @@ export const listStrategies = <ThrowOnError extends boolean = false>(
|
|
|
316
322
|
* different means are two strategies, because deciding otherwise would mean deciding program
|
|
317
323
|
* equivalence.
|
|
318
324
|
*
|
|
325
|
+
* The response also lists `declaredProperties` — the sweep/execute param keys this strategy
|
|
326
|
+
* is known to accept, so a caller can catch a typo'd key before submitting a sweep instead of
|
|
327
|
+
* only learning it from a rejected one. See `DeclaredProperty`: best-effort, not exhaustive.
|
|
328
|
+
*
|
|
319
329
|
*/
|
|
320
330
|
export const compileStrategy = <ThrowOnError extends boolean = false>(
|
|
321
331
|
options: Options<CompileStrategyData, ThrowOnError>
|
|
@@ -689,6 +699,41 @@ export const getSweepSensitivity = <ThrowOnError extends boolean = false>(
|
|
|
689
699
|
});
|
|
690
700
|
};
|
|
691
701
|
|
|
702
|
+
/**
|
|
703
|
+
* Get one sweep trial's equity curve
|
|
704
|
+
* The resource a leaderboard row's `equityCurve.url` points at — only reachable when that
|
|
705
|
+
* trial's curve was actually selected (`equityCurve.mode: topN` or `topPct` on the sweep
|
|
706
|
+
* submission, and this trial ranked among the winners). Returns the exact same
|
|
707
|
+
* `{points|timestamps+equities, meta}` shape a plain backtest's inline `equityCurve` carries.
|
|
708
|
+
*
|
|
709
|
+
* Query params reshape the response the same way a plain backtest's `equityCurve` options do.
|
|
710
|
+
* A param genuinely absent from the query string falls back to the `equityCurve` transform
|
|
711
|
+
* preference the sweep was submitted with — a param
|
|
712
|
+
* present but malformed does not fall back, it degrades the same way it always has. Above a
|
|
713
|
+
* server-side size threshold, the shape is forced regardless of either — `meta.outMode` in
|
|
714
|
+
* the response, not the query string or the submitted default, is the source of truth for
|
|
715
|
+
* what shape actually came back.
|
|
716
|
+
*
|
|
717
|
+
*/
|
|
718
|
+
export const getSweepRunEquityCurve = <ThrowOnError extends boolean = false>(
|
|
719
|
+
options: Options<GetSweepRunEquityCurveData, ThrowOnError>
|
|
720
|
+
) => {
|
|
721
|
+
return (options.client ?? _heyApiClient).get<
|
|
722
|
+
GetSweepRunEquityCurveResponse,
|
|
723
|
+
GetSweepRunEquityCurveError,
|
|
724
|
+
ThrowOnError
|
|
725
|
+
>({
|
|
726
|
+
security: [
|
|
727
|
+
{
|
|
728
|
+
scheme: "bearer",
|
|
729
|
+
type: "http",
|
|
730
|
+
},
|
|
731
|
+
],
|
|
732
|
+
url: "/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}/runs/{runIx}/equityCurve",
|
|
733
|
+
...options,
|
|
734
|
+
});
|
|
735
|
+
};
|
|
736
|
+
|
|
692
737
|
/**
|
|
693
738
|
* Execute a compiled strategy against a prepared dataset
|
|
694
739
|
* Enqueues an execute task that runs the strategy identified by `strategyId` over the data
|
|
@@ -698,8 +743,9 @@ export const getSweepSensitivity = <ThrowOnError extends boolean = false>(
|
|
|
698
743
|
* Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`
|
|
699
744
|
* for the result.
|
|
700
745
|
*
|
|
701
|
-
* The same params (same `prepareJobId`, `strategyId`, `storeSignals`) always
|
|
702
|
-
* `jobId` (idempotent)
|
|
746
|
+
* The same params (same `prepareJobId`, `strategyId`, `storeSignals`, `equityCurve`) always
|
|
747
|
+
* return the same `jobId` (idempotent) — a request that omits `equityCurve` dedupes exactly
|
|
748
|
+
* as it did before that field existed.
|
|
703
749
|
*
|
|
704
750
|
* Works unchanged for a dataset-backed prepare (`exchangeId: user`) — the request body is
|
|
705
751
|
* identical either way, since the instrument and range are recovered from `prepareJobId`.
|
|
@@ -816,6 +862,10 @@ export const listDatasets = <ThrowOnError extends boolean = false>(
|
|
|
816
862
|
* `POST /datasets/{datasetId}/uploads/{uploadId}/finalize` once the upload completes to kick
|
|
817
863
|
* off ingest.
|
|
818
864
|
*
|
|
865
|
+
* Losing this response loses nothing: calling this dataset's
|
|
866
|
+
* `POST /datasets/{datasetId}/uploads` returns the very same upload session again rather than
|
|
867
|
+
* opening a new one, as long as nothing has been finalized against it yet.
|
|
868
|
+
*
|
|
819
869
|
* v1 is ticker data only — `type` is not a request field, it is always `"ticker"` in the
|
|
820
870
|
* response. `instrument` must be a plain spot pair (`BASE/QUOTE`, exactly one `/`); derivative
|
|
821
871
|
* forms (e.g. `BTC/USDT:USDT`) are rejected.
|
|
@@ -899,14 +949,48 @@ export const getDataset = <ThrowOnError extends boolean = false>(
|
|
|
899
949
|
});
|
|
900
950
|
};
|
|
901
951
|
|
|
952
|
+
/**
|
|
953
|
+
* Open a new upload session for an existing dataset
|
|
954
|
+
* Get a fresh presigned URL to upload a new version into a dataset you already have — a
|
|
955
|
+
* corrected file, or the next chunk of history. Behaves the same way `POST /datasets` does
|
|
956
|
+
* for a brand-new dataset's own upload: at most one upload session is open per dataset at a
|
|
957
|
+
* time, so calling this again before finalizing just hands back that same session rather
|
|
958
|
+
* than opening a second one — safe to call repeatedly if a response gets lost.
|
|
959
|
+
*
|
|
960
|
+
* Once a session has been finalized (successfully or not), the next call here opens a
|
|
961
|
+
* genuinely new one for that dataset's next version.
|
|
962
|
+
*
|
|
963
|
+
*/
|
|
964
|
+
export const openDatasetUpload = <ThrowOnError extends boolean = false>(
|
|
965
|
+
options: Options<OpenDatasetUploadData, ThrowOnError>
|
|
966
|
+
) => {
|
|
967
|
+
return (options.client ?? _heyApiClient).post<
|
|
968
|
+
OpenDatasetUploadResponse,
|
|
969
|
+
OpenDatasetUploadError,
|
|
970
|
+
ThrowOnError
|
|
971
|
+
>({
|
|
972
|
+
security: [
|
|
973
|
+
{
|
|
974
|
+
scheme: "bearer",
|
|
975
|
+
type: "http",
|
|
976
|
+
},
|
|
977
|
+
],
|
|
978
|
+
url: "/datasets/{datasetId}/uploads",
|
|
979
|
+
...options,
|
|
980
|
+
});
|
|
981
|
+
};
|
|
982
|
+
|
|
902
983
|
/**
|
|
903
984
|
* Finalize an uploaded file and start ingest
|
|
904
|
-
* Call once the file has been PUT to the `upload.url` from `POST /datasets
|
|
905
|
-
* and returns immediately; poll
|
|
985
|
+
* Call once the file has been PUT to the `upload.url` from `POST /datasets` (or from
|
|
986
|
+
* `POST /datasets/{datasetId}/uploads`). Enqueues ingest and returns immediately; poll
|
|
906
987
|
* `GET /datasets/{datasetId}/uploads/{uploadId}` for the result.
|
|
907
988
|
*
|
|
908
|
-
* Idempotent
|
|
909
|
-
* enqueueing a second ingest.
|
|
989
|
+
* Idempotent while the upload is still open — a repeat finalize before it has produced a
|
|
990
|
+
* version returns the same `jobId` rather than enqueueing a second ingest. Once it HAS
|
|
991
|
+
* produced a version, `uploadId` is spent: finalizing it again is a `409`, even with
|
|
992
|
+
* different bytes freshly PUT to the same URL — open a new upload session instead
|
|
993
|
+
* (`POST /datasets/{datasetId}/uploads`) rather than reusing a spent one.
|
|
910
994
|
*
|
|
911
995
|
*/
|
|
912
996
|
export const finalizeDatasetUpload = <ThrowOnError extends boolean = false>(
|