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:
Python 3.12 or higher installed
project-x-py package installed (see Installation)
TopStepX account with API access
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 pre-loaded 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 ProjectX, create_order_manager, create_position_manager, create_realtime_client
async def trading_workflow():
# 1. Initialize client
async with ProjectX.from_env() as client:
await client.authenticate()
# Get instrument details
instrument = await client.get_instrument('MNQ') # V3: actual symbol
# 2. V3: Set up trading managers with JWT and account ID
realtime_client = await create_realtime_client(
jwt_token=client.jwt_token,
account_id=str(client.account_id)
)
order_manager = create_order_manager(client, realtime_client)
position_manager = create_position_manager(client, realtime_client)
# 3. Check account status
print(f"Account balance: ${client.account_info.balance:,.2f}")
# 4. Get market data
data = await client.get_bars('MNQ', days=1, interval=5) # V3: actual symbol
current_price = float(data.select('close').tail(1).item())
# 5. Place bracket order (entry + stop + target)
bracket = await order_manager.place_bracket_order(
contract_id=instrument.id,
side=0, # Buy
size=1,
entry_price=current_price - 5.0, # Entry below market
stop_loss_price=current_price - 10.0, # $5 risk
take_profit_price=current_price + 5.0 # $10 profit target
)
if bracket.success:
print("Bracket order placed successfully!")
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 ProjectXError, ProjectXOrderError
async def place_order_with_error_handling():
try:
async with ProjectX.from_env() as client:
await client.authenticate()
instrument = await client.get_instrument('MNQ') # V3: actual symbol
# V3: Create realtime client with JWT
realtime_client = await create_realtime_client(
jwt_token=client.jwt_token,
account_id=str(client.account_id)
)
order_manager = create_order_manager(client, realtime_client)
# Attempt to place order
response = await order_manager.place_limit_order(
contract_id=instrument.id,
side=0,
size=1,
limit_price=21050.0 # V3: realistic MNQ price
)
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:
Technical Analysis: Explore the comprehensive indicators library (55+ TA-Lib compatible indicators)
Learn the API: Explore the API reference
Study Examples: Check out detailed examples
Configure Advanced Features: See configuration options
Real-time Trading: Learn about real-time capabilities
Risk Management: Read about position management
Tips for Success
Start with Demo: Always test with a simulated account first
Small Sizes: Use minimal position sizes while learning
Error Handling: Always wrap API calls in try/catch blocks
Rate Limits: Be mindful of API rate limits
Logging: Enable debug logging during development:
from project_x_py import setup_logging setup_logging(level='DEBUG')
Getting Help
If you run into issues:
Check the troubleshooting section
Browse the examples directory
Review the API documentation
Open an issue on GitHub