The Official Python SDK for Alpaca APIs providing access to trading, market data, and broker services
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The Trading Client provides comprehensive functionality for managing orders, positions, account information, and trading-related activities in both paper and live trading environments.
from alpaca.trading import TradingClient
class TradingClient(RESTClient):
def __init__(
self,
api_key: Optional[str] = None,
secret_key: Optional[str] = None,
oauth_token: Optional[str] = None,
paper: bool = True,
raw_data: bool = False,
url_override: Optional[str] = None,
) -> None:
"""
Initialize trading client for paper or live trading.
Args:
api_key: API key for authentication
secret_key: Secret key for authentication
oauth_token: OAuth token for user-on-behalf trading
paper: True for paper trading, False for live trading
raw_data: Return raw API responses instead of models
url_override: Override base URL for testing/proxy
"""# Paper trading client
trading_client = TradingClient(
api_key="your-paper-api-key",
secret_key="your-paper-secret-key",
paper=True
)
# Live trading client
trading_client = TradingClient(
api_key="your-live-api-key",
secret_key="your-live-secret-key",
paper=False
)
# OAuth-based client for user-on-behalf trading
trading_client = TradingClient(
oauth_token="user-oauth-token",
paper=True
)def submit_order(self, order_data: OrderRequest) -> Union[Order, RawData]:
"""
Submit a new order for execution.
Args:
order_data: Order request with order details
Returns:
Order: The submitted order with server-assigned ID and status
"""from alpaca.trading.requests import MarketOrderRequest
from alpaca.trading.enums import OrderSide, TimeInForce
class MarketOrderRequest(OrderRequest):
"""Market order that executes immediately at current market price."""
def __init__(
self,
symbol: str,
qty: Optional[float] = None,
notional: Optional[float] = None, # Dollar amount for stocks
side: OrderSide,
time_in_force: TimeInForce,
extended_hours: Optional[bool] = None,
client_order_id: Optional[str] = None,
order_class: Optional[OrderClass] = None,
take_profit: Optional[TakeProfitRequest] = None,
stop_loss: Optional[StopLossRequest] = None,
position_intent: Optional[PositionIntent] = None # For options: BTO, BTC, STO, STC
):Usage Examples:
# Basic market buy order
market_buy = MarketOrderRequest(
symbol="AAPL",
qty=100,
side=OrderSide.BUY,
time_in_force=TimeInForce.DAY
)
order = trading_client.submit_order(market_buy)
# Notional market order (buy $1000 worth)
dollar_buy = MarketOrderRequest(
symbol="TSLA",
notional=1000.00,
side=OrderSide.BUY,
time_in_force=TimeInForce.GTC
)
order = trading_client.submit_order(dollar_buy)
# Market order with bracket (take profit + stop loss)
bracket_order = MarketOrderRequest(
symbol="MSFT",
qty=50,
side=OrderSide.BUY,
time_in_force=TimeInForce.DAY,
order_class=OrderClass.BRACKET,
take_profit=TakeProfitRequest(limit_price=200.00),
stop_loss=StopLossRequest(stop_price=180.00)
)
order = trading_client.submit_order(bracket_order)from alpaca.trading.requests import LimitOrderRequest
class LimitOrderRequest(OrderRequest):
"""Limit order that executes only at specified price or better."""
def __init__(
self,
symbol: str,
qty: Optional[float] = None,
notional: Optional[float] = None,
side: OrderSide,
time_in_force: TimeInForce,
limit_price: float, # Maximum buy price or minimum sell price
extended_hours: Optional[bool] = None,
client_order_id: Optional[str] = None,
order_class: Optional[OrderClass] = None,
take_profit: Optional[TakeProfitRequest] = None,
stop_loss: Optional[StopLossRequest] = None,
position_intent: Optional[PositionIntent] = None
):Usage Examples:
# Limit buy order
limit_buy = LimitOrderRequest(
symbol="NVDA",
qty=25,
side=OrderSide.BUY,
time_in_force=TimeInForce.GTC,
limit_price=450.00
)
order = trading_client.submit_order(limit_buy)
# Limit sell order
limit_sell = LimitOrderRequest(
symbol="AMZN",
qty=10,
side=OrderSide.SELL,
time_in_force=TimeInForce.DAY,
limit_price=155.00
)
order = trading_client.submit_order(limit_sell)from alpaca.trading.requests import StopOrderRequest
class StopOrderRequest(OrderRequest):
"""Stop order that becomes market order when stop price is reached."""
def __init__(
self,
symbol: str,
qty: Optional[float] = None,
notional: Optional[float] = None,
side: OrderSide,
time_in_force: TimeInForce,
stop_price: float, # Price that triggers the order
extended_hours: Optional[bool] = None,
client_order_id: Optional[str] = None,
order_class: Optional[OrderClass] = None,
take_profit: Optional[TakeProfitRequest] = None,
stop_loss: Optional[StopLossRequest] = None,
position_intent: Optional[PositionIntent] = None
):Usage Examples:
# Stop loss order
stop_loss = StopOrderRequest(
symbol="GOOG",
qty=15,
side=OrderSide.SELL,
time_in_force=TimeInForce.GTC,
stop_price=2800.00
)
order = trading_client.submit_order(stop_loss)from alpaca.trading.requests import StopLimitOrderRequest
class StopLimitOrderRequest(OrderRequest):
"""Stop-limit order: becomes limit order when stop price is reached."""
def __init__(
self,
symbol: str,
qty: Optional[float] = None,
notional: Optional[float] = None,
side: OrderSide,
time_in_force: TimeInForce,
stop_price: float, # Price that triggers the order
limit_price: float, # Limit price after trigger
extended_hours: Optional[bool] = None,
client_order_id: Optional[str] = None,
order_class: Optional[OrderClass] = None,
take_profit: Optional[TakeProfitRequest] = None,
stop_loss: Optional[StopLossRequest] = None,
position_intent: Optional[PositionIntent] = None
):Usage Examples:
# Stop-limit sell order
stop_limit_sell = StopLimitOrderRequest(
symbol="META",
qty=20,
side=OrderSide.SELL,
time_in_force=TimeInForce.DAY,
stop_price=320.00, # Trigger price
limit_price=315.00 # Minimum sell price after trigger
)
order = trading_client.submit_order(stop_limit_sell)from alpaca.trading.requests import TrailingStopOrderRequest
class TrailingStopOrderRequest(OrderRequest):
"""Trailing stop order that adjusts stop price as stock moves favorably."""
def __init__(
self,
symbol: str,
qty: Optional[float] = None,
notional: Optional[float] = None,
side: OrderSide,
time_in_force: TimeInForce,
trail_price: Optional[float] = None, # Fixed dollar trail amount
trail_percent: Optional[float] = None, # Percentage trail amount
extended_hours: Optional[bool] = None,
client_order_id: Optional[str] = None,
order_class: Optional[OrderClass] = None,
take_profit: Optional[TakeProfitRequest] = None,
stop_loss: Optional[StopLossRequest] = None,
position_intent: Optional[PositionIntent] = None
):Usage Examples:
# Trailing stop with dollar amount
trailing_stop_dollar = TrailingStopOrderRequest(
symbol="AAPL",
qty=100,
side=OrderSide.SELL,
time_in_force=TimeInForce.GTC,
trail_price=5.00 # Trail by $5
)
order = trading_client.submit_order(trailing_stop_dollar)
# Trailing stop with percentage
trailing_stop_percent = TrailingStopOrderRequest(
symbol="TSLA",
qty=50,
side=OrderSide.SELL,
time_in_force=TimeInForce.GTC,
trail_percent=0.02 # Trail by 2%
)
order = trading_client.submit_order(trailing_stop_percent)def get_orders(
self,
filter: Optional[GetOrdersRequest] = None
) -> Union[List[Order], RawData]:
"""
Retrieve orders with optional filtering.
Args:
filter: Optional filtering parameters
Returns:
List[Order]: List of orders matching filter criteria
"""from alpaca.trading.requests import GetOrdersRequest
from alpaca.trading.enums import OrderStatus, OrderSide
from datetime import datetime
class GetOrdersRequest(NonEmptyRequest):
def __init__(
self,
status: Optional[QueryOrderStatus] = None, # NEW, OPEN, CLOSED, ALL
limit: Optional[int] = None, # Max 500
after: Optional[datetime] = None, # Orders after timestamp
until: Optional[datetime] = None, # Orders before timestamp
direction: Optional[Sort] = None, # ASC, DESC
nested: Optional[bool] = None, # Include nested orders
symbols: Optional[Union[str, List[str]]] = None, # Filter by symbols
side: Optional[OrderSide] = None, # BUY, SELL
asof: Optional[datetime] = None # Point-in-time query
):Usage Examples:
# Get all orders
all_orders = trading_client.get_orders()
# Get open orders only
open_orders = trading_client.get_orders(
GetOrdersRequest(status=QueryOrderStatus.OPEN)
)
# Get recent orders for specific symbols
recent_orders = trading_client.get_orders(GetOrdersRequest(
symbols=["AAPL", "TSLA", "MSFT"],
after=datetime.now() - timedelta(days=7),
limit=100
))
# Get buy orders from last month
buy_orders = trading_client.get_orders(GetOrdersRequest(
side=OrderSide.BUY,
after=datetime.now() - timedelta(days=30),
status=QueryOrderStatus.ALL
))def get_order_by_id(
self,
order_id: Union[UUID, str],
filter: Optional[GetOrderByIdRequest] = None
) -> Union[Order, RawData]:
"""
Get specific order by ID.
Args:
order_id: UUID of the order
filter: Optional nested order inclusion
Returns:
Order: The specified order
"""def get_order_by_client_id(self, client_id: str) -> Union[Order, RawData]:
"""
Get order by client-assigned ID.
Args:
client_id: Client order identifier
Returns:
Order: The order with specified client ID
"""Usage Examples:
# Get order by server ID
order = trading_client.get_order_by_id("f47ac10b-58cc-4372-a567-0e02b2c3d479")
# Get order by client ID
order = trading_client.get_order_by_client_id("my-order-123")
# Get order with nested details
order = trading_client.get_order_by_id(
"f47ac10b-58cc-4372-a567-0e02b2c3d479",
GetOrderByIdRequest(nested=True)
)def replace_order_by_id(
self,
order_id: Union[UUID, str],
order_data: Optional[ReplaceOrderRequest] = None,
) -> Union[Order, RawData]:
"""
Update an existing order with new parameters.
Args:
order_id: ID of order to replace
order_data: New order parameters
Returns:
Order: Updated order
"""from alpaca.trading.requests import ReplaceOrderRequest
class ReplaceOrderRequest(NonEmptyRequest):
def __init__(
self,
qty: Optional[float] = None,
time_in_force: Optional[TimeInForce] = None,
limit_price: Optional[float] = None,
stop_price: Optional[float] = None,
trail_price: Optional[float] = None,
trail_percent: Optional[float] = None,
client_order_id: Optional[str] = None
):Usage Examples:
# Update order quantity
updated_order = trading_client.replace_order_by_id(
"order-id-123",
ReplaceOrderRequest(qty=150)
)
# Update limit price
updated_order = trading_client.replace_order_by_id(
"order-id-456",
ReplaceOrderRequest(limit_price=105.50)
)
# Update multiple parameters
updated_order = trading_client.replace_order_by_id(
"order-id-789",
ReplaceOrderRequest(
qty=200,
limit_price=99.99,
time_in_force=TimeInForce.GTC
)
)def cancel_orders(self) -> Union[List[CancelOrderResponse], RawData]:
"""
Cancel all open orders.
Returns:
List[CancelOrderResponse]: Status of each cancellation attempt
"""def cancel_order_by_id(self, order_id: Union[UUID, str]) -> None:
"""
Cancel specific order.
Args:
order_id: ID of order to cancel
"""Usage Examples:
# Cancel all orders
cancel_responses = trading_client.cancel_orders()
for response in cancel_responses:
print(f"Order {response.id}: Status {response.status}")
# Cancel specific order
trading_client.cancel_order_by_id("f47ac10b-58cc-4372-a567-0e02b2c3d479")def get_all_positions(self) -> Union[List[Position], RawData]:
"""
Get all open positions.
Returns:
List[Position]: All current positions
"""def get_open_position(
self,
symbol_or_asset_id: Union[str, UUID]
) -> Union[Position, RawData]:
"""
Get specific open position.
Args:
symbol_or_asset_id: Symbol or UUID of the asset
Returns:
Position: The position for specified asset
"""Usage Examples:
# Get all positions
positions = trading_client.get_all_positions()
for position in positions:
print(f"{position.symbol}: {position.qty} shares, ${position.market_value}")
# Get specific position
aapl_position = trading_client.get_open_position("AAPL")
print(f"AAPL P&L: ${aapl_position.unrealized_pl}")def close_all_positions(
self,
cancel_orders: Optional[bool] = None
) -> Union[List[ClosePositionResponse], RawData]:
"""
Liquidate all open positions.
Args:
cancel_orders: Whether to cancel existing orders first
Returns:
List[ClosePositionResponse]: Results of position closures
"""def close_position(
self,
symbol_or_asset_id: Union[str, UUID],
close_options: Optional[ClosePositionRequest] = None,
) -> Union[Order, RawData]:
"""
Close specific position.
Args:
symbol_or_asset_id: Symbol or UUID of asset to close
close_options: Partial close options
Returns:
Order: The liquidation order
"""from alpaca.trading.requests import ClosePositionRequest
class ClosePositionRequest(NonEmptyRequest):
def __init__(
self,
qty: Optional[str] = None, # Shares to close
percentage: Optional[str] = None # Percentage to close
):
# Must specify either qty OR percentage, not bothUsage Examples:
# Close all positions
close_responses = trading_client.close_all_positions(cancel_orders=True)
# Close entire position
close_order = trading_client.close_position("AAPL")
# Partial close by quantity
close_order = trading_client.close_position(
"TSLA",
ClosePositionRequest(qty="50")
)
# Partial close by percentage
close_order = trading_client.close_position(
"MSFT",
ClosePositionRequest(percentage="25") # Close 25% of position
)def exercise_options_position(
self,
symbol_or_contract_id: Union[str, UUID]
) -> None:
"""
Exercise options contracts.
Args:
symbol_or_contract_id: Option symbol or contract ID
"""Usage Examples:
# Exercise option by symbol
trading_client.exercise_options_position("AAPL230317C00150000")
# Exercise option by contract ID
trading_client.exercise_options_position("contract-uuid-here")def get_account(self) -> Union[TradeAccount, RawData]:
"""
Get current account information.
Returns:
TradeAccount: Account details and balances
"""class TradeAccount:
"""Account information and balances."""
id: UUID
account_number: str
status: AccountStatus
currency: str
cash: float # Available cash
buying_power: float # Total buying power
regt_buying_power: float # Regulation T buying power
daytrading_buying_power: float # Day trading buying power
equity: float # Total equity
last_equity: float # Previous day equity
multiplier: float # Buying power multiplier
portfolio_value: float # Total portfolio value
initial_margin: float # Initial margin requirement
maintenance_margin: float # Maintenance margin requirement
long_market_value: float # Long positions market value
short_market_value: float # Short positions market value
position_market_value: float # Total positions market value
last_maintenance_margin: float
sma: float # Special Memorandum Account
daytrade_count: int # PDT rule day trades count
balance_asof: datetime # Balance as-of timestamp
crypto_status: Optional[AccountStatus]Usage Examples:
# Get account information
account = trading_client.get_account()
print(f"Account: {account.account_number}")
print(f"Status: {account.status}")
print(f"Buying Power: ${account.buying_power:,.2f}")
print(f"Cash: ${account.cash:,.2f}")
print(f"Portfolio Value: ${account.portfolio_value:,.2f}")
print(f"Day Trade Count: {account.daytrade_count}")
# Check if account can day trade
if account.daytrade_count >= 3 and account.equity < 25000:
print("Warning: Approaching PDT limit")def get_account_configurations(self) -> Union[AccountConfiguration, RawData]:
"""
Get account configuration settings.
Returns:
AccountConfiguration: Current account settings
"""def set_account_configurations(
self,
account_configurations: AccountConfiguration
) -> Union[AccountConfiguration, RawData]:
"""
Update account configuration settings.
Args:
account_configurations: New configuration settings
Returns:
AccountConfiguration: Updated configuration
"""from alpaca.trading.enums import DTBPCheck, TradeConfirmationEmail
class AccountConfiguration:
"""Account configuration and preferences."""
dtbp_check: DTBPCheck # Day trade buying power check
fractional_trading: bool # Allow fractional shares
max_margin_multiplier: float # Maximum margin multiplier
no_shorting: bool # Disable short selling
pdt_check: PDTCheck # Pattern day trader check
suspend_trade: bool # Suspend trading capability
trade_confirm_email: TradeConfirmationEmail # Email confirmation settingUsage Examples:
# Get current configuration
config = trading_client.get_account_configurations()
print(f"Fractional Trading: {config.fractional_trading}")
print(f"Max Margin: {config.max_margin_multiplier}")
# Update configuration
from alpaca.trading.models import AccountConfiguration
# Get current configuration and modify it
config = trading_client.get_account_configurations()
config.fractional_trading = True
config.dtbp_check = DTBPCheck.BOTH
config.trade_confirm_email = TradeConfirmationEmail.ALL
updated_config = trading_client.set_account_configurations(config)def get_portfolio_history(
self,
history_filter: Optional[GetPortfolioHistoryRequest] = None
) -> Union[PortfolioHistory, RawData]:
"""
Get historical portfolio performance.
Args:
history_filter: Time range and resolution parameters
Returns:
PortfolioHistory: Portfolio performance data
"""from alpaca.trading.requests import GetPortfolioHistoryRequest
from datetime import datetime, date
class GetPortfolioHistoryRequest(NonEmptyRequest):
def __init__(
self,
period: Optional[str] = None, # 1D, 1W, 1M, 3M, 1A, etc.
timeframe: Optional[str] = None, # 1Min, 5Min, 15Min, 1H, 1D
intraday_reporting: Optional[str] = None, # continuous, end_of_day
start: Optional[datetime] = None, # Start timestamp
end: Optional[datetime] = None, # End timestamp
date_end: Optional[date] = None, # End date
extended_hours: Optional[bool] = None, # Include extended hours
pnl_reset: Optional[str] = None, # per_day, per_position
cashflow_types: Optional[str] = None # Cashflow activities to include
):class PortfolioHistory:
"""Historical portfolio performance data."""
timestamp: List[datetime] # Timestamps for data points
equity: List[float] # Portfolio equity values
profit_loss: List[float] # Profit/loss values
profit_loss_pct: List[float] # Profit/loss percentages
base_value: float # Starting portfolio value
timeframe: str # Data timeframe resolutionUsage Examples:
# Get 1 month portfolio history
history = trading_client.get_portfolio_history(
GetPortfolioHistoryRequest(period="1M", timeframe="1D")
)
print(f"Base Value: ${history.base_value:,.2f}")
print(f"Current Value: ${history.equity[-1]:,.2f}")
print(f"Total Return: {history.profit_loss_pct[-1]:.2%}")
# Get detailed intraday history
detailed_history = trading_client.get_portfolio_history(
GetPortfolioHistoryRequest(
period="1W",
timeframe="15Min",
extended_hours=True,
intraday_reporting="continuous"
)
)
# Calculate daily returns
import pandas as pd
df = pd.DataFrame({
'timestamp': history.timestamp,
'equity': history.equity,
'pnl_pct': history.profit_loss_pct
})
print(df.tail())def get_all_assets(
self,
filter: Optional[GetAssetsRequest] = None
) -> Union[List[Asset], RawData]:
"""
Get tradeable assets with optional filtering.
Args:
filter: Asset filtering parameters
Returns:
List[Asset]: Available assets
"""def get_asset(
self,
symbol_or_asset_id: Union[str, UUID]
) -> Union[Asset, RawData]:
"""
Get specific asset details.
Args:
symbol_or_asset_id: Asset symbol or UUID
Returns:
Asset: Asset information
"""from alpaca.trading.requests import GetAssetsRequest
from alpaca.trading.enums import AssetStatus, AssetClass
class GetAssetsRequest(NonEmptyRequest):
def __init__(
self,
status: Optional[AssetStatus] = None, # ACTIVE, INACTIVE
asset_class: Optional[AssetClass] = None, # US_EQUITY, CRYPTO, US_OPTION
exchange: Optional[AssetExchange] = None, # NYSE, NASDAQ, etc.
attributes: Optional[str] = None # ptp_no_exception, etc.
):class Asset:
"""Tradeable asset information."""
id: UUID
asset_class: AssetClass # US_EQUITY, CRYPTO, US_OPTION
exchange: AssetExchange # NYSE, NASDAQ, ARCA, etc.
symbol: str # Trading symbol
name: str # Asset name
status: AssetStatus # ACTIVE, INACTIVE, DELISTED
tradable: bool # Can be traded
marginable: bool # Can be bought on margin
shortable: bool # Can be sold short
easy_to_borrow: bool # Easy to borrow for shorting
fractionable: bool # Supports fractional shares
min_order_size: Optional[float] # Minimum order size
min_trade_increment: Optional[float] # Minimum price increment
price_increment: Optional[float] # Tick sizeUsage Examples:
# Get all active US equities
active_stocks = trading_client.get_all_assets(
GetAssetsRequest(
status=AssetStatus.ACTIVE,
asset_class=AssetClass.US_EQUITY
)
)
# Get specific asset details
aapl = trading_client.get_asset("AAPL")
print(f"Name: {aapl.name}")
print(f"Exchange: {aapl.exchange}")
print(f"Fractionable: {aapl.fractionable}")
print(f"Marginable: {aapl.marginable}")
print(f"Shortable: {aapl.shortable}")
# Get crypto assets
crypto_assets = trading_client.get_all_assets(
GetAssetsRequest(asset_class=AssetClass.CRYPTO)
)
for asset in crypto_assets[:5]:
print(f"{asset.symbol}: {asset.name}")def get_clock(self) -> Union[Clock, RawData]:
"""
Get market status and trading hours.
Returns:
Clock: Current market status and times
"""class Clock:
"""Market status and trading hours."""
timestamp: datetime # Current timestamp
is_open: bool # Whether market is currently open
next_open: datetime # Next market open time
next_close: datetime # Next market close timeUsage Examples:
# Check market status
clock = trading_client.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}")
# Wait for market open
if not clock.is_open:
import time
wait_seconds = (clock.next_open - clock.timestamp).total_seconds()
print(f"Market opens in {wait_seconds/3600:.1f} hours")def get_calendar(
self,
filters: Optional[GetCalendarRequest] = None
) -> Union[List[Calendar], RawData]:
"""
Get market calendar with trading days and hours.
Args:
filters: Date range for calendar
Returns:
List[Calendar]: Market calendar entries
"""from alpaca.trading.requests import GetCalendarRequest
from datetime import date
class GetCalendarRequest(NonEmptyRequest):
def __init__(
self,
start: Optional[date] = None, # Start date
end: Optional[date] = None # End date
):class Calendar:
"""Market trading day information."""
date: date # Trading date
open: datetime # Market open time
close: datetime # Market close time
session_open: Optional[datetime] # Extended session open
session_close: Optional[datetime] # Extended session closeUsage Examples:
from datetime import date, timedelta
# Get next 30 days of market calendar
calendar = trading_client.get_calendar(
GetCalendarRequest(
start=date.today(),
end=date.today() + timedelta(days=30)
)
)
print("Upcoming trading days:")
for day in calendar[:5]:
print(f"{day.date}: {day.open.time()} - {day.close.time()}")
# Check if today is a trading day
today = date.today()
is_trading_day = any(day.date == today for day in calendar)
print(f"Today is {'a' if is_trading_day else 'not a'} trading day")def get_watchlists(self) -> Union[List[Watchlist], RawData]:
"""
Get all watchlists.
Returns:
List[Watchlist]: All user watchlists
"""def get_watchlist_by_id(
self,
watchlist_id: Union[UUID, str]
) -> Union[Watchlist, RawData]:
"""
Get specific watchlist.
Args:
watchlist_id: Watchlist UUID
Returns:
Watchlist: The specified watchlist
"""def create_watchlist(
self,
watchlist_data: CreateWatchlistRequest
) -> Union[Watchlist, RawData]:
"""
Create new watchlist.
Args:
watchlist_data: Watchlist creation parameters
Returns:
Watchlist: Created watchlist
"""def update_watchlist_by_id(
self,
watchlist_id: Union[UUID, str],
watchlist_data: UpdateWatchlistRequest,
) -> Union[Watchlist, RawData]:
"""
Update watchlist details.
Args:
watchlist_id: Watchlist UUID
watchlist_data: New watchlist parameters
Returns:
Watchlist: Updated watchlist
"""def add_asset_to_watchlist_by_id(
self,
watchlist_id: Union[UUID, str],
symbol: str,
) -> Union[Watchlist, RawData]:
"""
Add asset to watchlist.
Args:
watchlist_id: Watchlist UUID
symbol: Asset symbol to add
Returns:
Watchlist: Updated watchlist
"""def remove_asset_from_watchlist_by_id(
self,
watchlist_id: Union[UUID, str],
symbol: str,
) -> Union[Watchlist, RawData]:
"""
Remove asset from watchlist.
Args:
watchlist_id: Watchlist UUID
symbol: Asset symbol to remove
Returns:
Watchlist: Updated watchlist
"""def delete_watchlist_by_id(self, watchlist_id: Union[UUID, str]) -> None:
"""
Delete watchlist.
Args:
watchlist_id: Watchlist UUID to delete
"""from alpaca.trading.requests import CreateWatchlistRequest, UpdateWatchlistRequest
class CreateWatchlistRequest(NonEmptyRequest):
def __init__(
self,
name: str, # Watchlist name
symbols: Optional[List[str]] = None # Initial symbols
):
class UpdateWatchlistRequest(NonEmptyRequest):
def __init__(
self,
name: Optional[str] = None, # New name
symbols: Optional[List[str]] = None # Replace symbols
):class Watchlist:
"""User-created watchlist of assets."""
id: UUID # Watchlist UUID
name: str # Watchlist name
assets: List[Asset] # Assets in watchlist
created_at: datetime # Creation timestamp
updated_at: datetime # Last update timestamp
account_id: UUID # Owner account IDUsage Examples:
# Create new watchlist
tech_watchlist = trading_client.create_watchlist(
CreateWatchlistRequest(
name="Tech Stocks",
symbols=["AAPL", "MSFT", "GOOGL", "AMZN", "TSLA"]
)
)
print(f"Created watchlist: {tech_watchlist.id}")
# Get all watchlists
watchlists = trading_client.get_watchlists()
for wl in watchlists:
print(f"{wl.name}: {len(wl.assets)} assets")
# Add stock to watchlist
updated_watchlist = trading_client.add_asset_to_watchlist_by_id(
tech_watchlist.id, "NVDA"
)
# Remove stock from watchlist
updated_watchlist = trading_client.remove_asset_from_watchlist_by_id(
tech_watchlist.id, "AMZN"
)
# Update watchlist name
updated_watchlist = trading_client.update_watchlist_by_id(
tech_watchlist.id,
UpdateWatchlistRequest(name="FAANG+ Stocks")
)
# Delete watchlist
trading_client.delete_watchlist_by_id(tech_watchlist.id)def get_option_contracts(
self,
request: GetOptionContractsRequest
) -> Union[OptionContractsResponse, RawData]:
"""
Get available option contracts.
Args:
request: Option contract query parameters
Returns:
OptionContractsResponse: Available contracts and pagination
"""def get_option_contract(
self,
symbol_or_id: Union[str, UUID]
) -> Union[OptionContract, RawData]:
"""
Get specific option contract details.
Args:
symbol_or_id: Option symbol or contract UUID
Returns:
OptionContract: Contract details
"""from alpaca.trading.requests import GetOptionContractsRequest
from alpaca.trading.enums import ContractType, ExerciseStyle
from datetime import date
class GetOptionContractsRequest(NonEmptyRequest):
def __init__(
self,
underlying_symbols: Optional[Union[str, List[str]]] = None, # Underlying stocks
underlying_asset_ids: Optional[Union[str, List[str]]] = None, # Underlying UUIDs
type: Optional[ContractType] = None, # CALL, PUT
strike_price_gte: Optional[float] = None, # Min strike price
strike_price_lte: Optional[float] = None, # Max strike price
expiration_date: Optional[date] = None, # Specific expiry
expiration_date_gte: Optional[date] = None, # Min expiry
expiration_date_lte: Optional[date] = None, # Max expiry
root_symbol: Optional[str] = None, # Option root
limit: Optional[int] = None, # Max contracts returned
page_token: Optional[str] = None, # Pagination token
exercise_style: Optional[ExerciseStyle] = None, # AMERICAN, EUROPEAN
style: Optional[ExerciseStyle] = None, # Deprecated alias
):class OptionContract:
"""Option contract details."""
id: UUID # Contract UUID
symbol: str # Option symbol (OCC format)
name: str # Contract name
status: AssetStatus # Contract status
tradable: bool # Can be traded
underlying_asset_id: UUID # Underlying stock UUID
underlying_symbol: str # Underlying stock symbol
type: ContractType # CALL or PUT
exercise_style: ExerciseStyle # AMERICAN or EUROPEAN
strike_price: float # Strike price
expiration_date: date # Expiration date
size: int # Contract size (usually 100)
open_interest: Optional[int] # Current open interest
close_price: Optional[float] # Last close price
close_price_date: Optional[date] # Last close price dateUsage Examples:
# Get AAPL call options expiring next month
from datetime import date, timedelta
next_month = date.today() + timedelta(days=30)
aapl_calls = trading_client.get_option_contracts(
GetOptionContractsRequest(
underlying_symbols="AAPL",
type=ContractType.CALL,
expiration_date_gte=date.today(),
expiration_date_lte=next_month,
limit=50
)
)
print(f"Found {len(aapl_calls.option_contracts)} AAPL call contracts")
for contract in aapl_calls.option_contracts[:5]:
print(f"{contract.symbol}: Strike ${contract.strike_price}, Expires {contract.expiration_date}")
# Get specific option contract
contract = trading_client.get_option_contract("AAPL230317C00150000")
print(f"Contract: {contract.name}")
print(f"Strike: ${contract.strike_price}")
print(f"Expiry: {contract.expiration_date}")
print(f"Open Interest: {contract.open_interest}")
# Find at-the-money puts
current_price = 150.00 # Assume current AAPL price
atm_puts = trading_client.get_option_contracts(
GetOptionContractsRequest(
underlying_symbols="AAPL",
type=ContractType.PUT,
strike_price_gte=current_price - 5,
strike_price_lte=current_price + 5,
expiration_date_gte=date.today() + timedelta(days=7)
)
)# Buy call option
call_buy = MarketOrderRequest(
symbol="AAPL230317C00150000", # OCC option symbol
qty=1, # 1 contract = 100 shares
side=OrderSide.BUY,
time_in_force=TimeInForce.DAY,
position_intent=PositionIntent.BTO # Buy to Open
)
option_order = trading_client.submit_order(call_buy)
# Sell put option (cash-secured)
put_sell = LimitOrderRequest(
symbol="AAPL230317P00140000",
qty=2,
side=OrderSide.SELL,
time_in_force=TimeInForce.GTC,
limit_price=3.50, # Premium per share ($350 per contract)
position_intent=PositionIntent.STO # Sell to Open
)
option_order = trading_client.submit_order(put_sell)
# Close option position
option_close = MarketOrderRequest(
symbol="AAPL230317C00150000",
qty=1,
side=OrderSide.SELL,
time_in_force=TimeInForce.DAY,
position_intent=PositionIntent.BTC # Buy to Close (for short position)
)
close_order = trading_client.submit_order(option_close)def get_corporate_announcements(
self,
filter: GetCorporateAnnouncementsRequest
) -> Union[List[CorporateActionAnnouncement], RawData]:
"""
Get corporate action announcements.
Args:
filter: Corporate action query parameters
Returns:
List[CorporateActionAnnouncement]: Corporate actions
"""def get_corporate_announcement_by_id(
self,
corporate_announcement_id: Union[str, UUID]
) -> Union[CorporateActionAnnouncement, RawData]:
"""
Get specific corporate action by ID.
Args:
corporate_announcement_id: Corporate action UUID
Returns:
CorporateActionAnnouncement: Corporate action details
"""from alpaca.trading.requests import GetCorporateAnnouncementsRequest
from alpaca.trading.enums import CorporateActionType, CorporateActionDateType
class GetCorporateAnnouncementsRequest(NonEmptyRequest):
def __init__(
self,
ca_types: Union[CorporateActionType, List[CorporateActionType]], # Required
since: datetime, # Required
until: datetime, # Required
symbol: Optional[str] = None, # Specific symbol
cusip: Optional[str] = None, # CUSIP filter
date_type: Optional[CorporateActionDateType] = None, # ex_date, record_date, etc.
):Usage Examples:
from alpaca.trading.enums import CorporateActionType
from datetime import datetime, timedelta
# Get recent dividend announcements
recent_dividends = trading_client.get_corporate_announcements(
GetCorporateAnnouncementsRequest(
ca_types=CorporateActionType.DIVIDEND,
since=datetime.now() - timedelta(days=30),
until=datetime.now()
)
)
# Get stock split announcements for AAPL
aapl_splits = trading_client.get_corporate_announcements(
GetCorporateAnnouncementsRequest(
ca_types=CorporateActionType.SPLIT,
symbol="AAPL",
since=datetime.now() - timedelta(days=365),
until=datetime.now()
)
)from alpaca.trading.stream import TradingStream
class TradingStream:
def __init__(
self,
api_key: Optional[str] = None,
secret_key: Optional[str] = None,
paper: bool = True,
raw_data: bool = False,
url_override: Optional[str] = None,
websocket_params: Optional[dict] = None
):
"""
Initialize trading stream for real-time trade updates.
Args:
api_key: API key for authentication
secret_key: Secret key for authentication
paper: True for paper trading, False for live
raw_data: Return raw data instead of models
url_override: Override WebSocket URL
websocket_params: Additional WebSocket configuration
"""
def subscribe_trade_updates(self, handler: Callable) -> None:
"""
Subscribe to trade execution updates.
Args:
handler: Async callback function for trade updates
"""
async def run(self) -> None:
"""Start the WebSocket connection and begin streaming."""# Trade update streaming example
from alpaca.trading.stream import TradingStream
stream = TradingStream(
api_key="your-api-key",
secret_key="your-secret-key",
paper=True
)
async def trade_update_handler(data):
"""Handle trade update events."""
print(f"Trade Update: {data.event}")
print(f"Order ID: {data.order.id}")
print(f"Symbol: {data.order.symbol}")
print(f"Status: {data.order.status}")
if data.event == "filled":
print(f"Filled: {data.order.filled_qty} @ ${data.order.filled_avg_price}")
elif data.event == "canceled":
print(f"Order canceled: {data.order.cancel_requested_at}")
# Subscribe to trade updates
stream.subscribe_trade_updates(trade_update_handler)
# Start streaming (async)
import asyncio
asyncio.run(stream.run())from alpaca.trading.enums import (
OrderSide, OrderType, OrderClass, OrderStatus, TimeInForce,
PositionSide, PositionIntent, QueryOrderStatus
)
class OrderSide(str, Enum):
BUY = "buy"
SELL = "sell"
class OrderType(str, Enum):
MARKET = "market"
LIMIT = "limit"
STOP = "stop"
STOP_LIMIT = "stop_limit"
TRAILING_STOP = "trailing_stop"
class OrderClass(str, Enum):
SIMPLE = "simple"
BRACKET = "bracket"
OCO = "oco" # One-Cancels-Other
OTO = "oto" # One-Triggers-Other
MLEG = "multileg" # Multi-leg options
class TimeInForce(str, Enum):
DAY = "day" # Good for day
GTC = "gtc" # Good till canceled
OPG = "opg" # Market on open
CLS = "cls" # Market on close
IOC = "ioc" # Immediate or cancel
FOK = "fok" # Fill or kill
class OrderStatus(str, Enum):
NEW = "new"
PARTIALLY_FILLED = "partially_filled"
FILLED = "filled"
DONE_FOR_DAY = "done_for_day"
CANCELED = "canceled"
EXPIRED = "expired"
REPLACED = "replaced"
PENDING_CANCEL = "pending_cancel"
PENDING_REPLACE = "pending_replace"
PENDING_REVIEW = "pending_review"
ACCEPTED = "accepted"
PENDING_NEW = "pending_new"
ACCEPTED_FOR_BIDDING = "accepted_for_bidding"
STOPPED = "stopped"
REJECTED = "rejected"
SUSPENDED = "suspended"
CALCULATED = "calculated"
class PositionIntent(str, Enum):
BTO = "buy_to_open" # Buy to open position
BTC = "buy_to_close" # Buy to close short position
STO = "sell_to_open" # Sell to open short position
STC = "sell_to_close" # Sell to close long positionfrom alpaca.trading.enums import AssetClass, AssetStatus, AssetExchange
class AssetClass(str, Enum):
US_EQUITY = "us_equity"
CRYPTO = "crypto"
US_OPTION = "us_option"
class AssetStatus(str, Enum):
ACTIVE = "active"
INACTIVE = "inactive"
DELISTED = "delisted"
class AssetExchange(str, Enum):
NASDAQ = "NASDAQ"
NYSE = "NYSE"
ARCA = "ARCA"
BATS = "BATS"
# ... many more exchangesfrom alpaca.trading.enums import DTBPCheck, TradeConfirmationEmail
class DTBPCheck(str, Enum):
NONE = "none" # No day trading buying power check
BOTH = "both" # Check on entry and exit
ENTRY = "entry" # Check on position entry only
EXIT = "exit" # Check on position exit only
class TradeConfirmationEmail(str, Enum):
NONE = "none" # No email confirmations
ALL = "all" # Email for all tradesfrom alpaca.common.exceptions import APIError
try:
# Submit order that might fail
order = trading_client.submit_order(order_data)
except APIError as e:
print(f"Order failed: {e.message}")
print(f"HTTP Status: {e.status_code}")
print(f"Request ID: {e.request_id}")
# Handle specific error cases
if e.status_code == 403:
print("Insufficient buying power or permissions")
elif e.status_code == 422:
print("Invalid order parameters")
elif e.status_code == 429:
print("Rate limit exceeded")
except Exception as e:
print(f"Unexpected error: {e}")import asyncio
from datetime import datetime, timedelta
from alpaca.trading import TradingClient
from alpaca.trading.stream import TradingStream
from alpaca.trading.requests import MarketOrderRequest, LimitOrderRequest
from alpaca.trading.enums import OrderSide, TimeInForce, QueryOrderStatus
class TradingBot:
def __init__(self, api_key: str, secret_key: str, paper: bool = True):
self.trading_client = TradingClient(api_key, secret_key, paper=paper)
self.stream = TradingStream(api_key, secret_key, paper=paper)
self.stream.subscribe_trade_updates(self.on_trade_update)
def check_account(self):
"""Check account status and buying power."""
account = self.trading_client.get_account()
print(f"Account: {account.account_number}")
print(f"Buying Power: ${account.buying_power:,.2f}")
print(f"Portfolio Value: ${account.portfolio_value:,.2f}")
return account
def get_positions(self):
"""Get current positions."""
positions = self.trading_client.get_positions()
print(f"\nCurrent Positions ({len(positions)}):")
for pos in positions:
pnl_pct = (float(pos.unrealized_pl) / float(pos.cost_basis)) * 100
print(f"{pos.symbol}: {pos.qty} shares, P&L: ${pos.unrealized_pl} ({pnl_pct:.1f}%)")
return positions
def place_bracket_order(self, symbol: str, qty: float, take_profit_pct: float = 0.05, stop_loss_pct: float = 0.03):
"""Place bracket order with take profit and stop loss."""
try:
# Get current price for bracket calculations
asset = self.trading_client.get_asset(symbol)
bracket_order = MarketOrderRequest(
symbol=symbol,
qty=qty,
side=OrderSide.BUY,
time_in_force=TimeInForce.DAY,
order_class=OrderClass.BRACKET,
take_profit=TakeProfitRequest(
limit_price=None # Will be calculated by server based on percentage
),
stop_loss=StopLossRequest(
stop_price=None # Will be calculated by server
)
)
order = self.trading_client.submit_order(bracket_order)
print(f"Bracket order placed: {order.id}")
return order
except APIError as e:
print(f"Order failed: {e.message}")
return None
def cancel_all_orders(self):
"""Cancel all open orders."""
cancel_responses = self.trading_client.cancel_orders()
print(f"Attempted to cancel {len(cancel_responses)} orders")
async def on_trade_update(self, data):
"""Handle real-time trade updates."""
print(f"\n[{datetime.now()}] Trade Update: {data.event.upper()}")
print(f"Order: {data.order.symbol} {data.order.side} {data.order.qty}")
if data.event == "filled":
print(f"✅ FILLED: {data.order.filled_qty} @ ${data.order.filled_avg_price}")
elif data.event == "canceled":
print(f"❌ CANCELED")
elif data.event == "rejected":
print(f"🚫 REJECTED")
async def run_strategy(self):
"""Main trading strategy loop."""
print("🚀 Starting trading bot...")
# Check initial account state
account = self.check_account()
if account.buying_power < 1000:
print("⚠️ Insufficient buying power")
return
# Get current positions
self.get_positions()
# Start stream for real-time updates
stream_task = asyncio.create_task(self.stream.run())
# Example strategy: Buy some stocks if we have buying power
if account.buying_power > 5000:
print("\n📈 Executing sample trades...")
# Place some orders
self.place_bracket_order("AAPL", 10)
await asyncio.sleep(2)
self.place_bracket_order("TSLA", 5)
await asyncio.sleep(2)
# Monitor for 60 seconds, then cleanup
await asyncio.sleep(60)
print("\n🧹 Cleaning up...")
self.cancel_all_orders()
# Close positions if desired
positions = self.trading_client.get_all_positions()
if positions:
print("Closing all positions...")
self.trading_client.close_all_positions(cancel_orders=True)
stream_task.cancel()
print("✅ Trading session complete")
# Run the trading bot
if __name__ == "__main__":
bot = TradingBot(
api_key="your-paper-api-key",
secret_key="your-paper-secret-key",
paper=True
)
asyncio.run(bot.run_strategy())Install with Tessl CLI
npx tessl i tessl/pypi-alpaca-py