Python client SDK for TradePose trading platform
Project description
TradePose Client SDK
Python SDK for TradePose quantitative trading platform. Simple, type-safe, production-ready.
What is this?
Official Python client for the TradePose trading platform API. Designed for quantitative traders, algo developers, and trading system architects who need:
- 🎯 Simple synchronous API - No async/await required, works out of the box
- 📊 Batch testing - Multi-strategy, multi-period backtesting with background polling
- 🔒 Type safety - Pydantic models, IDE autocomplete, compile-time validation
- 🎨 Fluent builder API - 60% less boilerplate for strategy construction
- 🔄 Production-ready - Comprehensive error handling, automatic retries, Jupyter support
- 📋 CRUD Resources - Strategy, Portfolio, Account, Binding management via Gateway API
Installation
pip install tradepose-client
Requirements:
- Python 3.13+
- Dependencies: httpx, pydantic, polars, nest-asyncio
Quick Start
Batch Testing (Recommended)
Test multiple strategies across multiple periods - no async/await needed:
from tradepose_client import BatchTester
from tradepose_client.batch import Period
# Create tester
tester = BatchTester(api_key="tp_live_xxx")
# Submit batch (non-blocking, returns immediately)
batch = tester.submit(
strategies=[strategy1, strategy2, strategy3],
periods=[
Period.Q1(2024), # 2024-01-01 to 2024-03-31
Period.Q2(2024), # 2024-04-01 to 2024-06-30
Period.Q3(2024), # 2024-07-01 to 2024-09-30
]
)
print(f"Submitted {batch.task_count} tasks")
print(f"Progress: {batch.progress:.1%}")
# Wait for completion (blocking)
batch.wait()
# Access results (Polars DataFrames)
summary_df = batch.summary() # Performance across all periods
all_trades_df = batch.all_trades() # All trades with period column
# Period-specific results
q1 = batch.get_period(Period.Q1(2024))
print(f"Q1 trades: {len(q1.trades)}")
print(f"Q1 PNL: {q1.trades['pnl'].sum()}")
Period Objects (Type-Safe Dates)
Use Period objects for type-safe date validation:
from tradepose_client.batch import Period
# Quarterly testing
periods = [
Period.Q1(2024), # Jan-Mar
Period.Q2(2024), # Apr-Jun
Period.Q3(2024), # Jul-Sep
Period.Q4(2024), # Oct-Dec
]
# Full year
full_year = Period.from_year(2024) # 2024-01-01 to 2024-12-31
# Single month
march = Period.from_month(2024, 3) # 2024-03-01 to 2024-03-31
# Flexible multi-month ranges
three_months = Period.from_month(2024, 3, n_months=3) # Mar-May 2024
half_year = Period.from_month(2024, 1, n_months=6) # Jan-Jun 2024
winter = Period.from_month(2024, 11, n_months=3) # Nov 2024 - Jan 2025
# Custom range
custom = Period(start="2024-01-15", end="2024-02-15")
Benefits:
- ✅ Compile-time type checking
- ✅ IDE autocomplete and validation
- ✅ Automatic validation (start < end)
- ✅ Clear error messages
Strategy Builder
Build strategies with a fluent, type-safe API:
from tradepose_client import (
StrategyBuilder,
BlueprintBuilder,
IndicatorType,
OrderStrategy,
TradeDirection,
TrendType,
Freq
)
import polars as pl
# Create strategy builder
builder = StrategyBuilder(
name="SuperTrend_Strategy",
base_instrument="TXF_M1_SHIOAJI_FUTURE",
base_freq=Freq.MIN_15
)
# Add indicators
atr = builder.add_indicator(
IndicatorType.ATR,
period=21,
freq=Freq.DAY_1,
shift=1
)
supertrend = builder.add_indicator(
IndicatorType.SUPERTREND,
multiplier=3.0,
volatility_column=atr.display_name(),
freq=Freq.DAY_1,
shift=1
)
# Build blueprint with entry/exit conditions
blueprint = (
BlueprintBuilder(
name="trend_follow",
direction=TradeDirection.LONG,
trend_type=TrendType.TREND
)
.add_entry_trigger(
name="supertrend_long",
conditions=[
supertrend.col().struct.field("direction") == 1,
pl.col("ts").dt.hour().is_between(1, 11)
],
price_expr=pl.col("open"),
order_strategy=OrderStrategy.IMMEDIATE_ENTRY,
priority=1
)
.add_exit_trigger(
name="friday_exit",
conditions=[
(pl.col("ts").dt.weekday() == 4) &
(pl.col("ts").dt.hour() == 23)
],
price_expr=pl.col("open"),
order_strategy=OrderStrategy.IMMEDIATE_EXIT,
priority=1
)
.build()
)
# Build final strategy
strategy = builder.set_base_blueprint(blueprint).build(
volatility_indicator=atr
)
# Use in backtest
tester = BatchTester(api_key="tp_live_xxx")
batch = tester.submit(
strategies=[strategy],
periods=[Period.from_year(2024)]
)
batch.wait()
trades_df = batch.all_trades()
print(f"Total PNL: {trades_df['pnl'].sum():,.2f}")
Core Concepts
Batch Testing API (Primary Interface)
BatchTester is the main way to interact with the platform:
from tradepose_client import BatchTester
from tradepose_client.batch import Period
tester = BatchTester(api_key="tp_live_xxx")
# Submit tasks
batch = tester.submit(
strategies=[strategy1, strategy2],
periods=[Period.Q1(2024), Period.Q2(2024)]
)
# Monitor progress
print(f"Progress: {batch.progress:.1%}")
print(f"Completed: {batch.completed_count}/{batch.task_count}")
# Wait for completion
batch.wait() # Blocks until all tasks complete
# Access results
summary = batch.summary() # Aggregate results
all_trades = batch.all_trades() # All trades across periods
# Period-specific results
q1_result = batch.get_period(Period.Q1(2024))
print(f"Q1 trades: {len(q1_result.trades)}")
Features:
- Synchronous interface - No async/await required
- Background polling - Tasks execute in background, results auto-download
- Type-safe dates - Period objects with validation
- Polars DataFrames - High-performance data analysis
- Jupyter-friendly - Automatic event loop setup
Instrument Discovery
Query available trading instruments:
from tradepose_client import BatchTester
tester = BatchTester(api_key="tp_live_xxx")
# List all available instruments
instruments = tester.list_instruments()
print(f"Available instruments: {len(instruments)}")
for inst in instruments[:5]:
print(f" {inst.symbol} - {inst.exchange} ({inst.freq})")
# Filter by exchange
binance = [i for i in instruments if i.exchange == "BINANCE"]
CRUD Resources (v0.3.0)
Manage trading entities via Gateway API:
from tradepose_client import TradePoseClient
client = TradePoseClient(api_key="tp_live_xxx")
# Strategy management
strategies = client.strategies.list()
strategy = client.strategies.create(name="MyStrategy", config={...})
# Portfolio management
portfolios = client.portfolios.list()
portfolio = client.portfolios.create(
name="MyPortfolio",
capital=100000,
currency="USD"
)
# Account management (MT5, Binance, etc.)
accounts = client.accounts.list()
# Binding (connect Portfolio to Account)
binding = client.bindings.create(
account_id=account.id,
portfolio_id=portfolio.id
)
Low-Level API (Advanced Users)
For fine-grained control over HTTP connections, custom retry logic, or manual event loop management, see Low-Level API Documentation.
Most users should use BatchTester - it's simpler and handles async complexity automatically.
Task Polling Pattern
Long-running operations return immediately with a task ID. Results are downloaded automatically in the background:
# Submit returns immediately
batch = tester.submit(strategies=[strategy], periods=[Period.Q1(2024)])
print(f"Task ID: {batch.task_ids[0]}") # Submitted
# Background polling starts automatically
# Do other work while tasks run...
# Wait when you need results
batch.wait() # Blocks until completion
# Results ready
trades = batch.all_trades()
Documentation
- 💡 Examples - Real-world usage patterns (start here!)
- 📚 API Reference - Complete API documentation
- 🔧 Low-Level API - Advanced async API (for experts)
- ⚠️ Error Handling - Exception types and handling strategies
- ⚙️ Configuration - Environment variables, timeout settings
- 📐 Architecture - Design decisions and data flow
Features
Current (Alpha)
Batch Testing API
- ✅ Multi-strategy, multi-period testing
- ✅ Background polling (daemon thread)
- ✅ Auto-download on completion
- ✅ Type-safe Period objects with validation
- ✅ Convenient constructors (Q1, Q2, from_year, from_month)
- ✅ Reactive results (lazy loading)
- ✅ Memory caching
- ✅ Jupyter support (nest_asyncio auto-applied)
Builder API
- ✅ Fluent strategy construction
- ✅ Type-safe indicator references
- ✅ 60% less boilerplate
- ✅ TradingContext convenience accessors
- ✅ Automatic field inheritance
Low-Level Client API
- ✅ Authentication (API key + JWT)
- ✅ Resource-based organization (6 resources, 21 methods)
- ✅ Async-first with HTTP/2
- ✅ Automatic retry with exponential backoff
- ✅ Comprehensive error handling (18 exception types)
- ✅ Type-safe with Pydantic models
CRUD Resources (v0.3.0)
- ✅ Strategy management (create, list, get, update, delete)
- ✅ Portfolio management with capital allocation
- ✅ Account management (MT5, Binance, etc.)
- ✅ Binding management (Account ↔ Portfolio)
- ✅ Instrument discovery (
list_instruments()) - ✅ TradingContext convenience accessors
Roadmap
- ⏳ Webhook support (replace polling)
- ⏳ GraphQL endpoint (reduce requests)
- ⏳ Result streaming (large datasets)
Configuration
Environment Variables
# Authentication (required, at least one)
export TRADEPOSE_API_KEY="tp_live_xxx"
export TRADEPOSE_JWT_TOKEN="eyJ..."
# Server (optional)
export TRADEPOSE_SERVER_URL="https://api.tradepose.com"
# HTTP (optional)
export TRADEPOSE_TIMEOUT="30.0" # Request timeout (1.0 - 600.0s)
export TRADEPOSE_MAX_RETRIES="3" # Max retry attempts (0 - 10)
# Task polling (optional)
export TRADEPOSE_POLL_INTERVAL="2.0" # Poll interval (0.5 - 60.0s)
export TRADEPOSE_POLL_TIMEOUT="300.0" # Max poll duration (10.0 - 3600.0s)
# Logging (optional)
export TRADEPOSE_DEBUG="false"
export TRADEPOSE_LOG_LEVEL="INFO" # DEBUG/INFO/WARNING/ERROR/CRITICAL
Configuration Methods
# Method 1: Environment variables (recommended)
tester = BatchTester() # Auto-loads from TRADEPOSE_API_KEY
# Method 2: Direct parameters
tester = BatchTester(
api_key="tp_live_xxx",
poll_interval=2.0,
auto_download=True
)
# Method 3: Configuration file (see Configuration Guide)
See Configuration Guide for details.
Error Handling
All exceptions inherit from TradePoseError:
from tradepose_client import (
BatchTester,
AuthenticationError,
RateLimitError,
TaskTimeoutError,
ValidationError
)
from tradepose_client.batch import Period
tester = BatchTester(api_key="tp_xxx")
try:
batch = tester.submit(
strategies=[strategy],
periods=[Period.Q1(2024)]
)
batch.wait(timeout=600.0)
except AuthenticationError:
# Invalid API key
print("Authentication failed")
except ValidationError as e:
# Invalid Period or strategy configuration
print(f"Validation error: {e.errors}")
except RateLimitError as e:
# Rate limit exceeded
print(f"Rate limited. Wait {e.retry_after}s")
except TaskTimeoutError as e:
# Task didn't complete in time
print(f"Timeout. Task ID: {e.task_id}")
See Error Handling Guide for complete reference.
Period Validation
Period objects automatically validate date ranges:
from tradepose_client.batch import Period
# Valid period
period = Period(start="2024-01-01", end="2024-12-31") # ✅ OK
# Invalid period (start >= end)
try:
period = Period(start="2024-12-31", end="2024-01-01") # ❌ Error
except ValueError as e:
print(e) # "Period start (2024-12-31) must be before end (2024-01-01)"
# Invalid date format
try:
period = Period(start="invalid", end="2024-12-31") # ❌ Error
except ValueError as e:
print(e) # "Cannot parse datetime from type..."
Migration from Tuple-Based Periods
Before (deprecated):
# ❌ No longer supported
batch = tester.submit(
strategies=[strategy],
periods=[("2024-01-01", "2024-12-31")] # Tuple not accepted
)
After (type-safe):
# ✅ Required: Use Period objects
from tradepose_client.batch import Period
batch = tester.submit(
strategies=[strategy],
periods=[Period(start="2024-01-01", end="2024-12-31")]
)
# ✅ Even better: Use convenience constructors
batch = tester.submit(
strategies=[strategy],
periods=[Period.from_year(2024)] # Clearer and type-safe
)
This is a Breaking Change in version 0.2.0+. Update your code to use Period objects.
Development Status
Alpha - API is stable but subject to minor changes. Production use at your own risk.
Python Version Support
Requires Python 3.13+ to leverage:
- Type parameter syntax (
[T]) Selftype hint- Performance improvements
License
MIT License - see LICENSE file for details.
Support
- Documentation: docs/
- Issues: GitHub Issues
- Email: support@tradepose.com
Project details
Release history Release notifications | RSS feed
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 tradepose_client-1.7.0.tar.gz.
File metadata
- Download URL: tradepose_client-1.7.0.tar.gz
- Upload date:
- Size: 239.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b56793cb85475633075530b6f0adc0f5e82fefc673715133fc93e61a2af3cf6
|
|
| MD5 |
0ef079f00bb142b673fce17b6a48774d
|
|
| BLAKE2b-256 |
f9437290154d3776c22f18632a0cd4086c91f22330f852cd72cd7fadd9afa559
|
Provenance
The following attestation bundles were made for tradepose_client-1.7.0.tar.gz:
Publisher:
publish-python-client.yml on codeotter0201/tradepose-monorepo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tradepose_client-1.7.0.tar.gz -
Subject digest:
3b56793cb85475633075530b6f0adc0f5e82fefc673715133fc93e61a2af3cf6 - Sigstore transparency entry: 1171688035
- Sigstore integration time:
-
Permalink:
codeotter0201/tradepose-monorepo@a666c86e3a598e7407c789822147b8b7437f8154 -
Branch / Tag:
refs/tags/client-v1.7.0 - Owner: https://github.com/codeotter0201
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python-client.yml@a666c86e3a598e7407c789822147b8b7437f8154 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tradepose_client-1.7.0-py3-none-any.whl.
File metadata
- Download URL: tradepose_client-1.7.0-py3-none-any.whl
- Upload date:
- Size: 180.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6816c8ee38b99de56ffd96c7ca9db01511a79403c25865128ef6eb9ab7ff4bd
|
|
| MD5 |
be20271f749f4094e85d9cb5112e486c
|
|
| BLAKE2b-256 |
9310891abe1ea0a8095cf0fbd0f0fc9ebacee81106bdf7548fad1f5601866525
|
Provenance
The following attestation bundles were made for tradepose_client-1.7.0-py3-none-any.whl:
Publisher:
publish-python-client.yml on codeotter0201/tradepose-monorepo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tradepose_client-1.7.0-py3-none-any.whl -
Subject digest:
a6816c8ee38b99de56ffd96c7ca9db01511a79403c25865128ef6eb9ab7ff4bd - Sigstore transparency entry: 1171688043
- Sigstore integration time:
-
Permalink:
codeotter0201/tradepose-monorepo@a666c86e3a598e7407c789822147b8b7437f8154 -
Branch / Tag:
refs/tags/client-v1.7.0 - Owner: https://github.com/codeotter0201
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python-client.yml@a666c86e3a598e7407c789822147b8b7437f8154 -
Trigger Event:
push
-
Statement type: