Quick Start Guide

Get up and running with the ProjectX Python SDK in minutes to start building your trading applications.

Prerequisites

Before you begin, make sure you have:

  1. Python 3.12 or higher installed

  2. project-x-py package installed (see Installation)

  3. TopStepX account with API access

  4. Your API credentials (username and API key)

Step 1: Set Up Credentials

Set your API credentials as environment variables:

export PROJECT_X_API_KEY='your_api_key_here'
export PROJECT_X_USERNAME='your_username_here'

On Windows:

set PROJECT_X_API_KEY=your_api_key_here
set PROJECT_X_USERNAME=your_username_here

Or create a .env file in your project directory:

PROJECT_X_API_KEY=your_api_key_here
PROJECT_X_USERNAME=your_username_here

Step 2: Create Your First Client

import asyncio
from project_x_py import ProjectX

async def main():
    # Create client using environment variables
    async with ProjectX.from_env() as client:
        # Authenticate
        await client.authenticate()

        # Get account information
        print(f"Account: {client.account_info.name}")
        print(f"Balance: ${client.account_info.balance:,.2f}")

# Run the async function
asyncio.run(main())

Step 3: Get Market Data

async def get_market_data():
    async with ProjectX.from_env() as client:
        await client.authenticate()

        # Get historical data for Micro E-mini NASDAQ futures (V3: actual symbol)
        data = await client.get_bars('MNQ', days=5, interval=15)
        print(f"Retrieved {len(data)} bars of data")
        print(data.head())

        # Search for instruments
        instruments = await client.search_instruments('MNQ')
        for instrument in instruments:
            print(f"{instrument.name}: {instrument.description}")

asyncio.run(get_market_data())

Step 4: Place Your First Order

Warning

The following examples place real orders! Make sure you’re using a demo account for testing.

from project_x_py import TradingSuite

async def place_order():
    # V3.1: Use TradingSuite for simplified initialization
    suite = await TradingSuite.create("MNQ")

    # Place a limit order using the integrated order manager
    response = await suite.orders.place_limit_order(
        contract_id=suite.instrument_id,  # Use instrument ID
        side=0,                     # 0=Buy, 1=Sell
        size=1,                     # 1 contract
        limit_price=21050.0         # Limit price
    )

    if response.success:
        print(f"Order placed! Order ID: {response.orderId}")
    else:
        print(f"Order failed: {response}")

    await suite.disconnect()

asyncio.run(place_order())

Step 5: Monitor Positions

from project_x_py import TradingSuite

async def monitor_positions():
    # V3.1: Use TradingSuite for all components
    suite = await TradingSuite.create("MNQ")

    # Get all open positions using integrated position manager
    positions = await suite.positions.get_all_positions()
    for position in positions:
        direction = "LONG" if position.side == 0 else "SHORT"
        print(f"{position.contract_id}: {direction} {position.size} @ ${position.average_price:.2f}")

    # Get portfolio metrics
    portfolio = await suite.positions.get_portfolio_pnl()
    print(f"Total positions: {portfolio['position_count']}")

    await suite.disconnect()

asyncio.run(monitor_positions())

Step 6: Real-time Data (Optional)

from project_x_py import TradingSuite, EventType

async def setup_realtime():
    # V3.1: Use TradingSuite for complete setup
    suite = await TradingSuite.create(
        instrument='MNQ',
        timeframes=['1min', '5min', '15min']
    )

    # Register event handlers via integrated EventBus
    @suite.events.on(EventType.NEW_BAR)
    async def on_new_bar(event):
        print(f"New bar: {event.data['timeframe']} - {event.data['close']}")

    # Access live data (automatically initialized)
    live_data = await suite.data.get_data('5min')
    print(f"Live data: {len(live_data)} bars")

    # Keep running for 60 seconds to collect data
    await asyncio.sleep(60)
    await suite.disconnect()

asyncio.run(setup_realtime())

Common Patterns

Basic Trading Workflow

from project_x_py import TradingSuite

async def trading_workflow():
    # V3.1: Use TradingSuite for simplified initialization
    suite = await TradingSuite.create('MNQ')

    # All managers are automatically initialized and connected
    # suite.client - Authenticated ProjectX client
    # suite.orders - Order manager
    # suite.positions - Position manager
    # suite.data - Real-time data manager
    # suite.events - Event bus for notifications

    # Check account status
    print(f"Account balance: ${suite.client.account_info.balance:,.2f}")

    # Get market data using integrated data manager
    data = await suite.data.get_data('5min')
    if data is not None and not data.is_empty():
        current_price = float(data['close'].tail(1).item())
    else:
        # Fallback to client API if real-time data not available
        data = await suite.client.get_bars('MNQ', days=1, interval=5)
        current_price = float(data.select('close').tail(1).item())

    # Place bracket order (entry + stop + target)
    bracket = await suite.orders.place_bracket_order(
        contract_id=suite.instrument_id,
        side=0,                    # Buy
        size=1,
        entry_price=current_price - 5.0,   # Entry below market
        stop_loss_price=current_price - 10.0,  # $10 risk
        take_profit_price=current_price + 10.0  # $10 profit target
    )

    if bracket.success:
        print("Bracket order placed successfully!")

    await suite.disconnect()

asyncio.run(trading_workflow())

Market Analysis with Technical Indicators

from project_x_py.indicators import RSI, SMA, BBANDS, MACD

async def analyze_market():
    async with ProjectX.from_env() as client:
        await client.authenticate()

        # Get data
        data = await client.get_bars('MNQ', days=30, interval=60)  # V3: actual symbol

        # Calculate technical indicators using TA-Lib style functions
        data = RSI(data, period=14)
        data = SMA(data, period=20)
        data = SMA(data, period=50)
        data = BBANDS(data, period=20, std_dev=2.0)
        data = MACD(data, fast_period=12, slow_period=26, signal_period=9)

        # Check latest values
        latest = data.tail(1)
        print(f"Current RSI: {latest['rsi_14'].item():.2f}")
        print(f"Price: ${latest['close'].item():.2f}")
        print(f"SMA(20): ${latest['sma_20'].item():.2f}")
        print(f"SMA(50): ${latest['sma_50'].item():.2f}")
        print(f"MACD: {latest['macd'].item():.4f}")

        # Simple signal logic
        rsi_val = latest['rsi_14'].item()
        price = latest['close'].item()
        sma_20 = latest['sma_20'].item()
        sma_50 = latest['sma_50'].item()

        if rsi_val < 30 and price > sma_20 > sma_50:
            print("🟢 Potential BUY signal: Oversold RSI + Uptrend")
        elif rsi_val > 70 and price < sma_20 < sma_50:
            print("🔴 Potential SELL signal: Overbought RSI + Downtrend")

asyncio.run(analyze_market())

Error Handling

from project_x_py import TradingSuite, ProjectXError, ProjectXOrderError

async def place_order_with_error_handling():
    try:
        # V3.1: Use TradingSuite for all trading operations
        suite = await TradingSuite.create('MNQ')

        # Attempt to place order using integrated order manager
        response = await suite.orders.place_limit_order(
            contract_id=suite.instrument_id,
            side=0,
            size=1,
            limit_price=21050.0  # Realistic MNQ price
        )

        if response.success:
            print(f"Order placed: {response.orderId}")

        await suite.disconnect()

    except ProjectXOrderError as e:
        print(f"Order error: {e}")

    except ProjectXError as e:
        print(f"API error: {e}")

    except Exception as e:
        print(f"Unexpected error: {e}")

asyncio.run(place_order_with_error_handling())

Next Steps

Now that you have the basics working:

  1. Technical Analysis: Explore the comprehensive indicators library (55+ TA-Lib compatible indicators)

  2. Learn the API: Explore the API reference

  3. Study Examples: Check out detailed examples

  4. Configure Advanced Features: See configuration options

  5. Real-time Trading: Learn about real-time capabilities

  6. Risk Management: Read about position management

Tips for Success

  1. Start with Demo: Always test with a simulated account first

  2. Small Sizes: Use minimal position sizes while learning

  3. Error Handling: Always wrap API calls in try/catch blocks

  4. Rate Limits: Be mindful of API rate limits

  5. Logging: Enable debug logging during development:

    from project_x_py import setup_logging
    setup_logging(level='DEBUG')
    

Getting Help

If you run into issues: