Client API

The main ProjectX client provides access to market data, account information, and core trading functionality.

ProjectX Client

V3 Async ProjectX Python SDK - Core Async Client Module

Author: @TexasCoding Date: 2025-08-02

This module contains the async version of the ProjectX client class for the ProjectX Python SDK. It provides a comprehensive asynchronous interface for interacting with the ProjectX Trading Platform Gateway API, enabling developers to build high-performance trading applications.

The async client handles authentication, account management, market data retrieval, and basic trading operations using async/await patterns for improved performance and concurrency.

Key Features: - Async multi-account authentication and management - Concurrent API operations with httpx - Async historical market data retrieval with caching - Non-blocking position tracking and trade history - Async error handling and connection management - HTTP/2 support for improved performance

For advanced trading operations, use the specialized managers: - OrderManager: Complete order lifecycle management - PositionManager: Portfolio analytics and risk management - ProjectXRealtimeDataManager: Real-time multi-timeframe OHLCV data - OrderBook: Level 2 market depth and microstructure analysis

class ProjectX(username, api_key, config=None, account_name=None)[source]

Bases: ProjectXBase

Async core ProjectX client for the ProjectX Python SDK.

This class provides the async foundation for building trading applications by offering comprehensive asynchronous access to the ProjectX Trading Platform Gateway API. It handles core functionality including:

  • Multi-account authentication and JWT token management

  • Async instrument search and contract selection with caching

  • High-performance historical market data retrieval

  • Non-blocking position and trade history access

  • Automatic retry logic and connection pooling

  • Rate limiting and error handling

The async client is designed for high-performance applications requiring concurrent operations, real-time data processing, or integration with async frameworks like FastAPI, aiohttp, or Discord.py.

For order management and real-time data, use the specialized async managers from the project_x_py.async_api module which integrate seamlessly with this client.

Example

>>> # V3: Basic async SDK usage with environment variables (recommended)
>>> import asyncio
>>> from project_x_py import ProjectX
>>>
>>> async def main():
>>> # V3: Create and authenticate client with context manager
>>>     async with ProjectX.from_env() as client:
>>>         await client.authenticate()
>>>
>>> # V3: Get account info with typed models
>>>         account = client.account_info  # After authentication
>>>         print(f"Account: {account.name}")
>>>         print(f"ID: {account.id}")
>>>         print(f"Balance: ${account.balance:,.2f}")
>>>
>>> # V3: Search for instruments with smart contract selection
>>>         instruments = await client.search_instruments("MNQ")
>>>         mnq = instruments[0] if instruments else None
>>>         if mnq:
>>>             print(f"Found: {mnq.name} ({mnq.symbol})")
>>>             print(f"Contract ID: {mnq.id}")
>>>
>>> # V3: Get historical data concurrently (returns Polars DataFrames)
>>>         tasks = [
>>>             client.get_bars("MNQ", days=5, interval=5),  # 5-min bars
>>>             client.get_bars("ES", days=1, interval=1),   # 1-min bars
>>>         ]
>>>         nasdaq_data, sp500_data = await asyncio.gather(*tasks)
>>>
>>>         print(f"Nasdaq bars: {len(nasdaq_data)} (Polars DataFrame)")
>>>         print(f"S&P 500 bars: {len(sp500_data)} (Polars DataFrame)")
>>>         print(f"Columns: {nasdaq_data.columns}")
>>>
>>> asyncio.run(main())
For advanced async trading applications, use the TradingSuite:
>>> # V3: Advanced trading with the TradingSuite
>>> import asyncio
>>> from project_x_py import TradingSuite
>>>
>>> async def trading_app():
>>> # The TradingSuite simplifies setup and integrates all managers
>>>     suite = await TradingSuite.create(
...         "MNQ",
...         timeframes=["1min", "5min"],
...         features=["orderbook", "risk_manager"]
...     )
>>>
>>> # Client is authenticated and real-time data is streaming.
>>>
>>> # Access integrated managers easily
>>>     order = await suite.orders.place_market_order(
...         contract_id=suite.instrument_id,
...         side=0,  # Buy
...         size=1
...     )
>>>
>>>     position = await suite.positions.get_position("MNQ")
>>>     bars = await suite.data.get_data("1min")
>>>
>>>     print(f"Placed order {order.id}, current position: {position.netPos}")
>>>     print(f"Latest 1-min bar: {bars.tail(1)}")
>>>
>>> asyncio.run(trading_app())
class ProjectXBase(username, api_key, config=None, account_name=None)[source]

Bases: AuthenticationMixin, HttpMixin, CacheMixin, MarketDataMixin, TradingMixin

Base class combining all ProjectX client functionality.

async __aenter__()[source]

Async context manager entry.

Return type:

ProjectXBase

async __aexit__(exc_type, exc_val, exc_tb)[source]

Async context manager exit.

Return type:

None

__init__(username, api_key, config=None, account_name=None)[source]

Initialize async ProjectX client for building trading applications.

Parameters:
  • username (str) – ProjectX username for authentication

  • api_key (str) – API key for ProjectX authentication

  • config (ProjectXConfig | None) – Optional configuration object with endpoints and settings

  • account_name (str | None) – Optional account name to select specific account

classmethod from_config_file(cls, config_file, account_name=None)[source]

Create async ProjectX client using a configuration file.

Alternative initialization method that loads configuration and credentials from a JSON file instead of environment variables. Useful for managing multiple configurations or environments.

Parameters:
  • config_file (str) – Path to JSON configuration file containing: - username: ProjectX account username - api_key: API authentication key - api_url: API endpoint URL (optional) - websocket_url: WebSocket URL (optional) - timezone: Preferred timezone (optional)

  • account_name (str | None) – Optional account name to select when multiple accounts are available. Overrides any account name specified in the config file.

Yields:

ProjectX – Configured client instance ready for trading operations

Raises:
Return type:

AsyncGenerator[ProjectXBase, None]

Example

>>> # V3: Create config file
>>> import json
>>> config = {
...     "username": "your_username",
...     "api_key": "your_api_key",
...     "api_url": "https://gateway.topstepx.com/api",
...     "websocket_url": "wss://gateway.topstepx.com/signalr",
...     "timezone": "US/Central",
... }
>>> with open("config.json", "w") as f:
...     json.dump(config, f)
>>>
>>> # V3: Use client with config file
>>> import asyncio
>>> from project_x_py import ProjectX
>>>
>>> async def main():
>>>     async with ProjectX.from_config_file("config.json") as client:
>>>         await client.authenticate()
>>> # Client is ready for trading operations
>>>         positions = await client.search_open_positions()
>>>         print(f"Open positions: {len(positions)}")
>>>
>>> asyncio.run(main())

Note

  • Config file should not be committed to version control

  • Consider using environment variables for production

  • File permissions should restrict access to the config file

classmethod from_env(cls, config=None, account_name=None)[source]

Create async ProjectX client using environment variables (recommended approach).

This is the preferred method for initializing the async client as it keeps sensitive credentials out of your source code.

Environment Variables Required:

PROJECT_X_API_KEY: API key for ProjectX authentication PROJECT_X_USERNAME: Username for ProjectX account

Optional Environment Variables:

PROJECT_X_ACCOUNT_NAME: Account name to select specific account

Parameters:
  • config (ProjectXConfig | None) – Optional configuration object with endpoints and settings

  • account_name (str | None) – Optional account name (overrides environment variable)

Yields:

ProjectX – Configured async client instance ready for building trading applications

Raises:

ValueError – If required environment variables are not set

Return type:

AsyncGenerator[ProjectXBase, None]

Example

>>> # V3: Set environment variables first
>>> import os
>>> os.environ["PROJECT_X_API_KEY"] = "your_api_key_here"
>>> os.environ["PROJECT_X_USERNAME"] = "your_username_here"
>>> os.environ["PROJECT_X_ACCOUNT_NAME"] = (
...     "PRACTICEJUL2415232717"  # Optional
... )
>>>
>>> # V3: Create async client using context manager (recommended approach)
>>> import asyncio
>>> from project_x_py import ProjectX
>>>
>>> async def main():
>>>     async with ProjectX.from_env() as client:
>>>         await client.authenticate()
>>> # Client is now ready for use
>>>         instrument = await client.get_instrument("MNQ")
>>>         bars = await client.get_bars("MNQ", days=1, interval=5)
>>>         print(f"Retrieved {len(bars)} bars for {instrument.name}")
>>>
>>> asyncio.run(main())
get_account_info()[source]

Get the currently selected account information.

Returns:

Current account details

Return type:

Account

Raises:

ProjectXAuthenticationError – If not authenticated

get_session_token()[source]

Get the current session JWT token.

Returns:

JWT token for authentication

