
Trading bots, also commonly called algorithmic trading systems, are programs that execute orders based on predefined rules without requiring manual intervention for each trade. Developers and quantitative traders can use Alpaca's Trading API and Market Data API to implement rule-based systems that fetch price data, evaluate conditions, and submit orders programmatically.
This guide covers how to set up an Alpaca account and API credentials, retrieve historical and real-time market data, implement a basic signal-based US stock strategy, and submit orders through Alpaca's paper trading environment through an automated trading bot. All examples are strictly educational and hypothetical.
NOTE: This article is for general informational and educational purposes only. The examples provided are for educational and technical demonstration purposes only and are not intended as a recommendation or endorsement of any automated trading strategy.
This article was written and provided by a third party that received compensation for its creation. The views and opinions expressed are those of the third party, are presented for informational purposes only, and do not necessarily reflect the views of Alpaca. This content has not been independently verified by Alpaca and does not constitute investment, legal, or tax advice, or a recommendation or endorsement by Alpaca. Any third-party descriptions, comparisons, platform features, statements, or images are provided by such third parties and are not endorsed by Alpaca.
Investing and trading involve risk, including the potential loss of principal. Past performance, whether actual or backtested, is not indicative of future results. No investment strategy is guaranteed to achieve its objectives. Diversification does not ensure a profit or protect against loss. Investors should carefully consider their investment objectives and risks before investing.
Key Takeaways
- Alpaca's Trading API can help developers submit stock orders programmatically through a REST-based interface using the
alpaca-pyPython SDK. - Alpaca's Market Data API provides access to historical OHLCV bar data and real-time WebSocket streams that can be used as inputs for signal generation.
- Paper trading provides a simulated environment using real market data without deploying real capital, though simulated results may not reflect live trading conditions.
- API credentials should be stored in environment variables or a .env file and never be committed to version control.
- Rule-based trading systems carry execution risk, automation risk, and market risk, including the potential loss of principal.
- Backtesting against historical data is a common practice before considering any live deployment, but past performance is not indicative of future results.
- Position checks, error handling, and logging can be important operational components for any automated system.
This article is for general informational and educational purposes only. It is believed to be accurate as of the posting date but may be subject to change. All examples are for illustrative purposes only. The information presented is educational in nature and is not tailored to any individual’s financial situation. Readers are responsible for evaluating whether any strategy or approach is appropriate for their circumstances.
This article was commissioned and compensated by Alpaca. The content was developed for informational purposes and reflects an educational comparison of publicly available information. Compensation was provided for content creation and distribution.
What Is a Stock Trading Bot?
A stock trading bot is an automated system that evaluates market data against a set of rules and submits buy or sell orders when specified conditions are met. The rules might reference technical indicators, price thresholds, time-based conditions, or a combination of factors.
Automated systems carry their own categories of risk, including:
- Execution risk: Orders may not fill at the expected price due to slippage or low liquidity.
- Automation risk: Coding errors or logic bugs can lead to unintended orders executing rapidly.
- Data risk: Incorrect, delayed, or missing data may cause erroneous signal generation.
- Market risk: The underlying strategy logic may not perform as expected in all market conditions, including trending, range-bound, or high-volatility environments.
Prerequisites
Before working through the code examples in this guide, you will need:
- An Alpaca's Trading API account (paper trading does not require funded capital)
- Python 3.12 or later installed (per the alpaca-py listing)
- The following Python packages:
alpaca-py,pandas,python-dotenv - API keys from your Alpaca dashboard
Install the required packages:
uv pip install alpaca-py pandas python-dotenvFor SDK details, refer to the alpaca-py SDK documentation and the Alpaca API documentation.
API Key Configuration Using Environment Variables
API keys can be stored outside source files to reduce the risk of accidental exposure. Using a .env file or environment variables is a common practice. Keys must never be committed to repositories. Add .env to your .gitignore file.
The following pattern supports both local development and Google Colab environments:
import os
from dotenv import load_dotenv
import sys
if "google.colab" in sys.modules:
# In Google Colab environment, fetch API keys from Secrets.
# Users can set ALPACA_API_KEY and ALPACA_SECRET_KEY
# in Colab Secrets via the sidebar.
from google.colab import userdata
ALPACA_API_KEY = userdata.get("ALPACA_API_KEY")
ALPACA_SECRET_KEY = userdata.get("ALPACA_SECRET_KEY")
else:
# Store API keys safely and never commit them to repositories.
# Use .gitignore for .env files.
load_dotenv()
ALPACA_API_KEY = os.environ.get("ALPACA_API_KEY")
ALPACA_SECRET_KEY = os.environ.get("ALPACA_SECRET_KEY")Your .env file can contain:
ALPACA_API_KEY="insert_key_here"
ALPACA_SECRET_KEY="insert_secret_here"For production deployments, consider using a dedicated secrets manager such as AWS Secrets Manager or HashiCorp Vault. Never share API keys in public repositories, chat messages, or documentation.
Set Up the Alpaca Clients
Alpaca's alpaca-py SDK provides two primary clients relevant to a trading bot: the StockHistoricalDataClient for retrieving price data, and the TradingClient for managing orders and positions.
Initialize the Market Data Client
from alpaca.data.historical import StockHistoricalDataClient
stock_historical_data_client = StockHistoricalDataClient(ALPACA_API_KEY, ALPACA_SECRET_KEY)What this code does: It instantiates the market data client using your credentials. This client can be used to request historical bar data for any supported symbol.
Why this step exists: Technical indicator computations in this example rely on price history. This client provides the data pipeline for that computation.
When to use this: At startup, before any data fetching or signal evaluation occurs.
Initialize the Trading Client
from alpaca.trading.client import TradingClient
trade_client = TradingClient(api_key=ALPACA_API_KEY, secret_key=ALPACA_SECRET_KEY, paper=ALPACA_PAPER_TRADE)What this code does: It instantiates the trading client and directs requests to Alpaca's paper trading endpoint via paper=True.
Why this step exists: The trading client can be used for order submission, position queries, and account management. Setting paper=True routes all requests to the simulated environment.
When to use this: Whenever the bot needs to submit orders or check current positions.
Fetch Historical Bar Data
To generate trading signals, the bot needs historical OHLCV (Open, High, Low, Close, Volume) data. Alpaca's Market Data API provides access to historical stock bar data across multiple timeframes. For details on available data coverage, refer to our Historical Stock Data documentation.
Request Daily Bars
from alpaca.data.requests import StockBarsRequest from alpaca.data.timeframe import TimeFrame from datetime import datetime, timedelta import pandas as pd
trade_client = TradingClient(api_key=ALPACA_API_KEY, secret_key=ALPACA_SECRET_KEY, paper=ALPACA_PAPER_TRADE)What this code does: It requests daily bars for a given symbol over a configurable lookback window and returns a pandas DataFrame indexed by timestamp.
Why this step exists: A sufficient lookback window may help provide enough data so that moving averages and other indicators based on multiple periods may produce more stable values. A 120-day window provides a buffer that may be suitable for common indicator parameters, though the appropriate lookback period depends on the specific strategy.
When to use this: At the start of each evaluation cycle, before computing indicators or checking signals.
Request Historical Bars
from alpaca.data.requests import StockBarsRequest
from alpaca.data.timeframe import TimeFrame
from datetime import datetime, timedelta
import pandas as pd
def fetch_bars(symbol: str, lookback_days: int = 252) -> pd.DataFrame:
"""Fetch daily OHLCV bar data for a given symbol.
Args:
symbol: Ticker symbol, for example `SPY`.
lookback_days: Number of calendar days to look back.
Returns:
DataFrame indexed by timestamp with OHLCV columns.
"""
request_params = StockBarsRequest(
symbol_or_symbols=symbol,
timeframe=TimeFrame.Day,
start=datetime.now() - timedelta(days=lookback_days),
end=datetime.now() - timedelta(days=1),
)
bars = stock_historical_data_client.get_stock_bars(request_params)
df = bars.df
if isinstance(df.index, pd.MultiIndex):
df = df.xs(symbol, level="symbol")
return dfWhat this code does: It requests daily bar data for a symbol over a specified lookback window and returns a flat DataFrame.
Why 252 days: A 252-day window is a commonly used convention in quantitative finance as an approximation for one trading year of daily data. It may provide a sufficient lookback period for computing rolling statistics, though the appropriate lookback period may vary depending on the asset and market conditions. Additional history can help stabilize rolling mean and standard deviation values.
When to use this: As the first step in any signal computation or backtesting pipeline that requires closing price history.
Compute a Simple Moving Average Signal
The following example uses a simple moving average (SMA) crossover as a hypothetical signal. A shorter-period SMA crossing above a longer-period SMA is sometimes interpreted by some traders as a potential bullish signal, while crossing below may be interpreted by some traders as bearish. These interpretations are not guarantees of price direction and may produce false signals, particularly in range-bound or choppy markets.
Calculate SMAs
def compute_sma(
df: pd.DataFrame, short: int = 20, long: int = 50
) -> pd.DataFrame:
"""Add short and long SMA columns to the DataFrame.
Args:
df: DataFrame with a `close` column.
short: Short SMA period.
long: Long SMA period.
Returns:
DataFrame with `sma_short` and `sma_long` columns added.
"""
df = df.copy()
df["sma_short"] = df["close"].rolling(window=short).mean()
df["sma_long"] = df["close"].rolling(window=long).mean()
return dfWhat this code does: It computes rolling simple moving averages of closing prices and appends them as new columns.
Why this step exists: Moving averages can smooth price data over a specified period and are often used in rule-based systems as a basis for signal generation.
When to use this: After fetching bar data and before running crossover detection.
Detect Crossover Events
A crossover event is detected by comparing the relative positions of the short and long SMAs across two consecutive bars. If the short SMA was below the long SMA in the previous bar and is now above it, a bullish crossover may have occurred, and vice versa for a bearish crossover.
def detect_sma_crossover(df: pd.DataFrame) -> str:
"""Detect the most recent SMA crossover signal.
Args:
df: DataFrame with `sma_short` and `sma_long` columns.
Returns:
`bullish`, `bearish`, or `none`.
"""
if len(df) < 2:
return "none"
prev = df.iloc[-2]
curr = df.iloc[-1]
prev_diff = prev["sma_short"] - prev["sma_long"]
curr_diff = curr["sma_short"] - curr["sma_long"]
# Bullish crossover: short SMA crosses above long SMA.
if prev_diff <= 0 and curr_diff > 0:
return "bullish"
# Bearish crossover: short SMA crosses below long SMA.
if prev_diff >= 0 and curr_diff < 0:
return "bearish"
return "none"What this code does: It checks consecutive rows for a sign change in the difference between the short and long SMAs, returning the corresponding signal type.
Why this step exists: Evaluating two consecutive bars, rather than just the current bar, can help identify whether a transition has occurred rather than a persistent state.
When to use this: After computing SMAs, as the immediate input to the order submission logic.
Check Existing Positions
Before submitting a new order, it is common practice to query any currently open position in the symbol, which can help reduce the risk of duplicate entries or invalid exit orders.
from alpaca.common.exceptions import APIError
def get_position(symbol: str):
"""Retrieve the open position for a given symbol, if any.
Args:
symbol: The stock ticker symbol.
Returns:
The position object, or `None` if no position is open.
"""
try:
position = trade_client.get_open_position(symbol)
return position
except APIError as exc:
error_message = str(exc).lower()
if "position" in error_message and (
"does not exist" in error_message or "not found" in error_message
):
return None
logging.exception("Failed to fetch position for %s", symbol)
raiseWhat this code does: It queries Alpaca's Trading API for any open position in the specified symbol. If no position exists, the API raises an exception, which this function handles by returning None.
Why this step exists: Attempting to sell a position that does not exist, or entering a duplicate long position, can cause unintended order behavior.
When to use this: Immediately before any conditional order submission logic.
Submit Orders
When a signal condition is met, the bot can submit orders using Alpaca's Trading API. The examples below use market orders for illustrative purposes. In practice, other order types may be more appropriate depending on execution requirements. For the full range of available order types, read our documentation about orders at Alpaca.
Submit a Market Order
def submit_market_order(symbol: str, qty: int, side: OrderSide):
"""Submit a market order through Alpaca's Trading API.
Args:
symbol: The stock ticker symbol.
qty: Number of shares to trade.
side: `OrderSide.BUY` or `OrderSide.SELL`.
Returns:
The submitted order object.
"""
order_data = MarketOrderRequest(
symbol=symbol,
qty=qty,
side=side,
time_in_force=TimeInForce.DAY,
)
order = trade_client.submit_order(order_data=order_data)
return orderWhat this code does: It creates a MarketOrderRequest object with the specified parameters and submits it to Alpaca's Trading API. The TimeInForce.DAY setting means the order is valid for the current trading session only.
Why this step exists: Market orders are generally designed to execute at the next available price and can be relatively straightforward to implement in automated systems. However, market orders may experience slippage, particularly in fast-moving or low-liquidity conditions.
When to use this: After signal detection indicates a condition is met and the position check indicates that the action is appropriate.
Assemble a Hypothetical SMA Crossover Strategy
The following example assembles the components above into a single hypothetical strategy function. This is a simplified illustration and is not a production-ready system or a trading recommendation.
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(message)s",
)
def run_sma_strategy(symbol: str = "SPY", qty: int = 1) -> None:
"""Run a simple SMA crossover strategy.
Fetch historical data, compute SMAs, detect crossovers, and submit
hypothetical paper-trading orders.
Args:
symbol: The stock ticker symbol to evaluate.
qty: Number of shares to use in hypothetical orders.
"""
# Step 1: Fetch historical bar data.
df = fetch_bars(symbol, lookback_days=120)
# Step 2: Compute SMAs.
df = compute_sma(df, short=20, long=50)
# Step 3: Detect crossover signal.
signal = detect_sma_crossover(df)
logging.info("Signal detected for %s: %s", symbol, signal)
# Step 4: Check current position.
try:
position = get_position(symbol)
except APIError:
logging.exception(
"Aborting strategy because position lookup failed for %s", symbol
)
return
position_qty = float(position.qty) if position is not None else 0.0
# Step 5: Conditionally submit orders.
if signal == "bullish" and position is None:
logging.info(
"Bullish crossover detected for %s. "
"Submitting buy order for %s share(s).",
symbol,
qty,
)
order = submit_market_order(symbol, qty, OrderSide.BUY)
logging.info("Order submitted: %s", order.id)
elif signal == "bullish" and position_qty < 0:
cover_qty = abs(int(position_qty))
logging.info(
"Bullish crossover detected for %s. "
"Covering short position of %s share(s).",
symbol,
cover_qty,
)
order = submit_market_order(symbol, cover_qty, OrderSide.BUY)
logging.info("Order submitted: %s", order.id)
elif signal == "bearish" and position_qty > 0:
held_qty = int(position_qty)
logging.info(
"Bearish crossover detected for %s. "
"Submitting sell order for %s share(s).",
symbol,
held_qty,
)
order = submit_market_order(symbol, held_qty, OrderSide.SELL)
logging.info("Order submitted: %s", order.id)
else:
logging.info(
"No actionable signal for %s. Signal: %s. Position: %s",
symbol,
signal,
position,
)What this code does: It runs through the complete workflow: fetching data, computing SMAs, detecting crossovers, checking position status, and conditionally submitting paper orders. Logging captures each step for review.
Limitations of this example:
- It does not include position sizing or risk management logic such as stop-loss or take-profit conditions.
- It runs once and exits. A production system would require scheduling, for example, a cron job, cloud function, or an event loop with appropriate delays and market-hours awareness.
- It uses daily bars. Intraday strategies require different data frequencies and considerations.
- Market orders may experience slippage. Other order types available through Alpaca's orders documentation may be more appropriate in specific scenarios.
- This example does not account for trading halts, market closures, or partial fills.
For a working example that incorporates MACD and RSI signals, read our guide on building an RSI and MACD trading bot with ChatGPT and Alpaca.
Using Real-Time Data Streams
Beyond historical bars, Alpaca's WebSocket streaming interface can be used to receive real-time trade and quote updates. This may be useful for intraday strategies that need to react to price events as they occur rather than polling on a schedule.
Subscribe to Real-Time Bar Data
from alpaca.data.live import StockDataStream
def handle_bar(bar) -> None:
"""Handle a newly received bar."""
print(
f"Bar received: {bar.symbol} | Close: {bar.close} | Time: {bar.timestamp}"
)
def start_stream(symbol: str) -> None:
"""
Start a WebSocket stream for real-time minute bar data.
Args:
symbol: The stock ticker symbol to subscribe to.
"""
stream = StockDataStream(ALPACA_API_KEY, ALPACA_SECRET_KEY)
stream.subscribe_bars(handle_bar, symbol)
stream.run()What this code does: It creates a StockDataStream client, subscribes the handle_bar callback to incoming bar events for the specified symbol, and starts the WebSocket connection.
Why this step exists: Polling historical data on a fixed schedule may introduce latency for intraday use cases. WebSocket streams can help reduce that latency by pushing data when new bars become available.
When to use this: For intraday or event-driven strategies where near-real-time data is part of the system's design requirements.
For more detail on streaming capabilities, refer to Alpaca's real-time stock data documentation.
Use Paper Trading for Testing
Alpaca's paper trading environment simulates order execution using real market data without involving real capital. Setting paper=True on the TradingClient directs all requests to the paper endpoint. This can be useful for:
- Verifying that code executes correctly
- Observing how the strategy behaves during live market hours
- Identifying edge cases or bugs before considering any live deployment
It is important to note that simulated results from paper trading may not reflect live trading conditions. Factors such as slippage, partial fills, and real-time liquidity can differ between paper and live environments. Paper trading results cannot be interpreted as indicative of future performance. Read our full guide on paper trading vs. live trading and when to make the shift.
Logging and Monitoring
For systems that run autonomously, logging can be an important operational component. Python's built-in logging module or third-party tools can be used to record:
- Timestamps and signal values at each evaluation cycle
- Order submission confirmations and order IDs
- Fill status and execution prices
- Error messages and exception traces
- Account balance and position snapshots
A logging configuration example:
import logging
logging.basicConfig( filename="trading_bot.log", level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s" )What this code does: It configures the logging module to write timestamped entries to a file named trading_bot.log at the INFO level and above.
Why this step exists: Log files can provide an audit trail for reviewing what the system did and why, which can be valuable for debugging or evaluating strategy behavior over time.
When to use this: At startup, before any strategy logic runs.
Backtest Before Live Deployment
Before deploying any strategy with real capital, backtesting against historical data is a common practice. Backtesting applies strategy logic to historical price data to observe how it would have behaved under those conditions.
Key considerations for backtesting:
- Past performance is not indicative of future results.
- Backtests may not account for slippage, partial fills, or market impact.
- Overfitting to historical data is a risk in quantitative strategy development. A strategy that shows favorable results in backtesting may not perform similarly in live markets.
- Data quality and the lookback period used in testing can significantly affect backtesting results.
We also have resources that include guides on backtesting with VectorBT and backtesting options strategies.
Additional Use Cases
Intraday Strategies
Daily-bar strategies run once per session. Intraday strategies may use minute-level or hourly bars and evaluate signals more frequently. Our Market Data API supports TimeFrame.Minute, TimeFrame.Hour, TimeFrame.Day, TimeFrame.Week, and TimeFrame.Month. For detailed timeframe options, refer to the alpaca-py SDK TimeFrame documentation and the historical stock data documentation.
Intraday strategies may produce more frequent signals and can amplify both potential outcomes and risk. Adjusting indicator parameters for shorter timeframes and incorporating additional filters may help reduce false signals, though no approach can fully prevent them.
Combine Multiple Indicators
Some traders combine multiple indicators as a way to seek confirmation before acting on a signal. For example, an SMA crossover might be evaluated alongside a momentum indicator such as RSI, or alongside volume conditions. Our resources on technical analysis with TA-Lib and Market Data API covers how to integrate additional indicators into a data pipeline.
Note: No combination of indicators can predict future price movements or prevent trading losses.
Scheduling and Deployment
A bot that runs once and exits is not a production system. Common scheduling approaches include:
- Cron jobs on a local machine or cloud server
- Cloud functions such as AWS Lambda or Google Cloud Functions triggered on a schedule
- Containerized deployments using Docker on a cloud VM
For an example of deploying a trading bot with CI/CD integration, see our resources on building an end-to-end trading bot using Alpaca's Trading API, CircleCI, and Slack.
Risk Considerations
All automated trading strategies carry risk. Specific risks to consider when building a stock trading bot include:
- False signals: Rule-based signals may not lead to sustained price movements, particularly in low-volatility or range-bound markets.
- Lag: Strategies based on moving averages or other lagging indicators may generate signals after a price move has already occurred.
- Execution risk: Market orders may not fill at the expected price due to slippage or liquidity conditions at the time of execution.
- Automation risk: An automated system can execute orders rapidly. Errors in logic or data handling can lead to unintended trades.
- Data risk: Delayed, incorrect, or missing data can cause erroneous signal generation.
- Connectivity risk: API outages, network interruptions, or rate-limiting can interrupt bot operations at critical moments.
There is always the potential of losing money when trading securities.
Conclusion
Once your trading bot has been set up and tested in paper, readers interested in learning more about live trading infrastructure can visit our guide on how to open a live Alpaca Trading API account as a US resident or non US resident. Once your live account is open, check out our guide on how to fund your Alpaca Trading API Account.
If you want to keep building, explore the resources below for account setup, paper trading, and advanced Trading API workflows.
- How to Open a Live Alpaca Trading API Account as a US Resident
- How to Open a Live Alpaca Trading API Account as a Non-US Resident
- How to Fund Your Alpaca Live Trading Account
- How to Start Paper Trading with Alpaca's Trading API
- Alpaca-py GitHub Page
- Alpaca-py Documentation
- Alpaca's Trading API Reference
Frequently Asked Questions
What is the difference between paper trading and live trading with Alpaca?
Paper trading uses the same API spec and SDK methods as live trading, but routes requests to a simulated environment that does not involve real capital. Execution uses real market data to simulate fills, but simulated results may not match live trading outcomes. Factors such as slippage, partial fills, and real-time liquidity can differ. For a detailed comparison, see our data-backed guide on paper trading vs. live trading.
How can API keys be stored when building a trading bot?
API keys can be stored in environment variables or a .env file loaded at runtime, and must never be committed to version control. For production deployments, a dedicated secrets manager such as AWS Secrets Manager or HashiCorp Vault may provide an additional layer of access control. Never include API keys in code comments, screenshots, or documentation. See the environment variable configuration section above for an implementation pattern compatible with both local environments and Google Colab.
Can a trading bot run continuously without manual intervention?
A bot can be scheduled to run on a recurring basis using a cron job, cloud function, or containerized process. However, fully automated operation introduces operational risk. Network interruptions, API rate limits, data issues, or logic errors may occur without a human present to identify them. Logging and monitoring can help surface these issues. Robust error handling, position checks, and alerts can be important components of any autonomous system.
What order types are available through Alpaca's Trading API?
Our Trading API supports market orders, limit orders, stop orders, stop-limit orders, trailing stop orders, and bracket orders, among others. Each order type has different execution characteristics and may be suited to different scenarios. For a full description of available order types and their parameters, refer to Orders at Alpaca.
Is backtesting required before deploying a trading bot?
Backtesting is a common practice in quantitative strategy development and can help identify how a strategy would have behaved against historical data. However, past results, whether actual or backtested, are not indicative of future outcomes. Overfitting to historical data and failing to account for real-world execution conditions such as slippage are common limitations of backtesting.
Additional References
- About Trading API, Alpaca, Accessed March 2026.
- About Market Data API, Alpaca, Accessed March 2026.
- Paper Trading, Alpaca, Accessed March 2026.
- Alpaca Trading API Signup, Alpaca, Accessed March 2026.
- alpaca-py, PyPI, Accessed March 2026.
- Getting Started with alpaca-py, Alpaca, Accessed March 2026.
- Alpaca API Documentation, Alpaca, Accessed March 2026.
- Historical Stock Data, Alpaca, Accessed March 2026.
- Orders at Alpaca, Alpaca, Accessed March 2026.
- How to Build a Free RSI and MACD Trading Bot with ChatGPT and Alpaca, Alpaca, May 2025.
- WebSocket Streaming, Alpaca, Accessed March 2026.
- Real-Time Stock Pricing Data, Alpaca, Accessed March 2026.
- Advanced Live Websocket Crypto Data Streams in Python, Alpaca, July 2022.
- Paper Trading vs. Live Trading: A Data-Backed Guide on When to Start Trading Real Money, Alpaca, August 2025.
- Introduction to Backtesting with VectorBT, Alpaca, January 2022.
- Options Backtesting: How to Backtest with Alpaca's Trading API, Alpaca, February 2024.
- Building Your Algorithmic Trading Setup, Alpaca, February 2024.
- alpaca-py SDK TimeFrame Documentation, Alpaca, Accessed March 2026.
- Technical Analysis with TA-Lib and Market Data API, Alpaca, February 2022.
- Building an End-to-End Trading Bot Using Alpaca's API, CircleCI, and Slack, Alpaca, June 2023.
- Risks of Automated Trading Systems, Alpaca, August 2021.
The Paper Trading API is offered by AlpacaDB, Inc. and does not require real money or permit a user to transact in real securities in the market. Providing use of the Paper Trading API is not an offer or solicitation to buy or sell securities, securities derivative or futures products of any kind, or any type of trading or investment advice, recommendation or strategy, given or in any manner endorsed by AlpacaDB, Inc. or any AlpacaDB, Inc. affiliate and the information made available through the Paper Trading API is not an offer or solicitation of any kind in any jurisdiction where AlpacaDB, Inc. or any AlpacaDB, Inc. affiliate (collectively, “Alpaca”) is not authorized to do business.
Securities brokerage services are provided by Alpaca Securities LLC (dba "Alpaca Clearing"), member FINRA/SIPC, a wholly-owned subsidiary of AlpacaDB, Inc. Technology and services are offered by AlpacaDB, Inc.
Options trading is not suitable for all investors due to its inherent high risk, which can potentially result in significant losses. Please read “Characteristics and Risks of Standardized Options” before investing in options.
Cryptocurrency services are made available by Alpaca Crypto LLC ("Alpaca Crypto"), a FinCEN registered money services business (NMLS # 2160858), and a wholly-owned subsidiary of AlpacaDB, Inc. Alpaca Crypto is not a member of SIPC or FINRA. Cryptocurrencies are not stocks and your cryptocurrency investments are not protected by either FDIC or SIPC. Please see the Disclosure Library for more information.
This is not an offer, solicitation of an offer, or advice to buy or sell securities or cryptocurrencies or open a brokerage account or cryptocurrency account in any jurisdiction where Alpaca Securities or Alpaca Crypto, respectively, are not registered or licensed, as applicable.