Spaces:
Sleeping
PrimoGreedy v7.0 β Team Guide
What Is PrimoGreedy?
PrimoGreedy is an AI-powered micro-cap stock discovery agent. It systematically hunts for undervalued companies with market caps between $10M and $300M, priced under $30/share, across four markets: USA, UK, Canada, and Australia. It uses Benjamin Graham's value investing math combined with real-time data from multiple APIs, then delivers structured investment memos to the team via email.
The system runs automatically every day at 6:00 AM UTC via a GitHub Actions cron job, and also has an interactive web UI (Chainlit) for on-demand analysis.
How It Works β The Pipeline
Every stock goes through a 4-step pipeline built with LangGraph:
SCOUT ββ> GATEKEEPER ββ> ANALYST ββ> EMAIL
Step 1: Scout (Discovery)
The Scout uses a two-pronged approach to find candidates:
- yFinance Screener β Directly queries Yahoo Finance for stocks matching our market cap and price criteria. Uses a seed pool of known micro-cap tickers per region, updated over time.
- Brave Search Trending β Searches the web for currently-trending micro-cap discussions (Reddit, financial blogs, news). Extracts ticker symbols from the results and merges them into the screener pool.
Both feeds are merged, then run through a quantitative scoring system (0β100 points) that ranks candidates on:
| Criterion | Points |
|---|---|
| Profitability (EPS > 0) | 20 |
| Graham Number undervaluation | 25 |
| Price-to-Book < 1.0 | 15 |
| Free Cash Flow positive | 15 |
| Low Debt (Net Debt/EBITDA) | 10 |
| Current Ratio > 1.5 | 10 |
| Cash runway (if unprofitable) | 5 |
Only the highest-scoring candidate gets sent to the expensive LLM analyst step. Up to 4 backups are queued in case the top pick fails the Gatekeeper.
Step 2: Gatekeeper (Validation)
Hard filters that reject stocks automatically:
- Price > $30/share
- Market cap outside $10Mβ$300M
- Financial health fails sector-specific checks:
- Banks: Price/Book must be near or under 1.0
- Tech/Healthcare: Must have at least 6 months of cash runway (zombie filter)
- Industrials/Default: Net Debt/EBITDA must be under 3.5x
If rejected, the pipeline loops back to Scout to try the next candidate. After 4 failed attempts per region, a failure report is sent instead.
Step 3: Analyst (AI Investment Memo)
For stocks that pass the Gatekeeper, the AI writes a structured investment memo using two valuation frameworks:
- Graham Classic β For profitable companies:
sqrt(22.5 Γ EPS Γ BookValue)to calculate intrinsic value and margin of safety. - Deep Value Asset Play β For unprofitable companies (miners, biotech, turnarounds): evaluates Price vs Book Value as the safety net.
The memo is structured in 4 sections:
- Quantitative Base β Price vs calculated intrinsic value, margin of safety math
- Lynch Pitch β What insiders are doing + the one catalyst that could move the stock
- Munger Invert β How you could lose money, what metric proves the bear case
- Final Verdict β STRONG BUY / BUY / WATCH / AVOID with a one-sentence bottom line
Data sources fed into the prompt:
- yFinance (price, EPS, book value, EBITDA, sector)
- Finnhub (insider sentiment, company news, 52W high/low, beta, ROE)
- Insider Feed (6-month insider buying/selling via MSPR score)
- Brave Search (recent news and catalysts)
Step 4: Email
The memo (or failure report) is sent to all team members via Resend. Each team member uses their own API key for reliability.
How to Use the Web UI (Chainlit)
The Chainlit app runs on Hugging Face Spaces. Commands:
| Command | What It Does |
|---|---|
AUTO |
Runs the full screener + Brave scan and returns a hot list |
NVDA |
Analyses a single ticker through the full pipeline |
NVDA, AMD, TSLA |
Analyses multiple tickers |
@DeItaone |
Scouts the web for stocks mentioned by a social media personality |
PORTFOLIO |
Shows the paper portfolio with live P&L for all past calls |
BACKTEST |
Runs a Backtrader backtest on the paper portfolio vs Buy & Hold |
What is the Graham Number? |
Chat mode β ask the AI broker anything |
Architecture Overview
src/
βββ core/ # Shared modules used by everything
β βββ logger.py # Structured logging
β βββ search.py # Single Brave Search implementation
β βββ ticker_utils.py # Ticker extraction, suffix resolution, price normalization
β βββ memory.py # Seen-tickers ledger (30-day TTL)
β βββ state.py # Shared LangGraph state schema
β
βββ discovery/ # Stock discovery and ranking
β βββ screener.py # yFinance micro-cap screener + Brave trending merge
β βββ scoring.py # Quantitative 0-100 scoring system
β βββ insider_feed.py # SEC Form 4 + Finnhub insider sentiment feeds
β
βββ backtesting/ # Backtrader integration
β βββ engine.py # Cerebro setup and run helpers
β βββ strategies.py # PrimoAgent and Buy & Hold strategies
β βββ portfolio_bridge.py # Converts paper portfolio into backtest signals
β βββ data.py # Data loading for backtests
β βββ plotting.py # Chart generation
β βββ reporting.py # Markdown report generation
β
βββ whale_hunter.py # Daily cron pipeline (ScoutβGatekeeperβAnalystβEmail)
βββ agent.py # Interactive Chainlit pipeline (adds Chat, Chart, manual lookup)
βββ llm.py # LLM connection with 6-model fallback chain
βββ finance_tools.py # Graham Number, health checks, Finnhub tools
βββ portfolio_tracker.py # Paper portfolio ledger
βββ email_utils.py # Thread-safe email dispatch via Resend
βββ scanner.py # Trending stock scanner
βββ social_scout.py # Social media handle scouting
βββ niche_hunter.py # Standalone Brave-only global hunter
βββ global_router.py # Market config (suffixes, gov filing links)
app.py # Chainlit web UI entry point
backtest.py # Interactive backtesting CLI
main.py # Workflow-based analysis CLI
API Keys Required
| Key | Service | Used For |
|---|---|---|
OPENROUTER_API_KEY |
OpenRouter | LLM access (free tier) |
BRAVE_API_KEY |
Brave Search | Web search for trending stocks and news |
FINNHUB_API_KEY |
Finnhub | Insider sentiment, company news, fundamentals |
RESEND_API_KEY_* |
Resend | Email delivery (one per team member) |
EMAIL_* |
β | Team member email addresses |
All keys are stored as GitHub Secrets for the cron job and in .env for local development.
LLM Model Fallback
The system uses free models via OpenRouter. If one model is rate-limited (429 error), it automatically tries the next:
nvidia/nemotron-3-nano-30b-a3b(primary β fast, reliable)stepfun/step-3.5-flasharcee-ai/trinity-large-previewgoogle/gemma-3-27b-itmeta-llama/llama-3.3-70b-instructmistralai/mistral-small-3.1-24b-instruct
Daily Cron Schedule
The GitHub Actions workflow (.github/workflows/hunter.yml) runs at 06:00 UTC daily:
- Hunts all 4 regions: USA, UK, Canada, Australia
- Sends email reports for each region (success or failure)
- Commits the updated
seen_tickers.jsonmemory ledger to the repo - 60-minute timeout
To trigger manually: go to Actions > Global Hunter Cron > Run workflow on GitHub.
Paper Portfolio
Every BUY / STRONG BUY / WATCH call is recorded in paper_portfolio.json with the entry price and date. Use PORTFOLIO in the UI to see live P&L, or BACKTEST to compare against a Buy & Hold baseline using Backtrader.
Key Concepts
- Graham Number:
sqrt(22.5 Γ EPS Γ Book Value)β the maximum price a defensive investor should pay. If the current price is below this, there's a margin of safety. - Margin of Safety:
(Graham Value - Price) / Graham Valueβ the bigger this %, the more undervalued. - MSPR (Monthly Share Purchase Ratio): Finnhub's insider sentiment metric. Positive = insiders buying, negative = insiders selling.
- Zombie Filter: Rejects tech/healthcare companies burning cash with less than 6 months of runway.
- Seen Tickers Memory: A JSON ledger that prevents re-analysing the same stock within 30 days.