@qtsurfer/api-client 0.10.0 → 0.12.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.
@@ -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,
@@ -67,6 +70,23 @@ import type {
67
70
  GetBacktestResultData,
68
71
  GetBacktestResultResponse,
69
72
  GetBacktestResultError,
73
+ ListDatasetsData,
74
+ ListDatasetsResponse,
75
+ CreateDatasetData,
76
+ CreateDatasetResponse,
77
+ CreateDatasetError,
78
+ DeleteDatasetData,
79
+ DeleteDatasetResponse,
80
+ DeleteDatasetError,
81
+ GetDatasetData,
82
+ GetDatasetResponse,
83
+ GetDatasetError,
84
+ FinalizeDatasetUploadData,
85
+ FinalizeDatasetUploadResponse,
86
+ FinalizeDatasetUploadError,
87
+ GetDatasetUploadData,
88
+ GetDatasetUploadResponse,
89
+ GetDatasetUploadError,
70
90
  } from "./types.gen";
71
91
  import { client as _heyApiClient } from "./client.gen";
72
92
 
@@ -299,6 +319,10 @@ export const listStrategies = <ThrowOnError extends boolean = false>(
299
319
  * different means are two strategies, because deciding otherwise would mean deciding program
300
320
  * equivalence.
301
321
  *
322
+ * The response also lists `declaredProperties` — the sweep/execute param keys this strategy
323
+ * is known to accept, so a caller can catch a typo'd key before submitting a sweep instead of
324
+ * only learning it from a rejected one. See `DeclaredProperty`: best-effort, not exhaustive.
325
+ *
302
326
  */
303
327
  export const compileStrategy = <ThrowOnError extends boolean = false>(
304
328
  options: Options<CompileStrategyData, ThrowOnError>
@@ -456,6 +480,11 @@ export const getStrategyCode = <ThrowOnError extends boolean = false>(
456
480
  * The same params always return the same `jobId` (idempotent). Repeated calls with identical
457
481
  * params do not enqueue duplicate work — they reuse the existing job.
458
482
  *
483
+ * **`exchangeId: user` is reserved for your own uploaded data.** Instead of a managed
484
+ * exchange, it prepares from a dataset you created via `POST /datasets` (see the **Dataset**
485
+ * endpoints) — send `datasetId` in place of `instrument`. See `PrepareRequest` below for the
486
+ * two request shapes.
487
+ *
459
488
  */
460
489
  export const prepareBacktest = <ThrowOnError extends boolean = false>(
461
490
  options: Options<PrepareBacktestData, ThrowOnError>
@@ -485,6 +514,9 @@ export const prepareBacktest = <ThrowOnError extends boolean = false>(
485
514
  * Retrieves the current state of the prepare job identified by `jobId`.
486
515
  * Poll until `status` is `Completed`, `Failed`, or `Aborted`.
487
516
  *
517
+ * For a dataset prepare (`exchangeId: user`), coverage is reported against the dataset's own
518
+ * cadence grid instead of hours — see `cadence`/`gaps`/`largestGapSteps` on `PrepareJobState`.
519
+ *
488
520
  */
489
521
  export const getPrepareStatus = <ThrowOnError extends boolean = false>(
490
522
  options: Options<GetPrepareStatusData, ThrowOnError>
@@ -664,6 +696,41 @@ export const getSweepSensitivity = <ThrowOnError extends boolean = false>(
664
696
  });
665
697
  };
666
698
 
699
+ /**
700
+ * Get one sweep trial's equity curve
701
+ * The resource a leaderboard row's `equityCurve.url` points at — only reachable when that
702
+ * trial's curve was actually selected (`equityCurve.mode: topN` or `topPct` on the sweep
703
+ * submission, and this trial ranked among the winners). Returns the exact same
704
+ * `{points|timestamps+equities, meta}` shape a plain backtest's inline `equityCurve` carries.
705
+ *
706
+ * Query params reshape the response the same way a plain backtest's `equityCurve` options do.
707
+ * A param genuinely absent from the query string falls back to the `equityCurve` transform
708
+ * preference the sweep was submitted with — a param
709
+ * present but malformed does not fall back, it degrades the same way it always has. Above a
710
+ * server-side size threshold, the shape is forced regardless of either — `meta.outMode` in
711
+ * the response, not the query string or the submitted default, is the source of truth for
712
+ * what shape actually came back.
713
+ *
714
+ */
715
+ export const getSweepRunEquityCurve = <ThrowOnError extends boolean = false>(
716
+ options: Options<GetSweepRunEquityCurveData, ThrowOnError>
717
+ ) => {
718
+ return (options.client ?? _heyApiClient).get<
719
+ GetSweepRunEquityCurveResponse,
720
+ GetSweepRunEquityCurveError,
721
+ ThrowOnError
722
+ >({
723
+ security: [
724
+ {
725
+ scheme: "bearer",
726
+ type: "http",
727
+ },
728
+ ],
729
+ url: "/backtest/{exchangeId}/{type}/executeSweep/{requestId}/{sweepId}/runs/{runIx}/equityCurve",
730
+ ...options,
731
+ });
732
+ };
733
+
667
734
  /**
668
735
  * Execute a compiled strategy against a prepared dataset
669
736
  * Enqueues an execute task that runs the strategy identified by `strategyId` over the data
@@ -673,8 +740,12 @@ export const getSweepSensitivity = <ThrowOnError extends boolean = false>(
673
740
  * Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`
674
741
  * for the result.
675
742
  *
676
- * The same params (same `prepareJobId`, `strategyId`, `storeSignals`) always return the same
677
- * `jobId` (idempotent).
743
+ * The same params (same `prepareJobId`, `strategyId`, `storeSignals`, `equityCurve`) always
744
+ * return the same `jobId` (idempotent) — a request that omits `equityCurve` dedupes exactly
745
+ * as it did before that field existed.
746
+ *
747
+ * Works unchanged for a dataset-backed prepare (`exchangeId: user`) — the request body is
748
+ * identical either way, since the instrument and range are recovered from `prepareJobId`.
678
749
  *
679
750
  */
680
751
  export const executeBacktest = <ThrowOnError extends boolean = false>(
@@ -755,3 +826,172 @@ export const getBacktestResult = <ThrowOnError extends boolean = false>(
755
826
  ...options,
756
827
  });
757
828
  };
829
+
830
+ /**
831
+ * List your datasets
832
+ * Every dataset you have created and not deleted, most recently created first. Never a `404`
833
+ * — an empty array if you have none, same convention as `GET /strategies`.
834
+ *
835
+ */
836
+ export const listDatasets = <ThrowOnError extends boolean = false>(
837
+ options?: Options<ListDatasetsData, ThrowOnError>
838
+ ) => {
839
+ return (options?.client ?? _heyApiClient).get<
840
+ ListDatasetsResponse,
841
+ unknown,
842
+ ThrowOnError
843
+ >({
844
+ security: [
845
+ {
846
+ scheme: "bearer",
847
+ type: "http",
848
+ },
849
+ ],
850
+ url: "/datasets",
851
+ ...options,
852
+ });
853
+ };
854
+
855
+ /**
856
+ * Create a dataset and get a URL to upload it to
857
+ * Creates a dataset AND its first upload session in one call — a presigned URL your client
858
+ * PUTs the file to directly, no API credentials involved in that PUT. Call
859
+ * `POST /datasets/{datasetId}/uploads/{uploadId}/finalize` once the upload completes to kick
860
+ * off ingest.
861
+ *
862
+ * v1 is ticker data only — `type` is not a request field, it is always `"ticker"` in the
863
+ * response. `instrument` must be a plain spot pair (`BASE/QUOTE`, exactly one `/`); derivative
864
+ * forms (e.g. `BTC/USDT:USDT`) are rejected.
865
+ *
866
+ * **Upload format.** A CSV with a header row. Required columns: `timestamp` (ISO-8601, or
867
+ * numeric epoch seconds/millis/micros — detected from the first row, then enforced for every
868
+ * later row), `close`. Optional columns: `open`, `high`, `low`, `volume`, `quoteVolume`,
869
+ * `bid`, `bidSize`, `ask`, `askSize`. Cadence and timestamp unit are discovered from the data,
870
+ * not declared.
871
+ *
872
+ */
873
+ export const createDataset = <ThrowOnError extends boolean = false>(
874
+ options: Options<CreateDatasetData, ThrowOnError>
875
+ ) => {
876
+ return (options.client ?? _heyApiClient).post<
877
+ CreateDatasetResponse,
878
+ CreateDatasetError,
879
+ ThrowOnError
880
+ >({
881
+ security: [
882
+ {
883
+ scheme: "bearer",
884
+ type: "http",
885
+ },
886
+ ],
887
+ url: "/datasets",
888
+ ...options,
889
+ headers: {
890
+ "Content-Type": "application/json",
891
+ ...options?.headers,
892
+ },
893
+ });
894
+ };
895
+
896
+ /**
897
+ * Delete a dataset
898
+ * Soft-delete — the dataset stops appearing in `GET /datasets`/`GET /datasets/{datasetId}` and
899
+ * can no longer be prepared from, but its object data is reclaimed later rather than purged
900
+ * inline, so a backtest already running against one of its versions is not disrupted.
901
+ *
902
+ */
903
+ export const deleteDataset = <ThrowOnError extends boolean = false>(
904
+ options: Options<DeleteDatasetData, ThrowOnError>
905
+ ) => {
906
+ return (options.client ?? _heyApiClient).delete<
907
+ DeleteDatasetResponse,
908
+ DeleteDatasetError,
909
+ ThrowOnError
910
+ >({
911
+ security: [
912
+ {
913
+ scheme: "bearer",
914
+ type: "http",
915
+ },
916
+ ],
917
+ url: "/datasets/{datasetId}",
918
+ ...options,
919
+ });
920
+ };
921
+
922
+ /**
923
+ * Get a dataset by id
924
+ * Detail for one dataset, plus a self link.
925
+ */
926
+ export const getDataset = <ThrowOnError extends boolean = false>(
927
+ options: Options<GetDatasetData, ThrowOnError>
928
+ ) => {
929
+ return (options.client ?? _heyApiClient).get<
930
+ GetDatasetResponse,
931
+ GetDatasetError,
932
+ ThrowOnError
933
+ >({
934
+ security: [
935
+ {
936
+ scheme: "bearer",
937
+ type: "http",
938
+ },
939
+ ],
940
+ url: "/datasets/{datasetId}",
941
+ ...options,
942
+ });
943
+ };
944
+
945
+ /**
946
+ * Finalize an uploaded file and start ingest
947
+ * Call once the file has been PUT to the `upload.url` from `POST /datasets`. Enqueues ingest
948
+ * and returns immediately; poll
949
+ * `GET /datasets/{datasetId}/uploads/{uploadId}` for the result.
950
+ *
951
+ * Idempotent — a repeat finalize of the same upload returns the same `jobId` rather than
952
+ * enqueueing a second ingest.
953
+ *
954
+ */
955
+ export const finalizeDatasetUpload = <ThrowOnError extends boolean = false>(
956
+ options: Options<FinalizeDatasetUploadData, ThrowOnError>
957
+ ) => {
958
+ return (options.client ?? _heyApiClient).post<
959
+ FinalizeDatasetUploadResponse,
960
+ FinalizeDatasetUploadError,
961
+ ThrowOnError
962
+ >({
963
+ security: [
964
+ {
965
+ scheme: "bearer",
966
+ type: "http",
967
+ },
968
+ ],
969
+ url: "/datasets/{datasetId}/uploads/{uploadId}/finalize",
970
+ ...options,
971
+ });
972
+ };
973
+
974
+ /**
975
+ * Get the state of an upload/ingest
976
+ * Poll after `POST .../finalize` until `status` is `ready` or `failed`. Also reports
977
+ * `uploading` (finalize not called yet, but the file was PUT) before you finalize at all.
978
+ *
979
+ */
980
+ export const getDatasetUpload = <ThrowOnError extends boolean = false>(
981
+ options: Options<GetDatasetUploadData, ThrowOnError>
982
+ ) => {
983
+ return (options.client ?? _heyApiClient).get<
984
+ GetDatasetUploadResponse,
985
+ GetDatasetUploadError,
986
+ ThrowOnError
987
+ >({
988
+ security: [
989
+ {
990
+ scheme: "bearer",
991
+ type: "http",
992
+ },
993
+ ],
994
+ url: "/datasets/{datasetId}/uploads/{uploadId}",
995
+ ...options,
996
+ });
997
+ };