qtsurfer-api-client 0.98.0__py3-none-any.whl

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.
Files changed (74) hide show
  1. qtsurfer/__init__.py +0 -0
  2. qtsurfer/api/__init__.py +0 -0
  3. qtsurfer/api/client/__init__.py +38 -0
  4. qtsurfer/api/client/_generated/__init__.py +8 -0
  5. qtsurfer/api/client/_generated/api/__init__.py +1 -0
  6. qtsurfer/api/client/_generated/api/auth/__init__.py +1 -0
  7. qtsurfer/api/client/_generated/api/auth/auth.py +174 -0
  8. qtsurfer/api/client/_generated/api/backtesting/__init__.py +1 -0
  9. qtsurfer/api/client/_generated/api/backtesting/cancel_execution.py +214 -0
  10. qtsurfer/api/client/_generated/api/backtesting/execute_backtesting.py +251 -0
  11. qtsurfer/api/client/_generated/api/backtesting/get_execution_result.py +211 -0
  12. qtsurfer/api/client/_generated/api/backtesting/get_preparation_status.py +211 -0
  13. qtsurfer/api/client/_generated/api/backtesting/prepare_backtesting.py +235 -0
  14. qtsurfer/api/client/_generated/api/exchange/__init__.py +1 -0
  15. qtsurfer/api/client/_generated/api/exchange/get_exchange_klines_hour.py +269 -0
  16. qtsurfer/api/client/_generated/api/exchange/get_exchange_tickers_hour.py +349 -0
  17. qtsurfer/api/client/_generated/api/exchange/get_exchanges.py +129 -0
  18. qtsurfer/api/client/_generated/api/exchange/get_instruments.py +181 -0
  19. qtsurfer/api/client/_generated/api/exchange/get_segment_instruments.py +196 -0
  20. qtsurfer/api/client/_generated/api/strategy/__init__.py +1 -0
  21. qtsurfer/api/client/_generated/api/strategy/get_strategy_status.py +173 -0
  22. qtsurfer/api/client/_generated/client.py +268 -0
  23. qtsurfer/api/client/_generated/errors.py +16 -0
  24. qtsurfer/api/client/_generated/models/__init__.py +79 -0
  25. qtsurfer/api/client/_generated/models/accepted_job.py +66 -0
  26. qtsurfer/api/client/_generated/models/auth_token_error.py +72 -0
  27. qtsurfer/api/client/_generated/models/auth_token_error_code.py +10 -0
  28. qtsurfer/api/client/_generated/models/auth_token_response.py +101 -0
  29. qtsurfer/api/client/_generated/models/auth_token_response_tier.py +11 -0
  30. qtsurfer/api/client/_generated/models/auth_token_response_token_type.py +8 -0
  31. qtsurfer/api/client/_generated/models/backtest_job_result.py +80 -0
  32. qtsurfer/api/client/_generated/models/cancel_execution_response_200.py +78 -0
  33. qtsurfer/api/client/_generated/models/cancel_execution_response_200_status.py +8 -0
  34. qtsurfer/api/client/_generated/models/coverage_window.py +105 -0
  35. qtsurfer/api/client/_generated/models/data_source_type.py +8 -0
  36. qtsurfer/api/client/_generated/models/equity_point.py +71 -0
  37. qtsurfer/api/client/_generated/models/exchange.py +81 -0
  38. qtsurfer/api/client/_generated/models/execute_backtesting_body.py +83 -0
  39. qtsurfer/api/client/_generated/models/get_exchange_klines_hour_format.py +9 -0
  40. qtsurfer/api/client/_generated/models/get_exchange_tickers_hour_format.py +9 -0
  41. qtsurfer/api/client/_generated/models/get_segment_instruments_segment.py +9 -0
  42. qtsurfer/api/client/_generated/models/get_strategy_status_response_200.py +102 -0
  43. qtsurfer/api/client/_generated/models/get_strategy_status_response_200_status.py +12 -0
  44. qtsurfer/api/client/_generated/models/hal_link.py +74 -0
  45. qtsurfer/api/client/_generated/models/instrument_coverage.py +91 -0
  46. qtsurfer/api/client/_generated/models/instrument_detail.py +120 -0
  47. qtsurfer/api/client/_generated/models/instrument_links.py +102 -0
  48. qtsurfer/api/client/_generated/models/instrument_list_meta.py +82 -0
  49. qtsurfer/api/client/_generated/models/instrument_list_meta_segment.py +9 -0
  50. qtsurfer/api/client/_generated/models/instrument_list_response.py +96 -0
  51. qtsurfer/api/client/_generated/models/job_state.py +178 -0
  52. qtsurfer/api/client/_generated/models/job_state_status.py +12 -0
  53. qtsurfer/api/client/_generated/models/post_strategy_response_200.py +61 -0
  54. qtsurfer/api/client/_generated/models/prepare_backtesting_body.py +110 -0
  55. qtsurfer/api/client/_generated/models/prepare_backtesting_body_cadence.py +15 -0
  56. qtsurfer/api/client/_generated/models/prepare_job_state.py +302 -0
  57. qtsurfer/api/client/_generated/models/prepare_job_state_hours_without_data_item.py +101 -0
  58. qtsurfer/api/client/_generated/models/prepare_job_state_hours_without_data_item_rationale.py +10 -0
  59. qtsurfer/api/client/_generated/models/response_error.py +70 -0
  60. qtsurfer/api/client/_generated/models/result_map.py +286 -0
  61. qtsurfer/api/client/_generated/models/result_map_signals_upload.py +10 -0
  62. qtsurfer/api/client/_generated/py.typed +1 -0
  63. qtsurfer/api/client/_generated/types.py +54 -0
  64. qtsurfer/api/client/api/__init__.py +11 -0
  65. qtsurfer/api/client/api/auth.py +5 -0
  66. qtsurfer/api/client/api/backtesting.py +17 -0
  67. qtsurfer/api/client/api/exchange.py +15 -0
  68. qtsurfer/api/client/api/strategy.py +11 -0
  69. qtsurfer/api/client/models/__init__.py +9 -0
  70. qtsurfer/api/client/py.typed +0 -0
  71. qtsurfer_api_client-0.98.0.dist-info/METADATA +238 -0
  72. qtsurfer_api_client-0.98.0.dist-info/RECORD +74 -0
  73. qtsurfer_api_client-0.98.0.dist-info/WHEEL +4 -0
  74. qtsurfer_api_client-0.98.0.dist-info/licenses/LICENSE +201 -0
qtsurfer/__init__.py ADDED
File without changes
File without changes
@@ -0,0 +1,38 @@
1
+ """qtsurfer-api-client — auto-generated Python client for the QTSurfer API.
2
+
3
+ Low-level: one function per OpenAPI endpoint. For workflow orchestration
4
+ (``backtest = compile + prepare + execute + poll``), use
5
+ `qtsurfer-sdk <https://github.com/QTSurfer/sdk-python>`_ (coming soon).
6
+
7
+ Public surface (re-exported from the generated package):
8
+
9
+ * :class:`Client` — unauthenticated client (rarely useful in practice).
10
+ * :class:`AuthenticatedClient` — Bearer-token client; pass to every
11
+ endpoint function as ``client=...``.
12
+ * :mod:`qtsurfer.api.client.api` — endpoint modules grouped by tag.
13
+ * :mod:`qtsurfer.api.client.models` — request/response dataclasses.
14
+
15
+ Endpoint modules expose four entry points: ``sync``, ``sync_detailed``,
16
+ ``asyncio``, ``asyncio_detailed``. See the README for examples.
17
+ """
18
+
19
+ from importlib.metadata import PackageNotFoundError, version
20
+
21
+ # Re-export the generated public types.
22
+ from qtsurfer.api.client._generated import api, errors, models, types
23
+ from qtsurfer.api.client._generated.client import AuthenticatedClient, Client
24
+
25
+ try:
26
+ __version__ = version("qtsurfer-api-client")
27
+ except PackageNotFoundError: # pragma: no cover - editable installs in dev
28
+ __version__ = "0.0.0+unknown"
29
+
30
+ __all__ = [
31
+ "AuthenticatedClient",
32
+ "Client",
33
+ "__version__",
34
+ "api",
35
+ "errors",
36
+ "models",
37
+ "types",
38
+ ]
@@ -0,0 +1,8 @@
1
+ """A client library for accessing QTSurfer API"""
2
+
3
+ from .client import AuthenticatedClient, Client
4
+
5
+ __all__ = (
6
+ "AuthenticatedClient",
7
+ "Client",
8
+ )
@@ -0,0 +1 @@
1
+ """Contains methods for accessing the API"""
@@ -0,0 +1 @@
1
+ """Contains endpoint functions for accessing the API"""
@@ -0,0 +1,174 @@
1
+ from http import HTTPStatus
2
+ from typing import Any, cast
3
+
4
+ import httpx
5
+
6
+ from ... import errors
7
+ from ...client import AuthenticatedClient, Client
8
+ from ...models.auth_token_error import AuthTokenError
9
+ from ...models.auth_token_response import AuthTokenResponse
10
+ from ...types import Response
11
+
12
+
13
+ def _get_kwargs() -> dict[str, Any]:
14
+
15
+ _kwargs: dict[str, Any] = {
16
+ "method": "post",
17
+ "url": "/auth/token",
18
+ }
19
+
20
+ return _kwargs
21
+
22
+
23
+ def _parse_response(
24
+ *, client: AuthenticatedClient | Client, response: httpx.Response
25
+ ) -> Any | AuthTokenError | AuthTokenResponse | None:
26
+ if response.status_code == 200:
27
+ response_200 = AuthTokenResponse.from_dict(response.json())
28
+
29
+ return response_200
30
+
31
+ if response.status_code == 401:
32
+ response_401 = AuthTokenError.from_dict(response.json())
33
+
34
+ return response_401
35
+
36
+ if response.status_code == 429:
37
+ response_429 = cast(Any, None)
38
+ return response_429
39
+
40
+ if client.raise_on_unexpected_status:
41
+ raise errors.UnexpectedStatus(response.status_code, response.content)
42
+ else:
43
+ return None
44
+
45
+
46
+ def _build_response(
47
+ *, client: AuthenticatedClient | Client, response: httpx.Response
48
+ ) -> Response[Any | AuthTokenError | AuthTokenResponse]:
49
+ return Response(
50
+ status_code=HTTPStatus(response.status_code),
51
+ content=response.content,
52
+ headers=response.headers,
53
+ parsed=_parse_response(client=client, response=response),
54
+ )
55
+
56
+
57
+ def sync_detailed(
58
+ *,
59
+ client: AuthenticatedClient,
60
+ ) -> Response[Any | AuthTokenError | AuthTokenResponse]:
61
+ """Exchange API key for a short-lived JWT
62
+
63
+ Exchanges a long-lived API key for a short-lived JWT used by every other
64
+ endpoint. This is the only endpoint that accepts an API key directly —
65
+ callers should obtain a JWT here, then send it as `Authorization: Bearer
66
+ <token>` to all other operations.
67
+
68
+ The returned JWT carries the caller's subscription `tier` as a claim and
69
+ expires after `expires_in` seconds. Callers should refresh the token
70
+ before expiry (or on a `401` response) by calling this endpoint again.
71
+
72
+ Raises:
73
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
74
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
75
+
76
+ Returns:
77
+ Response[Any | AuthTokenError | AuthTokenResponse]
78
+ """
79
+
80
+ kwargs = _get_kwargs()
81
+
82
+ response = client.get_httpx_client().request(
83
+ **kwargs,
84
+ )
85
+
86
+ return _build_response(client=client, response=response)
87
+
88
+
89
+ def sync(
90
+ *,
91
+ client: AuthenticatedClient,
92
+ ) -> Any | AuthTokenError | AuthTokenResponse | None:
93
+ """Exchange API key for a short-lived JWT
94
+
95
+ Exchanges a long-lived API key for a short-lived JWT used by every other
96
+ endpoint. This is the only endpoint that accepts an API key directly —
97
+ callers should obtain a JWT here, then send it as `Authorization: Bearer
98
+ <token>` to all other operations.
99
+
100
+ The returned JWT carries the caller's subscription `tier` as a claim and
101
+ expires after `expires_in` seconds. Callers should refresh the token
102
+ before expiry (or on a `401` response) by calling this endpoint again.
103
+
104
+ Raises:
105
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
106
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
107
+
108
+ Returns:
109
+ Any | AuthTokenError | AuthTokenResponse
110
+ """
111
+
112
+ return sync_detailed(
113
+ client=client,
114
+ ).parsed
115
+
116
+
117
+ async def asyncio_detailed(
118
+ *,
119
+ client: AuthenticatedClient,
120
+ ) -> Response[Any | AuthTokenError | AuthTokenResponse]:
121
+ """Exchange API key for a short-lived JWT
122
+
123
+ Exchanges a long-lived API key for a short-lived JWT used by every other
124
+ endpoint. This is the only endpoint that accepts an API key directly —
125
+ callers should obtain a JWT here, then send it as `Authorization: Bearer
126
+ <token>` to all other operations.
127
+
128
+ The returned JWT carries the caller's subscription `tier` as a claim and
129
+ expires after `expires_in` seconds. Callers should refresh the token
130
+ before expiry (or on a `401` response) by calling this endpoint again.
131
+
132
+ Raises:
133
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
134
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
135
+
136
+ Returns:
137
+ Response[Any | AuthTokenError | AuthTokenResponse]
138
+ """
139
+
140
+ kwargs = _get_kwargs()
141
+
142
+ response = await client.get_async_httpx_client().request(**kwargs)
143
+
144
+ return _build_response(client=client, response=response)
145
+
146
+
147
+ async def asyncio(
148
+ *,
149
+ client: AuthenticatedClient,
150
+ ) -> Any | AuthTokenError | AuthTokenResponse | None:
151
+ """Exchange API key for a short-lived JWT
152
+
153
+ Exchanges a long-lived API key for a short-lived JWT used by every other
154
+ endpoint. This is the only endpoint that accepts an API key directly —
155
+ callers should obtain a JWT here, then send it as `Authorization: Bearer
156
+ <token>` to all other operations.
157
+
158
+ The returned JWT carries the caller's subscription `tier` as a claim and
159
+ expires after `expires_in` seconds. Callers should refresh the token
160
+ before expiry (or on a `401` response) by calling this endpoint again.
161
+
162
+ Raises:
163
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
164
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
165
+
166
+ Returns:
167
+ Any | AuthTokenError | AuthTokenResponse
168
+ """
169
+
170
+ return (
171
+ await asyncio_detailed(
172
+ client=client,
173
+ )
174
+ ).parsed
@@ -0,0 +1 @@
1
+ """Contains endpoint functions for accessing the API"""
@@ -0,0 +1,214 @@
1
+ from http import HTTPStatus
2
+ from typing import Any
3
+ from urllib.parse import quote
4
+
5
+ import httpx
6
+
7
+ from ... import errors
8
+ from ...client import AuthenticatedClient, Client
9
+ from ...models.cancel_execution_response_200 import CancelExecutionResponse200
10
+ from ...models.data_source_type import DataSourceType
11
+ from ...models.response_error import ResponseError
12
+ from ...types import Response
13
+
14
+
15
+ def _get_kwargs(
16
+ exchange_id: str,
17
+ type_: DataSourceType,
18
+ job_id: str,
19
+ ) -> dict[str, Any]:
20
+
21
+ _kwargs: dict[str, Any] = {
22
+ "method": "delete",
23
+ "url": "/backtest/{exchange_id}/{type_}/execute/{job_id}".format(
24
+ exchange_id=quote(str(exchange_id), safe=""),
25
+ type_=quote(str(type_), safe=""),
26
+ job_id=quote(str(job_id), safe=""),
27
+ ),
28
+ }
29
+
30
+ return _kwargs
31
+
32
+
33
+ def _parse_response(
34
+ *, client: AuthenticatedClient | Client, response: httpx.Response
35
+ ) -> CancelExecutionResponse200 | ResponseError | None:
36
+ if response.status_code == 200:
37
+ response_200 = CancelExecutionResponse200.from_dict(response.json())
38
+
39
+ return response_200
40
+
41
+ if response.status_code == 404:
42
+ response_404 = ResponseError.from_dict(response.json())
43
+
44
+ return response_404
45
+
46
+ if client.raise_on_unexpected_status:
47
+ raise errors.UnexpectedStatus(response.status_code, response.content)
48
+ else:
49
+ return None
50
+
51
+
52
+ def _build_response(
53
+ *, client: AuthenticatedClient | Client, response: httpx.Response
54
+ ) -> Response[CancelExecutionResponse200 | ResponseError]:
55
+ return Response(
56
+ status_code=HTTPStatus(response.status_code),
57
+ content=response.content,
58
+ headers=response.headers,
59
+ parsed=_parse_response(client=client, response=response),
60
+ )
61
+
62
+
63
+ def sync_detailed(
64
+ exchange_id: str,
65
+ type_: DataSourceType,
66
+ job_id: str,
67
+ *,
68
+ client: AuthenticatedClient,
69
+ ) -> Response[CancelExecutionResponse200 | ResponseError]:
70
+ """Cancel a running backtest execution
71
+
72
+ Requests cancellation of the specified execution. The execution
73
+ status will transition to `Aborted` once the cancellation is
74
+ processed. Cancellation is asynchronous — poll the GET endpoint
75
+ to confirm the final status.
76
+
77
+ Args:
78
+ exchange_id (str): Example: binance.
79
+ type_ (DataSourceType): Managed exchange data sources available for backtesting. Example:
80
+ ticker.
81
+ job_id (str): Example: 13RBLGQlPnfDjO6wyKSX8i.
82
+
83
+ Raises:
84
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
85
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
86
+
87
+ Returns:
88
+ Response[CancelExecutionResponse200 | ResponseError]
89
+ """
90
+
91
+ kwargs = _get_kwargs(
92
+ exchange_id=exchange_id,
93
+ type_=type_,
94
+ job_id=job_id,
95
+ )
96
+
97
+ response = client.get_httpx_client().request(
98
+ **kwargs,
99
+ )
100
+
101
+ return _build_response(client=client, response=response)
102
+
103
+
104
+ def sync(
105
+ exchange_id: str,
106
+ type_: DataSourceType,
107
+ job_id: str,
108
+ *,
109
+ client: AuthenticatedClient,
110
+ ) -> CancelExecutionResponse200 | ResponseError | None:
111
+ """Cancel a running backtest execution
112
+
113
+ Requests cancellation of the specified execution. The execution
114
+ status will transition to `Aborted` once the cancellation is
115
+ processed. Cancellation is asynchronous — poll the GET endpoint
116
+ to confirm the final status.
117
+
118
+ Args:
119
+ exchange_id (str): Example: binance.
120
+ type_ (DataSourceType): Managed exchange data sources available for backtesting. Example:
121
+ ticker.
122
+ job_id (str): Example: 13RBLGQlPnfDjO6wyKSX8i.
123
+
124
+ Raises:
125
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
126
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
127
+
128
+ Returns:
129
+ CancelExecutionResponse200 | ResponseError
130
+ """
131
+
132
+ return sync_detailed(
133
+ exchange_id=exchange_id,
134
+ type_=type_,
135
+ job_id=job_id,
136
+ client=client,
137
+ ).parsed
138
+
139
+
140
+ async def asyncio_detailed(
141
+ exchange_id: str,
142
+ type_: DataSourceType,
143
+ job_id: str,
144
+ *,
145
+ client: AuthenticatedClient,
146
+ ) -> Response[CancelExecutionResponse200 | ResponseError]:
147
+ """Cancel a running backtest execution
148
+
149
+ Requests cancellation of the specified execution. The execution
150
+ status will transition to `Aborted` once the cancellation is
151
+ processed. Cancellation is asynchronous — poll the GET endpoint
152
+ to confirm the final status.
153
+
154
+ Args:
155
+ exchange_id (str): Example: binance.
156
+ type_ (DataSourceType): Managed exchange data sources available for backtesting. Example:
157
+ ticker.
158
+ job_id (str): Example: 13RBLGQlPnfDjO6wyKSX8i.
159
+
160
+ Raises:
161
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
162
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
163
+
164
+ Returns:
165
+ Response[CancelExecutionResponse200 | ResponseError]
166
+ """
167
+
168
+ kwargs = _get_kwargs(
169
+ exchange_id=exchange_id,
170
+ type_=type_,
171
+ job_id=job_id,
172
+ )
173
+
174
+ response = await client.get_async_httpx_client().request(**kwargs)
175
+
176
+ return _build_response(client=client, response=response)
177
+
178
+
179
+ async def asyncio(
180
+ exchange_id: str,
181
+ type_: DataSourceType,
182
+ job_id: str,
183
+ *,
184
+ client: AuthenticatedClient,
185
+ ) -> CancelExecutionResponse200 | ResponseError | None:
186
+ """Cancel a running backtest execution
187
+
188
+ Requests cancellation of the specified execution. The execution
189
+ status will transition to `Aborted` once the cancellation is
190
+ processed. Cancellation is asynchronous — poll the GET endpoint
191
+ to confirm the final status.
192
+
193
+ Args:
194
+ exchange_id (str): Example: binance.
195
+ type_ (DataSourceType): Managed exchange data sources available for backtesting. Example:
196
+ ticker.
197
+ job_id (str): Example: 13RBLGQlPnfDjO6wyKSX8i.
198
+
199
+ Raises:
200
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
201
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
202
+
203
+ Returns:
204
+ CancelExecutionResponse200 | ResponseError
205
+ """
206
+
207
+ return (
208
+ await asyncio_detailed(
209
+ exchange_id=exchange_id,
210
+ type_=type_,
211
+ job_id=job_id,
212
+ client=client,
213
+ )
214
+ ).parsed
@@ -0,0 +1,251 @@
1
+ from http import HTTPStatus
2
+ from typing import Any
3
+ from urllib.parse import quote
4
+
5
+ import httpx
6
+
7
+ from ... import errors
8
+ from ...client import AuthenticatedClient, Client
9
+ from ...models.accepted_job import AcceptedJob
10
+ from ...models.data_source_type import DataSourceType
11
+ from ...models.execute_backtesting_body import ExecuteBacktestingBody
12
+ from ...models.response_error import ResponseError
13
+ from ...types import Response
14
+
15
+
16
+ def _get_kwargs(
17
+ exchange_id: str,
18
+ type_: DataSourceType,
19
+ *,
20
+ body: ExecuteBacktestingBody,
21
+ ) -> dict[str, Any]:
22
+ headers: dict[str, Any] = {}
23
+
24
+ _kwargs: dict[str, Any] = {
25
+ "method": "post",
26
+ "url": "/backtest/{exchange_id}/{type_}/execute".format(
27
+ exchange_id=quote(str(exchange_id), safe=""),
28
+ type_=quote(str(type_), safe=""),
29
+ ),
30
+ }
31
+
32
+ _kwargs["json"] = body.to_dict()
33
+
34
+ headers["Content-Type"] = "application/json"
35
+
36
+ _kwargs["headers"] = headers
37
+ return _kwargs
38
+
39
+
40
+ def _parse_response(
41
+ *, client: AuthenticatedClient | Client, response: httpx.Response
42
+ ) -> AcceptedJob | ResponseError | None:
43
+ if response.status_code == 202:
44
+ response_202 = AcceptedJob.from_dict(response.json())
45
+
46
+ return response_202
47
+
48
+ if response.status_code == 400:
49
+ response_400 = ResponseError.from_dict(response.json())
50
+
51
+ return response_400
52
+
53
+ if response.status_code == 404:
54
+ response_404 = ResponseError.from_dict(response.json())
55
+
56
+ return response_404
57
+
58
+ if response.status_code == 429:
59
+ response_429 = ResponseError.from_dict(response.json())
60
+
61
+ return response_429
62
+
63
+ if client.raise_on_unexpected_status:
64
+ raise errors.UnexpectedStatus(response.status_code, response.content)
65
+ else:
66
+ return None
67
+
68
+
69
+ def _build_response(
70
+ *, client: AuthenticatedClient | Client, response: httpx.Response
71
+ ) -> Response[AcceptedJob | ResponseError]:
72
+ return Response(
73
+ status_code=HTTPStatus(response.status_code),
74
+ content=response.content,
75
+ headers=response.headers,
76
+ parsed=_parse_response(client=client, response=response),
77
+ )
78
+
79
+
80
+ def sync_detailed(
81
+ exchange_id: str,
82
+ type_: DataSourceType,
83
+ *,
84
+ client: AuthenticatedClient,
85
+ body: ExecuteBacktestingBody,
86
+ ) -> Response[AcceptedJob | ResponseError]:
87
+ """Execute a compiled strategy against a prepared dataset
88
+
89
+ Enqueues an execute task that runs the strategy identified by `strategyId` over the data
90
+ prepared by the prepare job identified by `prepareJobId`. The instrument and date range are
91
+ recovered from the prepare job — they do not need to be sent again.
92
+
93
+ Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`
94
+ for the result.
95
+
96
+ The same params (same `prepareJobId`, `strategyId`, `storeSignals`) always return the same
97
+ `jobId` (idempotent).
98
+
99
+ Args:
100
+ exchange_id (str): Example: binance.
101
+ type_ (DataSourceType): Managed exchange data sources available for backtesting. Example:
102
+ ticker.
103
+ body (ExecuteBacktestingBody):
104
+
105
+ Raises:
106
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
107
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
108
+
109
+ Returns:
110
+ Response[AcceptedJob | ResponseError]
111
+ """
112
+
113
+ kwargs = _get_kwargs(
114
+ exchange_id=exchange_id,
115
+ type_=type_,
116
+ body=body,
117
+ )
118
+
119
+ response = client.get_httpx_client().request(
120
+ **kwargs,
121
+ )
122
+
123
+ return _build_response(client=client, response=response)
124
+
125
+
126
+ def sync(
127
+ exchange_id: str,
128
+ type_: DataSourceType,
129
+ *,
130
+ client: AuthenticatedClient,
131
+ body: ExecuteBacktestingBody,
132
+ ) -> AcceptedJob | ResponseError | None:
133
+ """Execute a compiled strategy against a prepared dataset
134
+
135
+ Enqueues an execute task that runs the strategy identified by `strategyId` over the data
136
+ prepared by the prepare job identified by `prepareJobId`. The instrument and date range are
137
+ recovered from the prepare job — they do not need to be sent again.
138
+
139
+ Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`
140
+ for the result.
141
+
142
+ The same params (same `prepareJobId`, `strategyId`, `storeSignals`) always return the same
143
+ `jobId` (idempotent).
144
+
145
+ Args:
146
+ exchange_id (str): Example: binance.
147
+ type_ (DataSourceType): Managed exchange data sources available for backtesting. Example:
148
+ ticker.
149
+ body (ExecuteBacktestingBody):
150
+
151
+ Raises:
152
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
153
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
154
+
155
+ Returns:
156
+ AcceptedJob | ResponseError
157
+ """
158
+
159
+ return sync_detailed(
160
+ exchange_id=exchange_id,
161
+ type_=type_,
162
+ client=client,
163
+ body=body,
164
+ ).parsed
165
+
166
+
167
+ async def asyncio_detailed(
168
+ exchange_id: str,
169
+ type_: DataSourceType,
170
+ *,
171
+ client: AuthenticatedClient,
172
+ body: ExecuteBacktestingBody,
173
+ ) -> Response[AcceptedJob | ResponseError]:
174
+ """Execute a compiled strategy against a prepared dataset
175
+
176
+ Enqueues an execute task that runs the strategy identified by `strategyId` over the data
177
+ prepared by the prepare job identified by `prepareJobId`. The instrument and date range are
178
+ recovered from the prepare job — they do not need to be sent again.
179
+
180
+ Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`
181
+ for the result.
182
+
183
+ The same params (same `prepareJobId`, `strategyId`, `storeSignals`) always return the same
184
+ `jobId` (idempotent).
185
+
186
+ Args:
187
+ exchange_id (str): Example: binance.
188
+ type_ (DataSourceType): Managed exchange data sources available for backtesting. Example:
189
+ ticker.
190
+ body (ExecuteBacktestingBody):
191
+
192
+ Raises:
193
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
194
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
195
+
196
+ Returns:
197
+ Response[AcceptedJob | ResponseError]
198
+ """
199
+
200
+ kwargs = _get_kwargs(
201
+ exchange_id=exchange_id,
202
+ type_=type_,
203
+ body=body,
204
+ )
205
+
206
+ response = await client.get_async_httpx_client().request(**kwargs)
207
+
208
+ return _build_response(client=client, response=response)
209
+
210
+
211
+ async def asyncio(
212
+ exchange_id: str,
213
+ type_: DataSourceType,
214
+ *,
215
+ client: AuthenticatedClient,
216
+ body: ExecuteBacktestingBody,
217
+ ) -> AcceptedJob | ResponseError | None:
218
+ """Execute a compiled strategy against a prepared dataset
219
+
220
+ Enqueues an execute task that runs the strategy identified by `strategyId` over the data
221
+ prepared by the prepare job identified by `prepareJobId`. The instrument and date range are
222
+ recovered from the prepare job — they do not need to be sent again.
223
+
224
+ Returns immediately with a `jobId`; poll `GET /backtest/{exchangeId}/{type}/execute/{jobId}`
225
+ for the result.
226
+
227
+ The same params (same `prepareJobId`, `strategyId`, `storeSignals`) always return the same
228
+ `jobId` (idempotent).
229
+
230
+ Args:
231
+ exchange_id (str): Example: binance.
232
+ type_ (DataSourceType): Managed exchange data sources available for backtesting. Example:
233
+ ticker.
234
+ body (ExecuteBacktestingBody):
235
+
236
+ Raises:
237
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
238
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
239
+
240
+ Returns:
241
+ AcceptedJob | ResponseError
242
+ """
243
+
244
+ return (
245
+ await asyncio_detailed(
246
+ exchange_id=exchange_id,
247
+ type_=type_,
248
+ client=client,
249
+ body=body,
250
+ )
251
+ ).parsed