RyanJHamby
stock-screener
Python

Automated stock screener scanning 3,800+ stocks daily for confirmed Stage 2 uptrends passing 8 strict criteria. Features: smart caching (74% fewer API calls), market regime filtering, automated stop-loss calculation, and GitHub Actions automation. Follows Mark Minervini's Trend Template.

Last updated Jul 7, 2026
24
Stars
29
Forks
1
Issues
+1
Stars/day
Attention Score
72
Language breakdown
No language data available.
โ–ธ Files click to expand
README

Intelligent Stock Screener

A production-grade systematic trading system for identifying high-probability stock setups using phase-based technical analysis, relative strength momentum, and smart fundamental screening.

Python License Code Style Daily Scan


Example scan output showing benchmark summary, market breadth, and top buy signals


Table of Contents


Overview

Intelligent Stock Screener is a fully automated, data-driven stock screening and position management system that scans 3,800+ US stocks daily to identify high-conviction buy and sell signals based on:

  • Phase-based trend classification (4-stage market cycle analysis)
  • Relative strength momentum (smooth linear scoring vs SPY)
  • Fundamental quality filters (growth, profitability, financial health)
  • Volume-weighted breakout detection
  • Risk-managed stop loss recommendations
This system was built to eliminate emotional decision-making and provide objective, repeatable trade signals backed by technical and fundamental analysis.

What This System Does

  • Screens 3,800+ stocks every market day using GitHub Actions automation
  • Identifies buy signals for stocks in confirmed Phase 2 uptrends that pass Minervini's 8-criteria Trend Template
  • Identifies sell signals when stocks enter Phase 3 (distribution) or Phase 4 (downtrend) with weakening momentum
  • Calculates precise stop losses with risk/reward ratios for every buy signal (max 10% risk, min 2:1 R:R)
  • Generates daily reports with ranked opportunities and full technical analysis
  • Manages existing positions with automated stop-loss trailing recommendations

Why I Built It This Way

Problem: Most stock screeners rely on static fundamental metrics (P/E, P/B) or generic technical patterns that don't adapt to market conditions. They ignore:

  • Market regime (is SPY in an uptrend or downtrend?)
  • Relative strength (is the stock outperforming the market?)
  • Phase transitions (is the stock breaking out or breaking down?)
  • Smart caching (redundant API calls wasting time and hitting rate limits)
Solution: This system implements Mark Minervini's Trend Template methodology where:
  • Only buy confirmed Phase 2 uptrends (not early Phase 1 bases)
  • Must pass 7 of 8 strict technical criteria (50>150>200 SMA, price near highs, etc.)
  • Timing matters - only buy when market (SPY) is also healthy
  • Relative strength matters - only buy stocks outperforming the market
  • Cache-first design - 74% reduction in API calls through Git-based fundamental storage

Methodology & Attribution

This system implements Mark Minervini's Trend Template (also known as SEPA - Specific Entry Point Analysis), a systematic approach to identifying high-probability stock setups in confirmed Stage 2 uptrends.

Mark Minervini's Influence

The core buy signal methodology is based on principles from:

  • "Trade Like a Stock Market Wizard" (2013) - Minervini's systematic approach to stock selection using the Trend Template
  • "Think & Trade Like a Champion" (2017) - Advanced stage analysis and risk management techniques
  • "Momentum Masters" (2015) - Multi-contributor insights on momentum trading strategies

The Minervini Trend Template (8 Criteria)

Buy signals only trigger when stocks pass 7 of 8 strict criteria:

  • โœ… Price > 150 SMA AND 200 SMA - Stock must be in established uptrend
  • โœ… 150 SMA > 200 SMA - Moving averages in bullish alignment
  • โœ… 200 SMA trending up โ‰ฅ1 month - Long-term trend is bullish
  • โœ… 50 SMA > 150 SMA > 200 SMA - Strongest SMA configuration (cascading)
  • โœ… Price > 50 SMA - Stock respecting short-term support
  • โœ… Price โ‰ฅ30% above 52-week low - Stock has built significant base
  • โœ… Price within 25% of 52-week high - Near new highs (not extended)
  • โœ… Relative Strength โ‰ฅ70 - Outperforming market (we use RS slope โ‰ฅ +0.15)
Why This Works:
  • Identifies stocks in confirmed uptrends (not early bases)
  • Filters out weak stocks with poor price structure
  • Ensures proper risk/reward (stocks near highs with strong momentum)
  • Aligns with institutional buying (big money follows strong trends)

Additional Influences

While the core entry criteria follow Minervini's template, this system also incorporates concepts from:

  • Stan Weinstein - 4-stage market cycle analysis ("Secrets for Profiting in Bull and Bear Markets")
  • William O'Neil - Fundamental screening criteria (CANSLIM methodology)
  • IBD Methodology - Relative strength ranking and market regime awareness

Our Implementation

We've automated Minervini's manual screening process with additional enhancements:

  • Smooth linear scoring instead of binary pass/fail (reduces false signals)
  • Market regime filtering (SPY phase + breadth checks - only buy in healthy markets)
  • Automated fundamental screening (growth, profitability, financial health)
  • Precise stop-loss calculation (ATR-based + swing lows, max 10% risk)
  • R:R validation (only include signals with โ‰ฅ2:1 reward/risk ratio)
The system stays true to Minervini's core principle: Buy confirmed Stage 2 breakouts with strong fundamentals and clear risk management.

System Architecture

graph TB
    subgraph "Data Layer"
        A[Universe Fetcher<br/>3800+ US Stocks] --> B[Price Fetcher<br/>1 Year OHLCV]
        B --> C[Fundamental Fetcher<br/>Quarterly Financials]
        C --> D[Git Storage<br/>Smart Caching]
    end

subgraph "Analysis Engine" D --> E[Phase Classifier<br/>4-Stage Trend Analysis] D --> F[RS Calculator<br/>Smooth Linear Scoring] D --> G[Fundamental Analyzer<br/>Growth + Quality]

E --> H[Signal Engine] F --> H G --> H

H --> I[Buy Signals<br/>Phase 1/2 Breakouts] H --> J[Sell Signals<br/>Phase 3/4 Breakdowns] end

subgraph "Risk Management" I --> K[Stop Loss Calculator<br/>ATR + Swing Lows] K --> L[R:R Analysis<br/>Min 2:1 Ratio] end

subgraph "Outputs" L --> M[Daily Report<br/>Ranked Signals] J --> M M --> N[GitHub Actions<br/>Automated Delivery] end

subgraph "Position Management" O[Robinhood API<br/>Read-Only] --> P[Position Fetcher] D --> P P --> Q[Stop Adjuster<br/>Linear Trailing] Q --> R[Position Report<br/>Manual Review] end

style D fill:#e1f5e1 style H fill:#fff4e1 style M fill:#e1f0ff style R fill:#ffe1f0

Data Flow

  • Daily Scan (GitHub Actions, 1 PM UTC M-F):
- Fetches universe of 3,800+ US stocks from NASDAQ/NYSE - Downloads 1 year price history for each (250 trading days) - Fetches fundamentals using earnings-aware cache refresh strategy - Stores in Git-based cache (persists beyond Actions cache limits)
  • Signal Generation:
- Classifies SPY phase to determine market regime - Calculates market breadth (% stocks in each phase) - For each stock: classifies phase, calculates RS, analyzes fundamentals - Scores buy/sell signals using weighted formula - Ranks results and generates formatted report
  • Position Management (Manual):
- Fetches current positions from Robinhood (read-only) - Loads cached price/fundamental data (zero extra API calls) - Analyzes each position's phase, SMA levels, momentum - Recommends stop loss adjustments using linear scaling formulas - Outputs actionable report with exact price targets

Key Features

โœ… Phase-Based Trend Classification

Stocks are classified into 4 phases based on moving average slopes and price position:

  • Phase 1 (Base Building): Consolidation after decline. 50/200 SMA flattening, price finding support. NOT YET READY
  • Phase 2 (Uptrend): Confirmed uptrend. 50>150>200 SMA (all rising), price above all SMAs. BUY ZONE โญ
  • Phase 3 (Distribution): Topping pattern. SMAs starting to flatten/cross, momentum weakening. SELL ZONE
  • Phase 4 (Downtrend): Declining trend. 50 SMA < 200 SMA, both falling, price below both. AVOID
Important: Following Minervini's methodology, buy signals only trigger for Phase 2 stocks that pass the Trend Template. Phase 1 stocks are still basing and not ready for entry.

๐Ÿ“ˆ Relative Strength Momentum

  • Smooth linear scoring (0-10 scale) vs SPY benchmark
  • 63-day RS slope calculation (captures 3-month momentum trend)
  • Penalizes underperformance, rewards outperformance
  • Crucial filter: only buy stocks beating the market

๐Ÿ’ฐ Fundamental Quality Screening

  • Growth: Revenue growth, EPS growth trends
  • Profitability: Operating margins, ROE
  • Financial Health: Debt ratios, current ratio
  • Only applied to Phase 1/2 stocks (Phase 3/4 skip fundamentals - price action is king)

๐ŸŽฏ Risk-Managed Stop Losses

Every buy signal includes:

  • Entry price: Current market price or breakout level
  • Stop loss: ATR-based or swing low-based
  • Risk amount: $ per share risked
  • Reward target: 2-3x risk minimum
  • R:R ratio: Always โ‰ฅ 2:1 for inclusion

๐Ÿ”„ Smart Caching Strategy

  • Price data: Always fetch fresh (needed for current signals)
  • Fundamentals: Git-based storage with earnings-aware refresh
- Earnings season (6-week windows): Refresh if >7 days old - Normal periods: Refresh if >90 days old - Result: 74% reduction in API calls, zero GitHub Actions cache expiry issues

๐Ÿค– Full Automation

  • Runs daily via GitHub Actions (1 PM UTC, weekdays only)
  • No manual intervention required
  • Results committed to repository (full history)
  • Adaptable to market conditions (skips buy signals in weak markets)

Design Philosophy

1. Cache-First, API-Second

Rationale: yfinance has strict rate limits (~2 req/sec). Scanning 3,800 stocks requires 3,800+ API calls. At 1 TPS, that's 63 minutes. But fundamentals change slowly (quarterly earnings), so why re-fetch every day?

Solution:

  • Store fundamentals in Git repository as JSON files
  • Add metadata with fetched_at timestamp
  • During scan: Check if cache exists and is fresh
  • Only fetch if stale or missing
  • Result: 1,762 cached stocks = 74% fewer API calls = 15-20 min faster scans

2. Confirmed Uptrends Only (Minervini's Stage 2)

Rationale: Traditional screeners look for "cheap" stocks (low P/E) or early bases (Phase 1). But cheap stocks can get cheaper, and bases can fail. Minervini only buys confirmed Stage 2 uptrends.

Solution:

  • Classify stocks into 4 phases based on SMA slopes and price position
  • Only buy Phase 2 (confirmed uptrends with 50>150>200 SMA alignment)
  • Reject Phase 1 (still basing, not confirmed)
  • Only sell Phase 2 โ†’ 3/4 transitions (breakdowns from tops)
  • This filters out 70%+ of stocks immediately, leaving only the highest-quality setups

3. Relative Strength as Primary Filter

Rationale: Absolute returns don't matter - relative returns do. A stock up 5% when SPY is up 10% is actually underperforming. Market leaders (high RS) tend to continue leading.

Solution:

  • Calculate 63-day RS slope (3-month trend)
  • Smooth linear scoring (not bucket-based)
  • 10 points max for RS in buy signal scoring
  • Filters out weak stocks even if other metrics look good

4. Linear Formulas Over Buckets

Rationale: Bucket-based scoring (e.g., "P/E < 15 = 10 points, P/E 15-20 = 5 points") creates artificial cliffs. A stock with P/E 14.9 and P/E 15.1 shouldn't have a 5-point difference.

Solution:

  • All scoring uses linear interpolation
  • Example: RS slope scoring scales smoothly from -0.3 (0 points) to +0.3 (10 points)
  • Stop loss trailing scales linearly with gain % (5% gain โ†’ lock 1% profit, 40% gain โ†’ lock 18% profit)
  • Result: Smoother, more reasonable scoring

5. Market Regime Awareness

Rationale: Buy signals in a bear market (SPY in Phase 4) have low win rates. Why generate signals that are likely to fail?

Solution:

  • Classify SPY phase before generating signals
  • Calculate market breadth (% stocks in Phase 2)
  • Only generate buy signals if:
- SPY in Phase 1 or 2 (market not declining) - AND โ‰ฅ15% of stocks in Phase 2 (sufficient breadth)
  • Sell signals always generated (can exit in any market)

6. Read-Only Position Management

Rationale: Executing trades programmatically is risky and requires extensive safeguards. But analyzing positions and recommending adjustments can be automated safely.

Solution:

  • Robinhood integration is read-only (only fetches positions)
  • Never calls trading functions (no orderbuy, ordersell)
  • Position manager recommends stop adjustments
  • Human executes trades manually on Robinhood app
  • Best of both worlds: automation + human oversight

Quick Start

Prerequisites

  • Python 3.13+
  • GitHub account (for automation)
  • Robinhood account (optional, for position management)

Installation

# Clone repository
git clone https://github.com/RyanJHamby/stock-screener.git
cd stock-screener

Create virtual environment

python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate

Install dependencies

pip install -r requirements.txt

(Optional) Install robin-stocks for position management

pip install robin-stocks

Configuration

# Copy environment template
cp .env.example .env

Edit .env (only needed for manual position management)

Add: ROBINHOODUSERNAME=youremail@example.com

Run Your First Scan

# Test mode: Scan 100 stocks to verify setup
python runoptimizedscan.py --test-mode

Full scan: All 3,800+ stocks (30-40 minutes)

python runoptimizedscan.py --conservative

View Results

# Latest scan results
cat data/dailyscans/latestoptimized_scan.txt

All historical scans

ls -l data/daily_scans/

Daily Workflow

Automated Mode (GitHub Actions)

The system runs automatically every weekday at 1 PM UTC (9 AM EST):

  • Scan triggers via GitHub Actions schedule
  • Fetches universe of 3,800+ US stocks
  • Downloads price data for all stocks
  • Loads cached fundamentals (or fetches if stale)
  • Classifies phases and calculates RS
  • Generates signals based on market regime
  • Saves report to data/dailyscans/latestoptimized_scan.txt
  • Commits results to repository
You receive:
  • Daily email/Slack notification (if configured)
  • Ranked buy signals with stop losses
  • Ranked sell signals with breakdown levels
  • Market regime analysis (SPY phase + breadth)

Manual Mode (Local)

Run on-demand scans:

# Conservative scan (2 workers, 1.0s delay = ~2 TPS)
python runoptimizedscan.py --conservative

Default scan (3 workers, 0.5s delay = ~6 TPS)

python runoptimizedscan.py

Aggressive scan (5 workers, 0.3s delay = ~17 TPS) - MAY HIT RATE LIMITS

python runoptimizedscan.py --aggressive

Resume from interruption

python runoptimizedscan.py --resume

Clear cached progress and start fresh

python runoptimizedscan.py --clear-progress

Manual Position Management

โš ๏ธ Note: Position management requires manual execution. This is intentional for safety.

Step 1: Ensure Robinhood Username is Set

In your .env file:

ROBINHOODUSERNAME=youremail@example.com

Important: Password is NEVER stored. You will be prompted interactively.

Step 2: Run Position Manager

# Basic analysis (prompts for password + SMS MFA)
python manage_positions.py

With entry dates for tax-aware recommendations

python managepositions.py --entry-dates entrydates.json

Export report to file

python manage_positions.py --export

Step 3: Interactive Authentication

Logging in to Robinhood...
Robinhood password for you@example.com: 

MFA required - check your phone for SMS code from Robinhood Enter SMS code from Robinhood: 123456

โœ“ Robinhood login successful with SMS MFA

Step 4: Review Recommendations

The tool will:

  • Fetch your current positions from Robinhood
  • Analyze each using cached market data (zero extra API calls)
  • Calculate phase, SMA levels, recent swing lows
  • Recommend stop loss adjustments using linear formulas

Example Output

================================================================================
POSITION MANAGEMENT REPORT - STOP LOSS RECOMMENDATIONS
Generated: 2025-12-06 10:30:15
================================================================================

PORTFOLIO SUMMARY


Total Positions: 3 Need Stop Adjustment: 2 Short-term (<1 year): 2 Long-term (1+ years): 1 Average Gain: +8.47%

โš ๏ธ URGENT ACTIONS NEEDED


NVDA (+10.10%) โ€ข Big winner - consider taking partial profits

================================================================================

################################################################################ POSITION #1: AAPL ################################################################################ Entry: $175.50 | Current: $182.30 | Gain: +3.87% Tax Treatment: SHORT_TERM Days Held: 45

ACTION: HOLD

RATIONALE: Position up 3.9% - hold initial stop. Wait for 5-10% gain before adjusting.

Technical: Phase 2 | 50 SMA: $178.20

################################################################################

POSITION #2: NVDA ################################################################################ Entry: $495.00 | Current: $545.00 | Gain: +10.10% Tax Treatment: SHORT_TERM Days Held: 20

ACTION: TRAIL TO PROFIT

โœ“ RECOMMENDED STOP LOSS: $519.75

RATIONALE: Position up 10.1% - TRAIL TO PROFIT

NEW STOP LOSS: $519.75 โ€ข Locks in minimum +5.0% profit โ€ข Stop type: profit-based

Technical: Phase 2 | 50 SMA: $512.30

################################################################################

POSITION #3: MSFT ################################################################################ Entry: $380.00 | Current: $385.50 | Gain: +1.45% Tax Treatment: LONG_TERM Days Held: 400

ACTION: HOLD

RATIONALE: LONG-TERM HOLD (400 days) - Preserve long-term capital gains tax rate. No stop adjustment recommended.

================================================================================

Stop Loss Logic

Recommendations use linear formulas (not buckets):

| Gain Range | Recommendation | Stop Level | |------------|----------------|------------| | 0-5% | Hold initial stop | Original stop | | 5-10% | Trail to breakeven | Entry price | | 10-20% | Trail to profit | Entry ร— (1 + lockedprofitpct/100) | | 20-30% | Take 25-30% partial | Remaining at +10% profit | | 30%+ | Take 50% partial | Remaining at tight trail |

Locked profit % formula:

lockedprofitpct = min(gainpct - 3, gainpct * 0.5)

Examples:

  • 5% gain โ†’ Lock 2% profit
  • 10% gain โ†’ Lock 3.5% profit
  • 20% gain โ†’ Lock 8.5% profit
  • 40% gain โ†’ Lock 18.5% profit

Tax-Aware Filtering

Long-term positions (365+ days held) are excluded from stop adjustments to preserve favorable capital gains tax treatment (15-20% vs ordinary income rate).

To enable:

  • Create entry_dates.json:
{
  "AAPL": "2024-10-18T00:00:00",
  "NVDA": "2024-11-13T00:00:00",
  "MSFT": "2023-05-10T00:00:00"
}
  • Run with --entry-dates:
python managepositions.py --entry-dates entrydates.json

Project Structure

stock-screener/
โ”œโ”€โ”€ .github/
โ”‚   โ””โ”€โ”€ workflows/
โ”‚       โ””โ”€โ”€ dailyscreeninggit_storage.yml  # Automated daily scan
โ”‚
โ”œโ”€โ”€ src/                                # Core library
โ”‚   โ”œโ”€โ”€ data/
โ”‚   โ”‚   โ”œโ”€โ”€ fetcher.py                  # YahooFinanceFetcher (price data)
โ”‚   โ”‚   โ”œโ”€โ”€ fundamentals_fetcher.py     # Quarterly financials fetcher
โ”‚   โ”‚   โ”œโ”€โ”€ gitstoragefetcher.py      # Smart cache (74% API reduction)
โ”‚   โ”‚   โ”œโ”€โ”€ enhanced_fundamentals.py    # FMP integration (optional)
โ”‚   โ”‚   โ”œโ”€โ”€ universe_fetcher.py         # NASDAQ/NYSE stock universe
โ”‚   โ”‚   โ””โ”€โ”€ robinhood_positions.py      # Robinhood read-only API
โ”‚   โ”œโ”€โ”€ screening/
โ”‚   โ”‚   โ”œโ”€โ”€ phase_indicators.py         # 4-phase classification
โ”‚   โ”‚   โ”œโ”€โ”€ signal_engine.py            # Buy/sell signal scoring
โ”‚   โ”‚   โ”œโ”€โ”€ benchmark.py                # SPY analysis + market breadth
โ”‚   โ”‚   โ””โ”€โ”€ optimizedbatchprocessor.py
โ”‚   โ””โ”€โ”€ analysis/
โ”‚       โ””โ”€โ”€ position_manager.py         # Stop loss recommendations
โ”‚
โ”œโ”€โ”€ tests/                              # Test suite
โ”œโ”€โ”€ examples/                           # Demo scripts and sample configs
โ”œโ”€โ”€ scripts/                            # Utility runners and shell scripts
โ”œโ”€โ”€ assets/                             # Screenshots and images
โ”œโ”€โ”€ docs/                               # Extended documentation
โ”‚
โ”œโ”€โ”€ data/
โ”‚   โ”œโ”€โ”€ fundamentals_cache/             # Git-tracked fundamentals (1,762 stocks)
โ”‚   โ”œโ”€โ”€ daily_scans/                    # Historical scan reports
โ”‚   โ””โ”€โ”€ position_reports/               # Position management reports
โ”‚
โ”œโ”€โ”€ runoptimizedscan.py               # Main scanner CLI
โ”œโ”€โ”€ manage_positions.py                 # Position management CLI
โ”œโ”€โ”€ automatedpositionreport.py        # GitHub Actions position report
โ”œโ”€โ”€ run_screen.sh                       # Convenience wrapper (full scan)
โ”œโ”€โ”€ run_test.sh                         # Convenience wrapper (test scan)
โ”‚
โ”œโ”€โ”€ config.yaml                         # Scan configuration
โ”œโ”€โ”€ requirements.txt
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ CHANGELOG.md
โ”œโ”€โ”€ CONTRIBUTING.md
โ””โ”€โ”€ LICENSE

Technical Details

Phase Classification Algorithm

def classifyphase(pricedata: pd.DataFrame, current_price: float) -> Dict:
    """
    Classifies stock into 4 phases based on SMA slopes and price position.

Returns: { 'phase': int (1-4), 'phase_name': str, 'confidence': float (0-100), 'sma_50': float, 'sma_200': float, 'slope_50': float (annualized), 'slope_200': float (annualized), 'reasons': List[str] } """

Logic:

  • Calculate 50-day and 200-day SMAs
  • Calculate slopes (annualized % change rate)
  • Classify phase based on:
- SMA ordering (50 > 200 or 50 < 200) - Slope directions (rising, falling, or flat) - Price position relative to SMAs
  • Return phase with confidence score

Relative Strength Calculation

def calculaterelativestrength(
    stock_prices: pd.Series,
    spy_prices: pd.Series,
    period: int = 63
) -> pd.Series:
    """
    Calculates smooth RS using linear regression slope.

Args: stock_prices: Stock close prices spy_prices: SPY close prices (benchmark) period: Lookback window (63 days = 3 months)

Returns: Series of RS slopes (annualized) """

Formula:

RSratio = stockreturn / spy_return RSslope = linearregressionslope(RSratio, period) RSscore = clip((RSslope + 0.3) / 0.6 * 10, 0, 10)

Interpretation:

  • RS slope +0.3 = 10 points (strong outperformance)
  • RS slope 0.0 = 5 points (matching market)
  • RS slope -0.3 = 0 points (strong underperformance)

Buy Signal Scoring (110 points max)

| Component | Max Points | Criteria | |-----------|------------|----------| | Phase | 30 | Phase 2 = 30, Phase 1 = 20 | | RS Momentum | 10 | Linear scale from RS slope | | Volume | 10 | Breakout on high volume | | Proximity to Breakout | 10 | Close to resistance level | | Fundamentals | 50 | Growth (20) + Profitability (15) + Health (15) |

Threshold: Buy signal score โ‰ฅ 70 for inclusion in report.

Sell Signal Scoring (110 points max)

| Component | Max Points | Criteria | |-----------|------------|----------| | Phase | 30 | Phase 4 = 30, Phase 3 = 20 | | RS Momentum | 10 | Negative RS (underperformance) | | Volume | 10 | Breakdown on high volume | | SMA Breakdown | 15 | Broke below 50/200 SMA | | Price Action | 15 | Lower highs, lower lows | | Severity | 30 | Combination of above factors |

Threshold: Sell signal score โ‰ฅ 60 for inclusion in report.

Stop Loss Calculation

def calculatestoploss(
    entry_price: float,
    price_data: pd.DataFrame,
    atr_period: int = 14,
    atr_multiplier: float = 2.0
) -> Dict:
    """
    Calculates stop loss using ATR or swing lows.

Returns: { 'stop_price': float, 'risk_amount': float, 'stoptype': str ('atr' or 'swinglow') } """

Method 1: ATR-Based

ATR = Average True Range (14 days) Stop = Entry - (ATR ร— 2.0)

Method 2: Swing Low-Based

Swing_Low = Lowest low in last 20 days Stop = Swing_Low ร— 0.98  (2% buffer)

Uses whichever is higher (more conservative).

Risk/Reward Validation

Every buy signal calculates:

risk = entryprice - stoploss reward = (entryprice ร— 1.20) - entryprice  # 20% target rrratio = reward / risk

Filter: Only include signals with R:R โ‰ฅ 2:1.


Future Improvements

Short-Term (Next 3 Months)

  • [ ] Backtesting Engine
- Simulate historical trades using phase transitions - Calculate win rate, profit factor, max drawdown - Optimize signal thresholds based on historical performance - Compare against buy-and-hold SPY baseline
  • [ ] Enhanced Reporting
- Add charts to daily report (SPY trend, market breadth, top signals) - Email delivery with HTML formatting - Slack integration with interactive buttons - Web dashboard for historical tracking
  • [ ] Smart Alerts
- Real-time alerts when positions hit stop levels - Notify when new high-score buy signals appear - Alert on market regime changes (SPY phase transitions)

Medium-Term (3-6 Months)

  • [ ] Multi-Timeframe Analysis
- Add weekly phase classification (longer-term trend) - Combine daily + weekly phases for higher-conviction signals - Filter out counter-trend trades (daily bullish, weekly bearish)
  • [ ] Sector Rotation
- Track which sectors are leading/lagging - Adjust signal thresholds based on sector strength - Identify sector rotation opportunities
  • [ ] Options Integration
- Fetch option chain data for buy signals - Recommend covered call strikes for profitable positions - Identify protective put opportunities for Phase 3 stocks
  • [ ] Paper Trading
- Simulate trades in paper account - Track P&L of generated signals - Validate system performance before real capital

Long-Term (6-12 Months)

  • [ ] Machine Learning Enhancement
- Train ML model on historical phase transitions - Predict probability of Phase 1 โ†’ 2 breakout success - Improve signal ranking using learned features
  • [ ] Alternative Data Sources
- Integrate insider trading data (SEC Form 4) - Add institutional ownership changes (13F filings) - Sentiment analysis from news/social media
  • [ ] Portfolio Construction
- Optimal position sizing based on volatility - Correlation-based diversification - Risk parity allocation across sectors
  • [ ] Execution Optimization
- Optimal entry timing (limit orders vs market orders) - Partial entry strategies (scale in over multiple days) - Bracket orders (auto-set stops and targets)

Infrastructure

  • [ ] Database Migration
- Move from file-based cache to PostgreSQL - Enable complex queries (sector rotation, correlation analysis) - Faster lookups for backtesting
  • [ ] Real-Time Data
- Integrate with real-time data provider (IEX Cloud, Polygon) - Intraday phase classification (15-min bars) - Live stop loss monitoring
  • [ ] Web UI
- Interactive dashboard for browsing signals - Position tracker with live P&L - Backtest explorer with equity curves

Contributing

This project is currently a personal trading system. If you'd like to contribute:

  • Fork the repository
  • Create a feature branch (git checkout -b feature/amazing-feature)
  • Make your changes with tests
  • Commit (git commit -m 'Add amazing feature')
  • Push (git push origin feature/amazing-feature)
  • Open a Pull Request
Code Standards:
  • Python 3.13+
  • Type hints required
  • Docstrings for all public functions
  • Black code formatting
  • pytest for tests (>80% coverage)

License

MIT License - See LICENSE file for details.


Disclaimer

This system is for educational and informational purposes only.

  • Not financial advice
  • Past performance does not guarantee future results
  • Trading stocks involves risk of loss
  • Always do your own research
  • Never invest more than you can afford to lose
  • Consult a licensed financial advisor before making investment decisions
The author is not responsible for any financial losses incurred using this system.

Contact

Ryan Hamby GitHub: github.com/RyanJHamby LinkedIn: linkedin.com/in/ryanhamby


Built with Python, powered by data, driven by discipline.

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท RyanJHamby/stock-screener ยท Updated daily from GitHub