{"id":48713276,"url":"https://github.com/shaadyemad/tradezero-sdk","last_synced_at":"2026-04-13T18:01:01.781Z","repository":{"id":350674926,"uuid":"1204104777","full_name":"ShaadyEmad/tradezero-sdk","owner":"ShaadyEmad","description":"Unofficial TradeZero SDK for Python that provides a clean and structured interface to automate trading, manage orders, and access account data through TradeZero API endpoints. Built for developers and trading bots. Not affiliated with TradeZero.","archived":false,"fork":false,"pushed_at":"2026-04-11T14:33:05.000Z","size":98,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-11T15:12:26.123Z","etag":null,"topics":["api-client","async","broker","finance","python","rest-api","sdk","stocks","tradezero","trading"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ShaadyEmad.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-07T17:38:13.000Z","updated_at":"2026-04-11T14:33:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ShaadyEmad/tradezero-sdk","commit_stats":null,"previous_names":["shaadyemad/tradezero-sdk"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/ShaadyEmad/tradezero-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShaadyEmad%2Ftradezero-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShaadyEmad%2Ftradezero-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShaadyEmad%2Ftradezero-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShaadyEmad%2Ftradezero-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ShaadyEmad","download_url":"https://codeload.github.com/ShaadyEmad/tradezero-sdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShaadyEmad%2Ftradezero-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31764317,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T15:25:13.801Z","status":"ssl_error","status_checked_at":"2026-04-13T15:25:09.162Z","response_time":93,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","async","broker","finance","python","rest-api","sdk","stocks","tradezero","trading"],"created_at":"2026-04-11T15:11:55.078Z","updated_at":"2026-04-13T18:01:01.760Z","avatar_url":"https://github.com/ShaadyEmad.png","language":"Python","funding_links":["https://www.paypal.me/shaadyemad"],"categories":[],"sub_categories":[],"readme":"# tradezero-sdk\n\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)\n[![PyPI](https://img.shields.io/pypi/v/tradezero-sdk.svg)](https://pypi.org/project/tradezero-sdk/)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n[![CI](https://github.com/shadyemad/tradezero-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/shadyemad/tradezero-sdk/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/shadyemad/tradezero-sdk/branch/main/graph/badge.svg)](https://codecov.io/gh/shadyemad/tradezero-sdk)\n\nAn unofficial, production-ready Python SDK for the [TradeZero](https://www.tradezero.com/) REST API.\n\nTradeZero 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.\n\n\u003e **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.\n\n---\n\n## Documentation \u0026 Links\n\n| Resource | Description |\n|----------|-------------|\n| [DOCUMENTATION.md](DOCUMENTATION.md) | **Complete reference** — every class, method, model, enum, and exception explained in full |\n| [CHANGELOG.md](CHANGELOG.md) | Full version history and breaking-change notes |\n| [CONTRIBUTING.md](CONTRIBUTING.md) | How to set up a dev environment and submit pull requests |\n| [SECURITY.md](SECURITY.md) | Vulnerability reporting policy and credential safety |\n| [examples/basic_sync.py](examples/basic_sync.py) | Runnable synchronous usage example |\n| [examples/basic_async.py](examples/basic_async.py) | Runnable asynchronous usage example |\n\n---\n\n## Features\n\n- **Dual sync/async support** — `TradeZeroClient` for scripts, `AsyncTradeZeroClient` for async frameworks\n- **Full Pydantic v2 validation** — all API responses parsed into typed Python models\n- **Automatic retries with exponential backoff** — 429 and 5xx errors retried up to 3 times automatically\n- **Rich exception hierarchy** — catch `AuthenticationError`, `RateLimitError`, `NotFoundError`, `ServerError`, and more\n- **Environment variable support** — inject credentials via `TZ_API_KEY` / `TZ_API_SECRET`\n- **Context-manager lifecycle** — connections released automatically via `with` / `async with`\n- **Typed models for all resources** — accounts, P\u0026L, positions, orders, trade history, and locates\n\n---\n\n## Installation\n\n### From PyPI\n\n```bash\npip install tradezero-sdk\n```\n\n### From Source\n\n```bash\ngit clone https://github.com/shadyemad/tradezero-sdk.git\ncd tradezero-sdk\npip install poetry\npoetry install\n```\n\nRequires **Python 3.11+**.\n\n---\n\n## Quick Start\n\n### Synchronous\n\n```python\nfrom tradezero import TradeZeroClient\n\nwith TradeZeroClient(api_key=\"YOUR_KEY\", api_secret=\"YOUR_SECRET\") as client:\n    # List all accounts\n    accounts = client.accounts.list_accounts()\n    account_id = accounts[0].account\n    print(f\"Account: {account_id}, Equity: {accounts[0].equity:,.2f}\")\n\n    # Get day P\u0026L\n    pnl = client.accounts.get_account_pnl(account_id)\n    print(f\"Day P\u0026L: {pnl.day_pnl:+,.2f}, Realized: {pnl.day_realized:+,.2f}\")\n\n    # Open positions with computed unrealized P\u0026L\n    positions = client.positions.get_positions(account_id)\n    for pos in positions:\n        print(f\"{pos.symbol} {pos.side}: unrealized = {pos.unrealized_pnl:+,.2f}\")\n\n    # Place a limit buy order\n    resp = client.trading.create_order(\n        account_id=account_id,\n        symbol=\"AAPL\",\n        quantity=100,\n        side=\"Buy\",\n        order_type=\"Limit\",\n        time_in_force=\"Day\",\n        limit_price=185.0,\n    )\n    print(f\"Order status: {resp.order_status}\")\n\n    # Check short-sell borrow availability\n    etb = client.trading.is_easy_to_borrow(account_id, \"AAPL\")\n    print(f\"AAPL easy to borrow: {etb}\")\n\n    # Cancel all open orders\n    client.trading.cancel_all_orders(account_id)\n```\n\n### Asynchronous\n\n```python\nimport asyncio\nfrom tradezero import AsyncTradeZeroClient\n\nasync def main():\n    async with AsyncTradeZeroClient(api_key=\"YOUR_KEY\", api_secret=\"YOUR_SECRET\") as client:\n        accounts = await client.accounts.list_accounts()\n        account_id = accounts[0].account\n\n        pnl = await client.accounts.get_account_pnl(account_id)\n        print(f\"Day P\u0026L: {pnl.day_pnl:+,.2f}\")\n\n        positions = await client.positions.get_positions(account_id)\n        for pos in positions:\n            print(f\"{pos.symbol}: {pos.unrealized_pnl:+,.2f}\")\n\n        resp = await client.trading.create_order(\n            account_id=account_id,\n            symbol=\"TSLA\",\n            quantity=50,\n            side=\"Sell\",\n            order_type=\"Market\",\n            time_in_force=\"Day\",\n        )\n        print(f\"Order: {resp.order_status}\")\n\nasyncio.run(main())\n```\n\nMore complete examples are in the [`examples/`](examples/) directory.\n\n---\n\n## Configuration\n\nCredentials can be passed explicitly or loaded from environment variables:\n\n| Environment Variable | Description               | Default                               |\n|----------------------|---------------------------|---------------------------------------|\n| `TZ_API_KEY`         | TradeZero API key ID      | —                                     |\n| `TZ_API_SECRET`      | TradeZero API secret key  | —                                     |\n| `TZ_BASE_URL`        | Override the API base URL | `https://webapi.tradezero.com/v1/api` |\n\n```bash\nexport TZ_API_KEY=\"your-key\"\nexport TZ_API_SECRET=\"your-secret\"\n```\n\n```python\n# Credentials resolved automatically from environment\nclient = TradeZeroClient()\n```\n\nAdditional constructor options:\n\n```python\nclient = TradeZeroClient(\n    api_key=\"...\",\n    api_secret=\"...\",\n    timeout=60.0,   # per-request timeout in seconds (default: 30)\n)\n```\n\n---\n\n## API Reference\n\n\u003e For full method signatures, parameter descriptions, return types, and code examples for every endpoint, see [DOCUMENTATION.md](DOCUMENTATION.md).\n\n### `client.accounts`\n\n| Method | Returns | Description |\n|--------|---------|-------------|\n| `list_accounts()` | `list[Account]` | All accounts for your API credentials |\n| `get_account_details(account_id)` | `Account` | Full account details including all financial fields |\n| `get_account_pnl(account_id)` | `AccountPnL` | Daily P\u0026L, exposure, and balance metrics |\n\n### `client.positions`\n\n| Method | Returns | Description |\n|--------|---------|-------------|\n| `get_positions(account_id)` | `list[Position]` | All open positions with computed `unrealized_pnl` |\n\n### `client.trading`\n\n| Method | Returns | Description |\n|--------|---------|-------------|\n| `create_order(account_id, symbol, quantity, side, order_type, time_in_force, ...)` | `OrderResponse` | Place a new order |\n| `get_order(account_id, order_id)` | `Order` | Retrieve a single current-day order by ID |\n| `list_orders(account_id)` | `list[Order]` | Current-day orders (all statuses) |\n| `list_historical_orders(account_id, start_date)` | `list[TradeRecord]` | Trade records up to one week back |\n| `list_historical_orders_paginated(account_id, start_date, *, page=None, page_size=None)` | `PaginatedTradeResponse` | Paginated trade records up to one year back |\n| `cancel_order(account_id, client_order_id)` | `None` | Cancel a specific open order |\n| `cancel_all_orders(account_id, *, symbol=None)` | `dict \\| None` | Cancel all open orders, optionally filtered by symbol |\n| `is_easy_to_borrow(account_id, symbol)` | `bool` | Check short-sell borrow availability |\n| `get_routes(account_id)` | `list[dict]` | Available trading routes |\n\n### `client.locates`\n\n| Method | Returns | Description |\n|--------|---------|-------------|\n| `request_quote(account, symbol, quantity, quote_req_id)` | `dict` | Submit a short-sell locate quote request |\n| `get_history(account_id)` | `list[LocateHistoryItem]` | Poll locate request history and status |\n| `get_inventory(account_id)` | `list[LocateInventoryItem]` | Active locate inventory |\n| `accept_quote(account_id, quote_req_id)` | `dict` | Accept an offered locate quote |\n| `sell_locate(account, symbol, quote_req_id, quantity, locate_type)` | `dict` | Sell locate back for credit |\n| `cancel_locate(account_id, quote_req_id)` | `None` | Cancel a pending locate quote |\n\n---\n\n## Enum Values\n\nAll enum values match the TradeZero API wire format exactly. String literals are accepted wherever enum members are — the SDK coerces them automatically:\n\n```python\n# These are equivalent:\nclient.trading.create_order(..., side=\"Buy\", order_type=\"Limit\", time_in_force=\"Day\")\nclient.trading.create_order(..., side=OrderSide.BUY, order_type=OrderType.LIMIT, time_in_force=TimeInForce.DAY)\n```\n\n| Enum | Members |\n|------|---------|\n| `OrderSide` | `BUY=\"Buy\"`, `SELL=\"Sell\"` |\n| `OrderType` | `MARKET=\"Market\"`, `LIMIT=\"Limit\"`, `STOP=\"Stop\"`, `STOP_LIMIT=\"StopLimit\"` |\n| `TimeInForce` | `DAY=\"Day\"`, `GTC=\"GoodTillCancel\"`, `IOC=\"ImmediateOrCancel\"`, `FOK=\"FillOrKill\"`, `AT_THE_OPENING`, `GOOD_TILL_CROSSING`, `DAY_PLUS`, `GTC_PLUS` |\n| `SecurityType` | `STOCK=\"Stock\"`, `OPTION=\"Option\"` |\n| `LocateStatus` | `NEW=48`, `FILLED=50`, `CANCELED=52`, `PENDING=54`, `REJECTED=56`, `OFFERED=65`, `EXPIRED=67`, `QUOTING=81` |\n| `LocateTypeStr` | `LOCATE=\"Locate\"`, `INTRADAY=\"IntraDay\"`, `PRE_BORROW=\"PreBorrow\"`, `SINGLE_USE=\"SingleUse\"` |\n\nSee [DOCUMENTATION.md § Enumerations](DOCUMENTATION.md#10-enumerations) for full descriptions of every member.\n\n---\n\n## Exception Handling\n\n```python\nfrom tradezero import (\n    TradeZeroSDKError,       # Base class for all SDK errors\n    TradeZeroAPIError,       # Non-2xx API response (.status_code, .response_body)\n    AuthenticationError,     # 401 — invalid credentials\n    ForbiddenError,          # 403 — insufficient permissions\n    NotFoundError,           # 404 — resource not found\n    RateLimitError,          # 429 — too many requests (auto-retried)\n    APIValidationError,      # 422 — request validation failed\n    InsufficientFundsError,  # insufficient buying power\n    ServerError,             # 5xx — server error (auto-retried)\n)\n\ntry:\n    resp = client.trading.create_order(...)\nexcept RateLimitError:\n    print(\"Still rate limited after 3 automatic retries\")\nexcept AuthenticationError:\n    print(\"Check your API credentials\")\nexcept InsufficientFundsError:\n    print(\"Not enough buying power for this order\")\nexcept TradeZeroAPIError as e:\n    print(f\"API error {e.status_code}: {e}\")\n    print(f\"Response body: {e.response_body}\")\n```\n\n### Retry Behaviour\n\n| Condition | Behaviour |\n|-----------|-----------|\n| `RateLimitError` (HTTP 429) | Retried up to 3 times |\n| `ServerError` (HTTP 5xx) | Retried up to 3 times |\n| `httpx.TransportError` (network) | Retried up to 3 times |\n| All other errors | Raised immediately, no retry |\n\nBackoff: 1 s → 2 s → 4 s, capped at 60 s.\n\n---\n\n## Package Structure\n\n```\ntradezero-sdk/\n│\n├── tradezero/                          # Main installable package\n│   ├── __init__.py                     # Public API surface \u0026 __version__\n│   ├── config.py                       # Constants and env-var helpers\n│   ├── enums.py                        # All API enumerations\n│   ├── exceptions.py                   # Exception hierarchy\n│   ├── client/\n│   │   ├── sync_client.py              # TradeZeroClient (synchronous)\n│   │   └── async_client.py             # AsyncTradeZeroClient (asynchronous)\n│   ├── http/\n│   │   ├── _base.py                    # Auth headers, utility functions\n│   │   ├── _retry.py                   # Tenacity retry decorator\n│   │   ├── sync_http.py                # SyncHTTPClient\n│   │   └── async_http.py               # AsyncHTTPClient\n│   ├── models/\n│   │   ├── accounts.py                 # Account, AccountPnL\n│   │   ├── orders.py                   # CreateOrderRequest, OrderResponse,\n│   │   │                               # Order, TradeRecord\n│   │   ├── positions.py                # Position (with computed unrealized_pnl)\n│   │   └── locates.py                  # All locate request/response models\n│   └── modules/\n│       ├── accounts.py                 # AccountsModule + AsyncAccountsModule\n│       ├── trading.py                  # TradingModule + AsyncTradingModule\n│       ├── positions.py                # PositionsModule + AsyncPositionsModule\n│       └── locates.py                  # LocatesModule + AsyncLocatesModule\n│\n├── tests/\n│   ├── conftest.py                     # Shared pytest fixtures\n│   ├── test_accounts.py                # 7 unit tests\n│   ├── test_trading.py                 # 14 unit tests\n│   ├── test_positions.py               # 5 unit tests\n│   ├── test_locates.py                 # 8 unit tests\n│   ├── test_async.py                   # 11 unit tests\n│   ├── test_exceptions.py              # 3 unit tests\n│   ├── test_retry.py                   # 6 unit tests\n│   └── live/                           # Live integration tests (real API, opt-in)\n│       ├── conftest.py                 # Reads TZ_API_KEY / TZ_API_SECRET from env\n│       ├── test_accounts.py\n│       ├── test_trading.py\n│       ├── test_positions.py\n│       ├── test_locates.py\n│       └── test_errors.py\n│\n├── examples/\n│   ├── basic_sync.py                   # Synchronous usage example\n│   └── basic_async.py                  # Asynchronous usage example\n│\n├── .github/\n│   ├── ISSUE_TEMPLATE/\n│   │   ├── bug_report.md\n│   │   └── feature_request.md\n│   └── workflows/ci.yml                # CI pipeline (Python 3.11 + 3.12)\n│\n├── README.md                           # This file\n├── DOCUMENTATION.md                    # Complete reference documentation\n├── CONTRIBUTING.md                     # Contributor guide\n├── CHANGELOG.md                        # Version history\n├── SECURITY.md                         # Security and vulnerability policy\n├── LICENSE                             # MIT License\n├── pyproject.toml                      # Package metadata, deps, tool config\n└── pytest.ini                          # Pytest settings\n```\n\n---\n\n## Development\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the full contributor guide.\n\n```bash\n# Install all dependencies including dev tools\npoetry install\n\n# Run unit tests (no API credentials required)\npoetry run pytest -m \"not live\" --cov=tradezero -v\n\n# Lint with ruff\npoetry run ruff check .\n\n# Type-check with mypy\npoetry run mypy tradezero\n```\n\nLive integration tests (require real credentials):\n\n```bash\nexport TZ_API_KEY=\"your-key\"\nexport TZ_API_SECRET=\"your-secret\"\npoetry run pytest tests/live/ -m live -v\n```\n\n---\n\n## Sponsorship\n\nIf this SDK saves you time or money, consider sponsoring the project:\n\n[![Donate via PayPal](https://img.shields.io/badge/Donate-PayPal-00457C.svg?logo=paypal)](https://www.paypal.me/shaadyemad)\n\n**Binance Pay** — UID: `751730419`\n\nYour support helps maintain the library, add new endpoints, and test against the live API.\n\n---\n\n## Contact \u0026 Contributing\n\n- **Email:** [ShadyEmadContact@gmail.com](mailto:ShadyEmadContact@gmail.com)\n- **Issues \u0026 feature requests:** [GitHub Issues](https://github.com/shadyemad/tradezero-sdk/issues)\n- **Pull requests:** Read [CONTRIBUTING.md](CONTRIBUTING.md) first\n\nContributions are welcome:\n\n1. Fork the repository and create a feature branch from `main`\n2. Make your change and add tests\n3. Run `pytest -m \"not live\"`, `ruff check .`, and `mypy tradezero` — all must pass\n4. Open a pull request with a clear description\n\n---\n\n## License\n\n[MIT](LICENSE) — Copyright (c) 2026 Shady Emad\n\n---\n\n\u003e **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.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshaadyemad%2Ftradezero-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshaadyemad%2Ftradezero-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshaadyemad%2Ftradezero-sdk/lists"}