You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit b477fff
Browse filesBrowse the repository at this point in the historyBrowse files
jwt = token_response.access_token # use this in subsequent calls
83
83
```
84
84
85
+
`token_response.scopes`, when present, is a `KeyScopes` map from resource to actions,
86
+
such as `{"backtests": ["read", "write", "execute"]}`, not an array. `get_account`
87
+
returns the same required map. The API reports grants but does not yet enforce them.
88
+
89
+
Exchange discovery returns required `venue_type`, `segments`, and `live_segments`.
90
+
Both instrument routes return `InstrumentCatalogueResponse`: either `InstrumentListResponse`
91
+
(`meta.venue_type == "cex"`) or `PoolListResponse` (`"dex"`). Pool ids are live-run
92
+
addresses; symbols name signals. Missing market values are `UNSET`, never null.
93
+
Live sources use `LiveSourceRequestVenueType.CEX` / `.DEX`; DEX needs exactly one
94
+
pool address, `kline`, and a discovered live protocol. CEX imports use
95
+
`DatasetImportRequestType.CEX` with a `DatasetImportCexRequest` block.
96
+
85
97
For production use, prefer the [`qtsurfer-sdk`](https://github.com/QTSurfer/sdk-python)
86
98
`auth(apikey)` helper — it handles token refresh, env-var pickup
87
99
(`QTSURFER_APIKEY`), and pluggable token storage so callers don't reinvent any
@@ -240,7 +252,7 @@ responses also expose optional `reason` text when a run stops or fails.
240
252
241
253
> Exact module/function names are produced from `operationId` in the OpenAPI spec. Run `scripts/regenerate.sh` to refresh and check `src/qtsurfer/api/client/_generated/api/` for the authoritative listing.
242
254
243
-
All generated model types (`Exchange`, `InstrumentDetail`, `InstrumentCoverage`, `CoverageWindow`, `JobState`, `PrepareJobState`, `StrategyState`, `StrategyLinks`, `BacktestJobResult`, `ResultMap`, `ResponseError`, `Dataset`, `DatasetWithLinks`, `DatasetCreated`, `DatasetVersion`, `DatasetUploadState`, …) live under `qtsurfer.api.client.models`. `list_instruments`/`list_segment_instruments` return an `InstrumentListResponse` (HAL envelope: `data` + `meta` + `_links`), not a bare list — each `InstrumentDetail.coverage` carries per-data-type `CoverageWindow`s instead of flat `dataFrom`/`dataTo`. A single-instrument `get_prepare_status` returns a `PrepareJobState` — always terminal (`status: Completed`), with a `coverage_ratio` and a per-hour `hours_without_data` breakdown to act on instead of polling. Against a dataset-backed prepare (`exchangeId: user`), `PrepareJobState` reports coverage on the dataset's own cadence grid instead — `cadence`/`gaps`/`largest_gap_steps` — with `total_hours`/`hours_with_data`/`hours_without_data` absent in that case. `get_strategy` returns a `StrategyState`, whose `validation` field (`not_validated` / `pending` / `passed` / `failed`) reports the outcome of the most recent `validate_strategy` check rather than a compile job status.
255
+
All generated model types (`Exchange`, `InstrumentDetail`, `InstrumentCoverage`, `CoverageWindow`, `JobState`, `PrepareJobState`, `StrategyState`, `StrategyLinks`, `BacktestJobResult`, `ResultMap`, `ResponseError`, `Dataset`, `DatasetWithLinks`, `DatasetCreated`, `DatasetVersion`, `DatasetUploadState`, …) live under `qtsurfer.api.client.models`. `list_instruments`/`list_segment_instruments` return `InstrumentCatalogueResponse`, either `InstrumentListResponse` for CEX or `PoolListResponse` for DEX (HAL envelope: `data` + `meta` + `_links`) — each `InstrumentDetail.coverage` carries per-data-type `CoverageWindow`s instead of flat `dataFrom`/`dataTo`. A single-instrument `get_prepare_status` returns a `PrepareJobState` — always terminal (`status: Completed`), with a `coverage_ratio` and a per-hour `hours_without_data` breakdown to act on instead of polling. Against a dataset-backed prepare (`exchangeId: user`), `PrepareJobState` reports coverage on the dataset's own cadence grid instead — `cadence`/`gaps`/`largest_gap_steps` — with `total_hours`/`hours_with_data`/`hours_without_data` absent in that case. `get_strategy` returns a `StrategyState`, whose `validation` field (`not_validated` / `pending` / `passed` / `failed`) reports the outcome of the most recent `validate_strategy` check rather than a compile job status.
244
256
245
257
A full `StrategyState` (from `get_strategy`, and from `validate_strategy`'s already-validated `200`) carries an optional `field_links` (`_links` on the wire) — a `StrategyLinks` with a `code: HalLink` pointing at `get_strategy_code`. `validate_strategy`'s `202` omits it, since a check that just started has nothing to link to yet. `list_strategies` returns every strategy you've registered and not deleted, most recently compiled first, but deliberately without each one's `validation` state — check that per strategy with `get_strategy`. `delete_strategy` removes a strategy from both `get_strategy` and `list_strategies`; it doesn't touch backtests already run against it, and re-submitting the same source afterwards registers a new strategy under a new id. `get_strategy_code`'s `404` covers two indistinguishable cases: an id never registered by you, or one that resolves only through a shared/marketplace reference with no source of its own.
246
258
@@ -259,10 +271,14 @@ server-applied size guard, so treat it as authoritative over requested defaults.
These endpoints return raw [Lastra](https://github.com/QTSurfer/lastra-java) bytes (default) or Parquet (`format=parquet`). The generated `sync()` helpers parse the response body as JSON and will raise on binary payloads; use `sync_detailed()` and read `response.content` directly:
274
+
These endpoints return raw [Lastra](https://github.com/QTSurfer/lastra-java) bytes (default) or
275
+
Parquet (`format=parquet`). Import the public `api.exchange` adapters: generated binary
276
+
success responses are omitted by the generator. Public `sync()` / `asyncio()` return bytes
277
+
or `ResponseError`; detailed variants retain headers, status, parsed value, and content.
263
278
264
279
```python
265
280
from qtsurfer.api.client import AuthenticatedClient
281
+
from datetime importUTC, datetime, timedelta
266
282
from qtsurfer.api.client.api.exchange import download_tickers
0 commit comments