Skip to content

Repository files navigation

Serverless Stocks Pipeline

A fully automated serverless pipeline that tracks daily top movers from a watchlist of tech stocks. Built on AWS using CDK for infrastructure as code.

Live Demo

http://serverless-stocks-frontend-707714592503.s3-website-us-east-1.amazonaws.com/


Architecture

  • EventBridge triggers a Lambda function on a daily schedule
  • Lambda (today-top) fetches open/close prices for each stock in the watchlist, calculates % change, and writes all results to DynamoDB with the top mover flagged
  • DynamoDB stores daily stock data with date as partition key and ticker as sort key
  • Lambda (past-toppers) scans DynamoDB, groups by date, and returns the most recent 7 trading days via API Gateway
  • API Gateway exposes a GET /movers endpoint for the frontend
  • S3 (CDK-managed) hosts the static frontend
  • CloudWatch + SNS monitors the ingestion lambda for errors and sends email alerts
  • Secrets Manager stores the stock API key securely

Watchlist

AAPL MSFT GOOGL AMZN TSLA NVDA


Prerequisites

  • Node.js v20+
  • AWS CLI configured (aws configure)
  • AWS CDK installed (npm install -g aws-cdk)
  • A free Massive account with an API key

Setup

git clone https://github.com/jinpas/serverless-stocks.git 
cd serverless-stocks
npm install

Create a .env file:

MASSIVE_API_KEY=your_api_key_here
ALERT_EMAIL=your@email.com

Store your API key in AWS Secrets Manager:

aws secretsmanager create-secret \
  --name "massive-api-key" \
  --secret-string "your_api_key_here"

Bootstrap CDK (one-time):

cdk bootstrap

Deploy:

cdk deploy

CI/CD

Pushing to main automatically:

  • Deploys the CDK stack
  • Uploads the frontend to the S3 website bucket

Required GitHub secrets:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • ALERT_EMAIL

API

GET /movers

Returns the most recent 7 trading days, including all tracked stocks for each day with the top mover flagged.

[
  {
    "date": "2026-03-27",
    "stocks": [
      {
        "ticker": "AAPL",
        "percentChange": -2.01,
        "closingPrice": 248.8,
        "isTopMover": true
      }
    ]
  }
]

Tradeoffs & Challenges

End-of-day data timing
The data provider returns end-of-day aggregates that are not consistently available immediately after market close. To ensure reliability, the ingestion lambda queries the most recently completed trading day (typically yesterday) rather than the current in-progress day.

Rate limiting
The free tier of the Massive API allows 5 requests per minute. With 6 stocks, the ingestion lambda introduces a 15 second delay between requests and retries up to 3 times on errors. On a paid plan this delay would be removed.

DynamoDB scan
The retrieval Lambda reads all records from the table and then filters out the most recent 7 days in code. This works fine because the dataset is small, but for larger datasets it would be more efficient to query only the needed dates instead of reading everything.

Weekend and market closures
The API returns no data on weekends and holidays. These days are skipped in ingestion and rendered as "market closed" in the UI.

Frontend data model
The API returns all stocks for each day (not just the top mover) with an isTopMover flag. This allows the UI to highlight the top mover while still letting users inspect the full watchlist.


Future Improvements

  • Remove rate limit delays on a paid API plan
  • Split CDK stack into modular constructs
  • Add CloudWatch dashboards for latency, success rate, and execution time
  • Move frontend deployment fully into CDK (instead of CLI upload)

About

This is a fully automated system that wakes up daily, analyzes the market, records the winner and displays the history on a public website.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages