Vector Trading Python SDK
vector-trading-sdk provides typed synchronous clients for seven account-key REST
operations and eight strategy-key signals. Requires Python 3.12+; locally verified on
Python 3.12 and 3.14.
Install the package:
pip install vector-trading-sdk==0.1.1
Build a local wheel with uv build in this directory, then install it in a consumer:
uv pip install /path/to/vector_trading_sdk-0.1.1-py3-none-any.whl
Import public clients, types, errors, and builders from vector_trading.
Internal _generated modules are implementation details. Runtime requirements are
httpx>=0.28.1,<1 and pydantic>=2.12.5,<3; development pins in uv.lock do not constrain
consumer versions. typing-extensions may be resolved transitively by these libraries;
the SDK itself uses Python's built-in typing facilities and does not require python-dateutil.
Quick start
| Environment variable | Purpose |
|---|---|
VECTOR_API_KEY |
Account API key for REST calls. |
VECTOR_BTCUSDT_API_KEY |
Strategy API key for your BTCUSDT strategy. |
VECTOR_SOLUSDT_API_KEY |
Strategy API key for your SOLUSDT strategy. |
To obtain a signal API key, copy the webhook URL for the intended strategy in
Vector Trading and take only its final path segment — the part after
/webhooks/signals/v1/. For example, from
https://www.vector-trading.app/webhooks/signals/v1/<strategy-api-key>, use only
<strategy-api-key> as VECTOR_BTCUSDT_API_KEY or VECTOR_SOLUSDT_API_KEY.
It must be 32 lowercase hexadecimal characters. Pass the key, not the full URL,
to the SDK's send method. Obtain each strategy's key from its own webhook URL;
VECTOR_API_KEY is the separate account REST credential.
Your application reads these variables; the SDK does not load .env files.
The names identify your strategies in application configuration. The strategy's
server configuration determines the traded instrument; the signal contains no symbol.
import os
from vector_trading import RestClient, SignalsClient, build_start_signal
with RestClient(account_api_key=os.environ["VECTOR_API_KEY"]) as rest:
bundles = rest.list_bundles(limit=20)
payload = build_start_signal(version=1)
with SignalsClient() as signals:
signals.send(payload, strategy_api_key=os.environ["VECTOR_BTCUSDT_API_KEY"])
signals.send(payload, strategy_api_key=os.environ["VECTOR_SOLUSDT_API_KEY"])
This queries bundles and starts two strategies through one signal client. Sending affects the selected strategies; use an explicitly authorized environment. The examples below also cover order opening, TP/SL updates, and target preservation or clearing.
Account-key REST
Account keys are for server-side integrations and differ from strategy keys.
The default REST base is https://www.vector-trading.app/api/rest; signal clients
default to https://www.vector-trading.app. Override base_url for another deployment;
the REST override includes /api/rest.
Imports and constructors perform no HTTP work.
import os
from vector_trading import RestClient, SdkError
account_key = os.environ["VECTOR_API_KEY"]
with RestClient(account_api_key=account_key) as client:
try:
for page in client.list_bundles_pages(limit=50):
names = [bundle.name for bundle in page.bundles]
except SdkError as error:
if error.status == 429:
# The caller decides whether and when another attempt is appropriate.
pass
else:
raise
| Public method | Parameters |
|---|---|
list_bundles |
optional keyword limit, cursor |
search_users |
required keyword display_name; optional limit, cursor |
get_checkout |
positional checkout_id |
list_bundle_users |
positional bundle_id; optional limit, cursor |
list_bundle_grants |
positional bundle_id; optional user_id, grant_type, source_id, starts_after, starts_before, ends_after, ends_before, created_after, created_before, sort, dir, limit, cursor |
create_bundle_grant |
positional bundle_id, request dictionary or CreateGrantRequest |
revoke_bundle_grant |
positional bundle_id, grant_id |
All methods accept optional keyword cancel_event: threading.Event. Responses are
Pydantic models with Python field names (next_cursor, user_id, and so on). Their
to_dict() / to_json() codecs use wire names. REST dates are timezone-aware datetime
values and serialize as ISO 8601, possibly normalized to an equivalent representation.
For raw request dictionaries and date filters, use ISO 8601 strings.
from vector_trading import CreateGrantRequest
request = CreateGrantRequest.from_dict(
{
"userId": user_id,
"grantType": "paid_external",
"sourceId": "invoice:123",
"endsAt": "2026-12-01T00:00:00.000Z",
}
)
with RestClient(base_url=rest_base_url, account_api_key=account_key) as client:
result = client.create_bundle_grant(bundle_id, request)
paid_external requires sourceId; a repeated grant may return 409. Revocation has
the server's documented access consequences. No SDK method promises idempotency.
list_bundles_pages, search_users_pages, list_bundle_users_pages, and
list_bundle_grants_pages lazily yield entire pages, preserving filters. An empty
array with nextCursor continues traversal; repeated cursors raise SdkError.
Stopping iteration stops additional requests; the client context closes its resources.
Offline signals and strategy-key delivery
Prices are illustrative; supply the current market price when preparing each message. The following example opens orders and prepares a later TP/SL update.
import os
from vector_trading import (
OpenSignalPayloadOrder,
OpenSignalPayloadOrderTakeProfitsInner,
SignalsClient,
UpdateSignalPayloadOrder,
build_open_signal,
build_update_signal,
)
opening_order = OpenSignalPayloadOrder(side="buy", stop=90)
opening_order.take_profits = [OpenSignalPayloadOrderTakeProfitsInner(price=110, percent=100)]
opening = build_open_signal(version=1, market_price=100, order=opening_order)
updated_order = UpdateSignalPayloadOrder(side="buy", stop=95)
updated_order.take_profits = [OpenSignalPayloadOrderTakeProfitsInner(price=115, percent=100)]
updated_protection = build_update_signal(version=1, market_price=100, order=updated_order)
with SignalsClient() as client:
client.send(opening, strategy_api_key=os.environ["VECTOR_BTCUSDT_API_KEY"])
client.send(opening, strategy_api_key=os.environ["VECTOR_SOLUSDT_API_KEY"])
# Send this separately when your application decides to adjust protection.
client.send(updated_protection, strategy_api_key=os.environ["VECTOR_BTCUSDT_API_KEY"])
# Offline alternatives: preserve TP while moving SL, or explicitly clear TP.
preserve_targets = build_update_signal(
version=1, market_price=100, order=UpdateSignalPayloadOrder(side="buy", stop=95)
)
cleared_order = UpdateSignalPayloadOrder(side="buy")
cleared_order.take_profits = []
clear_targets = build_update_signal(version=1, market_price=100, order=cleared_order)
SignalsClient retains transport configuration, not a strategy credential. Every
send requires the keyword strategy_api_key, so the same client can deliver to
different strategies, including concurrent calls. Keys remain in the webhook URL;
the JSON body contains only the prepared signal. The former constructor key option
is no longer accepted. Account credentials remain on RestClient.
The eight builders are build_open_signal, build_update_signal, build_cancel_signal,
build_close_signal, build_start_signal, build_pause_signal, build_stop_signal,
and build_delete_signal. Each requires keyword version, the strategy version.
Open/update require market_price and order; an order can be a generated model or a
wire dictionary. Open alone accepts force. Cancel/close may include market_price.
Every builder accepts optional timestamp and hashtag; absent timestamps are fixed
as decimal millisecond strings during construction. build_signal takes a complete
wire dictionary, supplying only an absent timestamp. serialize_signal validates and
serializes a prepared model or dictionary without supplying metadata.
Builders work offline and clone input messages. Sending the same prepared message preserves its timestamp; distinct builds within one millisecond need not be unique. The SDK rejects non-finite numbers, unsafe timestamps, invalid TP/SL relationships, unknown input fields, and bodies larger than 16 KiB of UTF-8. Strategy version is independent of SDK version. Internal event IDs and keys are not signal fields.
Omitted takeProfits preserves current targets; [] clears them; a non-empty list
replaces them. None is rejected for non-nullable signal fields. Generated models
track unset fields so omission does not become JSON null; nullable response fields
such as avatar retain explicit None.
send returns None for webhook 204: the signal was enqueued, not necessarily
executed. Automatic retries, polling, and background requests are absent. A timeout
or lost response leaves the operation's outcome unknown; the SDK does not resend it.
Transport, lifecycle, and errors
Both clients support close() and with; closing twice is safe, and a closed client
raises SdkError before another request. The default timeout is 10 seconds. HTTPX
bounds connection, pool, write, and read phases; the SDK also checks elapsed time while
reading a streaming body. Synchronous cancellation is cooperative: cancel_event is
checked before requests, between body chunks, and between pages. A blocked I/O phase
returns at its configured timeout; no extra worker or asynchronous API is created.
Production requests require HTTPS. Explicit allow_local_http=True allows only
loopback HTTP for local testing. Redirects are never followed and credentials are
never forwarded. Environment proxy settings are disabled. Optional transport accepts
an HTTPX BaseTransport; supplied transports must honor HTTPX timeout semantics and
must not introduce retries.
Responses, including errors, have a 1 MiB body limit checked while streaming.
Exceeding it raises protocol, closes the response, and leaves the client available
for independent calls. See the shared transport rules
for byte counting, request ID precedence, and the memory and delivery guarantees.
SdkError exposes kind, optional status, code, and request_id, plus a bounded
safe message. Kinds include validation, http, transport, timeout, cancelled,
protocol, pagination, and closed. HTTP errors handle JSON, non-JSON, empty bodies,
and rate limits. Private body values, credentials, URLs, and raw transport errors stay
out of diagnostics. Pydantic model error messages also hide input values.
HTTPX URL log representations redact private paths and queries;
actual request components remain intact.
Development
From this directory with pinned uv 0.12.1 and Python 3.12.9 available:
uv sync --locked
uv run ruff format --check .
uv run ruff check .
uv run mypy src
uv run pytest
uv build
uv run python scripts/check_package.py
The repository development guide describes the Python 3.14 matrix and root commands. Tests use isolated localhost servers and synthetic keys. The package check installs wheel and sdist separately into clean environments, exercises every public method, checks the dependency graph, and verifies public types and examples. The sdist carries derived models and builds without a server or SDK checkout.
Metadata
Release files for vector-trading-sdk 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vector_trading_sdk-0.1.1.tar.gz | 36.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vector_trading_sdk-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 119.3 kB
Release files / vector_trading_sdk-0.1.1.tar.gz
| Download URL | vector_trading_sdk-0.1.1.tar.gz |
|---|---|
| Size | 36.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5be8cef154dcaf8ed4ee5fa011961ad659e80174dde5527b50ce7fbef37ddff8
|
|
BLAKE2b-256 checksum How to use checksums |
7eef13b9f679bb7b546cd505d3bd8f780515c002485153f1d6a38152c63238c4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / vector_trading_sdk-0.1.1-py3-none-any.whl
| Download URL | vector_trading_sdk-0.1.1-py3-none-any.whl |
|---|---|
| Size | 82.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ea4051b79882bb1ca0aef2fe4e7b40baf66552f485105d8dcaff6effe3c996cd
|
|
BLAKE2b-256 checksum How to use checksums |
4420685d25d67d4fc83a4166c2e71e05ca39953095554f71b1e055b51d12b5b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|