Skip to content

Latest commit

 

History

99 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚡ LambdaForge

Serverless algorithmic trading — forged on AWS Lambda.

CI Python AWS SAM Ruff License: MIT Cost

No servers. No babysitting. No cloud bill.

Quick Start · Strategies · Architecture · Contributing


What is LambdaForge?

LambdaForge is a production-grade, fully serverless algorithmic stock trading bot. It runs entirely on AWS Lambda — no always-on server, no manual babysitting. EventBridge wakes it up on schedule, it scans a 200+ symbol watchlist, enforces 6-rule risk management, places trades through the Alpaca API, and emails you a digest. When the market closes, it goes back to sleep.

Paper trading is free. You can run this at ~$0/month using AWS Free Tier and Alpaca's paper trading account.

                    ┌─────────────────────────────────────┐
  Market opens      │         AWS EventBridge             │
  09:30 ET ────────►│  Triggers Lambda on schedule        │
                    └──────────────┬──────────────────────┘
                                   │
                    ┌──────────────▼──────────────────────┐
                    │        AWS Lambda (ARM64)           │
                    │  • Scans 200+ symbols               │
                    │  • Runs 3 of 7 built-in strategies  │
                    │  • Enforces 6 risk rules            │
                    │  • Places orders via Alpaca         │
                    │  • Sends email digest               │
                    └──────────────┬──────────────────────┘
                                   │
          ┌───────────────────────┼──────────────────────┐
          │                       │                      │
   ┌──────▼──────┐        ┌───────▼──────┐       ┌───────▼──────┐
   │  S3 Bucket  │        │  SSM Params  │       │  Alpaca API  │
   │  trades.db  │        │  (no deploy  │       │  paper/live  │
   │  persisted  │        │   needed)    │       │              │
   └─────────────┘        └──────────────┘       └──────────────┘

Prerequisites

Requirement Notes
🦙 Alpaca account Free. Paper trading requires no deposit. Live trading requires a funded account.
☁️ AWS account Free tier covers everything at paper trading volumes
🐳 Docker Required to build Lambda container images
🐍 Python 3.9+ Lambda runtime constraint
🔧 AWS SAM CLI For building and deploying
⚙️ AWS CLI Configured with aws configure

💸 Cost — Runs for ~$0/Month

One of LambdaForge's biggest advantages: it costs almost nothing to run.

AWS Service What LambdaForge uses Free Tier Estimated cost
Lambda 6 functions, ~1M invocations/month 1M req + 400K GB-s free $0
EventBridge 5 scheduled rules 14M events free $0
S3 2–12 MB trades.db, re-uploaded up to once a minute (noncurrent versions expire after 3 days, 5 newest kept; weekly audit exports go straight to Glacier Deep Archive for 7 years) 5 GB free $0
SSM Parameter Store 12 parameters, ~3K reads/month 10K API calls free $0
SNS < 1K email notifications/month 1K emails free $0
KMS SecureString decryption on cold starts 20K requests free ~$0.15
SES HTML trade digest emails 3K emails/month free $0
ECR Container image storage 500 MB free $0
Monthly total → ~$0.15

Running 3 stacks (paper + live + experimental) in parallel costs ~$0.50/month. Still cheaper than a cup of coffee.

Compare this to a VPS or dedicated server which would run $5–$50/month for equivalent uptime.


✨ Features

Feature Details
🧠 7 trading strategies (3 enabled by default) MACD, Bollinger Squeeze, Z-Score Mean Reversion (enabled); RSI Confluence, EMA Crossover + ADX, RSI + MACD Confluence, Relative Strength vs SPY (available via config.json)
🛡️ 6-rule risk manager Confidence gate, daily loss limit, max positions, concentration cap, stop-loss enforcement, dynamic position sizing
📈 Trailing stop-loss Hybrid trailing stop — the tighter of 5% below the high-water mark or 2×ATR — re-evaluated every minute during market hours, never moves down
🔴 Kill switch One command liquidates everything and halts trading instantly
📊 Multi-stack Paper and live run as independent stacks — no shared state
📧 Email digests Hourly trade summaries, daily P&L snapshots, weekly performance reports
⚙️ Zero-redeploy config Tune risk params and flip the kill switch via SSM — no deploy needed
🔒 Buy deduplication Prevents duplicate orders while still allowing pyramiding into winning positions
🕐 Market hours guard Checks Alpaca's market clock on every run — skips holidays, half-days, and anything outside 09:30–16:00 ET (weekday/time heuristic as fallback)
🏷️ Environment tagging Email subjects prefixed [PAPER], [LIVE], [BOT-2] for easy inbox filtering

🚀 Quick Start

1. Clone and install

git clone https://github.com/vishwakt/LambdaForge.git
cd LambdaForge
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt

2. Configure environment

cp .env.example .env
# Edit .env — add your Alpaca paper trading API keys

3. Bootstrap SSM parameters

# Core credentials (required)
aws ssm put-parameter --name "/stock-bot/alpaca_api_key" \
  --value "YOUR_ALPACA_KEY" --type SecureString

aws ssm put-parameter --name "/stock-bot/alpaca_secret_key" \
  --value "YOUR_ALPACA_SECRET" --type SecureString

aws ssm put-parameter --name "/stock-bot/notification_email" \
  --value "you@example.com" --type String

aws ssm put-parameter --name "/stock-bot/trading_mode" \
  --value "paper" --type String

4. Verify your SES email

aws ses verify-email-identity --email-address you@example.com
# Check your inbox and click the verification link

5. Deploy

cp samconfig.toml.example samconfig.toml
sam build
sam deploy --guided    # First time — sets up ECR repos and S3 bucket
sam deploy             # Subsequent deploys

6. Subscribe to alerts

If you passed NotificationEmail at deploy time, SAM already created the subscription — confirm it from the email SNS sends you. Otherwise: SNS → Topics → the topic whose display name is "Stock Trading Bot Alerts (paper)" → Create subscription → Email.

7. Verify everything is working

./scripts/test-lambdas.sh stock-trading-bot

📐 Trading Strategies

All strategies implement a common interface — they receive historical OHLCV bars and return a signal with action, confidence, stop_loss, and take_profit.

Strategy Entry Signal Stop Loss Take Profit Best for
MACD Crossover 12/26 EMA bullish cross + signal line 3% below entry 6% above Trending markets
Bollinger Squeeze Band compression → breakout + volume Middle band (20-SMA) 1:1 measured move above entry Volatility expansion
Z-Score Mean Reversion 50-day Z-score < −2 (oversold) 1 std-dev below entry Rolling mean (Z ≈ 0); SELL signal at Z > +2 Range-bound markets
RSI Confluence RSI oversold + uptrend + volume 4% below entry 8% above Momentum dips
EMA Crossover + ADX 9/21 EMA cross + ADX > 25 3% below entry 6% above Strong trends
RSI + MACD Confluence RSI oversold + MACD bullish cross 4% below entry 8% above Reversal signals
Relative Strength vs SPY Outperforming SPY on rolling basis 5% below entry 10% above Sector leaders

Trailing stops are managed centrally — once a position is open, the stop price ratchets up automatically as price rises.

Want to add your own? See CONTRIBUTING.md — it takes ~50 lines of code.


⚙️ Configuration

All runtime configuration lives in AWS SSM Parameter Store — change anything without redeploying.

# Example: tighten risk limits without redeploying
aws ssm put-parameter --name "/stock-bot/max_positions" --value "8" --type String --overwrite
aws ssm put-parameter --name "/stock-bot/trailing_stop_pct" --value "0.03" --type String --overwrite
Parameter Default Description
max_positions 12 Max simultaneous open positions
trailing_stop_pct 0.05 Trailing stop as fraction of price
max_concentration 0.15 Max portfolio fraction per symbol
max_daily_loss 0.02 Daily loss limit — stops trading if hit
min_confidence 0.5 Minimum signal confidence to trade
monitor_interval 1 MonitorStops interval in minutes
notify_frequency hourly realtime, hourly, or daily
kill-switch alive Set to kill to halt all trading immediately

🔴 Kill Switch

