@qtsurfer/api-client 0.1.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.
@@ -0,0 +1,588 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+
3
+ /**
4
+ * General response error
5
+ */
6
+ export type ResponseError = {
7
+ /**
8
+ * Status code
9
+ */
10
+ code: number;
11
+ /**
12
+ * Error description
13
+ */
14
+ message: string;
15
+ };
16
+
17
+ /**
18
+ * Exchange instrument identifier (e.g. a currency pair)
19
+ */
20
+ export type Instrument = string;
21
+
22
+ /**
23
+ * Exchange instrument with data availability and market info
24
+ */
25
+ export type InstrumentDetail = {
26
+ /**
27
+ * Instrument identifier (e.g. currency pair)
28
+ */
29
+ id: string;
30
+ /**
31
+ * Base currency
32
+ */
33
+ base: string;
34
+ /**
35
+ * Quote currency
36
+ */
37
+ quote: string;
38
+ /**
39
+ * Earliest timestamp with quality-verified data available for backtesting
40
+ */
41
+ dataFrom?: string;
42
+ /**
43
+ * Latest timestamp with quality-verified data available for backtesting
44
+ */
45
+ dataTo?: string;
46
+ /**
47
+ * Last traded price
48
+ */
49
+ lastPrice?: number;
50
+ /**
51
+ * Trading volume in the last 24 hours (in quote currency)
52
+ */
53
+ volume24h?: number;
54
+ };
55
+
56
+ /**
57
+ * Exchange service provider
58
+ */
59
+ export type Exchange = {
60
+ /**
61
+ * Unique identifier for the exchange
62
+ */
63
+ id: string;
64
+ /**
65
+ * Name of the exchange
66
+ */
67
+ name: string;
68
+ /**
69
+ * Description of the exchange
70
+ */
71
+ description?: string;
72
+ };
73
+
74
+ /**
75
+ * Managed exchange data sources available for backtesting. Currently only ticker is supported; kline and funding rate support is planned.
76
+ */
77
+ export type DataSourceType = 'ticker';
78
+
79
+ /**
80
+ * Information about a single job
81
+ */
82
+ export type JobState = {
83
+ /**
84
+ * Unique context ID for the job
85
+ */
86
+ contextId: string;
87
+ /**
88
+ * Current status of the job
89
+ */
90
+ status: 'New' | 'Started' | 'Completed' | 'Aborted' | 'Failed';
91
+ /**
92
+ * Detailed status information, if available
93
+ */
94
+ statusDetail?: string | null;
95
+ /**
96
+ * Total size of the data being prepared
97
+ */
98
+ size: number;
99
+ /**
100
+ * The amount of data processed so far
101
+ */
102
+ completed: number;
103
+ /**
104
+ * Timestamp for when the preparation started
105
+ */
106
+ startTime?: string | null;
107
+ /**
108
+ * Timestamp for when the preparation finished
109
+ */
110
+ endTime?: string | null;
111
+ };
112
+
113
+ /**
114
+ * Response returned by async endpoints (`202 Accepted`). The `jobId` is deterministic for the
115
+ * same input parameters — repeated calls with identical params return the same id.
116
+ *
117
+ */
118
+ export type AcceptedJob = {
119
+ /**
120
+ * Unique job identifier; use this to poll for completion.
121
+ */
122
+ jobId: string;
123
+ };
124
+
125
+ /**
126
+ * Backtest job result.
127
+ */
128
+ export type BacktestJobResult = {
129
+ results: ResultMap;
130
+ state: JobState;
131
+ };
132
+
133
+ /**
134
+ * 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.
135
+ */
136
+ export type ResultMap = {
137
+ /**
138
+ * Hostname of the worker node that executed the strategy
139
+ */
140
+ hostName?: string;
141
+ /**
142
+ * Instrument operations per second throughput during execution
143
+ */
144
+ iops?: number;
145
+ /**
146
+ * Redis key of the compiled strategy used for execution. Format: strategy:{userId}:ticker:{compilationId}
147
+ */
148
+ strategyId: string;
149
+ /**
150
+ * The instrument (currency pair) that was backtested
151
+ */
152
+ instrument: string;
153
+ /**
154
+ * Total profit and loss in the output currency
155
+ */
156
+ pnlTotal?: number;
157
+ /**
158
+ * Total number of trades executed by the strategy
159
+ */
160
+ totalTrades?: number;
161
+ /**
162
+ * Percentage of profitable trades (0-100)
163
+ */
164
+ winRate?: number;
165
+ /**
166
+ * Risk-adjusted return ratio (mean return / standard deviation of returns)
167
+ */
168
+ sharpeRatio?: number;
169
+ /**
170
+ * Downside risk-adjusted return ratio (mean return / downside deviation)
171
+ */
172
+ sortinoRatio?: number;
173
+ /**
174
+ * Compound Annual Growth Rate
175
+ */
176
+ cagr?: number;
177
+ /**
178
+ * Maximum absolute drawdown in the output currency
179
+ */
180
+ maxDrawdown?: number;
181
+ /**
182
+ * Maximum percentage drawdown from peak equity
183
+ */
184
+ maxDrawdownPercent?: number;
185
+ /**
186
+ * Number of signals emitted during strategy execution
187
+ */
188
+ signalCount?: number;
189
+ /**
190
+ * Storage key for the signal Parquet file. Format: {userId}/exec/{exchange}/{jobId}
191
+ */
192
+ signalsId?: string;
193
+ /**
194
+ * Public HTTPS URL to the Parquet file. Computed at setup time from publicBaseUrl + signalsId + .parquet. Available even before upload completes.
195
+ */
196
+ signalsUrl?: string;
197
+ /**
198
+ * Upload status. Done = file uploaded to R2. Failed = upload error (see signalsUploadReason). Skipped = no signals emitted or storage not configured.
199
+ */
200
+ signalsUpload?: 'Done' | 'Failed' | 'Skipped';
201
+ /**
202
+ * ISO 8601 timestamp of when the upload completed. Only present when signalsUpload is Done.
203
+ */
204
+ signalsUploadedAt?: string;
205
+ /**
206
+ * Human-readable reason when signalsUpload is Failed or Skipped.
207
+ */
208
+ signalsUploadReason?: string;
209
+ };
210
+
211
+ /**
212
+ * Unique identifier for a compiled strategy
213
+ */
214
+ export type StrategyId = string;
215
+
216
+ export type GetExchangesData = {
217
+ body?: never;
218
+ path?: never;
219
+ query?: never;
220
+ url: '/exchanges';
221
+ };
222
+
223
+ export type GetExchangesResponses = {
224
+ /**
225
+ * A JSON array of Exchanges
226
+ */
227
+ 200: Array<Exchange>;
228
+ };
229
+
230
+ export type GetExchangesResponse = GetExchangesResponses[keyof GetExchangesResponses];
231
+
232
+ export type GetInstrumentsData = {
233
+ body?: never;
234
+ path: {
235
+ /**
236
+ * ID of the exchange to retrieve instruments for
237
+ */
238
+ exchangeId: string;
239
+ };
240
+ query?: never;
241
+ url: '/exchange/{exchangeId}/instruments';
242
+ };
243
+
244
+ export type GetInstrumentsErrors = {
245
+ /**
246
+ * Exchange not found or instrument catalog not available
247
+ */
248
+ 404: ResponseError;
249
+ };
250
+
251
+ export type GetInstrumentsError = GetInstrumentsErrors[keyof GetInstrumentsErrors];
252
+
253
+ export type GetInstrumentsResponses = {
254
+ /**
255
+ * A JSON array of Instrument details with data availability
256
+ */
257
+ 200: Array<InstrumentDetail>;
258
+ };
259
+
260
+ export type GetInstrumentsResponse = GetInstrumentsResponses[keyof GetInstrumentsResponses];
261
+
262
+ export type PostStrategyData = {
263
+ /**
264
+ * Raw strategy Java source code
265
+ */
266
+ body: string;
267
+ headers?: {
268
+ /**
269
+ * When `true`, compile asynchronously and return `202` with a `jobId`.
270
+ */
271
+ 'X-Compile-Async'?: boolean;
272
+ };
273
+ path?: never;
274
+ query?: never;
275
+ url: '/strategy';
276
+ };
277
+
278
+ export type PostStrategyErrors = {
279
+ /**
280
+ * Invalid strategy (compilation error)
281
+ */
282
+ 400: ResponseError;
283
+ };
284
+
285
+ export type PostStrategyError = PostStrategyErrors[keyof PostStrategyErrors];
286
+
287
+ export type PostStrategyResponses = {
288
+ /**
289
+ * Strategy compiled successfully (sync mode)
290
+ */
291
+ 200: {
292
+ strategyId: StrategyId;
293
+ };
294
+ /**
295
+ * Compile task accepted (async mode — set `X-Compile-Async: true`)
296
+ */
297
+ 202: AcceptedJob;
298
+ };
299
+
300
+ export type PostStrategyResponse = PostStrategyResponses[keyof PostStrategyResponses];
301
+
302
+ export type GetStrategyStatusData = {
303
+ body?: never;
304
+ path: {
305
+ /**
306
+ * The id returned by `POST /strategy` (sync) or the `jobId` returned in async mode
307
+ */
308
+ strategyId: string;
309
+ };
310
+ query?: never;
311
+ url: '/strategy/{strategyId}';
312
+ };
313
+
314
+ export type GetStrategyStatusErrors = {
315
+ /**
316
+ * Strategy compile job not found
317
+ */
318
+ 404: ResponseError;
319
+ };
320
+
321
+ export type GetStrategyStatusError = GetStrategyStatusErrors[keyof GetStrategyStatusErrors];
322
+
323
+ export type GetStrategyStatusResponses = {
324
+ /**
325
+ * Strategy compile state
326
+ */
327
+ 200: {
328
+ /**
329
+ * Compile job id (only set in async mode)
330
+ */
331
+ jobId?: string;
332
+ status: 'New' | 'Started' | 'Completed' | 'Aborted' | 'Failed';
333
+ strategyId?: StrategyId;
334
+ /**
335
+ * Compilation error messages when `status` is `Failed`
336
+ */
337
+ statusDetail?: string | null;
338
+ };
339
+ };
340
+
341
+ export type GetStrategyStatusResponse = GetStrategyStatusResponses[keyof GetStrategyStatusResponses];
342
+
343
+ export type PrepareBacktestingData = {
344
+ /**
345
+ * The required data to prepare a backtesting
346
+ */
347
+ body: {
348
+ instrument: Instrument;
349
+ /**
350
+ * Start date for the preparation process. Supports the following formats:
351
+ * - ISO-8601 (e.g. 2024-12-14T23:59:59Z)
352
+ * - ISO DATE (e.g. 2024-12-14)
353
+ * - BASIC ISO DATE (e.g., 20241214)
354
+ *
355
+ */
356
+ from: string;
357
+ /**
358
+ * End date for the preparation process. Supports the following formats:
359
+ * - ISO-8601 (e.g. 2024-12-14T23:59:59Z)
360
+ * - ISO DATE (e.g. 2024-12-14)
361
+ * - BASIC ISO DATE (e.g., 20241214)
362
+ *
363
+ */
364
+ to: string;
365
+ };
366
+ path: {
367
+ /**
368
+ * ID of the exchange to prepare the backtesting for
369
+ */
370
+ exchangeId: string;
371
+ /**
372
+ * The type of data source to prepare from
373
+ */
374
+ type: DataSourceType;
375
+ };
376
+ query?: never;
377
+ url: '/backtest/{exchangeId}/{type}/prepare';
378
+ };
379
+
380
+ export type PrepareBacktestingErrors = {
381
+ /**
382
+ * Invalid request or parameters. Also returned when `from` is older than the configured
383
+ * lookback window or `to` is in the future.
384
+ *
385
+ */
386
+ 400: ResponseError;
387
+ /**
388
+ * Exchange or data source type not found
389
+ */
390
+ 404: ResponseError;
391
+ /**
392
+ * Rate limited. Returned when the global queue exceeds capacity or the user has too many
393
+ * active backtests.
394
+ *
395
+ */
396
+ 429: ResponseError;
397
+ };
398
+
399
+ export type PrepareBacktestingError = PrepareBacktestingErrors[keyof PrepareBacktestingErrors];
400
+
401
+ export type PrepareBacktestingResponses = {
402
+ /**
403
+ * Prepare task accepted (queued for processing)
404
+ */
405
+ 202: AcceptedJob;
406
+ };
407
+
408
+ export type PrepareBacktestingResponse = PrepareBacktestingResponses[keyof PrepareBacktestingResponses];
409
+
410
+ export type GetPreparationStatusData = {
411
+ body?: never;
412
+ path: {
413
+ /**
414
+ * ID of the exchange for the backtesting process
415
+ */
416
+ exchangeId: string;
417
+ /**
418
+ * The type of data source to prepare from
419
+ */
420
+ type: DataSourceType;
421
+ /**
422
+ * Job ID returned by `POST /prepare`
423
+ */
424
+ jobId: string;
425
+ };
426
+ query?: never;
427
+ url: '/backtest/{exchangeId}/{type}/prepare/{jobId}';
428
+ };
429
+
430
+ export type GetPreparationStatusErrors = {
431
+ /**
432
+ * Invalid request or parameters
433
+ */
434
+ 400: ResponseError;
435
+ /**
436
+ * Prepare job not found or expired
437
+ */
438
+ 404: ResponseError;
439
+ };
440
+
441
+ export type GetPreparationStatusError = GetPreparationStatusErrors[keyof GetPreparationStatusErrors];
442
+
443
+ export type GetPreparationStatusResponses = {
444
+ /**
445
+ * Current prepare job state
446
+ */
447
+ 200: JobState;
448
+ };
449
+
450
+ export type GetPreparationStatusResponse = GetPreparationStatusResponses[keyof GetPreparationStatusResponses];
451
+
452
+ export type ExecuteBacktestingData = {
453
+ /**
454
+ * Execute task parameters
455
+ */
456
+ body: {
457
+ /**
458
+ * Job ID returned by `POST /prepare` (must be in `Completed` state)
459
+ */
460
+ prepareJobId: string;
461
+ strategyId: StrategyId;
462
+ /**
463
+ * When true, the worker uploads emitted signals to object storage and the
464
+ * response includes `signalsUrl` / `signalsId` fields. Defaults to false.
465
+ *
466
+ */
467
+ storeSignals?: boolean;
468
+ };
469
+ path: {
470
+ /**
471
+ * ID of the exchange for the backtesting process
472
+ */
473
+ exchangeId: string;
474
+ /**
475
+ * The type of data source to execute from
476
+ */
477
+ type: DataSourceType;
478
+ };
479
+ query?: never;
480
+ url: '/backtest/{exchangeId}/{type}/execute';
481
+ };
482
+
483
+ export type ExecuteBacktestingErrors = {
484
+ /**
485
+ * Invalid request or parameters
486
+ */
487
+ 400: ResponseError;
488
+ /**
489
+ * Prepare job not found or expired
490
+ */
491
+ 404: ResponseError;
492
+ /**
493
+ * Rate limited (global queue at capacity or per-user limit reached)
494
+ */
495
+ 429: ResponseError;
496
+ };
497
+
498
+ export type ExecuteBacktestingError = ExecuteBacktestingErrors[keyof ExecuteBacktestingErrors];
499
+
500
+ export type ExecuteBacktestingResponses = {
501
+ /**
502
+ * Execute task accepted (queued for processing)
503
+ */
504
+ 202: AcceptedJob;
505
+ };
506
+
507
+ export type ExecuteBacktestingResponse = ExecuteBacktestingResponses[keyof ExecuteBacktestingResponses];
508
+
509
+ export type CancelExecutionData = {
510
+ body?: never;
511
+ path: {
512
+ exchangeId: string;
513
+ type: DataSourceType;
514
+ /**
515
+ * Job ID returned by `POST /execute`
516
+ */
517
+ jobId: string;
518
+ };
519
+ query?: never;
520
+ url: '/backtest/{exchangeId}/{type}/execute/{jobId}';
521
+ };
522
+
523
+ export type CancelExecutionErrors = {
524
+ /**
525
+ * Execution not found
526
+ */
527
+ 404: ResponseError;
528
+ };
529
+
530
+ export type CancelExecutionError = CancelExecutionErrors[keyof CancelExecutionErrors];
531
+
532
+ export type CancelExecutionResponses = {
533
+ /**
534
+ * Cancellation request accepted
535
+ */
536
+ 200: {
537
+ status?: 'cancelling';
538
+ jobId?: string;
539
+ };
540
+ };
541
+
542
+ export type CancelExecutionResponse = CancelExecutionResponses[keyof CancelExecutionResponses];
543
+
544
+ export type GetExecutionResultData = {
545
+ body?: never;
546
+ path: {
547
+ /**
548
+ * ID of the exchange for the backtesting process
549
+ */
550
+ exchangeId: string;
551
+ /**
552
+ * The type of data source to execute from
553
+ */
554
+ type: DataSourceType;
555
+ /**
556
+ * Job ID returned by `POST /execute`
557
+ */
558
+ jobId: string;
559
+ };
560
+ query?: never;
561
+ url: '/backtest/{exchangeId}/{type}/execute/{jobId}';
562
+ };
563
+
564
+ export type GetExecutionResultErrors = {
565
+ /**
566
+ * Invalid request or parameters
567
+ */
568
+ 400: ResponseError;
569
+ /**
570
+ * Execution job not found
571
+ */
572
+ 404: ResponseError;
573
+ };
574
+
575
+ export type GetExecutionResultError = GetExecutionResultErrors[keyof GetExecutionResultErrors];
576
+
577
+ export type GetExecutionResultResponses = {
578
+ /**
579
+ * Backtesting execution result
580
+ */
581
+ 200: BacktestJobResult;
582
+ };
583
+
584
+ export type GetExecutionResultResponse = GetExecutionResultResponses[keyof GetExecutionResultResponses];
585
+
586
+ export type ClientOptions = {
587
+ baseUrl: 'https://api.staging.qtsurfer.com/v1' | 'https://api.qtsurfer.com/v1' | (string & {});
588
+ };
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './generated';
2
+ export { client } from './generated/client.gen';