Home/Blog/List Companies with over $1B in Market Cap on NASDAQ + NYSE using Python + Massive

List Companies with over $1B in Market Cap on NASDAQ + NYSE using Python + Massive

Scan NASDAQ and NYSE stocks with Python and Massive to save companies with at least $1B in market cap.

pythonmassivestocksmarket-cap

In this tutorial, we are going to write a Python script that finds companies over $1B in market cap on the NYSE and NASDAQ. This is useful if you want to build a local list of large-cap stock tickers from Massive data.

This tutorial assumes you have Python installed and a basic understanding of programming. We are going to use Massive, which was previously Polygon.io.

Step 1: Create a Massive account

Sign up for a Massive account and find your API key. We are going to use the free tier for pulling the stock data.

This will not be an efficient way of finding these stocks because we will scan all stocks to disqualify them. I suggest finding a second attribute to filter by first and including that in the initial query to reduce the number of stocks you have to scan. For this tutorial, we will do it the brute-force way.

Step 2: Create the Python script

Create a file called main.py and add the following script:

import os
import time
import requests
from collections import deque

api_key = os.getenv('MASSIVE_API_KEY', '')

exchanges = ['XNAS', 'XNYS']

OUTPUT_FILE = 'billion_marketcap_tickers.txt'
MARKET_CAP_THRESHOLD = 1_000_000_000  # $1B

REQUESTS_PER_WINDOW = 5
REQUEST_WINDOW_SECONDS = 60
_request_times = deque()

def rate_limited_get(url, **kwargs):
    """Throttle outbound HTTP requests to keep us within API limits."""
    while True:
        now = time.monotonic()
        # Drop old request timestamps outside the window
        while _request_times and now - _request_times[0] > REQUEST_WINDOW_SECONDS:
            _request_times.popleft()

        if len(_request_times) < REQUESTS_PER_WINDOW:
            _request_times.append(now)
            break

        sleep_time = REQUEST_WINDOW_SECONDS - (now - _request_times[0])
        if sleep_time > 0:
            time.sleep(sleep_time)

    return requests.get(url, **kwargs)

def get_ticker_overview(ticker: str):
    url = f'https://api.massive.com/v3/reference/tickers/{ticker}?apiKey={api_key}'
    response = rate_limited_get(url)
    if response.status_code > 299:
        print(f'Error fetching overview for {ticker}: {response.status_code}')
        return None

    data = response.json()
    return data.get('results')

def get_page_of_tickers(url: str):
    response = rate_limited_get(url)
    if response.status_code > 299:
        print('Error fetching tickers: ' + str(response.status_code))
        raise Exception('Error fetching tickers: ' + str(response.status_code))

    data = response.json()
    next_url = data.get('next_url')
    results = data.get('results', [])
    return results, next_url

def load_existing_tickers(path: str) -> set:
    """Load already-processed tickers from file so we don't double-process them."""
    if not os.path.exists(path):
        return set()

    tickers = set()
    with open(path, 'r') as f:
        for line in f:
            line = line.strip().upper()
            if line:
                tickers.add(line)
    return tickers

def append_ticker_to_file(ticker: str, path: str):
    """Append a new ticker, one per line, to the output file."""
    with open(path, 'a') as f:
        f.write(ticker + '\n')

def find_large_caps_on_exchange(exchange: str, processed_tickers: set):
    """Find all tickers on an exchange with market cap >= $1B and save new ones."""
    url = (
        'https://api.massive.com/v3/reference/tickers'
        f'?market=stocks&exchange={exchange}&active=true'
        '&order=asc&limit=100&sort=ticker'
        f'&apiKey={api_key}'
    )

    while True:
        tickers, next_url = get_page_of_tickers(url)
        if not tickers:
            break

        for ticker in tickers:
            symbol = ticker.get('ticker')
            if not symbol:
                continue

            # Avoid re-processing tickers we've already saved
            if symbol in processed_tickers:
                print(f'Skipping already processed ticker: {symbol}')
                continue

            overview = get_ticker_overview(symbol)
            if not overview:
                continue

            market_cap = overview.get('market_cap')
            if not isinstance(market_cap, (int, float)):
                continue

            if market_cap >= MARKET_CAP_THRESHOLD:
                print(f'{symbol} has market cap {market_cap}, saving.')
                append_ticker_to_file(symbol, OUTPUT_FILE)
                processed_tickers.add(symbol)
            else:
                print(f'{symbol} market cap {market_cap} below threshold, skipping.')

        if not next_url:
            break

        url = next_url
        print(f'Finished page for exchange {exchange}, continuing to next page...')

def main():
    # Load already-saved large cap tickers to avoid re-processing
    processed_tickers = load_existing_tickers(OUTPUT_FILE)
    print(f'Loaded {len(processed_tickers)} existing tickers from {OUTPUT_FILE}')

    for exchange in exchanges:
        print(f'Processing exchange: {exchange}')
        find_large_caps_on_exchange(exchange, processed_tickers)

    print('Done.')

if __name__ == '__main__':
    main()

Step 3: Run the script

Run the script with your Massive API key:

MASSIVE_API_KEY='YOUR_API_KEY' python3 main.py

Step 4: Review the output

The console output will look like this:

Processing exchange: XNAS
AACB market cap 284222250.0 below threshold, skipping.
AACG market cap 39375594.88 below threshold, skipping.
AAL has market cap 8627330489.65, saving.
AAME market cap 61599628.56 below threshold, skipping.
AAOI has market cap 1427732458.08, saving.
AAON has market cap 7769113299.860001, saving.
AAPG has market cap 3130476376.7167, saving.
AAPL has market cap 4033205551350.0, saving.
AARD market cap 235586153.76 below threshold, skipping.
ABAT market cap 476339896.07 below threshold, skipping.
ABCL has market cap 1083592873.76, saving.
ABEO market cap 232291781.67000002 below threshold, skipping.
ABL market cap 632460971.85 below threshold, skipping.
ABLV market cap 39709497.288 below threshold, skipping.
ABNB has market cap 73483526929.64, saving.
ABOS market cap 109637899.25 below threshold, skipping.
ABP market cap 15726026.469999999 below threshold, skipping.
ABSI market cap 396980841.84000003 below threshold, skipping.
...

Any matching tickers will be saved to billion_marketcap_tickers.txt.

Conclusion

You now have a Python script that scans NASDAQ and NYSE tickers with Massive and saves companies with at least $1B in market cap.