Alpaca Trading API 2026: The Commission-Free Stock Brokerage API for Algorithmic Trading — Setup Guide

Complete guide to the Alpaca Trading API for commission-free algorithmic trading. Learn setup, order placement, WebSocket streaming, fractional shares, and paper trading with Python code examples.

  • ⭐ 4500
  • Apache-2.0
  • Updated 2026-05-20

{{< resource-info >}}

📌 Affiliate Disclosure: This article contains affiliate links. We may earn a commission if you sign up through our link — at no extra cost to you. Our reviews are independent and based on thorough research.

🚀 Try Minara for AI-Powered Trading: Sign up with Minara — the AI trading platform that helps you build, backtest, and deploy automated strategies with zero coding required.


Published: 2026-05-19 | Category: AI Trading | Reading Time: 15 min


What Is the Alpaca Trading API? #

The Alpaca Trading API is a commission-free, API-first brokerage platform designed specifically for developers and algorithmic traders. Founded in 2015 and headquartered in Silicon Valley, Alpaca has rapidly become one of the most popular choices for building automated trading systems, with over 7 million API-connected accounts and recognition as the #1 Best Broker by BrokerChooser as of January 2026.

Unlike traditional brokerages that offer clunky, outdated APIs as an afterthought, Alpaca was built from the ground up with developers in mind. The platform provides a complete ecosystem for algorithmic trading — from paper trading and backtesting to live execution and portfolio management — all accessible through clean, well-documented REST and WebSocket APIs.

What truly sets Alpaca apart is its commission-free model. You pay zero commissions on U.S. stock and ETF trades, making it exceptionally cost-effective for high-frequency strategies that execute dozens or hundreds of trades per day. The API is free to use, including the full paper trading environment, which means you can develop, test, and deploy strategies without ever paying platform fees.

FeatureSpecification
API TypesREST API, WebSocket Streaming, FIX API
Supported AssetsU.S. Stocks, ETFs, Options, Crypto
SDK LanguagesPython, JavaScript/Node.js, Go, C#
Commission$0 on U.S. equities and options
Paper TradingFull-featured sandbox with $1M virtual funds
System Uptime99.99% since January 2025
Order Processing1.5ms average latency
Trading Hours24 hours, 5 days a week (24/5)
Fractional SharesYes — invest by dollar amount
Margin Rates6.25%

Why Choose Alpaca for Algorithmic Trading? #

Commission-Free Execution #

For algorithmic traders, commissions are the silent killer of profitability. A strategy that generates $50 per trade in gross profit becomes unprofitable if you’re paying $5-10 in commissions and fees per side. Alpaca’s commission-free model eliminates this problem entirely, allowing you to trade as frequently as your strategy demands without eroding returns.

Developer-First Design #

Every aspect of Alpaca is built for developers. The API follows RESTful conventions, uses standard HTTP methods, and returns JSON responses. Authentication is handled via simple API key pairs. The documentation is comprehensive and includes interactive code examples in multiple languages. Webhooks enable event-driven architectures, and the WebSocket API provides real-time streaming without polling overhead.

Paper Trading That Mirrors Production #

Alpaca’s paper trading environment is not a simplified demo — it’s a full-featured sandbox that mirrors the production API exactly. You get real-time market data, can execute all order types, and receive realistic fill simulations. This means code written for paper trading requires zero changes when switching to live trading — just swap the API endpoint and credentials.

According to a 2025 Aite-Novarica Group study, algorithmic strategies paper-tested for at least 90 days before live deployment show 23% lower drawdowns in their first year of live trading.


Getting Started: Account Setup and API Keys #

Step 1: Create Your Alpaca Account #

Sign up at alpaca.markets and complete the identity verification process. You’ll need to provide standard KYC information including your Social Security Number (for U.S. residents) and link a bank account for funding.

Step 2: Generate API Keys #

Once your account is approved, navigate to the Paper Trading section to generate your first API keys:

# Your API credentials will look like this:
API_KEY = 'PKABCDEF1234567890EXAMPLE'
API_SECRET = 'abcdefghijklmnopqrstuvwxyz1234567890example'
BASE_URL = 'https://paper-api.alpaca.markets'  # Paper trading endpoint
// JavaScript/Node.js credential configuration
const API_KEY = 'PKABCDEF1234567890EXAMPLE';
const API_SECRET = 'abcdefghijklmnopqrstuvwxyz1234567890example';
const BASE_URL = 'https://paper-api.alpaca.markets';

Keep your secret key secure — never commit it to version control. Use environment variables or a secrets manager:

# Secure credential management with environment variables
import os
from alpaca_trade_api import REST

api = REST(
    key_id=os.getenv('ALPACA_API_KEY'),
    secret_key=os.getenv('ALPACA_SECRET_KEY'),
    base_url='https://paper-api.alpaca.markets'
)
# .env file (add to .gitignore!)
ALPACA_API_KEY=PKABCDEF1234567890EXAMPLE
ALPACA_SECRET_KEY=abcdefghijklmnopqrstuvwxyz1234567890example

Step 3: Install the SDK #

# Python SDK
pip install alpaca-trade-api

# JavaScript/Node.js SDK
npm install @alpacahq/alpaca-trade-api

# Go SDK
go get github.com/alpacahq/alpaca-trade-api-go/v3/alpaca

Core Trading Operations #

Placing Your First Order #

Alpaca supports multiple order types including market, limit, stop, stop-limit, and trailing stop orders. Here’s how to place each:

from alpaca_trade_api import REST
import os

api = REST(
    key_id=os.getenv('ALPACA_API_KEY'),
    secret_key=os.getenv('ALPACA_SECRET_KEY'),
    base_url='https://paper-api.alpaca.markets'
)

# Market order — executes immediately at best available price
market_order = api.submit_order(
    symbol='AAPL',
    qty=10,
    side='buy',
    type='market',
    time_in_force='day'
)
print(f"Market order submitted: {market_order.id}")
# Limit order — only executes at specified price or better
limit_order = api.submit_order(
    symbol='TSLA',
    qty=5,
    side='buy',
    type='limit',
    limit_price=180.00,
    time_in_force='gtc'  # Good-til-cancelled
)
print(f"Limit order submitted: {limit_order.id}")
# Stop-loss order — triggers market sell when price drops to stop price
stop_order = api.submit_order(
    symbol='MSFT',
    qty=20,
    side='sell',
    type='stop',
    stop_price=380.00,
    time_in_force='day'
)
# Stop-limit order — combines stop trigger with limit execution
stop_limit_order = api.submit_order(
    symbol='GOOGL',
    qty=2,
    side='sell',
    type='stop_limit',
    stop_price=165.00,
    limit_price=164.50,
    time_in_force='day'
)
# Trailing stop order — stop price follows the market at a set distance
trailing_stop = api.submit_order(
    symbol='AMZN',
    qty=3,
    side='sell',
    type='trailing_stop',
    trail_percent=5.0,  # 5% trailing distance
    time_in_force='gtc'
)

Fractional Share Trading #

One of Alpaca’s standout features is fractional share trading, which allows you to invest precise dollar amounts rather than whole shares:

# Buy $500 worth of Apple — regardless of share price
fractional_order = api.submit_order(
    symbol='AAPL',
    notional=500.00,  # Dollar amount instead of share quantity
    side='buy',
    type='market',
    time_in_force='day'
)
# Build a balanced portfolio with exact dollar allocations
portfolio = {
    'VTI': 2000.00,   # Total U.S. stock market
    'VXUS': 1000.00,  # International stocks
    'BND': 1000.00,   # U.S. bonds
    'VNQ': 500.00     # Real estate
}

for symbol, amount in portfolio.items():
    order = api.submit_order(
        symbol=symbol,
        notional=amount,
        side='buy',
        type='market',
        time_in_force='day'
    )
    print(f"Ordered ${amount} of {symbol}")

Extended Hours Trading (24/5) #

Alpaca supports 24/5 trading, allowing you to trade outside regular market hours (9:30 AM – 4:00 PM ET):

# Place an order for extended hours execution
extended_hours_order = api.submit_order(
    symbol='SPY',
    qty=50,
    side='buy',
    type='limit',
    limit_price=520.00,
    time_in_force='day',
    extended_hours=True  # Enable pre-market (4:00 AM) and after-hours (8:00 PM)
)
# Check available trading hours for a symbol
from alpaca_trade_api import REST

api = REST(key_id='YOUR_KEY', secret_key='YOUR_SECRET')
clock = api.get_clock()

print(f"Market is {'open' if clock.is_open else 'closed'}")
print(f"Next open: {clock.next_open}")
print(f"Next close: {clock.next_close}")

Real-Time Market Data with WebSocket Streaming #

Setting Up WebSocket Data Streams #

Alpaca’s WebSocket API provides real-time streaming of trades, quotes, and minute bars. This is essential for strategies that react to market events in real time:

import asyncio
from alpaca_trade_api.stream import Stream

# WebSocket streaming for real-time data
async def handle_trade(t):
    print(f"Trade: {t.symbol} @ ${t.price} x {t.size}")

async def handle_quote(q):
    print(f"Quote: {q.symbol} Bid: ${q.bid_price} Ask: ${q.ask_price}")

async def handle_bar(bar):
    print(f"Bar: {bar.symbol} O:{bar.open} H:{bar.high} L:{bar.low} C:{bar.close}")

# Initialize stream
stream = Stream(
    key_id='YOUR_API_KEY',
    secret_key='YOUR_SECRET_KEY',
    base_url='https://paper-api.alpaca.markets',
    data_feed='iex'  # 'iex' (free) or 'sip' (premium)
)

# Subscribe to channels
stream.subscribe_trades(handle_trade, 'AAPL', 'TSLA', 'MSFT')
stream.subscribe_quotes(handle_quote, 'AAPL', 'TSLA')
stream.subscribe_bars(handle_bar, 'SPY', 'QQQ')

# Run the stream
print("Starting WebSocket stream...")
stream.run()
# Async context manager pattern for WebSocket streams
import asyncio
from alpaca_trade_api.stream import Stream

async def run_streaming_strategy():
    stream = Stream(
        key_id='YOUR_API_KEY',
        secret_key='YOUR_SECRET_KEY',
        data_feed='iex'
    )
    
    async def on_bar(bar):
        # Your strategy logic here
        if bar.close > bar.vwap * 1.02:
            print(f"Potential breakout: {bar.symbol} at ${bar.close}")
    
    stream.subscribe_bars(on_bar, 'AAPL', 'MSFT', 'GOOGL', 'AMZN')
    
    # Run with proper cleanup
    await stream._run_forever()

# asyncio.run(run_streaming_strategy())
// Node.js WebSocket streaming
const Alpaca = require('@alpacahq/alpaca-trade-api');

const alpaca = new Alpaca({
    keyId: 'YOUR_API_KEY',
    secretKey: 'YOUR_SECRET_KEY',
    paper: true
});

const client = alpaca.data_ws;

client.onConnect(() => {
    console.log('WebSocket connected');
    client.subscribe(['alpacadatafeed/T.AAPL', 'alpacadatafeed/T.TSLA']);
});

client.onStockTrade((subject, data) => {
    console.log(`Trade: ${data.sym} @ $${data.p} x ${data.s}`);
});

client.connect();

Portfolio Management and Account Operations #

Checking Positions and Account Info #

from alpaca_trade_api import REST
import pandas as pd

api = REST(key_id='YOUR_KEY', secret_key='YOUR_SECRET')

# Get account information
account = api.get_account()
print(f"Account ID: {account.id}")
print(f"Portfolio Value: ${account.portfolio_value}")
print(f"Cash: ${account.cash}")
print(f"Buying Power: ${account.buying_power}")
print(f"Equity: ${account.equity}")
print(f"Day Trade Count: {account.daytrade_count}")
# List all current positions
positions = api.list_positions()
print(f"Number of positions: {len(positions)}")

for pos in positions:
    print(f"{pos.symbol}: {pos.qty} shares @ ${pos.avg_entry_price}")
    print(f"  Current: ${pos.current_price} | P&L: ${pos.unrealized_pl} ({pos.unrealized_plpc}%)")
# Get position for a specific symbol
aapl_position = api.get_position('AAPL')
print(f"AAPL Position: {aapl_position.qty} shares")
print(f"Market Value: ${aapl_position.market_value}")
print(f"Unrealized P&L: ${aapl_position.unrealized_pl}")

Order Management #

# List all open orders
open_orders = api.list_orders(status='open')
for order in open_orders:
    print(f"Order {order.id}: {order.side} {order.qty} {order.symbol} @ {order.type}")
# Cancel a specific order
api.cancel_order('ORDER_ID_HERE')
print("Order cancelled")
# Cancel all open orders
api.cancel_all_orders()
print("All orders cancelled")
# Get order history (closed orders)
closed_orders = api.list_orders(
    status='closed',
    limit=100,
    after='2026-05-01T00:00:00Z'
)

for order in closed_orders:
    print(f"{order.symbol}: {order.side} {order.filled_qty}/{order.qty} @ ${order.filled_avg_price}")

Historical Data and Backtesting #

Fetching Historical Bars #

from alpaca_trade_api import REST
from datetime import datetime, timedelta

api = REST(key_id='YOUR_KEY', secret_key='YOUR_SECRET')

# Get daily bars for the past 6 months
end_date = datetime.now()
start_date = end_date - timedelta(days=180)

bars = api.get_bars(
    'AAPL',
    timeframe='1Day',
    start=start_date.isoformat(),
    end=end_date.isoformat(),
    feed='iex'
).df

print(f"Retrieved {len(bars)} bars")
print(bars.head())
# Get minute bars for intraday strategies
minute_bars = api.get_bars(
    'SPY',
    timeframe='1Min',
    start='2026-05-15T09:30:00Z',
    end='2026-05-15T16:00:00Z',
    feed='iex'
).df

# Calculate simple moving averages
minute_bars['SMA_20'] = minute_bars['close'].rolling(20).mean()
minute_bars['SMA_50'] = minute_bars['close'].rolling(50).mean()

# Generate signals
minute_bars['signal'] = 0
minute_bars.loc[minute_bars['SMA_20'] > minute_bars['SMA_50'], 'signal'] = 1
minute_bars.loc[minute_bars['SMA_20'] < minute_bars['SMA_50'], 'signal'] = -1

print(minute_bars[['close', 'SMA_20', 'SMA_50', 'signal']].tail(10))
# Fetch multiple symbols efficiently
import pandas as pd

symbols = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'META']
all_bars = {}

for symbol in symbols:
    bars = api.get_bars(
        symbol,
        timeframe='1Day',
        start='2026-01-01T00:00:00Z',
        end='2026-05-19T00:00:00Z',
        feed='iex'
    ).df
    all_bars[symbol] = bars['close']

# Create a DataFrame with all closing prices
prices_df = pd.DataFrame(all_bars)
print(prices_df.head())

# Calculate returns
returns = prices_df.pct_change().dropna()
print("\nDaily Returns:")
print(returns.head())

Building a Complete Trading Strategy #

Here’s a complete momentum-based trading bot that combines everything we’ve covered:

"""
Alpaca Momentum Trading Bot
Strategy: Buy when price crosses above 20-period SMA with volume confirmation
"""
import os
import time
import pandas as pd
from alpaca_trade_api import REST, Stream

# Configuration
API_KEY = os.getenv('ALPACA_API_KEY')
API_SECRET = os.getenv('ALPACA_SECRET_KEY')
BASE_URL = 'https://paper-api.alpaca.markets'

WATCHLIST = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'NVDA']
POSITION_SIZE = 1000  # Dollar amount per trade
SMA_PERIOD = 20

class MomentumTrader:
    def __init__(self):
        self.api = REST(key_id=API_KEY, secret_key=API_SECRET, base_url=BASE_URL)
        self.price_history = {s: [] for s in WATCHLIST}
        self.positions_held = set()
    
    def get_sma(self, prices, period):
        """Calculate Simple Moving Average"""
        if len(prices) < period:
            return None
        return sum(prices[-period:]) / period
    
    def check_for_signal(self, symbol, current_price):
        """Generate buy/sell signals based on SMA crossover"""
        self.price_history[symbol].append(current_price)
        
        if len(self.price_history[symbol]) < SMA_PERIOD + 5:
            return None
        
        sma = self.get_sma(self.price_history[symbol], SMA_PERIOD)
        prev_price = self.price_history[symbol][-2]
        prev_sma = self.get_sma(self.price_history[symbol][:-1], SMA_PERIOD)
        
        # Buy signal: price crosses above SMA
        if prev_price <= prev_sma and current_price > sma:
            if symbol not in self.positions_held:
                return 'buy'
        
        # Sell signal: price crosses below SMA
        if prev_price >= prev_sma and current_price < sma:
            if symbol in self.positions_held:
                return 'sell'
        
        return None
    
    def execute_trade(self, symbol, signal):
        """Execute a trade based on signal"""
        try:
            if signal == 'buy':
                order = self.api.submit_order(
                    symbol=symbol,
                    notional=POSITION_SIZE,
                    side='buy',
                    type='market',
                    time_in_force='day'
                )
                self.positions_held.add(symbol)
                print(f"BUY {symbol}: ${POSITION_SIZE} | Order ID: {order.id}")
            
            elif signal == 'sell':
                position = self.api.get_position(symbol)
                order = self.api.submit_order(
                    symbol=symbol,
                    qty=position.qty,
                    side='sell',
                    type='market',
                    time_in_force='day'
                )
                self.positions_held.discard(symbol)
                print(f"SELL {symbol}: {position.qty} shares | Order ID: {order.id}")
        
        except Exception as e:
            print(f"Trade error for {symbol}: {e}")
    
    def run(self):
        """Main trading loop using polling"""
        print("Momentum Trader starting...")
        
        while True:
            try:
                clock = self.api.get_clock()
                if not clock.is_open:
                    print(f"Market closed. Next open: {clock.next_open}")
                    time.sleep(60)
                    continue
                
                for symbol in WATCHLIST:
                    # Get latest price
                    bars = self.api.get_latest_bar(symbol)
                    signal = self.check_for_signal(symbol, bars.c)
                    
                    if signal:
                        self.execute_trade(symbol, signal)
                
                time.sleep(60)  # Check every minute
                
            except Exception as e:
                print(f"Error in main loop: {e}")
                time.sleep(60)

if __name__ == '__main__':
    trader = MomentumTrader()
    trader.run()

Advanced Features and Best Practices #

Using Advanced Order Types (OCO, IOC) #

With Alpaca Elite, you can access sophisticated order types:

# One-Cancels-Other (OCO) bracket order
bracket_order = api.submit_order(
    symbol='TSLA',
    qty=10,
    side='buy',
    type='limit',
    limit_price=200.00,
    time_in_force='gtc',
    order_class='bracket',
    take_profit=dict(limit_price=220.00),
    stop_loss=dict(stop_price=185.00, limit_price=184.50)
)
# Immediate-Or-Cancel (IOC) order
ioc_order = api.submit_order(
    symbol='SPY',
    qty=100,
    side='buy',
    type='limit',
    limit_price=520.00,
    time_in_force='ioc'  # Cancelled if not filled immediately
)

Webhooks for Event-Driven Trading #

# Flask webhook handler for external signals
from flask import Flask, request, jsonify
from alpaca_trade_api import REST

app = Flask(__name__)
api = REST(key_id='YOUR_KEY', secret_key='YOUR_SECRET')

@app.route('/webhook/trading-signal', methods=['POST'])
def handle_trading_signal():
    data = request.json
    symbol = data.get('symbol')
    signal = data.get('signal')  # 'buy' or 'sell'
    
    if signal == 'buy':
        order = api.submit_order(
            symbol=symbol,
            notional=1000,
            side='buy',
            type='market',
            time_in_force='day'
        )
        return jsonify({'status': 'success', 'order_id': order.id})
    
    elif signal == 'sell':
        position = api.get_position(symbol)
        order = api.submit_order(
            symbol=symbol,
            qty=position.qty,
            side='sell',
            type='market',
            time_in_force='day'
        )
        return jsonify({'status': 'success', 'order_id': order.id})
    
    return jsonify({'status': 'unknown_signal'}), 400

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Frequently Asked Questions (FAQ) #

Is Alpaca really commission-free? #

Yes, Alpaca offers commission-free trading for U.S. stocks, ETFs, and options for retail customers. There are no per-trade commissions, no API access fees, and the paper trading environment is completely free. Alpaca generates revenue through payment for order flow, margin lending, and premium data subscriptions (SIP data feeds). Note that regulatory fees may still apply on certain transactions.

Does Alpaca support options trading? #

Yes, as of 2026, Alpaca supports options trading through its API. You can trade options commission-free alongside stocks and ETFs. However, options trading requires approval and may have additional requirements compared to stock trading. Alpaca does not currently offer options flow analytics — for that, you would need a complementary platform like TradeAlgo.

Can I use Alpaca from outside the United States? #

Alpaca is available to residents of over 100 countries for trading U.S. equities. However, certain features like IRA accounts and options trading may be restricted to U.S. residents with a valid Social Security Number. International users should check Alpaca’s current supported countries list for the most up-to-date information.

How does paper trading differ from live trading? #

Alpaca’s paper trading environment mirrors the production API almost exactly — same endpoints, same order types, same market data. The key differences are: (1) trades execute against a simulated matching engine rather than real markets, (2) you start with $100,000 in virtual cash (upgradeable to $1M), and (3) there are no real financial consequences. This makes it ideal for strategy development and testing before committing real capital.

What are the rate limits for the Alpaca API? #

Alpaca implements rate limits to ensure fair usage: 200 requests per minute for trading endpoints and 200 requests per minute for market data endpoints. The WebSocket streaming API does not count against these limits. For high-frequency strategies, consider using the WebSocket API for real-time data rather than polling REST endpoints.

How does Alpaca compare to Interactive Brokers? #

Alpaca and Interactive Brokers serve different use cases. Alpaca is ideal for developers and algo traders who want a modern, commission-free API with easy setup. Interactive Brokers is better suited for professional traders who need access to global markets, futures, forex, and advanced portfolio analytics. Many traders use both: Alpaca for U.S. equity strategies and IBKR for global multi-asset trading.


Before you deploy any of the tools above into production, you’ll need solid infrastructure. Two options dibi8 actually uses and recommends:

  • DigitalOcean — $200 free credit for 60 days across 14+ global regions.
  • HTStack — Hong Kong VPS with low-latency access from mainland China. This is the same IDC that hosts dibi8.com.

Affiliate links — they don’t cost you extra and they help keep dibi8.com running.

Conclusion #

The Alpaca Trading API represents a paradigm shift in algorithmic trading infrastructure. By eliminating commissions, providing a developer-first API, and offering a robust paper trading environment, Alpaca has democratized access to institutional-grade trading tools.

Whether you’re building a simple dollar-cost averaging bot, a complex momentum strategy, or a full-fledged fintech application, Alpaca provides the infrastructure you need to succeed. The combination of zero commissions, fractional shares, 24/5 extended hours trading, and real-time WebSocket streaming makes it one of the most compelling platforms for algorithmic traders in 2026.

For traders who want to accelerate their journey into automated trading without writing code from scratch, we recommend pairing Alpaca with Minara — an AI-powered trading platform that helps you build, backtest, and deploy strategies visually. Sign up for Minara today and see how AI can transform your trading workflow.


Last updated: 2026-05-19 | Alpaca API version: v2

💬 Discussion