Emergency halt — stops all trading and liquidates all positions within 1 minute.

# Get function name from your stack
KILL_FN=$(aws cloudformation describe-stacks --stack-name stock-trading-bot \
  --query "Stacks[0].Outputs[?OutputKey=='KillSwitchFunctionName'].OutputValue" \
  --output text)

# Check status
aws lambda invoke --function-name $KILL_FN \
  --cli-binary-format raw-in-base64-out \
  --payload '{"action":"status"}' /tmp/out.json && cat /tmp/out.json

# 🛑 ENGAGE — liquidate everything and halt
aws lambda invoke --function-name $KILL_FN \
  --cli-binary-format raw-in-base64-out \
  --payload '{"action":"kill"}' /tmp/out.json && cat /tmp/out.json

# ✅ DISENGAGE — resume normal trading
aws lambda invoke --function-name $KILL_FN \
  --cli-binary-format raw-in-base64-out \
  --payload '{"action":"alive"}' /tmp/out.json && cat /tmp/out.json

No CLI? Set /stock-bot/kill-switchkill directly in the AWS Console. The next Lambda invocation picks it up.

From your phone (Telegram)

A Telegram bot can operate any stack by name. Create a bot with @BotFather, message it once, read your chat ID from https://api.telegram.org/bot<TOKEN>/getUpdates, and put both in .env:

TELEGRAM_BOT_TOKEN=...
TELEGRAM_ALLOWED_CHAT_IDS=<your chat id>

Then run the poller on any machine with AWS CLI credentials for the account:

python -m src.telegram_bot
Message Effect
/bots List bots and commands
/stock-bot-2 status Kill-switch state, equity, cash, open positions
/stock-bot-2 positions Open positions with unrealized P&L
/stock-bot-2 kill Shows what would be liquidated and asks you to confirm
/stock-bot-2 kill confirm Invokes that stack's KillSwitchFunction: cancels orders, sells everything, halts
/stock-bot-2 alive Resumes trading

Bot names are the SSM prefixes without slashes: stock-bot, stock-bot-2, stock-bot-live. Only chat IDs on the allowlist get a reply; anyone else is ignored silently. kill runs inside the target stack's own Lambda, so the poller never needs Alpaca credentials of its own — it needs cloudformation:DescribeStacks, lambda:InvokeFunction, and SSM read/write on the stack prefixes, all of which the deployer policy already grants.


🏗️ Architecture

Six Lambda functions — five on EventBridge schedules, plus a manually invoked kill switch:

Function Schedule Purpose
DailyScan 09:30 ET weekdays Full scan: exits, entries, risk checks
MonitorStops Every 1 min (market hours) Trailing stop enforcement + opportunistic entries
EodSnapshot 15:55 ET weekdays End-of-day P&L + benchmark comparison
WeeklyDigest Friday 15:55 ET Weekly performance report
HourlyDigest Hourly (market hours) Consolidated trade activity digest
KillSwitch Manual invoke Emergency halt — liquidates everything

Schedules run on EventBridge Scheduler with ScheduleExpressionTimezone: America/New_York, so these times hold across daylight-saving transitions.

For the full architecture deep-dive including data flow diagrams, SQLite schema, and multi-stack setup: ARCHITECTURE.md.


🧪 Running Tests

python -m pytest tests/ -v

106 tests covering market hours, buy deduplication and fill reconciliation, strategy signal generation, SSM caching, environment labelling, config defaults, trade statistics, and the weekly audit archive.


🤝 Contributing

Pull requests welcome — especially new trading strategies. See CONTRIBUTING.md for the full guide, including the step-by-step process for adding a strategy in ~30 lines of code.


⚠️ Disclaimer

This software is for educational purposes only. It is not financial advice. Trading stocks involves significant risk of loss. Always paper trade first and never risk money you cannot afford to lose. The authors are not responsible for any financial losses incurred through the use of this software.


📄 License

MIT — see LICENSE.

About

Hands-off algorithmic stock trading on AWS Lambda — ~$0.15/month. Alpaca + SAM + Python.

Topics

Resources

Contributing

Security policy

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages