Historical Data
The history module provides access to historical price data, bars, and latest market data.
Overview
The history module allows you to:
Retrieve historical price bars (OHLCV data)
Get the latest bars for symbols
Access multi-timeframe data (1Min, 5Min, 15Min, 1Hour, 1Day, etc.)
Batch retrieve data for multiple symbols
Usage
Historical Bars
from py_alpaca_api import PyAlpacaAPI
import pendulum
api = PyAlpacaAPI(
api_key="your_api_key",
api_secret="your_secret_key"
)
# Get daily bars for the last 30 days
bars = api.stock.history.get_bars(
symbol="AAPL",
start=pendulum.now().subtract(days=30),
end=pendulum.now(),
timeframe="1Day"
)
# Returns a DataFrame with columns:
# - open: Opening price
# - high: High price
# - low: Low price
# - close: Closing price
# - volume: Trading volume
# - trade_count: Number of trades
# - vwap: Volume-weighted average price
Latest Bars
# Get the latest bar for a single symbol
latest = api.stock.history.get_latest_bars("AAPL")
print(f"Latest close: ${latest.iloc[0]['close']}")
print(f"Volume: {latest.iloc[0]['volume']:,}")
# Get latest bars for multiple symbols
symbols = ["AAPL", "MSFT", "GOOGL"]
latest_bars = api.stock.history.get_latest_bars(symbols)
# Returns a dictionary mapping symbols to DataFrames
for symbol, df in latest_bars.items():
print(f"{symbol}: ${df.iloc[0]['close']}")
Intraday Bars
# Get 5-minute bars for today
bars = api.stock.history.get_bars(
symbol="AAPL",
start=pendulum.today("America/New_York").add(hours=9, minutes=30),
end=pendulum.now("America/New_York"),
timeframe="5Min"
)
# Analyze price movements
print(f"Bars retrieved: {len(bars)}")
print(f"Day's range: ${bars['low'].min():.2f} - ${bars['high'].max():.2f}")
print(f"Total volume: {bars['volume'].sum():,}")
Methods
get_bars() / get_stock_data()
Retrieve historical bar data for a symbol.
Parameters:
symbol: Stock symbol
start: Start date/time (pendulum datetime)
end: End date/time (pendulum datetime)
timeframe: Bar timeframe (“1Min”, “5Min”, “15Min”, “30Min”, “1Hour”, “1Day”, “1Week”, “1Month”)
adjustment: Price adjustment for splits (“raw”, “split”, “dividend”, “all”)
feed: Data feed to use (“iex”, “sip”, “otc”)
limit: Maximum number of bars to return
page_limit: Number of bars per page
asof: As-of date for corporate actions
get_latest_bars()
Get the most recent bar for one or more symbols.
Parameters:
symbols: Single symbol string or list of symbols
feed: Data feed to use (“iex”, “sip”, “otc”)
currency: Currency for the bars (default: “USD”)
get_bars_multi()
Get bars for multiple symbols in a single request.
Parameters:
symbols: List of stock symbols
start: Start date/time
end: End date/time
timeframe: Bar timeframe
adjustment: Price adjustment
feed: Data feed
Timeframes
Available timeframes for bar data:
Timeframe |
Description |
|---|---|
1Min |
One minute bars |
5Min |
Five minute bars |
15Min |
Fifteen minute bars |
30Min |
Thirty minute bars |
1Hour |
Hourly bars |
1Day |
Daily bars |
1Week |
Weekly bars |
1Month |
Monthly bars |
Price Adjustments
Control how historical prices are adjusted:
# Raw prices (no adjustments)
bars_raw = api.stock.history.get_bars(
symbol="AAPL",
start=start_date,
end=end_date,
timeframe="1Day",
adjustment="raw"
)
# Split-adjusted only
bars_split = api.stock.history.get_bars(
symbol="AAPL",
start=start_date,
end=end_date,
timeframe="1Day",
adjustment="split"
)
# All adjustments (splits and dividends)
bars_adjusted = api.stock.history.get_bars(
symbol="AAPL",
start=start_date,
end=end_date,
timeframe="1Day",
adjustment="all"
)
Technical Analysis
# Calculate moving averages
bars = api.stock.history.get_bars(
symbol="AAPL",
start=pendulum.now().subtract(days=100),
end=pendulum.now(),
timeframe="1Day"
)
# Simple moving averages
bars['SMA_20'] = bars['close'].rolling(window=20).mean()
bars['SMA_50'] = bars['close'].rolling(window=50).mean()
# Bollinger Bands
bars['BB_middle'] = bars['close'].rolling(window=20).mean()
bars['BB_std'] = bars['close'].rolling(window=20).std()
bars['BB_upper'] = bars['BB_middle'] + (bars['BB_std'] * 2)
bars['BB_lower'] = bars['BB_middle'] - (bars['BB_std'] * 2)
# RSI calculation
def calculate_rsi(data, window=14):
delta = data.diff()
gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
rs = gain / loss
return 100 - (100 / (1 + rs))
bars['RSI'] = calculate_rsi(bars['close'])
Volume Analysis
# Analyze volume patterns
bars = api.stock.history.get_bars(
symbol="AAPL",
start=pendulum.now().subtract(days=30),
end=pendulum.now(),
timeframe="1Day"
)
# Volume indicators
bars['Volume_MA'] = bars['volume'].rolling(window=20).mean()
bars['Volume_Ratio'] = bars['volume'] / bars['Volume_MA']
# Find high volume days
high_volume_days = bars[bars['Volume_Ratio'] > 1.5]
print(f"Days with 50% above average volume: {len(high_volume_days)}")
# VWAP analysis
bars['VWAP_Diff'] = bars['close'] - bars['vwap']
bars['VWAP_Pct'] = (bars['VWAP_Diff'] / bars['vwap']) * 100
Batch Operations
# Get data for multiple symbols efficiently
symbols = ["AAPL", "MSFT", "GOOGL", "AMZN", "META"]
# Latest bars for all symbols
latest = api.stock.history.get_latest_bars(symbols)
# Historical data for multiple symbols
all_data = {}
for symbol in symbols:
all_data[symbol] = api.stock.history.get_bars(
symbol=symbol,
start=pendulum.now().subtract(days=7),
end=pendulum.now(),
timeframe="1Hour"
)
# Analyze correlations
closes = pd.DataFrame({
symbol: data['close']
for symbol, data in all_data.items()
})
correlation_matrix = closes.corr()
Error Handling
from py_alpaca_api.exceptions import APIRequestError
try:
bars = api.stock.history.get_bars(
symbol="INVALID",
start=pendulum.now().subtract(days=30),
end=pendulum.now(),
timeframe="1Day"
)
except APIRequestError as e:
print(f"API error: {e}")
except Exception as e:
print(f"Error retrieving data: {e}")
Performance Tips
Use appropriate timeframes: Don’t request minute bars for multi-year periods
Implement caching: The library includes built-in caching support
Batch requests: Use get_latest_bars() with multiple symbols instead of looping
Limit data range: Request only the data you need
Use pagination: For large datasets, the library handles pagination automatically