DEV Community

Cover image for How to Build a Real-Time SEC Filing Monitor in Python (Under 50 Lines)
Nicholas Rempel
Nicholas Rempel

Posted on

How to Build a Real-Time SEC Filing Monitor in Python (Under 50 Lines)

Ever wonder how hedge funds know about insider trades before you do?

They're not psychic. They just have systems monitoring SEC filings in real-time. The moment a Form 4 hits EDGAR, they know.

Today, we're building that system. In Python. In under 50 lines.

Why Monitor SEC Filings?

Three filings move markets:

  • 8-K: Unscheduled material events (CEO quits, merger announced, lawsuit filed)
  • 10-K/10-Q: Annual and quarterly financials
  • Form 4: Insider trading β€” when executives buy or sell their own stock

That last one is interesting. When a CEO buys $2M of their own company's stock, that's a signal. They know something.

What We're Building

A Python script that:

  1. Checks for new filings every 5 minutes
  2. Filters by your watchlist (specific tickers)
  3. Prints alerts to console (easily extendable to Slack, email, etc.)

No scraping. No parsing HTML. No dealing with EDGAR's... quirks.

First, grab a free API key.

The Code

import requests
import time
from datetime import datetime

# Config
API_KEY = "your_api_key"  # Free tier at earningsfeed.com
BASE_URL = "https://earningsfeed.com/api/v1"
WATCHLIST = ["AAPL", "TSLA", "NVDA", "MSFT", "GOOGL"]
CHECK_INTERVAL = 300  # 5 minutes

# Track what we've already seen
seen_filings = set()

def get_recent_filings():
    """Fetch recent SEC filings for watchlist tickers."""
    headers = {"Authorization": f"Bearer {API_KEY}"}
    filings = []

    for ticker in WATCHLIST:
        response = requests.get(
            f"{BASE_URL}/filings",
            headers=headers,
            params={"ticker": ticker, "limit": 10}
        )
        if response.ok:
            filings.extend(response.json().get("items", []))

    return filings

def check_for_new_filings():
    """Check for new filings and alert on any we haven't seen."""
    filings = get_recent_filings()

    for filing in filings:
        filing_id = filing.get("accessionNumber")

        if filing_id and filing_id not in seen_filings:
            seen_filings.add(filing_id)
            alert(filing)

def alert(filing):
    """Print alert for new filing. Swap this for Slack/email/SMS."""
    company = filing.get("companyName", "Unknown")
    form_type = filing.get("formType", "???")
    filed_at = filing.get("filedAt", "")
    url = filing.get("url", "")

    print(f"""
🚨 NEW FILING DETECTED
━━━━━━━━━━━━━━━━━━━━━
Company:   {company}
Form:      {form_type}
Filed:     {filed_at}
Link:      {url}
━━━━━━━━━━━━━━━━━━━━━
    """)

def main():
    print(f"πŸ‘€ Monitoring {len(WATCHLIST)} tickers: {', '.join(WATCHLIST)}")
    print(f"⏱️  Checking every {CHECK_INTERVAL // 60} minutes")
    print("Press Ctrl+C to stop\n")

    # Initial check
    check_for_new_filings()

    while True:
        time.sleep(CHECK_INTERVAL)
        print(f"[{datetime.now().strftime('%H:%M:%S')}] Checking...")
        check_for_new_filings()

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

That's it. Under 50 lines.

Running It

pip install requests
python sec_monitor.py
Enter fullscreen mode Exit fullscreen mode

Output:

πŸ‘€ Monitoring 5 tickers: AAPL, TSLA, NVDA, MSFT, GOOGL
⏱️  Checking every 5 minutes
Press Ctrl+C to stop

🚨 NEW FILING DETECTED
━━━━━━━━━━━━━━━━━━━━━
Company:   NVIDIA Corp
Form:      4
Filed:     2024-12-14T16:32:00.000Z
Link:      https://www.sec.gov/Archives/edgar/data/1045810/...
━━━━━━━━━━━━━━━━━━━━━
Enter fullscreen mode Exit fullscreen mode

Make It Actually Useful

The alert() function is where you customize. Some ideas:

Slack notifications:

def alert(filing):
    requests.post(SLACK_WEBHOOK, json={
        "text": f"🚨 {filing['companyName']} just filed a {filing['formType']}"
    })
Enter fullscreen mode Exit fullscreen mode

Filter by form type (only insider trades):

if filing.get("formType") == "4":
    alert(filing)
Enter fullscreen mode Exit fullscreen mode

Only material events:

# In get_recent_filings(), add forms filter
params={"ticker": ticker, "forms": "8-K,4", "limit": 10}
Enter fullscreen mode Exit fullscreen mode

Why I Built This

Full disclosure: I built Earnings Feed because I got tired of the alternatives.

EDGAR's direct API has rate limits that'll get you blocked. Most commercial APIs charge hundreds per month. I wanted something with a free tier that just... works.

The database covers every public company filing with the SEC. Every 10-K, every Form 4, every 8-K.

If you're building something in the fintech space, it might save you some headaches.

What Would You Build?

I'm curious what you'd do with real-time SEC data:

  • Trading signals based on insider buys?
  • Alerts when competitors file 8-Ks?
  • Tracking institutional ownership changes via 13F?

Drop a comment!

Top comments (0)