Getting Started
Growth Stock Screener is a web-scraping utility that screens all stocks listed on the NASDAQ Composite based on inputted criteria. It relies on AIOHTTP and asyncio for asynchronous web requests, and Selenium for browser automation when desired content is dynamically loaded.
Installation
First, ensure that you have Python 3.11+ and Firefox installed.
Note for Mac users: Python now includes its own private copy of OpenSSL and no longer uses Apple-supplied OpenSSL libraries. After installing Python, navigate to your
Applications/Python X.XX/
folder and double-clickInstall Certificates.command
.
Note for Linux users: the 'snap' version of Firefox that comes pre-installed may cause issues when running Selenium. To troubleshoot, follow these instructions to install Firefox via 'apt' (not snap).
Next, navigate to the directory where you would like to install the screener, and run the following commands in a terminal application:
- Clone the project repository:
git clone https://github.com/starboi-63/growth-stock-screener.git
- Navigate to the root directory:
cd growth-stock-screener
- Install Python dependencies:
pip3 install -r requirements.txt
Usage
Running the screener
To run the screener, execute the following command in the project root directory:
python3 growth_stock_screener/run_screen.py
Modifying settings
To customize screen settings, modify values in settings.py.
1import multiprocessing
2
3# ITERATIONS (modify these values as desired)
4
5# Iteration 1: Relative Strength
6min_rs: int = 90 # minimum RS rating to pass (integer from 0-100)
7
8# Iteration 2: Liquidity
9min_market_cap: float = 1000000000 # minimum market cap (USD)
10min_price: float = 10 # minimum price (USD)
11min_volume: int = 100000 # minimum 50-day average volume
12
13# Iteration 3: Trend
14trend_settings = {
15 "Price >= 50-day SMA": True, # set values to 'True' or 'False'
16 "Price >= 200-day SMA": True, # ^
17 "10-day SMA >= 20-day SMA": True, # ^
18 "20-day SMA >= 50-day SMA": True, # ^
19 "Price within 50% of 52-week High": True, # ^
20}
21
22# Iteration 4: Revenue Growth
23min_growth_percent: float = 25 # minimum revenue growth for a quarter compared to the same quarter 1 year ago (percentage)
24protected_rs: int = 97 # minimum RS rating to bypass revenue screen iteration (see README)
25
26# Iteration 5: Institutional Accumulation
27# (no parameters to modify)
28
29# THREADS (manually set the following value if the screener reports errors during the "Trend" or "Institutional Accumulation" iterations)
30# Recommended values are 1-10. Currently set to 3/4 the number of CPU cores on the system (with a max of 10)
31
32# Thread Pool Size
33threads: int = min(int(multiprocessing.cpu_count() * 0.75), 10) # number of concurrent browser instances to fetch dynamic data (positive integer)
Viewing results
Screen results are saved in .csv
format in the project root directory, and can be opened with software like Excel, Google Sheets, or Numbers.
Screen Iterations
An initial list of stocks from which to screen is sourced from NASDAQ.
Then, the following screen iterations are executed sequentially:
1. Relative Strength
The market's strongest stocks are determined by calculating a raw weighted average percentage price change over the last months of trading. A weight is attributed to the most recent quarter, while the previous three quarters each receive a weight of .
These raw values are then assigned a percentile rank from and turned into RS ratings. By default, only stocks with a relative strength rating greater than or equal to make it through this stage of screening.
2. Liquidity
All micro-cap companies and thinly traded stocks are filtered out based on the following criteria:
3. Trend
All stocks which are not in a stage-two uptrend are filtered out. We define a stage-two uptrend as:
4. Revenue Growth
Only the most rapidly growing companies with high revenue growth are allowed to pass this iteration of the screen. Specifically, the percent increase in the most recent reported quarterly revenue versus a year ago must be at least ; if available, the percent increase in the prior period versus the same quarter a year ago must also be at least . Revenue data is extracted from XBRL from company 10-K and 10-Q SEC filings, which eliminates foreign stocks in the process.
The current market often factors in future revenue growth; historically, this means certain exceptional stocks have exhibited super-performance without having strong on-paper revenue growth (examples include NVDA, UPST, PLTR, AI, etc.). To ensure that these stocks aren't needlessly filtered out, a small exception to revenue criteria is added: stocks with an can bypass revenue criteria and make it through this screen iteration.
5. Institutional Accumulation
Any stocks with a net-increase in institutional-ownership are marked as being under accumulation. Institutional-ownership is measured by the difference in total inflows and outflows in the most recently reported financial quarter.
Since this information lags behind the current market by a few months, no stocks are outright eliminated based on this screen iteration.
Troubleshooting Errors
By default, the screener attempts to calculate an ideal number of concurrent broswer instances to create based on the number of CPU cores present on your machine. In rare cases, this number may be too high.
If you notice failed stock symbols with errors such as Browsing context has been discarded
, Tried to run command without establishing a connection
, WebDriver session does not exist
, or Failed to decode response from marionette
during the trend or institutional-accumulation iterations, you are likely creating too many browser instances at once.
Consider decreasing the value of threads
in settings.py to 1-3 if you are experiencing this.