Skip to main content

tradezero-sdk

Python PyPI License: MIT CI codecov

An unofficial, production-ready Python SDK for the TradeZero REST API.

TradeZero is an online broker offering direct-access trading for equities. This SDK wraps their REST API with a clean Python interface — no manual HTTP, no raw JSON parsing, no retry boilerplate.

Disclaimer: This is an unofficial, community-maintained library. It is not affiliated with, endorsed by, or supported by TradeZero Global Ltd. Use at your own risk. Always verify order execution through the official TradeZero platform before making financial decisions.


Resource Description
DOCUMENTATION.md Complete reference — every class, method, model, enum, and exception explained in full
CHANGELOG.md Full version history and breaking-change notes
CONTRIBUTING.md How to set up a dev environment and submit pull requests
SECURITY.md Vulnerability reporting policy and credential safety
examples/basic_sync.py Runnable synchronous usage example
examples/basic_async.py Runnable asynchronous usage example

Features

  • Dual sync/async support — TradeZeroClient for scripts, AsyncTradeZeroClient for async frameworks
  • Full Pydantic v2 validation — all API responses parsed into typed Python models
  • Automatic retries with exponential backoff — 429 and 5xx errors retried up to 3 times automatically
  • Rich exception hierarchy — catch AuthenticationError, RateLimitError, NotFoundError, ServerError, and more
  • Environment variable support — inject credentials via TZ_API_KEY / TZ_API_SECRET
  • Context-manager lifecycle — connections released automatically via with / async with
  • Typed models for all resources — accounts, P&L, positions, orders, trade history, and locates

Installation

From PyPI

pip install tradezero-sdk

From Source

git clone https://github.com/shadyemad/tradezero-sdk.git
cd tradezero-sdk
pip install poetry
poetry install

Requires Python 3.11+.


Quick Start

Synchronous

from tradezero import TradeZeroClient

with TradeZeroClient(api_key="YOUR_KEY", api_secret="YOUR_SECRET") as client:
    # List all accounts
    accounts = client.accounts.list_accounts()
    account_id = accounts[0].account
    print(f"Account: {account_id}, Equity: {accounts[0].equity:,.2f}")

    # Get day P&L
    pnl = client.accounts.get_account_pnl(account_id)
    print(f"Day P&L: {pnl.day_pnl:+,.2f}, Realized: {pnl.day_realized:+,.2f}")

    # Open positions with computed unrealized P&L
    positions = client.positions.get_positions(account_id)
    for pos in positions:
        print(f"{pos.symbol} {pos.side}: unrealized = {pos.unrealized_pnl:+,.2f}")

    # Place a limit buy order
    resp = client.trading.create_order(
        account_id=account_id,
        symbol="AAPL",
        quantity=100,
        side="Buy",
        order_type="Limit",
        time_in_force="Day",
        limit_price=185.0,
    )
    print(f"Order status: {resp.order_status}")

    # Check short-sell borrow availability
    etb = client.trading.is_easy_to_borrow(account_id, "AAPL")
    print(f"AAPL easy to borrow: {etb}")

    # Cancel all open orders
    client.trading.cancel_all_orders(account_id)

Asynchronous

import asyncio
from tradezero import AsyncTradeZeroClient

async def main():
    async with AsyncTradeZeroClient(api_key="YOUR_KEY", api_secret="YOUR_SECRET") as client:
        accounts = await client.accounts.list_accounts()
        account_id = accounts[0].account

        pnl = await client.accounts.get_account_pnl(account_id)
        print(f"Day P&L: {pnl.day_pnl:+,.2f}")

        positions = await client.positions.get_positions(account_id)
        for pos in positions:
            print(f"{pos.symbol}: {pos.unrealized_pnl:+,.2f}")

        resp = await client.trading.create_order(
            account_id=account_id,
            symbol="TSLA",
            quantity=50,
            side="Sell",
            order_type="Market",
            time_in_force="Day",
        )
        print(f"Order: {resp.order_status}")

asyncio.run(main())

More complete examples are in the examples/ directory.


Configuration

Credentials can be passed explicitly or loaded from environment variables:

Environment Variable Description Default
TZ_API_KEY TradeZero API key ID —
TZ_API_SECRET TradeZero API secret key —
TZ_BASE_URL Override the API base URL https://webapi.tradezero.com/v1/api
export TZ_API_KEY="your-key"
export TZ_API_SECRET="your-secret"
# Credentials resolved automatically from environment
client = TradeZeroClient()

Additional constructor options:

client = TradeZeroClient(
    api_key="...",
    api_secret="...",
    timeout=60.0,   # per-request timeout in seconds (default: 30)
)

API Reference

For full method signatures, parameter descriptions, return types, and code examples for every endpoint, see DOCUMENTATION.md.

client.accounts

Method Returns Description
list_accounts() list[Account] All accounts for your API credentials
get_account_details(account_id) Account Full account details including all financial fields
get_account_pnl(account_id) AccountPnL Daily P&L, exposure, and balance metrics

