
As you can see above in the architecture, this post explains how to build a serverless trading signal system using AWS Lambda, Python, alpaca‑py, Amazon S3, and Amazon EventBridge Scheduler, structured clearly into prerequisites, steps, and benefits.
Prerequisites
Accounts & Access
- AWS account with permission to create:
- Lambda
- IAM roles
- S3 buckets
- EventBridge rules
- Alpaca account (paper trading strongly recommended)
Local Development
- Python 3.10+
- Basic Python knowledge
- Basic understanding of AWS services (Lambda, IAM, S3)
Python Libraries
alpaca-pypandasboto3
Steps
Step 1: Create an S3 Bucket
This bucket stores generated trading signal CSV files.
Example:
s3://alpaca-trading-signals-bucket/signals/AAPL-2026-01-09.csv
Step 2: Create an IAM Role for Lambda
Attach the following permissions:
- AWSLambdaBasicExecutionRole (CloudWatch logs)
- Permission to write to your S3 bucket
Minimal S3 policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::alpaca-trading-signals-bucket/*"
}
]
}
Step 3: Package Python Dependencies (Lambda Layer)
A SMA Cross Strategy Example
- BUY → Short SMA crosses above Long SMA
- SELL → Short SMA crosses below Long SMA
- HOLD → No crossover
Sample Codes
import os
import boto3
import pandas as pd
from datetime import datetime
from alpaca.data.historical import StockHistoricalDataClient
from alpaca.data.requests import StockBarsRequest
from alpaca.data.timeframe import TimeFrame
AWS clients
s3 = boto3.client(“s3”)
Environment variables
ALPACA_API_KEY = os.environ[“ALPACA_API_KEY”]
ALPACA_SECRET_KEY = os.environ[“ALPACA_SECRET_KEY”]
S3_BUCKET = os.environ[“S3_BUCKET”]
Alpaca client
data_client = StockHistoricalDataClient(
ALPACA_API_KEY,
ALPACA_SECRET_KEY
)
def generate_sma_signals(
symbol: str,
short_window: int = 5,
long_window: int = 20
) -> pd.DataFrame:
“””
Fetch market data and generate SMA crossover signals.
“””
request = StockBarsRequest(
symbol_or_symbols=symbol,
timeframe=TimeFrame.Day,
limit=long_window + 5
)
bars = data_client.get_stock_bars(request).df
df = bars.reset_index()
df = df[df["symbol"] == symbol]
# Calculate SMAs
df["sma_short"] = df["close"].rolling(short_window).mean()
df["sma_long"] = df["close"].rolling(long_window).mean()
# Generate signals
df["signal"] = "HOLD"
df.loc[
(df["sma_short"] > df["sma_long"]) &
(df["sma_short"].shift(1) <= df["sma_long"].shift(1)),
"signal"
] = "BUY"
df.loc[
(df["sma_short"] < df["sma_long"]) &
(df["sma_short"].shift(1) >= df["sma_long"].shift(1)),
"signal"
] = "SELL"
return df[[
"timestamp",
"close",
"sma_short",
"sma_long",
"signal"
]]
def lambda_handler(event, context):
symbol = “AAPL”
signals_df = generate_sma_signals(symbol)
date_str = datetime.utcnow().strftime("%Y-%m-%d")
s3_key = f"signals/{symbol}-sma-signals-{date_str}.csv"
s3.put_object(
Bucket=S3_BUCKET,
Key=s3_key,
Body=signals_df.to_csv(index=False)
)
return {
"status": "success",
"symbol": symbol,
"s3_key": s3_key
}
# Upload this ZIP as a Lambda Layer and attach it to your Lambda function.
Sample output:
timestamp,close,sma_short,sma_long,signal
2026-01-05,187.22,185.91,184.88,BUY
2026-01-06,188.10,186.80,185.42,HOLD
Now we can use this csv file as a staging area to connect to a broker, however, this part will not be focus in this post.
Step 4: Schedule Execution with EventBridge
Use EventBridge Scheduler to trigger Lambda automatically.
Example (Weekdays at 9:35am ET ≈ 13:35 UTC):
cron(35 13 ? * MON-FRI *)
This makes your trading system fully automated.
Step 5: Verify
- Check CloudWatch Logs for execution status
- Confirm CSV files appear in S3
- Validate trading signals
Benefits
Serverless & Low Cost
- No servers to manage
- Pay only when the function runs
Secure
- API keys stored as environment variables
- Least-privilege IAM permissions
Scalable & Flexible
- Add more symbols easily
- Extend to multiple strategies
- Increase frequency without infrastructure changes
Production-Ready Pattern
- Reliable scheduling with EventBridge
- Durable storage with S3
- Observability via CloudWatch
Easy to Extend
- Execute real trades via Alpaca Trading API
- Add backtesting logic
- Send alerts (SNS, Slack, email)
- Orchestrate workflows with Step Functions