Return type:

str

Raises:

ProjectXAuthenticationError – If not authenticated

class RateLimiter(max_requests, window_seconds)[source]

Bases: object

Async rate limiter using sliding window algorithm.

This rate limiter implements a sliding window algorithm that tracks the exact timestamp of each request. It ensures that at any point in time, no more than max_requests have been made in the past window_seconds.

Features:
  • Thread-safe using asyncio locks

  • Accurate sliding window implementation

  • Automatic cleanup of old request timestamps

  • Memory-efficient with bounded history

  • Zero CPU usage while waiting

Parameters:
  • max_requests (int) – Maximum number of requests allowed in the window

  • window_seconds (int) – Size of the sliding window in seconds

Example

>>> # Create a rate limiter for 10 requests per second
>>> limiter = RateLimiter(max_requests=10, window_seconds=1)
>>>
>>> # Use in an async function
>>> async def rate_limited_operation():
...     await limiter.acquire()
...     # Perform operation here
...     return "Success"
>>>
>>> # The limiter will automatically delay if needed
>>> async def bulk_operations():
...     tasks = [rate_limited_operation() for _ in range(50)]
...     results = await asyncio.gather(*tasks)
...     # This will take ~5 seconds (50 requests / 10 per second)
__init__(max_requests, window_seconds)[source]
async acquire()[source]

Wait if necessary to stay within rate limits.

Return type:

None

class ProjectX(username, api_key, config=None, account_name=None)[source]

Bases: ProjectXBase

Async core ProjectX client for the ProjectX Python SDK.

This class provides the async foundation for building trading applications by offering comprehensive asynchronous access to the ProjectX Trading Platform Gateway API. It handles core functionality including:

  • Multi-account authentication and JWT token management

  • Async instrument search and contract selection with caching

  • High-performance historical market data retrieval

  • Non-blocking position and trade history access

  • Automatic retry logic and connection pooling

  • Rate limiting and error handling

The async client is designed for high-performance applications requiring concurrent operations, real-time data processing, or integration with async frameworks like FastAPI, aiohttp, or Discord.py.

For order management and real-time data, use the specialized async managers from the project_x_py.async_api module which integrate seamlessly with this client.

Example

>>> # V3: Basic async SDK usage with environment variables (recommended)
>>> import asyncio
>>> from project_x_py import ProjectX
>>>
>>> async def main():
>>> # V3: Create and authenticate client with context manager
>>>     async with ProjectX.from_env() as client:
>>>         await client.authenticate()
>>>
>>> # V3: Get account info with typed models
>>>         account = client.account_info  # After authentication
>>>         print(f"Account: {account.name}")
>>>         print(f"ID: {account.id}")
>>>         print(f"Balance: ${account.balance:,.2f}")
>>>
>>> # V3: Search for instruments with smart contract selection
>>>         instruments = await client.search_instruments("MNQ")
>>>         mnq = instruments[0] if instruments else None
>>>         if mnq:
>>>             print(f"Found: {mnq.name} ({mnq.symbol})")
>>>             print(f"Contract ID: {mnq.id}")
>>>
>>> # V3: Get historical data concurrently (returns Polars DataFrames)
>>>         tasks = [
>>>             client.get_bars("MNQ", days=5, interval=5),  # 5-min bars
>>>             client.get_bars("ES", days=1, interval=1),   # 1-min bars
>>>         ]
>>>         nasdaq_data, sp500_data = await asyncio.gather(*tasks)
>>>
>>>         print(f"Nasdaq bars: {len(nasdaq_data)} (Polars DataFrame)")
>>>         print(f"S&P 500 bars: {len(sp500_data)} (Polars DataFrame)")
>>>         print(f"Columns: {nasdaq_data.columns}")
>>>
>>> asyncio.run(main())
For advanced async trading applications, use the TradingSuite:
>>> # V3: Advanced trading with the TradingSuite
>>> import asyncio
>>> from project_x_py import TradingSuite
>>>
>>> async def trading_app():
>>> # The TradingSuite simplifies setup and integrates all managers
>>>     suite = await TradingSuite.create(
...         "MNQ",
...         timeframes=["1min", "5min"],
...         features=["orderbook", "risk_manager"]
...     )
>>>
>>> # Client is authenticated and real-time data is streaming.
>>>
>>> # Access integrated managers easily
>>>     order = await suite.orders.place_market_order(
...         contract_id=suite.instrument_id,
...         side=0,  # Buy
...         size=1
...     )
>>>
>>>     position = await suite.positions.get_position("MNQ")
>>>     bars = await suite.data.get_data("1min")
>>>
>>>     print(f"Placed order {order.id}, current position: {position.netPos}")
>>>     print(f"Latest 1-min bar: {bars.tail(1)}")
>>>
>>> asyncio.run(trading_app())

