File size: 1,834 Bytes
8ed954c
 
 
 
 
 
68150f2
 
54287d1
8ed954c
 
 
 
 
 
54287d1
 
 
 
 
 
 
8ed954c
54287d1
68150f2
 
8ed954c
 
 
 
 
54287d1
8ed954c
68150f2
8ed954c
 
 
54287d1
68150f2
8ed954c
54287d1
68150f2
8ed954c
 
 
 
 
68150f2
8ed954c
 
 
 
68150f2
 
 
 
 
 
 
8ed954c
68150f2
8ed954c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
"""Trending stock scanner using Brave Search.

Uses shared core modules for search and ticker validation.
"""

import random
import re
import yfinance as yf

from src.core.logger import get_logger
from src.core.search import brave_search_raw
from src.core.ticker_utils import NOISE_WORDS

logger = get_logger(__name__)

SEARCH_QUERIES = [
    "stock market top trending gainers today",
    "most active stocks by volume today",
    "undervalued growth stocks 2026",
    "stocks with highest implied volatility today",
    "best performing tech stocks this week",
    "small cap stocks breaking out today",
    "unusual options activity tickers today",
]


def get_trending_stocks() -> list[str]:
    """Search the web for trending stocks, validate with yFinance.

    Returns up to 5 validated ticker symbols.
    """
    selected_query = random.choice(SEARCH_QUERIES)
    logger.info("Scanner strategy: '%s'", selected_query)

    full_text = brave_search_raw(selected_query, count=20, freshness="pw")
    if not full_text:
        logger.warning("Scanner got no search results")
        return ["NVDA", "TSLA", "AMD"]

    candidates = re.findall(r"\b[A-Z]{2,5}\b", full_text)
    random.shuffle(candidates)

    logger.info("Scanning %d raw candidates...", len(candidates))

    unique_tickers: list[str] = []
    seen: set[str] = set()

    for ticker in candidates:
        if ticker in NOISE_WORDS or ticker in seen:
            continue
        if len(unique_tickers) >= 5:
            break

        try:
            stock = yf.Ticker(ticker)
            price = stock.fast_info.last_price
            if price and price > 0:
                unique_tickers.append(ticker)
                seen.add(ticker)
        except Exception:
            continue

    return unique_tickers if unique_tickers else ["NVDA", "TSLA", "AMD"]