A Python wrapper for the TradeStation WebAPI, providing easy access to brokerage, order execution, and market data services.
Project description
TradeStation API Python Wrapper ๐
Hey there, Trader! ๐ Ready to connect your Python apps to the TradeStation universe? This library makes it easy-peasy.
Think of it as your friendly Pythonic remote control for TradeStation's API. Build trading bots, analyze data, manage your account โ all with clean, asynchronous Python code.
What Can You Do? โจ
- Log In Easily: Handles the tricky OAuth 2.0 stuff (including token refreshes) so you don't have to.
- Market Pulse: Grab real-time quotes, historical price bars, symbol details, and more.
- Account Access: Check your balances, see your positions, and review order history.
- Trade Time: Place, change, or cancel orders programmatically.
- Live Streams: Get data beamed straight to you with WebSocket support.
- Plays Nicely: Built-in rate limiting helps you avoid getting timed out by the API.
What You'll Need ๐
- Python 3.11 or newer (Gotta have that async power!)
- A TradeStation Account (Real or Simulated)
- Your TradeStation API Credentials (Client ID & Refresh Token - get these from the Developer Portal)
Get It Installed! ๐ป
Open your terminal and let's get this library installed.
# Option 1: Install directly from PyPI (Easiest ๐)
pip install tradestation-api-python
# Option 2: Clone the project (for developers)
git clone https://github.com/mxcoppell/tradestation-api-python.git
cd tradestation-api-python
# Then install using Poetry (Recommended for development โจ)
poetry install
# OR: Use pip if you prefer
# pip install -e .
Quick Start: Your First API Call! ๐
Let's fetch a stock quote right now!
- Set up your secrets: Copy
.env.sampleto.envand fill in yourCLIENT_ID,REFRESH_TOKEN, andENVIRONMENT(LiveorSimulation).cp .env.sample .env # Now edit .env with your details!
- Run this Python code:
import asyncio
import os
from dotenv import load_dotenv
from tradestation import TradeStationClient
async def get_a_quote():
# Load secrets from .env file
load_dotenv()
print(f"Using Environment: {os.getenv('ENVIRONMENT')}")
# Create the client (it reads your .env automatically!)
client = TradeStationClient()
try:
print("Asking TradeStation for an AAPL quote...")
# Use the market data service to get a quote snapshot
quote_response = await client.market_data.get_quote_snapshots("AAPL")
if quote_response and quote_response.Quotes:
aapl_price = quote_response.Quotes[0].Last
print(f"----> Got it! AAPL last price: ${aapl_price}")
else:
print("Hmm, couldn't get the quote. Error:", getattr(quote_response, 'Errors', 'Unknown error'))
except Exception as e:
print(f"Whoops! Something went wrong: {e}")
finally:
print("Closing the connection.")
# Always close the client when you're finished!
await client.close()
if __name__ == "__main__":
asyncio.run(get_a_quote())
Want more? Check out the examples/QuickStart directory for scripts you can run immediately!
Project Peek ๐
Curious how it's organized?
.
โโโ docs/ # You are here! (Hopefully useful docs)
โโโ examples/ # Ready-to-run example scripts!
โ โโโ QuickStart/ # Start here!
โ โโโ Brokerage/ # Account & order history examples
โ โโโ MarketData/ # Price, quote, & symbol examples
โ โโโ OrderExecution/ # Placing & managing orders examples
โโโ src/ # The heart of the library
โโโ tradestation/ # The importable package
โโโ client/ # The main TradeStationClient
โโโ services/ # API sections (MarketData, Brokerage, etc.)
โโโ streaming/ # WebSocket streaming code
โโโ ts_types/ # Data models (Pydantic types)
โโโ utils/ # Helpers (Auth, Rate Limiting, etc.)
Error Handling ๐ก๏ธ
This library provides a comprehensive exception system to help you handle API errors gracefully:
Exception Hierarchy
TradeStationAPIError (base exception)
โโโ TradeStationAuthError # Authentication failures (401, 403)
โโโ TradeStationRateLimitError # Rate limit exceeded (429)
โโโ TradeStationResourceNotFoundError # Resource not found (404)
โโโ TradeStationValidationError # Invalid request parameters (400)
โโโ TradeStationNetworkError # Network connectivity issues
โโโ TradeStationServerError # Server-side errors (5xx)
โโโ TradeStationTimeoutError # Request timeouts
โโโ TradeStationStreamError # WebSocket streaming issues
Using Exception Handling
from tradestation import TradeStationClient
from tradestation import (
TradeStationAPIError,
TradeStationAuthError,
TradeStationRateLimitError,
TradeStationValidationError,
TradeStationNetworkError
)
async def handle_with_care():
client = TradeStationClient()
try:
quotes = await client.market_data.get_quotes("AAPL,MSFT")
print(f"Success! Got quotes for {len(quotes)} symbols")
except TradeStationAuthError as e:
print(f"Authentication failed: {e}")
# Handle credential refresh or re-login
except TradeStationRateLimitError as e:
print(f"Rate limit hit: {e}")
if hasattr(e, 'retry_after') and e.retry_after:
print(f"Try again in {e.retry_after} seconds")
except TradeStationValidationError as e:
print(f"Invalid request: {e}")
if e.validation_errors:
print(f"Validation details: {e.validation_errors}")
except TradeStationNetworkError as e:
print(f"Network issue: {e}")
# Implement retry with backoff
except TradeStationAPIError as e:
# Catch-all for any other API errors
print(f"API error: {e}")
if e.status_code:
print(f"Status code: {e.status_code}")
if e.request_id:
print(f"Request ID: {e.request_id}")
Implementing Retries
For transient errors like rate limits, network issues, or server errors, you might want to implement retry logic:
import asyncio
import random
async def retry_with_backoff(func, max_attempts=3):
attempt = 0
while attempt < max_attempts:
try:
return await func()
except (TradeStationRateLimitError, TradeStationNetworkError,
TradeStationServerError, TradeStationTimeoutError) as e:
attempt += 1
if attempt >= max_attempts:
raise # Re-raise if we've hit max attempts
# Calculate backoff delay (with jitter)
if isinstance(e, TradeStationRateLimitError) and e.retry_after:
delay = e.retry_after
else:
# Exponential backoff with jitter
delay = (2 ** attempt) * (0.5 + 0.5 * random.random())
print(f"Retrying in {delay:.2f} seconds...")
await asyncio.sleep(delay)
For a complete error handling example, check out the examples/QuickStart/error_handling.py file.
Logging In (Authentication) ๐
The library needs your API keys to talk to TradeStation. The easiest way is the .env file (shown in Quick Start).
OAuth Client Types
The library supports both public and confidential OAuth clients:
- Public clients (default): No client secret needed - just provide
CLIENT_IDandREFRESH_TOKEN - Confidential clients: Require a
CLIENT_SECRETfor enhanced security in server-side applications
Other ways to provide credentials:
- Environment Variables: Set
CLIENT_ID,REFRESH_TOKEN,ENVIRONMENT(and optionallyCLIENT_SECRET) directly in your system. - Python Dictionary:
# Public client (no secret) client = TradeStationClient({ "client_id": "your_id", "refresh_token": "your_token", "environment": "Simulation" }) # Confidential client (with secret) client = TradeStationClient({ "client_id": "your_id", "client_secret": "your_secret", # Optional - only for confidential clients "refresh_token": "your_token", "environment": "Simulation" })
- Direct Parameters:
client = TradeStationClient( refresh_token="your_token", environment="Live" # CLIENT_ID and CLIENT_SECRET (if needed) can be in env or config )
See Authentication Guide for the full scoop on public vs. confidential clients.
Dive Deeper (Documentation) ๐
Ready for more details?
- ๐ Quick Start Guide
- ๐ Authentication
- ๐ Market Data
- ๐ผ Brokerage
- ๐ Order Execution
- โก Streaming Data
- ๐ฆ Rate Limiting
- ๐ก๏ธ Error Handling
Contributing ๐ค
Got ideas or found a bug? Feel free to open an issue or submit a pull request!
License ๐
This project is licensed under the MIT License - see the LICENSE file for details.
Happy Trading! ๐
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tradestation_api_python-1.3.2.tar.gz.
File metadata
- Download URL: tradestation_api_python-1.3.2.tar.gz
- Upload date:
- Size: 54.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.11.15 Linux/6.14.0-1017-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5d72d701a8b2d597bded7bff12c3aae9136f1e7b530035b9b7b81b973c88e23
|
|
| MD5 |
a83324c81b3053ea3b6a082c2efc79e0
|
|
| BLAKE2b-256 |
1571ac08d203f6bc3cb1d6fd9ed444c568ca737e49636f862fc95868b5e3704b
|
File details
Details for the file tradestation_api_python-1.3.2-py3-none-any.whl.
File metadata
- Download URL: tradestation_api_python-1.3.2-py3-none-any.whl
- Upload date:
- Size: 61.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.11.15 Linux/6.14.0-1017-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2051db86d9083ea3296b60a06811a9471047263d5448db667ee8a8cb32b384dc
|
|
| MD5 |
3390ab7e4c57118980acd25778cf1186
|
|
| BLAKE2b-256 |
970854a61caf1c4b5377525f13e376aefbd31767a07702de53f72286d6ba7970
|