Skip to content

Rohan5commit/tech_losers_bot

Repository files navigation

Tech Losers Bot 📉

A Python bot that scans for US Technology stocks with significant daily losses and sends email alerts via Gmail.

Features

  • Primary Data Source: Financial Modeling Prep (FMP) API

    • Biggest losers feed for candidate universe
    • Company profiles for market cap, sector, and industry
  • Secondary Data Source: Twelve Data (optional)

    • Verification of percent changes
    • Built-in credit tracking (8/min, 800/day limits)
  • Email Alerts: Gmail SMTP (App Password)

    • No OAuth required
    • HTML-formatted emails with summary tables
    • CSV attachment with raw data
  • Smart Caching: SQLite-based profile cache

    • Reduces API calls to stay within free tiers
    • Configurable cache duration (default: 7 days)

Filtering Criteria

  1. Daily % Change: <= -5% (close-to-close)
  2. Sector: Technology (exact match)
  3. Industry Override: include if industry contains keywords (default: software), even if sector is not Technology
  4. Market Cap: >= $1,000,000,000 (1 billion USD)

Optional overrides:

  • INCLUDE_INDUSTRY_KEYWORDS: comma-separated industry keywords to include (default: software)
  • EXTRA_SYMBOLS: comma-separated extra symbols to scan (added to the 544-universe)
  • FORCE_INCLUDE_SYMBOLS: comma-separated symbols that bypass the sector/industry check (still must meet % change + market cap)

Results are sorted by market cap (descending).

Installation

# Clone or download the project
cd tech_losers_bot

# Create virtual environment (recommended)
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

Configuration

1. Create .env file

cp .env.example .env

Edit .env with your API keys:

# Required
FMP_API_KEY=your_fmp_api_key_here
GMAIL_SENDER=your_email@gmail.com
EMAIL_RECIPIENTS=recipient@example.com

# Optional (for verification)
TWELVE_DATA_API_KEY=your_twelve_data_key_here

# Optional settings
PROFILE_CACHE_DAYS=7
TWELVE_DATA_DAILY_LIMIT=800
TWELVE_DATA_REQUEST_TIMEOUT=8
TWELVE_DATA_MAX_RETRIES=2
TWELVE_DATA_WORKERS_PER_KEY=1
TWELVE_DATA_API_KEYS_CSV=
INCLUDE_INDUSTRY_KEYWORDS=software
EXTRA_SYMBOLS=
FORCE_INCLUDE_SYMBOLS=

# SMTP (App Password)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your_email@gmail.com
SMTP_PASSWORD=your_app_password_here
SMTP_USE_TLS=true

# Optional AI summary (NVIDIA)
NVIDIA_API_KEY=your_nvidia_api_key_here
NVIDIA_MODEL=stockmark/stockmark-2-100b-instruct
NVIDIA_API_BASE_URL=https://integrate.api.nvidia.com
AI_SUMMARY_ENABLED=true
AI_SUMMARY_MAX_TOKENS=220
AI_SUMMARY_TEMPERATURE=0.2

2. Get API Keys

Financial Modeling Prep (Required)

  1. Sign up at financialmodelingprep.com
  2. Verify your email
  3. Use the "Free Plan Access" API key from your dashboard

Twelve Data (Optional)

  1. Create account at twelvedata.com
  2. Get your API key from the dashboard
  3. Note: Free tier has 8 credits/min and 800 credits/day

3. Set Up Gmail App Password (SMTP)

This project now sends email via SMTP using a Gmail App Password (no OAuth).

  1. Enable 2‑Step Verification on your Google account
  2. Create an App Password for “Mail”
  3. Set these in your .env:
    • SMTP_USER (your Gmail address)
    • SMTP_PASSWORD (the app password)
    • SMTP_HOST/SMTP_PORT if you want to change defaults

Usage

Basic Run (with email)

python main.py

Dry Run (no email)

python main.py --dry-run

Fast Dry Run (sampled universe)

python main.py --dry-run --sample-size 50

Use FMP Losers Feed (faster, fewer calls)

python main.py --scan-source fmp

Use FMP Single-Symbol Quotes (requires high quota or multiple keys)

python main.py --scan-source fmp-quotes

With Twelve Data Verification

python main.py --verify

Check Status

python main.py --status

Clear Expired Cache

python main.py --clear-cache

Email Format

Subject

US Technology Losers <= -5% (Close-to-Close), mcap >= $1B — YYYY-MM-DD

