@qtsurfer/api-client 0.1.2 → 0.2.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 +23 -0
- package/dist/index.d.ts +95 -2
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/generated/schemas.gen.ts +100 -1
- package/src/generated/sdk.gen.ts +26 -1
- package/src/generated/types.gen.ts +89 -1
package/README.md
CHANGED
|
@@ -41,12 +41,35 @@ if (error) throw error;
|
|
|
41
41
|
console.log(exchanges);
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
### API key → JWT
|
|
45
|
+
|
|
46
|
+
Every endpoint above expects a short-lived JWT in `Authorization: Bearer …`.
|
|
47
|
+
Exchange a long-lived API key for one via `auth`:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { auth } from '@qtsurfer/api-client';
|
|
51
|
+
|
|
52
|
+
const { data, error } = await auth({
|
|
53
|
+
baseUrl: 'https://api.qtsurfer.com/v1',
|
|
54
|
+
headers: { 'X-API-Key': process.env.QTSURFER_APIKEY! },
|
|
55
|
+
});
|
|
56
|
+
if (error) throw error;
|
|
57
|
+
|
|
58
|
+
const { access_token: jwt } = data; // feed to client.setConfig() for the rest
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For production use, prefer the [`@qtsurfer/sdk`](https://github.com/QTSurfer/sdk-ts)
|
|
62
|
+
`auth(apikey)` helper — it returns a session that refreshes the JWT
|
|
63
|
+
transparently, reads `QTSURFER_APIKEY` from the environment, and supports
|
|
64
|
+
pluggable token stores so callers don't reinvent that plumbing.
|
|
65
|
+
|
|
44
66
|
## API surface
|
|
45
67
|
|
|
46
68
|
All operations are exported as standalone functions; every operation accepts an `Options` object and returns `{ data, error, response }`.
|
|
47
69
|
|
|
48
70
|
| Function | Method | Path | Purpose |
|
|
49
71
|
| -------- | ------ | ---- | ------- |
|
|
72
|
+
| `auth` | POST | `/auth/token` | Exchange an API key for a short-lived JWT |
|
|
50
73
|
| `getExchanges` | GET | `/exchanges` | List available exchanges |
|
|
51
74
|
| `getInstruments` | GET | `/exchange/{exchangeId}/instruments` | List instruments for an exchange |
|
|
52
75
|
| `getExchangeTickersHour` | GET | `/exchange/{exchangeId}/tickers/{base}/{quote}` | Download one hour of tickers as Lastra/Parquet |
|
package/dist/index.d.ts
CHANGED
|
@@ -128,7 +128,7 @@ type BacktestJobResult = {
|
|
|
128
128
|
state: JobState;
|
|
129
129
|
};
|
|
130
130
|
/**
|
|
131
|
-
* Execution result map. Always includes core fields (hostName, iops, strategyId, instrument). Yield metrics (pnlTotal, totalTrades, winRate, etc.) are present when the strategy emitted at least one trade. When signal storage is enabled, includes signal fields described below.
|
|
131
|
+
* Execution result map. Always includes core fields (hostName, iops, strategyId, instrument). Yield metrics (pnlTotal, pnlTotalPercent, totalTrades, winRate, equityCurve, etc.) are present when the strategy emitted at least one trade. When signal storage is enabled, includes signal fields described below.
|
|
132
132
|
*/
|
|
133
133
|
type ResultMap = {
|
|
134
134
|
/**
|
|
@@ -151,6 +151,10 @@ type ResultMap = {
|
|
|
151
151
|
* Total profit and loss in the output currency
|
|
152
152
|
*/
|
|
153
153
|
pnlTotal?: number;
|
|
154
|
+
/**
|
|
155
|
+
* Total PnL as a percentage of the initial capital (`backtestFunding`). Zero when `backtestFunding` is 0.
|
|
156
|
+
*/
|
|
157
|
+
pnlTotalPercent?: number;
|
|
154
158
|
/**
|
|
155
159
|
* Total number of trades executed by the strategy
|
|
156
160
|
*/
|
|
@@ -179,6 +183,10 @@ type ResultMap = {
|
|
|
179
183
|
* Maximum percentage drawdown from peak equity
|
|
180
184
|
*/
|
|
181
185
|
maxDrawdownPercent?: number;
|
|
186
|
+
/**
|
|
187
|
+
* 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.
|
|
188
|
+
*/
|
|
189
|
+
equityCurve?: Array<EquityPoint>;
|
|
182
190
|
/**
|
|
183
191
|
* Number of signals emitted during strategy execution
|
|
184
192
|
*/
|
|
@@ -204,10 +212,82 @@ type ResultMap = {
|
|
|
204
212
|
*/
|
|
205
213
|
signalsUploadReason?: string;
|
|
206
214
|
};
|
|
215
|
+
/**
|
|
216
|
+
* Single sample of the running equity at a yield event.
|
|
217
|
+
*/
|
|
218
|
+
type EquityPoint = {
|
|
219
|
+
/**
|
|
220
|
+
* Epoch milliseconds. The first point in an equity curve is anchored at the backtest `from`; subsequent points carry the timestamp of each emitted yield.
|
|
221
|
+
*/
|
|
222
|
+
timestamp: number;
|
|
223
|
+
/**
|
|
224
|
+
* Running equity at this point (`initialCapital + cumulativePnl`).
|
|
225
|
+
*/
|
|
226
|
+
equity: number;
|
|
227
|
+
};
|
|
207
228
|
/**
|
|
208
229
|
* Unique identifier for a compiled strategy
|
|
209
230
|
*/
|
|
210
231
|
type StrategyId = string;
|
|
232
|
+
type AuthTokenResponse = {
|
|
233
|
+
/**
|
|
234
|
+
* Short-lived HS256 JWT. Send as `Authorization: Bearer <token>` on all other endpoints.
|
|
235
|
+
*/
|
|
236
|
+
access_token: string;
|
|
237
|
+
/**
|
|
238
|
+
* Always `Bearer`.
|
|
239
|
+
*/
|
|
240
|
+
token_type: 'Bearer';
|
|
241
|
+
/**
|
|
242
|
+
* Seconds until the JWT expires (typically 3600).
|
|
243
|
+
*/
|
|
244
|
+
expires_in: number;
|
|
245
|
+
/**
|
|
246
|
+
* Scopes granted to this token. Reserved for future use; currently always empty.
|
|
247
|
+
*/
|
|
248
|
+
scopes?: Array<string>;
|
|
249
|
+
/**
|
|
250
|
+
* Subscription tier this token was issued for. Drives rate limits and feature flags on downstream endpoints.
|
|
251
|
+
*/
|
|
252
|
+
tier: 'free' | 'basic' | 'pro' | 'elite';
|
|
253
|
+
};
|
|
254
|
+
/**
|
|
255
|
+
* Error envelope returned by `POST /auth/token` when the API key is rejected.
|
|
256
|
+
*/
|
|
257
|
+
type AuthTokenError = {
|
|
258
|
+
/**
|
|
259
|
+
* Machine-readable error reason.
|
|
260
|
+
*/
|
|
261
|
+
code: 'invalid_apikey' | 'apikey_revoked' | 'apikey_expired';
|
|
262
|
+
/**
|
|
263
|
+
* Human-readable description of the failure.
|
|
264
|
+
*/
|
|
265
|
+
message: string;
|
|
266
|
+
};
|
|
267
|
+
type AuthData = {
|
|
268
|
+
body?: never;
|
|
269
|
+
path?: never;
|
|
270
|
+
query?: never;
|
|
271
|
+
url: '/auth/token';
|
|
272
|
+
};
|
|
273
|
+
type AuthErrors = {
|
|
274
|
+
/**
|
|
275
|
+
* API key is invalid, revoked, or expired.
|
|
276
|
+
*/
|
|
277
|
+
401: AuthTokenError;
|
|
278
|
+
/**
|
|
279
|
+
* Rate limit exceeded for this API key.
|
|
280
|
+
*/
|
|
281
|
+
429: unknown;
|
|
282
|
+
};
|
|
283
|
+
type AuthError = AuthErrors[keyof AuthErrors];
|
|
284
|
+
type AuthResponses = {
|
|
285
|
+
/**
|
|
286
|
+
* API key accepted; JWT returned.
|
|
287
|
+
*/
|
|
288
|
+
200: AuthTokenResponse;
|
|
289
|
+
};
|
|
290
|
+
type AuthResponse = AuthResponses[keyof AuthResponses];
|
|
211
291
|
type GetExchangesData = {
|
|
212
292
|
body?: never;
|
|
213
293
|
path?: never;
|
|
@@ -677,6 +757,19 @@ type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean
|
|
|
677
757
|
*/
|
|
678
758
|
meta?: Record<string, unknown>;
|
|
679
759
|
};
|
|
760
|
+
/**
|
|
761
|
+
* Exchange API key for a short-lived JWT
|
|
762
|
+
* Exchanges a long-lived API key for a short-lived JWT used by every other
|
|
763
|
+
* endpoint. This is the only endpoint that accepts an API key directly —
|
|
764
|
+
* callers should obtain a JWT here, then send it as `Authorization: Bearer
|
|
765
|
+
* <token>` to all other operations.
|
|
766
|
+
*
|
|
767
|
+
* The returned JWT carries the caller's subscription `tier` as a claim and
|
|
768
|
+
* expires after `expires_in` seconds. Callers should refresh the token
|
|
769
|
+
* before expiry (or on a `401` response) by calling this endpoint again.
|
|
770
|
+
*
|
|
771
|
+
*/
|
|
772
|
+
declare const auth: <ThrowOnError extends boolean = false>(options?: Options<AuthData, ThrowOnError>) => _hey_api_client_fetch.RequestResult<AuthTokenResponse, unknown, ThrowOnError>;
|
|
680
773
|
/**
|
|
681
774
|
* Get a list of available exchanges
|
|
682
775
|
*/
|
|
@@ -808,4 +901,4 @@ declare const getExecutionResult: <ThrowOnError extends boolean = false>(options
|
|
|
808
901
|
|
|
809
902
|
declare const client: _hey_api_client_fetch.Client;
|
|
810
903
|
|
|
811
|
-
export { type AcceptedJob, type BacktestJobResult, type CancelExecutionData, type CancelExecutionError, type CancelExecutionErrors, type CancelExecutionResponse, type CancelExecutionResponses, type ClientOptions, type DataSourceType, type Exchange, type ExecuteBacktestingData, type ExecuteBacktestingError, type ExecuteBacktestingErrors, type ExecuteBacktestingResponse, type ExecuteBacktestingResponses, type GetExchangeKlinesHourData, type GetExchangeKlinesHourError, type GetExchangeKlinesHourErrors, type GetExchangeKlinesHourResponse, type GetExchangeKlinesHourResponses, type GetExchangeTickersHourData, type GetExchangeTickersHourError, type GetExchangeTickersHourErrors, type GetExchangeTickersHourResponse, type GetExchangeTickersHourResponses, type GetExchangesData, type GetExchangesResponse, type GetExchangesResponses, type GetExecutionResultData, type GetExecutionResultError, type GetExecutionResultErrors, type GetExecutionResultResponse, type GetExecutionResultResponses, type GetInstrumentsData, type GetInstrumentsError, type GetInstrumentsErrors, type GetInstrumentsResponse, type GetInstrumentsResponses, type GetPreparationStatusData, type GetPreparationStatusError, type GetPreparationStatusErrors, type GetPreparationStatusResponse, type GetPreparationStatusResponses, type GetStrategyStatusData, type GetStrategyStatusError, type GetStrategyStatusErrors, type GetStrategyStatusResponse, type GetStrategyStatusResponses, type Instrument, type InstrumentDetail, type JobState, type Options, type PostStrategyData, type PostStrategyError, type PostStrategyErrors, type PostStrategyResponse, type PostStrategyResponses, type PrepareBacktestingData, type PrepareBacktestingError, type PrepareBacktestingErrors, type PrepareBacktestingResponse, type PrepareBacktestingResponses, type ResponseError, type ResultMap, type StrategyId, cancelExecution, client, executeBacktesting, getExchangeKlinesHour, getExchangeTickersHour, getExchanges, getExecutionResult, getInstruments, getPreparationStatus, getStrategyStatus, postStrategy, prepareBacktesting };
|
|
904
|
+
export { type AcceptedJob, type AuthData, type AuthError, type AuthErrors, type AuthResponse, type AuthResponses, type AuthTokenError, type AuthTokenResponse, type BacktestJobResult, type CancelExecutionData, type CancelExecutionError, type CancelExecutionErrors, type CancelExecutionResponse, type CancelExecutionResponses, type ClientOptions, type DataSourceType, type EquityPoint, type Exchange, type ExecuteBacktestingData, type ExecuteBacktestingError, type ExecuteBacktestingErrors, type ExecuteBacktestingResponse, type ExecuteBacktestingResponses, type GetExchangeKlinesHourData, type GetExchangeKlinesHourError, type GetExchangeKlinesHourErrors, type GetExchangeKlinesHourResponse, type GetExchangeKlinesHourResponses, type GetExchangeTickersHourData, type GetExchangeTickersHourError, type GetExchangeTickersHourErrors, type GetExchangeTickersHourResponse, type GetExchangeTickersHourResponses, type GetExchangesData, type GetExchangesResponse, type GetExchangesResponses, type GetExecutionResultData, type GetExecutionResultError, type GetExecutionResultErrors, type GetExecutionResultResponse, type GetExecutionResultResponses, type GetInstrumentsData, type GetInstrumentsError, type GetInstrumentsErrors, type GetInstrumentsResponse, type GetInstrumentsResponses, type GetPreparationStatusData, type GetPreparationStatusError, type GetPreparationStatusErrors, type GetPreparationStatusResponse, type GetPreparationStatusResponses, type GetStrategyStatusData, type GetStrategyStatusError, type GetStrategyStatusErrors, type GetStrategyStatusResponse, type GetStrategyStatusResponses, type Instrument, type InstrumentDetail, type JobState, type Options, type PostStrategyData, type PostStrategyError, type PostStrategyErrors, type PostStrategyResponse, type PostStrategyResponses, type PrepareBacktestingData, type PrepareBacktestingError, type PrepareBacktestingErrors, type PrepareBacktestingResponse, type PrepareBacktestingResponses, type ResponseError, type ResultMap, type StrategyId, auth, cancelExecution, client, executeBacktesting, getExchangeKlinesHour, getExchangeTickersHour, getExchanges, getExecutionResult, getInstruments, getPreparationStatus, getStrategyStatus, postStrategy, prepareBacktesting };
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,18 @@ var client = createClient(createConfig({
|
|
|
5
5
|
}));
|
|
6
6
|
|
|
7
7
|
// src/generated/sdk.gen.ts
|
|
8
|
+
var auth = (options) => {
|
|
9
|
+
return (options?.client ?? client).post({
|
|
10
|
+
security: [
|
|
11
|
+
{
|
|
12
|
+
name: "X-API-Key",
|
|
13
|
+
type: "apiKey"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
url: "/auth/token",
|
|
17
|
+
...options
|
|
18
|
+
});
|
|
19
|
+
};
|
|
8
20
|
var getExchanges = (options) => {
|
|
9
21
|
return (options?.client ?? client).get({
|
|
10
22
|
url: "/exchanges",
|
|
@@ -127,6 +139,7 @@ var getExecutionResult = (options) => {
|
|
|
127
139
|
});
|
|
128
140
|
};
|
|
129
141
|
export {
|
|
142
|
+
auth,
|
|
130
143
|
cancelExecution,
|
|
131
144
|
client,
|
|
132
145
|
executeBacktesting,
|
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 { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } 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> = (override?: Config<DefaultClientOptions & T>) => Config<Required<DefaultClientOptions> & T>;\n\nexport const client = createClient(createConfig<ClientOptions>({\n baseUrl: 'https://api.staging.qtsurfer.com/v1'\n}));","// This file is auto-generated by @hey-api/openapi-ts\n\nimport type { Options as ClientOptions, TDataShape, Client } from '@hey-api/client-fetch';\nimport type { GetExchangesData, GetExchangesResponse, GetInstrumentsData, GetInstrumentsResponse, GetInstrumentsError, GetExchangeTickersHourData, GetExchangeTickersHourResponse, GetExchangeTickersHourError, GetExchangeKlinesHourData, GetExchangeKlinesHourResponse, GetExchangeKlinesHourError, PostStrategyData, PostStrategyResponse, PostStrategyError, GetStrategyStatusData, GetStrategyStatusResponse, GetStrategyStatusError, PrepareBacktestingData, PrepareBacktestingResponse, PrepareBacktestingError, GetPreparationStatusData, GetPreparationStatusResponse, GetPreparationStatusError, ExecuteBacktestingData, ExecuteBacktestingResponse, ExecuteBacktestingError, CancelExecutionData, CancelExecutionResponse, CancelExecutionError, GetExecutionResultData, GetExecutionResultResponse, GetExecutionResultError } from './types.gen';\nimport { client as _heyApiClient } from './client.gen';\n\nexport type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = 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 * Get a list of available exchanges\n */\nexport const getExchanges = <ThrowOnError extends boolean = false>(options?: Options<GetExchangesData, ThrowOnError>) => {\n return (options?.client ?? _heyApiClient).get<GetExchangesResponse, unknown, ThrowOnError>({\n url: '/exchanges',\n ...options\n });\n};\n\n/**\n * Get a list of Instruments from a specific exchange\n */\nexport const getInstruments = <ThrowOnError extends boolean = false>(options: Options<GetInstrumentsData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetInstrumentsResponse, GetInstrumentsError, ThrowOnError>({\n url: '/exchange/{exchangeId}/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 getExchangeTickersHour = <ThrowOnError extends boolean = false>(options: Options<GetExchangeTickersHourData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetExchangeTickersHourResponse, GetExchangeTickersHourError, ThrowOnError>({\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 getExchangeKlinesHour = <ThrowOnError extends boolean = false>(options: Options<GetExchangeKlinesHourData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetExchangeKlinesHourResponse, GetExchangeKlinesHourError, ThrowOnError>({\n url: '/exchange/{exchangeId}/klines/{base}/{quote}',\n ...options\n });\n};\n\n/**\n * Compile a strategy from source code\n * Submits raw strategy source for compilation. By default the call is synchronous and returns\n * the `strategyId` once compilation succeeds. Set the header `X-Compile-Async: true` to enqueue\n * the compile task and return immediately with a `jobId` — poll\n * `GET /strategy/{strategyId}` to check status.\n *\n * The `strategyId` is deterministic: the same source for the same user always produces the\n * same id.\n *\n */\nexport const postStrategy = <ThrowOnError extends boolean = false>(options: Options<PostStrategyData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).post<PostStrategyResponse, PostStrategyError, ThrowOnError>({\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 * Get the status of an async compile task\n * Polls the status of a strategy compilation. Useful when the strategy was submitted with\n * `X-Compile-Async: true`. Returns the resolved `strategyId` once compilation completes.\n *\n */\nexport const getStrategyStatus = <ThrowOnError extends boolean = false>(options: Options<GetStrategyStatusData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetStrategyStatusResponse, GetStrategyStatusError, ThrowOnError>({\n security: [\n {\n scheme: 'bearer',\n type: 'http'\n }\n ],\n url: '/strategy/{strategyId}',\n ...options\n });\n};\n\n/**\n * Prepare backtesting 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 */\nexport const prepareBacktesting = <ThrowOnError extends boolean = false>(options: Options<PrepareBacktestingData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).post<PrepareBacktestingResponse, PrepareBacktestingError, ThrowOnError>({\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 */\nexport const getPreparationStatus = <ThrowOnError extends boolean = false>(options: Options<GetPreparationStatusData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetPreparationStatusResponse, GetPreparationStatusError, ThrowOnError>({\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 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`) always return the same\n * `jobId` (idempotent).\n *\n */\nexport const executeBacktesting = <ThrowOnError extends boolean = false>(options: Options<ExecuteBacktestingData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).post<ExecuteBacktestingResponse, ExecuteBacktestingError, ThrowOnError>({\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 cancelExecution = <ThrowOnError extends boolean = false>(options: Options<CancelExecutionData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).delete<CancelExecutionResponse, CancelExecutionError, ThrowOnError>({\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 */\nexport const getExecutionResult = <ThrowOnError extends boolean = false>(options: Options<GetExecutionResultData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetExecutionResultResponse, GetExecutionResultError, ThrowOnError>({\n security: [\n {\n scheme: 'bearer',\n type: 'http'\n }\n ],\n url: '/backtest/{exchangeId}/{type}/execute/{jobId}',\n ...options\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 { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } 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> = (override?: Config<DefaultClientOptions & T>) => Config<Required<DefaultClientOptions> & T>;\n\nexport const client = createClient(createConfig<ClientOptions>({\n baseUrl: 'https://api.staging.qtsurfer.com/v1'\n}));","// This file is auto-generated by @hey-api/openapi-ts\n\nimport type { Options as ClientOptions, TDataShape, Client } from '@hey-api/client-fetch';\nimport type { AuthData, AuthResponse, AuthError, GetExchangesData, GetExchangesResponse, GetInstrumentsData, GetInstrumentsResponse, GetInstrumentsError, GetExchangeTickersHourData, GetExchangeTickersHourResponse, GetExchangeTickersHourError, GetExchangeKlinesHourData, GetExchangeKlinesHourResponse, GetExchangeKlinesHourError, PostStrategyData, PostStrategyResponse, PostStrategyError, GetStrategyStatusData, GetStrategyStatusResponse, GetStrategyStatusError, PrepareBacktestingData, PrepareBacktestingResponse, PrepareBacktestingError, GetPreparationStatusData, GetPreparationStatusResponse, GetPreparationStatusError, ExecuteBacktestingData, ExecuteBacktestingResponse, ExecuteBacktestingError, CancelExecutionData, CancelExecutionResponse, CancelExecutionError, GetExecutionResultData, GetExecutionResultResponse, GetExecutionResultError } from './types.gen';\nimport { client as _heyApiClient } from './client.gen';\n\nexport type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = 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 auth = <ThrowOnError extends boolean = false>(options?: Options<AuthData, ThrowOnError>) => {\n return (options?.client ?? _heyApiClient).post<AuthResponse, AuthError, ThrowOnError>({\n security: [\n {\n name: 'X-API-Key',\n type: 'apiKey'\n }\n ],\n url: '/auth/token',\n ...options\n });\n};\n\n/**\n * Get a list of available exchanges\n */\nexport const getExchanges = <ThrowOnError extends boolean = false>(options?: Options<GetExchangesData, ThrowOnError>) => {\n return (options?.client ?? _heyApiClient).get<GetExchangesResponse, unknown, ThrowOnError>({\n url: '/exchanges',\n ...options\n });\n};\n\n/**\n * Get a list of Instruments from a specific exchange\n */\nexport const getInstruments = <ThrowOnError extends boolean = false>(options: Options<GetInstrumentsData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetInstrumentsResponse, GetInstrumentsError, ThrowOnError>({\n url: '/exchange/{exchangeId}/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 getExchangeTickersHour = <ThrowOnError extends boolean = false>(options: Options<GetExchangeTickersHourData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetExchangeTickersHourResponse, GetExchangeTickersHourError, ThrowOnError>({\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 getExchangeKlinesHour = <ThrowOnError extends boolean = false>(options: Options<GetExchangeKlinesHourData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetExchangeKlinesHourResponse, GetExchangeKlinesHourError, ThrowOnError>({\n url: '/exchange/{exchangeId}/klines/{base}/{quote}',\n ...options\n });\n};\n\n/**\n * Compile a strategy from source code\n * Submits raw strategy source for compilation. By default the call is synchronous and returns\n * the `strategyId` once compilation succeeds. Set the header `X-Compile-Async: true` to enqueue\n * the compile task and return immediately with a `jobId` — poll\n * `GET /strategy/{strategyId}` to check status.\n *\n * The `strategyId` is deterministic: the same source for the same user always produces the\n * same id.\n *\n */\nexport const postStrategy = <ThrowOnError extends boolean = false>(options: Options<PostStrategyData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).post<PostStrategyResponse, PostStrategyError, ThrowOnError>({\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 * Get the status of an async compile task\n * Polls the status of a strategy compilation. Useful when the strategy was submitted with\n * `X-Compile-Async: true`. Returns the resolved `strategyId` once compilation completes.\n *\n */\nexport const getStrategyStatus = <ThrowOnError extends boolean = false>(options: Options<GetStrategyStatusData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetStrategyStatusResponse, GetStrategyStatusError, ThrowOnError>({\n security: [\n {\n scheme: 'bearer',\n type: 'http'\n }\n ],\n url: '/strategy/{strategyId}',\n ...options\n });\n};\n\n/**\n * Prepare backtesting 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 */\nexport const prepareBacktesting = <ThrowOnError extends boolean = false>(options: Options<PrepareBacktestingData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).post<PrepareBacktestingResponse, PrepareBacktestingError, ThrowOnError>({\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 */\nexport const getPreparationStatus = <ThrowOnError extends boolean = false>(options: Options<GetPreparationStatusData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetPreparationStatusResponse, GetPreparationStatusError, ThrowOnError>({\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 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`) always return the same\n * `jobId` (idempotent).\n *\n */\nexport const executeBacktesting = <ThrowOnError extends boolean = false>(options: Options<ExecuteBacktestingData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).post<ExecuteBacktestingResponse, ExecuteBacktestingError, ThrowOnError>({\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 cancelExecution = <ThrowOnError extends boolean = false>(options: Options<CancelExecutionData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).delete<CancelExecutionResponse, CancelExecutionError, ThrowOnError>({\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 */\nexport const getExecutionResult = <ThrowOnError extends boolean = false>(options: Options<GetExecutionResultData, ThrowOnError>) => {\n return (options.client ?? _heyApiClient).get<GetExecutionResultResponse, GetExecutionResultError, ThrowOnError>({\n security: [\n {\n scheme: 'bearer',\n type: 'http'\n }\n ],\n url: '/backtest/{exchangeId}/{type}/execute/{jobId}',\n ...options\n });\n};"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -185,7 +185,7 @@ export const BacktestJobResultSchema = {
|
|
|
185
185
|
|
|
186
186
|
export const ResultMapSchema = {
|
|
187
187
|
type: 'object',
|
|
188
|
-
description: 'Execution result map. Always includes core fields (hostName, iops, strategyId, instrument). Yield metrics (pnlTotal, totalTrades, winRate, etc.) are present when the strategy emitted at least one trade. When signal storage is enabled, includes signal fields described below.',
|
|
188
|
+
description: 'Execution result map. Always includes core fields (hostName, iops, strategyId, instrument). Yield metrics (pnlTotal, pnlTotalPercent, totalTrades, winRate, equityCurve, etc.) are present when the strategy emitted at least one trade. When signal storage is enabled, includes signal fields described below.',
|
|
189
189
|
required: ['strategyId', 'instrument'],
|
|
190
190
|
properties: {
|
|
191
191
|
hostName: {
|
|
@@ -215,6 +215,12 @@ export const ResultMapSchema = {
|
|
|
215
215
|
description: 'Total profit and loss in the output currency',
|
|
216
216
|
example: 42.75
|
|
217
217
|
},
|
|
218
|
+
pnlTotalPercent: {
|
|
219
|
+
type: 'number',
|
|
220
|
+
format: 'double',
|
|
221
|
+
description: 'Total PnL as a percentage of the initial capital (`backtestFunding`). Zero when `backtestFunding` is 0.',
|
|
222
|
+
example: 42.75
|
|
223
|
+
},
|
|
218
224
|
totalTrades: {
|
|
219
225
|
type: 'integer',
|
|
220
226
|
format: 'int64',
|
|
@@ -257,6 +263,27 @@ export const ResultMapSchema = {
|
|
|
257
263
|
description: 'Maximum percentage drawdown from peak equity',
|
|
258
264
|
example: 8.75
|
|
259
265
|
},
|
|
266
|
+
equityCurve: {
|
|
267
|
+
type: 'array',
|
|
268
|
+
description: "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.",
|
|
269
|
+
items: {
|
|
270
|
+
'$ref': '#/components/schemas/EquityPoint'
|
|
271
|
+
},
|
|
272
|
+
example: [
|
|
273
|
+
{
|
|
274
|
+
timestamp: 1700000000000,
|
|
275
|
+
equity: 100
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
timestamp: 1700000060000,
|
|
279
|
+
equity: 110.5
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
timestamp: 1700000120000,
|
|
283
|
+
equity: 90.25
|
|
284
|
+
}
|
|
285
|
+
]
|
|
286
|
+
},
|
|
260
287
|
signalCount: {
|
|
261
288
|
type: 'integer',
|
|
262
289
|
description: 'Number of signals emitted during strategy execution',
|
|
@@ -293,8 +320,80 @@ export const ResultMapSchema = {
|
|
|
293
320
|
}
|
|
294
321
|
} as const;
|
|
295
322
|
|
|
323
|
+
export const EquityPointSchema = {
|
|
324
|
+
type: 'object',
|
|
325
|
+
description: 'Single sample of the running equity at a yield event.',
|
|
326
|
+
required: ['timestamp', 'equity'],
|
|
327
|
+
properties: {
|
|
328
|
+
timestamp: {
|
|
329
|
+
type: 'integer',
|
|
330
|
+
format: 'int64',
|
|
331
|
+
description: 'Epoch milliseconds. The first point in an equity curve is anchored at the backtest `from`; subsequent points carry the timestamp of each emitted yield.',
|
|
332
|
+
example: 1700000000000
|
|
333
|
+
},
|
|
334
|
+
equity: {
|
|
335
|
+
type: 'number',
|
|
336
|
+
format: 'double',
|
|
337
|
+
description: 'Running equity at this point (`initialCapital + cumulativePnl`).',
|
|
338
|
+
example: 110.5
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
} as const;
|
|
342
|
+
|
|
296
343
|
export const strategyIdSchema = {
|
|
297
344
|
description: 'Unique identifier for a compiled strategy',
|
|
298
345
|
type: 'string',
|
|
299
346
|
example: '6bsh31ikwkuivhtgcoa6s4'
|
|
347
|
+
} as const;
|
|
348
|
+
|
|
349
|
+
export const AuthTokenResponseSchema = {
|
|
350
|
+
type: 'object',
|
|
351
|
+
required: ['access_token', 'token_type', 'expires_in', 'tier'],
|
|
352
|
+
properties: {
|
|
353
|
+
access_token: {
|
|
354
|
+
type: 'string',
|
|
355
|
+
description: 'Short-lived HS256 JWT. Send as `Authorization: Bearer <token>` on all other endpoints.'
|
|
356
|
+
},
|
|
357
|
+
token_type: {
|
|
358
|
+
type: 'string',
|
|
359
|
+
enum: ['Bearer'],
|
|
360
|
+
description: 'Always `Bearer`.'
|
|
361
|
+
},
|
|
362
|
+
expires_in: {
|
|
363
|
+
type: 'integer',
|
|
364
|
+
description: 'Seconds until the JWT expires (typically 3600).',
|
|
365
|
+
example: 3600
|
|
366
|
+
},
|
|
367
|
+
scopes: {
|
|
368
|
+
type: 'array',
|
|
369
|
+
description: 'Scopes granted to this token. Reserved for future use; currently always empty.',
|
|
370
|
+
items: {
|
|
371
|
+
type: 'string'
|
|
372
|
+
},
|
|
373
|
+
example: []
|
|
374
|
+
},
|
|
375
|
+
tier: {
|
|
376
|
+
type: 'string',
|
|
377
|
+
enum: ['free', 'basic', 'pro', 'elite'],
|
|
378
|
+
description: 'Subscription tier this token was issued for. Drives rate limits and feature flags on downstream endpoints.',
|
|
379
|
+
example: 'free'
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
} as const;
|
|
383
|
+
|
|
384
|
+
export const AuthTokenErrorSchema = {
|
|
385
|
+
type: 'object',
|
|
386
|
+
required: ['code', 'message'],
|
|
387
|
+
description: 'Error envelope returned by `POST /auth/token` when the API key is rejected.',
|
|
388
|
+
properties: {
|
|
389
|
+
code: {
|
|
390
|
+
type: 'string',
|
|
391
|
+
enum: ['invalid_apikey', 'apikey_revoked', 'apikey_expired'],
|
|
392
|
+
description: 'Machine-readable error reason.'
|
|
393
|
+
},
|
|
394
|
+
message: {
|
|
395
|
+
type: 'string',
|
|
396
|
+
description: 'Human-readable description of the failure.'
|
|
397
|
+
}
|
|
398
|
+
}
|
|
300
399
|
} as const;
|
package/src/generated/sdk.gen.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
2
|
|
|
3
3
|
import type { Options as ClientOptions, TDataShape, Client } from '@hey-api/client-fetch';
|
|
4
|
-
import type { GetExchangesData, GetExchangesResponse, GetInstrumentsData, GetInstrumentsResponse, GetInstrumentsError, GetExchangeTickersHourData, GetExchangeTickersHourResponse, GetExchangeTickersHourError, GetExchangeKlinesHourData, GetExchangeKlinesHourResponse, GetExchangeKlinesHourError, PostStrategyData, PostStrategyResponse, PostStrategyError, GetStrategyStatusData, GetStrategyStatusResponse, GetStrategyStatusError, PrepareBacktestingData, PrepareBacktestingResponse, PrepareBacktestingError, GetPreparationStatusData, GetPreparationStatusResponse, GetPreparationStatusError, ExecuteBacktestingData, ExecuteBacktestingResponse, ExecuteBacktestingError, CancelExecutionData, CancelExecutionResponse, CancelExecutionError, GetExecutionResultData, GetExecutionResultResponse, GetExecutionResultError } from './types.gen';
|
|
4
|
+
import type { AuthData, AuthResponse, AuthError, GetExchangesData, GetExchangesResponse, GetInstrumentsData, GetInstrumentsResponse, GetInstrumentsError, GetExchangeTickersHourData, GetExchangeTickersHourResponse, GetExchangeTickersHourError, GetExchangeKlinesHourData, GetExchangeKlinesHourResponse, GetExchangeKlinesHourError, PostStrategyData, PostStrategyResponse, PostStrategyError, GetStrategyStatusData, GetStrategyStatusResponse, GetStrategyStatusError, PrepareBacktestingData, PrepareBacktestingResponse, PrepareBacktestingError, GetPreparationStatusData, GetPreparationStatusResponse, GetPreparationStatusError, ExecuteBacktestingData, ExecuteBacktestingResponse, ExecuteBacktestingError, CancelExecutionData, CancelExecutionResponse, CancelExecutionError, GetExecutionResultData, GetExecutionResultResponse, GetExecutionResultError } from './types.gen';
|
|
5
5
|
import { client as _heyApiClient } from './client.gen';
|
|
6
6
|
|
|
7
7
|
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = ClientOptions<TData, ThrowOnError> & {
|
|
@@ -18,6 +18,31 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
|
|
|
18
18
|
meta?: Record<string, unknown>;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Exchange API key for a short-lived JWT
|
|
23
|
+
* Exchanges a long-lived API key for a short-lived JWT used by every other
|
|
24
|
+
* endpoint. This is the only endpoint that accepts an API key directly —
|
|
25
|
+
* callers should obtain a JWT here, then send it as `Authorization: Bearer
|
|
26
|
+
* <token>` to all other operations.
|
|
27
|
+
*
|
|
28
|
+
* The returned JWT carries the caller's subscription `tier` as a claim and
|
|
29
|
+
* expires after `expires_in` seconds. Callers should refresh the token
|
|
30
|
+
* before expiry (or on a `401` response) by calling this endpoint again.
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
33
|
+
export const auth = <ThrowOnError extends boolean = false>(options?: Options<AuthData, ThrowOnError>) => {
|
|
34
|
+
return (options?.client ?? _heyApiClient).post<AuthResponse, AuthError, ThrowOnError>({
|
|
35
|
+
security: [
|
|
36
|
+
{
|
|
37
|
+
name: 'X-API-Key',
|
|
38
|
+
type: 'apiKey'
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
url: '/auth/token',
|
|
42
|
+
...options
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
21
46
|
/**
|
|
22
47
|
* Get a list of available exchanges
|
|
23
48
|
*/
|
|
@@ -135,7 +135,7 @@ export type BacktestJobResult = {
|
|
|
135
135
|
};
|
|
136
136
|
|
|
137
137
|
/**
|
|
138
|
-
* Execution result map. Always includes core fields (hostName, iops, strategyId, instrument). Yield metrics (pnlTotal, totalTrades, winRate, etc.) are present when the strategy emitted at least one trade. When signal storage is enabled, includes signal fields described below.
|
|
138
|
+
* Execution result map. Always includes core fields (hostName, iops, strategyId, instrument). Yield metrics (pnlTotal, pnlTotalPercent, totalTrades, winRate, equityCurve, etc.) are present when the strategy emitted at least one trade. When signal storage is enabled, includes signal fields described below.
|
|
139
139
|
*/
|
|
140
140
|
export type ResultMap = {
|
|
141
141
|
/**
|
|
@@ -158,6 +158,10 @@ export type ResultMap = {
|
|
|
158
158
|
* Total profit and loss in the output currency
|
|
159
159
|
*/
|
|
160
160
|
pnlTotal?: number;
|
|
161
|
+
/**
|
|
162
|
+
* Total PnL as a percentage of the initial capital (`backtestFunding`). Zero when `backtestFunding` is 0.
|
|
163
|
+
*/
|
|
164
|
+
pnlTotalPercent?: number;
|
|
161
165
|
/**
|
|
162
166
|
* Total number of trades executed by the strategy
|
|
163
167
|
*/
|
|
@@ -186,6 +190,10 @@ export type ResultMap = {
|
|
|
186
190
|
* Maximum percentage drawdown from peak equity
|
|
187
191
|
*/
|
|
188
192
|
maxDrawdownPercent?: number;
|
|
193
|
+
/**
|
|
194
|
+
* 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.
|
|
195
|
+
*/
|
|
196
|
+
equityCurve?: Array<EquityPoint>;
|
|
189
197
|
/**
|
|
190
198
|
* Number of signals emitted during strategy execution
|
|
191
199
|
*/
|
|
@@ -212,11 +220,91 @@ export type ResultMap = {
|
|
|
212
220
|
signalsUploadReason?: string;
|
|
213
221
|
};
|
|
214
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Single sample of the running equity at a yield event.
|
|
225
|
+
*/
|
|
226
|
+
export type EquityPoint = {
|
|
227
|
+
/**
|
|
228
|
+
* Epoch milliseconds. The first point in an equity curve is anchored at the backtest `from`; subsequent points carry the timestamp of each emitted yield.
|
|
229
|
+
*/
|
|
230
|
+
timestamp: number;
|
|
231
|
+
/**
|
|
232
|
+
* Running equity at this point (`initialCapital + cumulativePnl`).
|
|
233
|
+
*/
|
|
234
|
+
equity: number;
|
|
235
|
+
};
|
|
236
|
+
|
|
215
237
|
/**
|
|
216
238
|
* Unique identifier for a compiled strategy
|
|
217
239
|
*/
|
|
218
240
|
export type StrategyId = string;
|
|
219
241
|
|
|
242
|
+
export type AuthTokenResponse = {
|
|
243
|
+
/**
|
|
244
|
+
* Short-lived HS256 JWT. Send as `Authorization: Bearer <token>` on all other endpoints.
|
|
245
|
+
*/
|
|
246
|
+
access_token: string;
|
|
247
|
+
/**
|
|
248
|
+
* Always `Bearer`.
|
|
249
|
+
*/
|
|
250
|
+
token_type: 'Bearer';
|
|
251
|
+
/**
|
|
252
|
+
* Seconds until the JWT expires (typically 3600).
|
|
253
|
+
*/
|
|
254
|
+
expires_in: number;
|
|
255
|
+
/**
|
|
256
|
+
* Scopes granted to this token. Reserved for future use; currently always empty.
|
|
257
|
+
*/
|
|
258
|
+
scopes?: Array<string>;
|
|
259
|
+
/**
|
|
260
|
+
* Subscription tier this token was issued for. Drives rate limits and feature flags on downstream endpoints.
|
|
261
|
+
*/
|
|
262
|
+
tier: 'free' | 'basic' | 'pro' | 'elite';
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Error envelope returned by `POST /auth/token` when the API key is rejected.
|
|
267
|
+
*/
|
|
268
|
+
export type AuthTokenError = {
|
|
269
|
+
/**
|
|
270
|
+
* Machine-readable error reason.
|
|
271
|
+
*/
|
|
272
|
+
code: 'invalid_apikey' | 'apikey_revoked' | 'apikey_expired';
|
|
273
|
+
/**
|
|
274
|
+
* Human-readable description of the failure.
|
|
275
|
+
*/
|
|
276
|
+
message: string;
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
export type AuthData = {
|
|
280
|
+
body?: never;
|
|
281
|
+
path?: never;
|
|
282
|
+
query?: never;
|
|
283
|
+
url: '/auth/token';
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
export type AuthErrors = {
|
|
287
|
+
/**
|
|
288
|
+
* API key is invalid, revoked, or expired.
|
|
289
|
+
*/
|
|
290
|
+
401: AuthTokenError;
|
|
291
|
+
/**
|
|
292
|
+
* Rate limit exceeded for this API key.
|
|
293
|
+
*/
|
|
294
|
+
429: unknown;
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
export type AuthError = AuthErrors[keyof AuthErrors];
|
|
298
|
+
|
|
299
|
+
export type AuthResponses = {
|
|
300
|
+
/**
|
|
301
|
+
* API key accepted; JWT returned.
|
|
302
|
+
*/
|
|
303
|
+
200: AuthTokenResponse;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
export type AuthResponse = AuthResponses[keyof AuthResponses];
|
|
307
|
+
|
|
220
308
|
export type GetExchangesData = {
|
|
221
309
|
body?: never;
|
|
222
310
|
path?: never;
|