scanner-bullish · git:20260621.3d6dc5b · 2026-06-21 · sha256 e0678c0f534d7fcc
scanner-bullish git:20260621.3d6dc5bA
Immutable. This exact content is served forever at /api/v1/blob/e0678c0f534d7fcc.
---
name: scanner-bullish
description: Scan stocks for bullish trends using technical indicators (SMA, RSI, MACD, ADX). Use when user asks to scan for bullish stocks, find trending stocks, or rank symbols by momentum.
dependencies: ["trading-skills"]
---
# Bullish Scanner
Scans symbols for bullish trends and ranks them by composite score.
## Instructions
> **Note:** If `uv` is not installed or `pyproject.toml` is not found, replace `uv run python` with `python` in all commands below.
```bash
uv run python scripts/scan.py SYMBOLS [--top N] [--period PERIOD]
```
## Arguments
- `SYMBOLS` - Comma-separated ticker symbols (e.g., `AAPL,MSFT,GOOGL,NVDA`)
- `--top` - Number of top results to return (default: 30)
- `--period` - Historical period for analysis: 1mo, 3mo, 6mo (default: 3mo)
## Scoring System (max ~9.5 points)
| Indicator | Condition | Points |
|-----------|-----------|--------|
| SMA20 | Price > SMA20 | +1.0 |
| SMA50 | Price > SMA50 | +1.0 |
| RSI | 50-70 (bullish) | +1.0 |
| | 30-50 (neutral) | +0.5 |
| | <30 (oversold) | +0.25 |
| MACD | MACD > Signal | +1.0 |
| | Histogram rising | +0.5 |
| EMA9/21 | EMA9 > EMA21 (golden cross) | +0.5 |
| | EMA9 < EMA21 (death cross) | -0.25 |
| Dual crossover | Both up, both ≤10 days | +1.0 |
| | Both up, any age | +0.5 |
| | Both down, both ≤10 days | -1.0 |
| | Both down, any age | -0.5 |
| | Directions conflict | -0.5 |
| ADX | >25 with +DI > -DI | +1.5 |
| | +DI > -DI only | +0.5 |
| Momentum | period return / 20 | -1 to +2 |
## Output
Returns JSON with:
- `scan_date` - Timestamp of scan
- `symbols_scanned` - Total symbols analyzed
- `results` - Array sorted by score (highest first):
- `symbol`, `score`, `price`
- `next_earnings`, `earnings_timing` (BMO/AMC)
- `period_return_pct`, `pct_from_sma20`, `pct_from_sma50`
- `rsi`, `macd`, `macd_signal`, `macd_hist`, `adx`, `dmp`, `dmn`
- `ema9`, `ema21` — current EMA9 and EMA21 values
- `ema_crossover` - Most recent EMA9/EMA21 crossover (or `null` if none found):
- `direction` - `"up"` (EMA9 crossed above EMA21 = bullish) or `"down"` (crossed below = bearish)
- `days_ago` - Trading days since the crossover bar (0 = happened in the most recent bar)
- `macd_crossover` - Most recent MACD crossover (or `null` if none found):
- `direction` - `"up"` (MACD crossed above signal = bullish) or `"down"` (crossed below = bearish)
- `days_ago` - Trading days since the crossover bar (0 = happened in the most recent bar)
- `signals` - List of triggered conditions
## EMA Crossover Interpretation
- EMA9 > EMA21 with small `days_ago` (0-5): fresh golden cross — short-term momentum confirmed
- EMA9 just crossed below EMA21: death cross — short-term momentum turning negative
- EMA9 crossover lagging MACD crossover by days: normal — MACD leads, EMA confirms
- `null`: EMA9/21 relationship unchanged throughout the period
## MACD Crossover Interpretation
- `direction: "up"` with small `days_ago` (0-5): fresh bullish crossover — early entry signal
- `direction: "up"` from a deeply negative signal: recovery from correction
- `direction: "down"`: momentum has turned bearish regardless of score
- `null`: no sign change found in the period — trend has been consistently one-directional
## Examples
```bash
# Scan a few symbols
uv run python scripts/scan.py AAPL,MSFT,GOOGL,NVDA,TSLA
# Get top 10 from larger list
uv run python scripts/scan.py AAPL,MSFT,GOOGL,NVDA,TSLA,AMD,AMZN,META --top 10
# Use 6-month lookback
uv run python scripts/scan.py AAPL,MSFT,GOOGL --period 6mo
```
## Interpretation
- Score > 6: Strong bullish trend
- Score 4-6: Moderate bullish
- Score 2-4: Neutral/weak
- Score < 2: Bearish or no trend
## Dependencies
- `pandas`
- `pandas-ta`
- `yfinance`
## Timezone
All timestamps and time-based calculations must use the `America/New_York` timezone. All JSON output must include `generated_at` (NY time string) and `data_delay` fields.