Configuration Management

class ConfigManager(config_file=None)[source]

Bases: object

Configuration manager for ProjectX client.

Handles loading configuration from: 1. Environment variables 2. Configuration files 3. Default values

Priority order: Environment variables > Config file > Defaults

__init__(config_file=None)[source]

Initialize configuration manager.

Parameters:

config_file (str | Path | None) – Optional path to configuration file

load_config()[source]

Load configuration with priority order.

Return type:

ProjectXConfig

Returns:

ProjectXConfig instance

save_config(config, file_path=None)[source]

Save configuration to file.

Parameters:
  • config (ProjectXConfig) – Configuration to save

  • file_path (str | Path | None) – Optional path to save to (uses self.config_file if None)

Return type:

None

get_auth_config()[source]

Get authentication configuration from environment variables.

Return type:

dict[str, str]

Returns:

Dictionary with authentication settings

Raises:

ValueError – If required authentication variables are missing or invalid

validate_config(config)[source]

Validate configuration settings.

Parameters:

config (ProjectXConfig) – Configuration to validate

Return type:

bool

Returns:

True if configuration is valid

Raises:

ValueError – If configuration is invalid

Configuration Models

class ProjectXConfig(api_url='https://api.topstepx.com/api', realtime_url='wss://realtime.topstepx.com/api', user_hub_url='https://rtc.topstepx.com/hubs/user', market_hub_url='https://rtc.topstepx.com/hubs/market', timezone='America/Chicago', timeout_seconds=30, retry_attempts=3, retry_delay_seconds=2.0, requests_per_minute=60, burst_limit=10)[source]

Bases: object

Configuration settings for the ProjectX client.

Default URLs are set for TopStepX endpoints. For custom ProjectX endpoints, update the URLs accordingly using create_custom_config() or direct assignment.

TopStepX (Default): - user_hub_url: “https://rtc.topstepx.com/hubs/user” - market_hub_url: “https://rtc.topstepx.com/hubs/market

api_url

Base URL for the API endpoints

Type:

str

realtime_url

URL for real-time WebSocket connections

Type:

str

user_hub_url

URL for user hub WebSocket (accounts, positions, orders)

Type:

str

market_hub_url

URL for market hub WebSocket (quotes, trades, depth)

Type:

str

timezone

Timezone for timestamp handling

Type:

str

timeout_seconds

Request timeout in seconds

Type:

int

retry_attempts

Number of retry attempts for failed requests

Type:

int

retry_delay_seconds

Delay between retry attempts

Type:

float

requests_per_minute

Rate limiting - requests per minute

Type:

int

burst_limit

Rate limiting - burst limit

Type:

int

api_url: str = 'https://api.topstepx.com/api'
realtime_url: str = 'wss://realtime.topstepx.com/api'
user_hub_url: str = 'https://rtc.topstepx.com/hubs/user'
market_hub_url: str = 'https://rtc.topstepx.com/hubs/market'
timezone: str = 'America/Chicago'
timeout_seconds: int = 30
retry_attempts: int = 3
retry_delay_seconds: float = 2.0
requests_per_minute: int = 60
burst_limit: int = 10
__init__(api_url='https://api.topstepx.com/api', realtime_url='wss://realtime.topstepx.com/api', user_hub_url='https://rtc.topstepx.com/hubs/user', market_hub_url='https://rtc.topstepx.com/hubs/market', timezone='America/Chicago', timeout_seconds=30, retry_attempts=3, retry_delay_seconds=2.0, requests_per_minute=60, burst_limit=10)

Factory Functions

Client Creation

Configuration Helpers

load_default_config()[source]

Load default configuration with environment variable overrides.

Return type:

ProjectXConfig

Returns:

ProjectXConfig instance

create_config_template(file_path)[source]

Create a configuration file template.

Parameters:

file_path (str | Path) – Path where to create the template

Return type:

None

check_environment()[source]

Check environment setup for ProjectX.

Return type:

dict[str, Any]

Returns:

Dictionary with environment status

Utility Functions