Alpaca¶
The Alpaca broker integration allows you to trade stocks, options, and cryptocurrencies through Alpaca Markets. This is one of the most popular brokers for algorithmic trading.
Features¶
Multiple Asset Types: Stocks, ETFs, options, and cryptocurrencies
Paper Trading: Full paper trading support for testing strategies
Real-time Data: Live market data and order execution
Order Types: Market, limit, stop, stop-limit, trailing stop orders
Advanced Orders: Bracket orders, one-cancels-other (OCO), one-triggers-other (OTO)
Multi-leg Options: Support for complex options strategies
Live Streaming: Real-time trade updates and market data
Cash Events: Live cloud payloads can include normalized broker cash events such as deposits, withdrawals, interest, dividends, fees, journals, and adjustments
Getting Started¶
Create Alpaca Account
Sign up for a free account at Alpaca Markets
Get Your API Keys
After creating your account:
Log into your Alpaca Dashboard
Go to “API Keys” in the left sidebar (or visit API Keys page)
Click “Create New Key”
Give it a name (e.g., “Lumibot Trading”)
Copy your API Key and Secret Key - you’ll need both
Important: Save these keys securely - you won’t be able to see the secret again
Set Environment Variables
Create a .env file in your project root and add your keys:
# Alpaca API Keys (RECOMMENDED) ALPACA_API_KEY=your_api_key_here ALPACA_API_SECRET=your_secret_key_here ALPACA_IS_PAPER=true
Start Trading
from lumibot.strategies import Strategy from lumibot.brokers import Alpaca from lumibot.traders import Trader from lumibot.entities import Asset class MyStrategy(Strategy): def on_trading_iteration(self): if self.first_iteration: # Buy 100 shares of SPY order = self.create_order( Asset(symbol="SPY", asset_type="stock"), quantity=100, side="buy" ) self.submit_order(order) # The broker will automatically use your environment variables broker = Alpaca() strategy = MyStrategy(broker=broker) trader = Trader() trader.add_strategy(strategy) trader.run_all()
Authentication Methods¶
API Keys (Recommended)¶
This is the recommended method. Set up your API keys in environment variables:
# In your .env file
ALPACA_API_KEY=your_api_key_here
ALPACA_API_SECRET=your_secret_key_here
ALPACA_IS_PAPER=true # Set to false for live trading
Then simply create your broker without any configuration:
from lumibot.brokers import Alpaca
# Automatically uses environment variables
broker = Alpaca()
OAuth Token (Advanced)¶
For OAuth authentication, visit botspot.trade to set up OAuth integration. Then set your OAuth token:
# In your .env file
ALPACA_OAUTH_TOKEN=your_oauth_token_here
ALPACA_IS_PAPER=true
Configuration Options¶
All configuration should be done via environment variables in your .env file:
Environment Var |
Type |
Default |
Description |
|---|---|---|---|
|
str |
None |
Your Alpaca API key (available from the Alpaca dashboard). |
|
str |
None |
Your Alpaca API secret (download from the dashboard). |
|
str |
None |
OAuth token issued via botspot.trade. |
|
bool |
|
Toggle paper trading ( |
Usage Examples¶
Basic Stock Trading¶
from lumibot.strategies import Strategy
from lumibot.brokers import Alpaca
from lumibot.traders import Trader
from lumibot.entities import Asset
class StockStrategy(Strategy):
def on_trading_iteration(self):
if self.first_iteration:
# Buy 100 shares of Apple
order = self.create_order(
Asset(symbol="AAPL", asset_type="stock"),
quantity=100,
side="buy"
)
self.submit_order(order)
# No configuration needed - uses environment variables
broker = Alpaca()
strategy = StockStrategy(broker=broker)
trader = Trader()
trader.add_strategy(strategy)
trader.run_all()
Cryptocurrency Trading¶
from lumibot.entities import Asset
class CryptoStrategy(Strategy):
def on_trading_iteration(self):
# Buy Bitcoin
btc = Asset(symbol="BTC", asset_type="crypto")
usd = Asset(symbol="USD", asset_type="forex")
order = self.create_order(
asset=btc,
quantity=0.1,
side="buy",
quote=usd
)
self.submit_order(order)
Options Trading¶
from datetime import datetime
class OptionsStrategy(Strategy):
def on_trading_iteration(self):
# Buy a call option
expiration = datetime(2024, 12, 20)
spy_call = Asset(
symbol="SPY",
asset_type="option",
expiration=expiration,
strike=450,
right="CALL"
)
order = self.create_order(
asset=spy_call,
quantity=1,
side="buy"
)
self.submit_order(order)
Advanced Order Types¶
# Bracket order (market order with profit target and stop loss)
bracket_order = self.create_order(
Asset("AAPL"),
quantity=100,
side="buy",
order_type="market",
order_class="bracket",
take_profit_price=155.0,
stop_loss_price=145.0
)
self.submit_order(bracket_order)
Cash Events¶
Lumibot can emit normalized live cash_events in the cloud payload for Alpaca strategies. This is separate from the
order event pipeline and is intended for non-trade account activity such as:
deposits and withdrawals
interest
dividends and withholding
fees
journals and other cash adjustments
The Alpaca implementation uses the authenticated Trading API client already configured inside LumiBot and calls the
account activities endpoint through the SDK’s inherited REST client. No extra broker client or raw requests setup
is required.
Normalized cash-event shape¶
Each emitted event includes:
event_id(stable deterministic ID for downstream idempotency)broker_event_id(when Alpaca provides one)broker_nameevent_typeraw_typeraw_subtypeamountcurrencyoccurred_atdescriptiondirectionis_external_cash_flow
Notes¶
Cash events are polled and deduplicated before they are added to the live cloud payload.
Payloads stay bounded and omit full raw broker blobs to avoid unnecessary listener payload growth.
Alpaca paper credentials can be used to validate the read path when the account activities endpoint is authorized.
See also: Cash Accounting
Important Notes¶
- Paper vs Live Trading
Paper trading is enabled by default (safe for testing)
Set
ALPACA_IS_PAPER=falsein your .env file to enable live tradingAlways test strategies thoroughly in paper trading first
- API Keys Security
Never put API keys directly in your code
Always use environment variables (.env file)
Add .env to your .gitignore file
Keep your secret key private - treat it like a password
- OAuth Integration
For OAuth setup, visit botspot.trade
OAuth tokens are managed through botspot.trade platform
OAuth provides enhanced security for third-party integrations
- Data & Pricing
Stock and options data has a 15-minute delay unless you have a paid data subscription
Cryptocurrency data is real-time
Price precision varies by asset type
- Order Limitations
Crypto orders support “gtc” and “ioc” time-in-force
Options orders default to “day” time-in-force
Some advanced features require both OAuth token and API credentials
Important Notes:
Paper Trading: All examples default to paper trading (
ALPACA_IS_PAPER=true)Rate Limits: Alpaca has rate limits on API calls - the library handles basic rate limiting
Market Hours: Stock trading is limited to market hours; crypto trading is 24/7
Minimum Quantities: Some assets have minimum quantity requirements
Authentication Issues: If you encounter “Unauthorized” errors:
For OAuth users: Check your
ALPACA_OAUTH_TOKENis valid and not expiredFor API key users: Verify
ALPACA_API_KEYandALPACA_API_SECRETare correctAccount permissions: Ensure your account has access to the data/trading features you’re using
Re-authentication: OAuth tokens may need periodic renewal via the OAuth flow
Error Handling:
The broker provides clear error messages for common authentication issues:
❌ ALPACA AUTHENTICATION ERROR: Your OAuth token appears to be invalid or expired.
🔧 To fix this:
1. Check that your ALPACA_OAUTH_TOKEN environment variable is set correctly
2. Verify your OAuth token is valid and not expired
3. Re-authenticate at: https://localhost:3000/oauth/alpaca/success
4. Or use API key/secret instead by setting ALPACA_API_KEY and ALPACA_API_SECRET
Polling vs Streaming:
OAuth-only configurations use polling (default: 5-second intervals) since TradingStream doesn’t support OAuth
API key/secret configurations use real-time WebSocket streaming
Mixed configurations (OAuth + API credentials) can use either method
Troubleshooting¶
- “No API credentials found” Error
Make sure your .env file is in the correct location and contains:
ALPACA_API_KEY=your_actual_key_here ALPACA_API_SECRET=your_actual_secret_here
- Paper Trading Not Working
Verify
ALPACA_IS_PAPER=trueis set in your .env file- Live Trading Issues
Ensure you have sufficient buying power
Check if your account is approved for the asset type you’re trading
Verify
ALPACA_IS_PAPER=falsefor live trading
API Reference¶
- class lumibot.brokers.alpaca.Alpaca(config, max_workers=20, chunk_size=100, connect_stream=True, data_source=None, polling_interval=5.0)
Bases:
BrokerA broker class that connects to Alpaca
- api
Alpaca API object
- Type:
tradeapi.REST
- get_timestamp()
Returns the current UNIX timestamp representation from Alpaca
- is_market_open()
Determines if the market is open.
- get_time_to_open()
How much time in seconds remains until the market next opens?
- get_time_to_close()
How much time in seconds remains until the market closes?
Examples
>>> # Connect to Alpaca >>> from lumibot.brokers import Alpaca >>> ALPACA_CONFIG = { ... # Put your own Alpaca key here: ... "API_KEY": "YOUR_API_KEY", ... # Put your own Alpaca secret here: ... "API_SECRET": "YOUR_API_SECRET", ... # Set this to False to use a live account ... "PAPER": True ... } >>> alpaca = Alpaca(ALPACA_CONFIG) >>> print(alpaca.get_time_to_open()) >>> print(alpaca.get_time_to_close()) >>> print(alpaca.is_market_open())
>>> # Run a strategy on Alpaca >>> from lumibot.strategies import Strategy >>> from lumibot.brokers import Alpaca >>> from lumibot.traders import Trader >>> >>> ALPACA_CONFIG = { ... # Put your own Alpaca key here: ... "API_KEY": "YOUR_API_KEY", ... # Put your own Alpaca secret here: ... "API_SECRET": "YOUR_API_SECRET", ... # Set this to False to use a live account ... "PAPER": True ... } >>> >>> class AlpacaStrategy(Strategy): ... def on_trading_interation(self): ... if self.broker.is_market_open(): ... self.create_order( ... asset=Asset(symbol="AAPL"), ... quantity=1, ... order_type="market", ... side="buy", ... ) >>> >>> alpaca = Alpaca(ALPACA_CONFIG) >>> strategy = AlpacaStrategy(broker=alpaca) >>> trader = Trader() >>> trader.add_strategy(strategy) >>> trader.run()
- ADJUSTMENT_ACTIVITY_TYPES = {'CIL', 'EXTRD', 'MA', 'MEM', 'NC', 'OCT', 'OPASN', 'OPCSH', 'OPEXC', 'OPEXP', 'PTC', 'REORG', 'SPIN', 'SPLIT', 'SWP', 'VOF'}
- ASSET_TYPE_MAP = {'crypto': ['crypto', 'CRYPTO'], 'forex': [], 'future': [], 'option': ['us_option'], 'stock': ['us_equity']}
- CASH_ACTIVITY_TYPES = ()
- DIVIDEND_ACTIVITY_TYPES = {'DIV', 'DIVCGL', 'DIVCGS', 'DIVNRA', 'DIVROC', 'DIVTXEX'}
- EXTERNAL_CASH_ACTIVITY_TYPES = {'ACATC', 'ACATS', 'CSD', 'CSW'}
- FEE_ACTIVITY_TYPES = {'CFEE', 'FEE'}
- INTEREST_ACTIVITY_TYPES = {'INT', 'INTPNL'}
- JOURNAL_ACTIVITY_TYPES = {'JNLC', 'JNLS'}
- TAX_ACTIVITY_TYPES = {'DIVWH', 'WH'}
- TRADE_LIKE_ACTIVITY_TYPES = {'FXTRD', 'OPTRD'}
- cancel_order(order)
Cancel an order
- Parameters:
order (Order) – The order to cancel
- Returns:
The order that was cancelled
- Return type:
Order
- do_polling()
This function is called every polling_interval for OAuth-only configurations. It checks for new orders and dispatches them to the stream for processing. Similar to Tradier’s polling implementation.
- get_cash_events(*, since: datetime | None = None, limit: int | None = 100) list[CashEvent]
Return normalized broker cash events.
Live brokers can override this to surface deposits, withdrawals, interest, dividends, fees, and other non-trade cash activity. The default implementation returns an empty list so unsupported brokers remain no-op.
- get_historical_account_value()
Get the historical account value of the account.
- get_quote(asset: Asset, quote: Asset | None = None, exchange: str | None = None) Quote
Get the latest quote for an asset (stock, option, or crypto). Returns a Quote object with bid, ask, last, and other fields if available.
- Parameters:
asset (Asset object) – The asset for which the quote is needed.
quote (Asset object, optional) – The quote asset for cryptocurrency pairs.
exchange (str, optional) – The exchange to get the quote from.
- Returns:
A Quote object with the quote information.
- Return type:
Quote
- get_time_to_close()
How much time in seconds remains until the market closes?
Return the remaining time for the market to closes in seconds
- Parameters:
None
- Returns:
Number of seconds until close.
- Return type:
int
Examples
If it is 1400 and the market closes at 1600, then there are 7,200 seconds until the market closes.
- get_time_to_open()
How much time in seconds remains until the market next opens?
Return the remaining time for the market to open in seconds
- Parameters:
None
- Returns:
Number of seconds until open.
- Return type:
int
Examples
If it is 0830 and the market next opens at 0930, then there are 3,600 seconds until the next market open.
>>> self.get_time_to_open()
- get_timestamp()
Returns the current UNIX timestamp representation from Alpaca
- Parameters:
None
- Returns:
Sample unix timestamp return value: 1612172730.000234
- Return type:
int
- is_market_open()
Determines if the market is open.
- Parameters:
None
- Returns:
True if market is open, false if the market is closed.
- Return type:
boolean
Examples
>>> self.is_market_open() True
- map_asset_type(alpaca_type)
- class lumibot.brokers.alpaca.OrderData(**kwargs)
Bases:
object- to_request_fields()
Market Hours Methods¶
- Alpaca.get_time_to_close()
How much time in seconds remains until the market closes?
Return the remaining time for the market to closes in seconds
- Parameters:
None
- Returns:
Number of seconds until close.
- Return type:
int
Examples
If it is 1400 and the market closes at 1600, then there are 7,200 seconds until the market closes.
- Alpaca.get_time_to_open()
How much time in seconds remains until the market next opens?
Return the remaining time for the market to open in seconds
- Parameters:
None
- Returns:
Number of seconds until open.
- Return type:
int
Examples
If it is 0830 and the market next opens at 0930, then there are 3,600 seconds until the next market open.
>>> self.get_time_to_open()
- Alpaca.get_timestamp()
Returns the current UNIX timestamp representation from Alpaca
- Parameters:
None
- Returns:
Sample unix timestamp return value: 1612172730.000234
- Return type:
int
- Alpaca.is_market_open()
Determines if the market is open.
- Parameters:
None
- Returns:
True if market is open, false if the market is closed.
- Return type:
boolean
Examples
>>> self.is_market_open() True
Additional Resources¶
Alpaca Markets - Main website
Alpaca Dashboard - Account management
Alpaca API Documentation - Technical details
botspot.trade - OAuth integration platform
Lumibot Examples - More strategy examples