Python14 min read·

Alpaca API Tutorial 2026: Algorithmic Trading in Python

Build your first trading bot with Alpaca - paper trading setup, market data, placing orders in Python and a moving-average crossover skeleton.

In 2018, a San Mateo startup founded three years earlier by Yoshi Yokokawa and Hitoshi Harada launched something that did not really exist at the time: a US stock broker with no trading commissions, no user interface to speak of, and an API as the entire product. Alpaca was built on the premise that some customers do not want a trading app at all - they want their code to be the customer.

That premise aged well. In 2026 Alpaca remains the lowest-friction route from a Python script to a real (or realistic) order: sign up, get two API keys, and you are paper trading against live market prices in under ten minutes, without depositing a penny. For anyone learning algorithmic trading, that free paper environment is the single most useful feature any broker offers.

This tutorial builds up the full workflow: account and key setup, installing the alpaca-py library, pulling market data, placing market and limit orders in the paper account, checking positions, and assembling a minimal moving-average crossover bot. It closes with what changes when you flip to live trading, the alternatives, and the caveats that matter - especially for UK readers.


Account Setup and API Keys

Go to alpaca.markets and create an account. You get a paper trading account immediately, seeded with $100,000 of virtual cash; a live brokerage account requires the usual identity checks and, for non-US residents, is available in many countries including the UK (US equities only - more on that in the caveats).

Everything in this tutorial runs against paper trading, which has its own endpoint and its own keys. From the dashboard, switch to the Paper view and generate an API key pair. Two things to get right from the start:

  • Paper and live keys are different credentials against different endpoints (paper-api.alpaca.markets vs api.alpaca.markets). A bot pointed at the wrong one fails loudly, which is the good outcome.
  • Keys go in environment variables, never in source code. A leaked live key can trade your account.
pip install alpaca-py pandas # Paper trading credentials - add to ~/.zshrc or a .env file export ALPACA_API_KEY="your_paper_key" export ALPACA_SECRET_KEY="your_paper_secret"

alpaca-py is the current official SDK. If you find tutorials importing alpaca_trade_api, they are written against the older, deprecated library; the concepts transfer but the class names will not.

Verify the connection by fetching your account:

import os from alpaca.trading.client import TradingClient trading = TradingClient( os.environ["ALPACA_API_KEY"], os.environ["ALPACA_SECRET_KEY"], paper=True, # routes to paper-api.alpaca.markets ) account = trading.get_account() print("Status: ", account.status) print("Equity (USD):", account.equity) print("Buying power:", account.buying_power)

If that prints ACTIVE and an equity of 100000, the plumbing works.


Fetching Market Data

Market data lives in a separate client from trading. The free data entitlement is the IEX exchange feed - real-time but covering only the small slice of US volume that executes on IEX, roughly 2% of the market. The full consolidated SIP feed is a paid subscription (Alpaca's Algo Trader Plus, around $99 per month at the time of writing). For daily-bar strategies the IEX-derived historical bars are fine; for anything sensitive to intraday prices, note the entitlement and read the caveats section.

import os from datetime import datetime from alpaca.data.historical import StockHistoricalDataClient from alpaca.data.requests import StockBarsRequest from alpaca.data.timeframe import TimeFrame data_client = StockHistoricalDataClient( os.environ["ALPACA_API_KEY"], os.environ["ALPACA_SECRET_KEY"], ) request = StockBarsRequest( symbol_or_symbols=["AAPL", "MSFT"], timeframe=TimeFrame.Day, start=datetime(2025, 1, 2), end=datetime(2025, 12, 31), ) bars = data_client.get_stock_bars(request) df = bars.df # multi-indexed pandas DataFrame print(df.loc["AAPL"].tail())

The .df property hands you a pandas DataFrame indexed by symbol and timestamp, with OHLCV columns - directly usable with everything in our pandas guide. Minute bars are the same request with TimeFrame.Minute.


Placing Orders in the Paper Account

Orders are built as request objects and submitted through the trading client. Start with a market order for ten shares of Apple:

from alpaca.trading.requests import MarketOrderRequest, LimitOrderRequest from alpaca.trading.enums import OrderSide, TimeInForce market_order = trading.submit_order( MarketOrderRequest( symbol="AAPL", qty=10, side=OrderSide.BUY, time_in_force=TimeInForce.DAY, ) ) print(market_order.id, market_order.status)

A limit order adds a price you are willing to pay, and rests on the (simulated) book until it fills, expires or is cancelled:

limit_order = trading.submit_order( LimitOrderRequest( symbol="MSFT", qty=5, side=OrderSide.BUY, time_in_force=TimeInForce.GTC, # good till cancelled limit_price=350.00, ) ) print(limit_order.id, limit_order.status) # Cancel it again trading.cancel_order_by_id(limit_order.id)

Orders submitted outside market hours (9.30am to 4pm New York time, 2.30pm to 9pm in the UK for most of the year) are queued for the open unless you request extended hours on a limit order. A surprising number of first bots "fail" simply because their author tested them at 10am London time.

Checking what you own and how the account stands is two calls:

for position in trading.get_all_positions(): print( position.symbol, position.qty, "avg entry:", position.avg_entry_price, "unrealised P/L:", position.unrealized_pl, ) account = trading.get_account() print("Equity now (USD):", account.equity)

A Minimal Moving-Average Crossover Bot

Here is the whole loop in one coherent skeleton: fetch recent daily bars, compute a fast and slow moving average, and hold the stock when the fast average is above the slow one. It rebalances one symbol, once per run, and is meant to be executed daily by a scheduler such as cron.

import os from datetime import datetime, timedelta from alpaca.trading.client import TradingClient from alpaca.trading.requests import MarketOrderRequest from alpaca.trading.enums import OrderSide, TimeInForce from alpaca.data.historical import StockHistoricalDataClient from alpaca.data.requests import StockBarsRequest from alpaca.data.timeframe import TimeFrame SYMBOL, FAST, SLOW, QTY = "AAPL", 20, 50, 10 keys = (os.environ["ALPACA_API_KEY"], os.environ["ALPACA_SECRET_KEY"]) trading = TradingClient(*keys, paper=True) data = StockHistoricalDataClient(*keys) bars = data.get_stock_bars(StockBarsRequest( symbol_or_symbols=SYMBOL, timeframe=TimeFrame.Day, start=datetime.now() - timedelta(days=SLOW * 2), )).df closes = bars.loc[SYMBOL]["close"] signal_long = closes.rolling(FAST).mean().iloc[-1] > closes.rolling(SLOW).mean().iloc[-1] held = {p.symbol for p in trading.get_all_positions()} if signal_long and SYMBOL not in held: trading.submit_order(MarketOrderRequest( symbol=SYMBOL, qty=QTY, side=OrderSide.BUY, time_in_force=TimeInForce.DAY, )) print("Entered long", SYMBOL) elif not signal_long and SYMBOL in held: trading.close_position(SYMBOL) print("Exited", SYMBOL) else: print("No action. Long signal:", signal_long)

This is deliberately a skeleton, not a strategy. It has no position sizing beyond a fixed quantity, no stop, no handling of partial fills or rejected orders, and the crossover itself is a teaching device rather than an edge. Before trusting any rule like this, backtest it properly against history - our Backtrader tutorial walks through exactly that, and the same signal logic ports across almost line for line. The right order of operations is backtest, then paper, then (maybe) live.


From Paper to Live

Mechanically, going live is anticlimactic: fund the account, generate live keys, and change paper=True to paper=False. Everything else about the code is identical, which is precisely why the switch deserves more ceremony than it demands.

Money becomes real, and so do edge cases. Paper trading never has a rejected order for insufficient settled funds, never suffers an API outage during a fast market, and never fills you at a price that makes you wince. Live trading has all three. Run new code live with the smallest size that still exercises the logic.

The pattern day trader rule applies. Under FINRA rules, a margin account that makes four or more day trades within five business days is flagged as a pattern day trader and must maintain at least $25,000 of equity, or it gets restricted. An intraday bot on a small live account will hit this quickly; it does not apply to paper accounts, so it tends to ambush people at exactly the wrong moment.

Add operational guard rails. A kill switch (Alpaca's dashboard can flatten and halt the account), maximum position and order-size checks in code, and alerting on errors are not optional extras for live bots; they are the difference between a bug costing basis points and costing your account.


Alternatives to Alpaca

Alpaca's main competition for API-first retail trading is Interactive Brokers, and the trade-off is clean: Alpaca is dramatically simpler, IB is dramatically broader. IB gives you global equities, options, futures and FX across 150 markets, real portfolio margining and decades of institutional plumbing - at the cost of a notoriously involved API (a running Gateway or TWS instance, connection management, a steeper learning curve all round). Our Interactive Brokers API tutorial covers that setup end to end if you need instruments beyond US stocks and crypto.

Between the two: learn and prototype on Alpaca, and adopt IB when your strategy actually requires its breadth. For a wider survey of the field, including options-centric and UK-accessible brokers, see our guide to the best brokers for algo trading.


Caveats Worth Reading Twice

An honest list of the gaps between this tutorial's happy path and production reality.

Paper fills are optimistic. The simulator fills market orders at the quote with no market impact and fills limit orders generously when the price touches your level. Live, you pay the spread, you queue behind other orders, and large orders move the price. A strategy whose backtest and paper profits are thinner than a few cents per share will likely not survive contact with real execution.

Free data is IEX-only. Prices derived from ~2% of consolidated volume can differ from the tape by a spread's width, and thinly traded names may barely print on IEX at all. Signals computed on IEX data but executed against the whole market embed a small, persistent mismatch. For serious intraday work, cost in the SIP subscription.

Entitlements and pricing move. The free tier's shape, the $99 figure and the crypto coverage are all as of the time of writing (mid-2026) and have changed before. Verify against Alpaca's current docs before building anything that depends on them.

For UK readers, this is a US-market account. You are trading US equities in dollars, so you carry cable exposure on your entire balance, US market hours run into the UK evening, and the tax treatment differs from a UK broker (no ISA or SIPP wrapper; you will need to file a W-8BEN and handle capital gains reporting yourself - check current HMRC guidance rather than relying on any blog, this one included).

A broker API is not a research platform. Alpaca executes; it does not backtest, and its data depth is modest. The strongest workflow pairs it with a proper research stack - historical data from a dedicated vendor, backtesting in a purpose-built framework - with Alpaca as the final, thin execution layer.


Frequently Asked Questions

Is Alpaca really commission-free, and how does it make money?

Trading US stocks through Alpaca carries no commission. The company earns revenue the way most zero-commission brokers do: payment for order flow, interest on uninvested cash balances, margin lending, crypto spreads and paid subscriptions for market data and its Broker API business. None of that changes your mechanics, but it is worth understanding that "free" execution is monetised elsewhere, and order-routing quality is part of what you are implicitly paying with.

Can I use Alpaca from the UK?

Yes, at the time of writing Alpaca accepts UK residents for live accounts trading US equities, and paper trading is available anywhere. The practical frictions are currency (accounts are denominated in dollars), market hours (the US session runs to 9pm UK time in winter), and tax (no ISA wrapper, W-8BEN paperwork, self-reported gains). If you primarily want to trade UK or European instruments, Alpaca is the wrong tool; Interactive Brokers covers those markets.

How realistic is paper trading?

Realistic enough to validate logic, not realistic enough to validate profitability. Paper trading uses real market prices, so your signals, order handling and scheduling all get a fair test. Fills are the weak point: no queue position, no market impact and optimistic limit-order behaviour mean paper P/L overstates live P/L, and the gap grows the faster you trade. Treat a month of good paper results as necessary, never sufficient.

Does Alpaca support options and crypto?

Alpaca added options trading to its API in 2024 and supports a set of crypto pairs, alongside US equities and ETFs. Entitlements differ by account type and region (UK users, in particular, should check current availability for options), and each asset class has its own data subscriptions. This tutorial's equity workflow is the stable core; treat the newer asset classes as check-the-docs territory.

What happens if my bot crashes mid-session?

Your orders and positions live on Alpaca's servers, not in your process, so a crashed bot leaves its last state standing - including any open orders, which will happily fill while your code is down. Production bots should reconcile on startup (fetch open orders and positions, compare against intent), use good-till-cancelled orders deliberately rather than by default, and alert a human when they restart. The get_all_positions and get_orders calls exist precisely for that reconciliation.

Skip the £25k programme - try the alternative

Master's programmes are slow and expensive. Quantt is a self-paced alternative. Start free with a real lesson and interview practice, then unlock 50+ courses and your personalised plan.

Free to start · No credit card required