client.positions

Method Returns Description
get_positions(account_id) list[Position] All open positions with computed unrealized_pnl

client.trading

Method Returns Description
create_order(account_id, symbol, quantity, side, order_type, time_in_force, ...) OrderResponse Place a new order
get_order(account_id, order_id) Order Retrieve a single current-day order by ID
list_orders(account_id) list[Order] Current-day orders (all statuses)
list_historical_orders(account_id, start_date) list[TradeRecord] Trade records up to one week back
list_historical_orders_paginated(account_id, start_date, *, page=None, page_size=None) PaginatedTradeResponse Paginated trade records up to one year back
cancel_order(account_id, client_order_id) None Cancel a specific open order
cancel_all_orders(account_id, *, symbol=None) dict | None Cancel all open orders, optionally filtered by symbol
is_easy_to_borrow(account_id, symbol) bool Check short-sell borrow availability
get_routes(account_id) list[dict] Available trading routes

client.locates

Method Returns Description
request_quote(account, symbol, quantity, quote_req_id) dict Submit a short-sell locate quote request
get_history(account_id) list[LocateHistoryItem] Poll locate request history and status
get_inventory(account_id) list[LocateInventoryItem] Active locate inventory
accept_quote(account_id, quote_req_id) dict Accept an offered locate quote
sell_locate(account, symbol, quote_req_id, quantity, locate_type) dict Sell locate back for credit
cancel_locate(account_id, quote_req_id) None Cancel a pending locate quote

Enum Values

All enum values match the TradeZero API wire format exactly. String literals are accepted wherever enum members are — the SDK coerces them automatically:

# These are equivalent:
client.trading.create_order(..., side="Buy", order_type="Limit", time_in_force="Day")
client.trading.create_order(..., side=OrderSide.BUY, order_type=OrderType.LIMIT, time_in_force=TimeInForce.DAY)
Enum Members
OrderSide BUY="Buy", SELL="Sell"
OrderType MARKET="Market", LIMIT="Limit", STOP="Stop", STOP_LIMIT="StopLimit"
TimeInForce DAY="Day", GTC="GoodTillCancel", IOC="ImmediateOrCancel", FOK="FillOrKill", AT_THE_OPENING, GOOD_TILL_CROSSING, DAY_PLUS, GTC_PLUS
SecurityType STOCK="Stock", OPTION="Option"
LocateStatus NEW=48, FILLED=50, CANCELED=52, PENDING=54, REJECTED=56, OFFERED=65, EXPIRED=67, QUOTING=81
LocateTypeStr LOCATE="Locate", INTRADAY="IntraDay", PRE_BORROW="PreBorrow", SINGLE_USE="SingleUse"

See DOCUMENTATION.md § Enumerations for full descriptions of every member.


Exception Handling

from tradezero import (
    TradeZeroSDKError,       # Base class for all SDK errors
    TradeZeroAPIError,       # Non-2xx API response (.status_code, .response_body)
    AuthenticationError,     # 401 — invalid credentials
    ForbiddenError,          # 403 — insufficient permissions
    NotFoundError,           # 404 — resource not found
    RateLimitError,          # 429 — too many requests (auto-retried)
    APIValidationError,      # 422 — request validation failed
    InsufficientFundsError,  # insufficient buying power
    ServerError,             # 5xx — server error (auto-retried)
)

try:
    resp = client.trading.create_order(...)
except RateLimitError:
    print("Still rate limited after 3 automatic retries")
except AuthenticationError:
    print("Check your API credentials")
except InsufficientFundsError:
    print("Not enough buying power for this order")
except TradeZeroAPIError as e:
    print(f"API error {e.status_code}: {e}")
    print(f"Response body: {e.response_body}")

Retry Behaviour

Condition Behaviour
RateLimitError (HTTP 429) Retried up to 3 times
ServerError (HTTP 5xx) Retried up to 3 times
httpx.TransportError (network) Retried up to 3 times
All other errors Raised immediately, no retry

Backoff: 1 s → 2 s → 4 s, capped at 60 s.


Package Structure

tradezero-sdk/
│
├── tradezero/                          # Main installable package
│   ├── __init__.py                     # Public API surface & __version__
│   ├── config.py                       # Constants and env-var helpers
│   ├── enums.py                        # All API enumerations
│   ├── exceptions.py                   # Exception hierarchy
│   ├── client/
│   │   ├── sync_client.py              # TradeZeroClient (synchronous)
│   │   └── async_client.py             # AsyncTradeZeroClient (asynchronous)
│   ├── http/
│   │   ├── _base.py                    # Auth headers, utility functions
│   │   ├── _retry.py                   # Tenacity retry decorator
│   │   ├── sync_http.py                # SyncHTTPClient
│   │   └── async_http.py               # AsyncHTTPClient
│   ├── models/
│   │   ├── accounts.py                 # Account, AccountPnL
│   │   ├── orders.py                   # CreateOrderRequest, OrderResponse,
│   │   │                               # Order, TradeRecord
│   │   ├── positions.py                # Position (with computed unrealized_pnl)
│   │   └── locates.py                  # All locate request/response models
│   └── modules/
│       ├── accounts.py                 # AccountsModule + AsyncAccountsModule
│       ├── trading.py                  # TradingModule + AsyncTradingModule
│       ├── positions.py                # PositionsModule + AsyncPositionsModule
│       └── locates.py                  # LocatesModule + AsyncLocatesModule
│
├── tests/
│   ├── conftest.py                     # Shared pytest fixtures
│   ├── test_accounts.py                # 7 unit tests
│   ├── test_trading.py                 # 14 unit tests
│   ├── test_positions.py               # 5 unit tests
│   ├── test_locates.py                 # 8 unit tests
│   ├── test_async.py                   # 11 unit tests
│   ├── test_exceptions.py              # 3 unit tests
│   ├── test_retry.py                   # 6 unit tests
│   └── live/                           # Live integration tests (real API, opt-in)
│       ├── conftest.py                 # Reads TZ_API_KEY / TZ_API_SECRET from env
│       ├── test_accounts.py
│       ├── test_trading.py
│       ├── test_positions.py
│       ├── test_locates.py
│       └── test_errors.py
│
├── examples/
│   ├── basic_sync.py                   # Synchronous usage example
│   └── basic_async.py                  # Asynchronous usage example
│
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows/ci.yml                # CI pipeline (Python 3.11 + 3.12)
│
├── README.md                           # This file
├── DOCUMENTATION.md                    # Complete reference documentation
├── CONTRIBUTING.md                     # Contributor guide
├── CHANGELOG.md                        # Version history
├── SECURITY.md                         # Security and vulnerability policy
├── LICENSE                             # MIT License
├── pyproject.toml                      # Package metadata, deps, tool config
└── pytest.ini                          # Pytest settings

Development

See CONTRIBUTING.md for the full contributor guide.

# Install all dependencies including dev tools
poetry install

# Run unit tests (no API credentials required)
poetry run pytest -m "not live" --cov=tradezero -v

# Lint with ruff
poetry run ruff check .

# Type-check with mypy
poetry run mypy tradezero

Live integration tests (require real credentials):

export TZ_API_KEY="your-key"
export TZ_API_SECRET="your-secret"
poetry run pytest tests/live/ -m live -v

Sponsorship

If this SDK saves you time or money, consider sponsoring the project:

Donate via PayPal

Binance Pay — UID: 751730419

Your support helps maintain the library, add new endpoints, and test against the live API.


Contact & Contributing

Contributions are welcome:

  1. Fork the repository and create a feature branch from main
  2. Make your change and add tests
  3. Run pytest -m "not live", ruff check ., and mypy tradezero — all must pass
  4. Open a pull request with a clear description

License

MIT — Copyright (c) 2026 Shady Emad


Disclaimer: tradezero-sdk is an unofficial, community-maintained project. It is not affiliated with, endorsed by, or sponsored by TradeZero Global Ltd. The TradeZero name and API are trademarks of TradeZero Global Ltd. The authors accept no responsibility for financial losses resulting from the use of this library. Always verify all trades through the official TradeZero platform.

Metadata

Release files for tradezero-sdk 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tradezero-sdk 1.0.2
File Size Uploaded Provenance Actions
tradezero_sdk-1.0.2.tar.gz 25.0 kB With provenance Details for tradezero_sdk-1.0.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for tradezero-sdk 1.0.2
File Interpreter ABI Platform Actions
tradezero_sdk-1.0.2-py3-none-any.whl Python 3 none any Details for tradezero_sdk-1.0.2-py3-none-any.whl

Total release size: 56.2 kB

Release files / tradezero_sdk-1.0.2.tar.gz

Download URL tradezero_sdk-1.0.2.tar.gz
Size 25.0 kB
Tags Source
SHA-256 checksum
How to use checksums
79547d747ac1d69664664cd5f16fd374478a2fc805091b26dbad67c180a57bb9
BLAKE2b-256 checksum
How to use checksums
50e1212baa92028bbc9dcb1e7cf5499af430f0c035a38775284674f15b9fafb0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 13, 2026.

Transparency log

Release files / tradezero_sdk-1.0.2-py3-none-any.whl

Download URL tradezero_sdk-1.0.2-py3-none-any.whl
Size 31.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
18dd91610102fdac8321a79ad485c948a2f604f90ba7dd338f3dc411b638174c
BLAKE2b-256 checksum
How to use checksums
b8f81839f0b8972b98ec6da9ea3ca01f2c9a47843920c2cec87214de227b0a8f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 13, 2026.

Transparency log

Security for tradezero-sdk 1.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for tradezero_sdk-1.0.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 13, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page