Body Contents

  • Run timestamp with timezone
  • Summary counts:
    • Total scanned
    • Candidates from losers feed
    • After -5% filter
    • After sector + mcap filter
  • Results table:
    • Rank
    • Symbol
    • Company
    • Daily % change
    • Price (USD)
    • Market cap (USD)
    • Sector ("Technology")
    • Industry
    • Reason (latest news summary)

Attachment

  • losers_tech_over1b_YYYY-MM-DD.csv with the same columns

Scheduling

macOS/Linux (cron)

# Run Tue–Sat at 5:00 PM SGT (after market close)
0 17 * * 2-6 cd /path/to/tech_losers_bot && ./venv/bin/python main.py

macOS (launchd)

Create ~/Library/LaunchAgents/com.techlosers.bot.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.techlosers.bot</string>
    <key>ProgramArguments</key>
    <array>
        <string>/path/to/tech_losers_bot/venv/bin/python</string>
        <string>/path/to/tech_losers_bot/main.py</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>17</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
    <key>WorkingDirectory</key>
    <string>/path/to/tech_losers_bot</string>
</dict>
</plist>

Load with:

launchctl load ~/Library/LaunchAgents/com.techlosers.bot.plist

GitHub Actions (Recommended)

The project includes a GitHub Actions workflow at .github/workflows/daily_scan.yml that runs automatically.

Schedule: Tue–Sat at 08:00 SGT (Mon–Fri US Market Close).

Manual trigger: Go to Actions → "Daily Tech Losers Scan" → "Run workflow".

Required Repository Secrets

Go to Settings → Secrets and variables → Actions → New repository secret and add:

Secret Name Description
FMP_API_KEY Financial Modeling Prep API key
TWELVE_DATA_API_KEYS_CSV Comma-separated Twelve Data keys
TWELVE_DATA_API_KEY Primary Twelve Data key
GMAIL_SENDER Sender email address
EMAIL_RECIPIENTS Comma-separated recipient emails
SMTP_USER Gmail address for SMTP auth
SMTP_PASSWORD Gmail App Password
NVIDIA_API_KEY (Optional) NVIDIA NIM API key

How to Re-create Secrets

  1. Copy values from your local .env file
  2. Each .env variable maps to a secret with the same name
  3. TWELVE_DATA_API_KEYS_CSV is a single comma-separated string of all Twelve Data keys

Running Locally vs GitHub Actions

Feature Local GitHub Actions
Trigger python main.py Automatic (cron) or manual
Secrets .env file Repository secrets
Network wait Default 5-min polling --no-wait flag
Data output Local data/ dir Downloadable artifact
Logs Terminal stdout Actions run logs

Project Structure

tech_losers_bot/
├── .github/
│   └── workflows/
│       └── daily_scan.yml # GitHub Actions workflow (daily cron)
├── main.py                 # Entry point
├── requirements.txt        # Dependencies
├── .env.example           # Environment template
├── .env                   # Your configuration (create this)
├── README.md              # This file
├── src/
│   ├── __init__.py        # Package exports
│   ├── config.py          # Configuration loader
│   ├── cache.py           # SQLite profile cache
│   ├── credit_tracker.py  # Twelve Data credit tracking
│   ├── fmp_client.py      # FMP API client
│   ├── twelve_data_client.py  # Twelve Data API client
│   ├── provider_router.py # Multi-source routing
│   └── gmail_sender.py    # SMTP email sender
├── data/                  # Generated data (auto-created)
│   ├── profile_cache.db   # SQLite cache
│   ├── credit_tracker.json
│   └── *.csv              # Generated reports
└── credentials/           # (unused) OAuth files no longer required

Free Tier Limits

Service Limit How Bot Stays Within
FMP Free 250 requests/day Profile caching (7-30 days)
Twelve Data 800 credits/day, 8/min Credit tracker + throttling
Gmail SMTP Varies by account One report per run

Troubleshooting

"FMP_API_KEY is required"

Make sure your .env file exists and contains a valid FMP API key.

SMTP email errors

  • Ensure SMTP_USER and SMTP_PASSWORD are set correctly
  • Confirm 2‑Step Verification is enabled and App Password is valid

Twelve Data credit exhausted

The bot will automatically skip verification if credits are exhausted. Credits reset daily.

No stocks found

This is normal on days without significant tech sector losses. The bot will send a "no stocks" notification.

License

MIT License - feel free to use and modify.

About

Python bot that scans for US Technology stocks with significant daily losses and sends email alerts

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors