Spaces:
Sleeping
Sleeping
Commit Β·
4e5d4fb
1
Parent(s): ad9c6a1
docs: add TEAM_GUIDE.md explaining the full v7.0 architecture and usage
Browse files- TEAM_GUIDE.md +189 -0
TEAM_GUIDE.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# PrimoGreedy v7.0 β Team Guide
|
| 2 |
+
|
| 3 |
+
## What Is PrimoGreedy?
|
| 4 |
+
|
| 5 |
+
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.
|
| 6 |
+
|
| 7 |
+
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.
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## How It Works β The Pipeline
|
| 12 |
+
|
| 13 |
+
Every stock goes through a 4-step pipeline built with [LangGraph](https://langchain-ai.github.io/langgraph/):
|
| 14 |
+
|
| 15 |
+
```
|
| 16 |
+
SCOUT ββ> GATEKEEPER ββ> ANALYST ββ> EMAIL
|
| 17 |
+
```
|
| 18 |
+
|
| 19 |
+
### Step 1: Scout (Discovery)
|
| 20 |
+
|
| 21 |
+
The Scout uses a **two-pronged approach** to find candidates:
|
| 22 |
+
|
| 23 |
+
1. **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.
|
| 24 |
+
2. **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.
|
| 25 |
+
|
| 26 |
+
Both feeds are merged, then run through a **quantitative scoring system** (0β100 points) that ranks candidates on:
|
| 27 |
+
|
| 28 |
+
| Criterion | Points |
|
| 29 |
+
|-----------|--------|
|
| 30 |
+
| Profitability (EPS > 0) | 20 |
|
| 31 |
+
| Graham Number undervaluation | 25 |
|
| 32 |
+
| Price-to-Book < 1.0 | 15 |
|
| 33 |
+
| Free Cash Flow positive | 15 |
|
| 34 |
+
| Low Debt (Net Debt/EBITDA) | 10 |
|
| 35 |
+
| Current Ratio > 1.5 | 10 |
|
| 36 |
+
| Cash runway (if unprofitable) | 5 |
|
| 37 |
+
|
| 38 |
+
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.
|
| 39 |
+
|
| 40 |
+
### Step 2: Gatekeeper (Validation)
|
| 41 |
+
|
| 42 |
+
Hard filters that reject stocks automatically:
|
| 43 |
+
|
| 44 |
+
- **Price** > $30/share
|
| 45 |
+
- **Market cap** outside $10Mβ$300M
|
| 46 |
+
- **Financial health** fails sector-specific checks:
|
| 47 |
+
- *Banks*: Price/Book must be near or under 1.0
|
| 48 |
+
- *Tech/Healthcare*: Must have at least 6 months of cash runway (zombie filter)
|
| 49 |
+
- *Industrials/Default*: Net Debt/EBITDA must be under 3.5x
|
| 50 |
+
|
| 51 |
+
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.
|
| 52 |
+
|
| 53 |
+
### Step 3: Analyst (AI Investment Memo)
|
| 54 |
+
|
| 55 |
+
For stocks that pass the Gatekeeper, the AI writes a structured investment memo using two valuation frameworks:
|
| 56 |
+
|
| 57 |
+
- **Graham Classic** β For profitable companies: `sqrt(22.5 Γ EPS Γ BookValue)` to calculate intrinsic value and margin of safety.
|
| 58 |
+
- **Deep Value Asset Play** β For unprofitable companies (miners, biotech, turnarounds): evaluates Price vs Book Value as the safety net.
|
| 59 |
+
|
| 60 |
+
The memo is structured in 4 sections:
|
| 61 |
+
|
| 62 |
+
1. **Quantitative Base** β Price vs calculated intrinsic value, margin of safety math
|
| 63 |
+
2. **Lynch Pitch** β What insiders are doing + the one catalyst that could move the stock
|
| 64 |
+
3. **Munger Invert** β How you could lose money, what metric proves the bear case
|
| 65 |
+
4. **Final Verdict** β STRONG BUY / BUY / WATCH / AVOID with a one-sentence bottom line
|
| 66 |
+
|
| 67 |
+
**Data sources fed into the prompt:**
|
| 68 |
+
- yFinance (price, EPS, book value, EBITDA, sector)
|
| 69 |
+
- Finnhub (insider sentiment, company news, 52W high/low, beta, ROE)
|
| 70 |
+
- Insider Feed (6-month insider buying/selling via MSPR score)
|
| 71 |
+
- Brave Search (recent news and catalysts)
|
| 72 |
+
|
| 73 |
+
### Step 4: Email
|
| 74 |
+
|
| 75 |
+
The memo (or failure report) is sent to all team members via Resend. Each team member uses their own API key for reliability.
|
| 76 |
+
|
| 77 |
+
---
|
| 78 |
+
|
| 79 |
+
## How to Use the Web UI (Chainlit)
|
| 80 |
+
|
| 81 |
+
The Chainlit app runs on Hugging Face Spaces. Commands:
|
| 82 |
+
|
| 83 |
+
| Command | What It Does |
|
| 84 |
+
|---------|-------------|
|
| 85 |
+
| `AUTO` | Runs the full screener + Brave scan and returns a hot list |
|
| 86 |
+
| `NVDA` | Analyses a single ticker through the full pipeline |
|
| 87 |
+
| `NVDA, AMD, TSLA` | Analyses multiple tickers |
|
| 88 |
+
| `@DeItaone` | Scouts the web for stocks mentioned by a social media personality |
|
| 89 |
+
| `PORTFOLIO` | Shows the paper portfolio with live P&L for all past calls |
|
| 90 |
+
| `BACKTEST` | Runs a Backtrader backtest on the paper portfolio vs Buy & Hold |
|
| 91 |
+
| `What is the Graham Number?` | Chat mode β ask the AI broker anything |
|
| 92 |
+
|
| 93 |
+
---
|
| 94 |
+
|
| 95 |
+
## Architecture Overview
|
| 96 |
+
|
| 97 |
+
```
|
| 98 |
+
src/
|
| 99 |
+
βββ core/ # Shared modules used by everything
|
| 100 |
+
β βββ logger.py # Structured logging
|
| 101 |
+
β βββ search.py # Single Brave Search implementation
|
| 102 |
+
β βββ ticker_utils.py # Ticker extraction, suffix resolution, price normalization
|
| 103 |
+
β βββ memory.py # Seen-tickers ledger (30-day TTL)
|
| 104 |
+
β βββ state.py # Shared LangGraph state schema
|
| 105 |
+
β
|
| 106 |
+
βββ discovery/ # Stock discovery and ranking
|
| 107 |
+
β βββ screener.py # yFinance micro-cap screener + Brave trending merge
|
| 108 |
+
β βββ scoring.py # Quantitative 0-100 scoring system
|
| 109 |
+
β βββ insider_feed.py # SEC Form 4 + Finnhub insider sentiment feeds
|
| 110 |
+
β
|
| 111 |
+
βββ backtesting/ # Backtrader integration
|
| 112 |
+
β βββ engine.py # Cerebro setup and run helpers
|
| 113 |
+
β βββ strategies.py # PrimoAgent and Buy & Hold strategies
|
| 114 |
+
β βββ portfolio_bridge.py # Converts paper portfolio into backtest signals
|
| 115 |
+
β βββ data.py # Data loading for backtests
|
| 116 |
+
β βββ plotting.py # Chart generation
|
| 117 |
+
β βββ reporting.py # Markdown report generation
|
| 118 |
+
β
|
| 119 |
+
βββ whale_hunter.py # Daily cron pipeline (ScoutβGatekeeperβAnalystβEmail)
|
| 120 |
+
βββ agent.py # Interactive Chainlit pipeline (adds Chat, Chart, manual lookup)
|
| 121 |
+
βββ llm.py # LLM connection with 6-model fallback chain
|
| 122 |
+
βββ finance_tools.py # Graham Number, health checks, Finnhub tools
|
| 123 |
+
βββ portfolio_tracker.py # Paper portfolio ledger
|
| 124 |
+
βββ email_utils.py # Thread-safe email dispatch via Resend
|
| 125 |
+
βββ scanner.py # Trending stock scanner
|
| 126 |
+
βββ social_scout.py # Social media handle scouting
|
| 127 |
+
βββ niche_hunter.py # Standalone Brave-only global hunter
|
| 128 |
+
βββ global_router.py # Market config (suffixes, gov filing links)
|
| 129 |
+
|
| 130 |
+
app.py # Chainlit web UI entry point
|
| 131 |
+
backtest.py # Interactive backtesting CLI
|
| 132 |
+
main.py # Workflow-based analysis CLI
|
| 133 |
+
```
|
| 134 |
+
|
| 135 |
+
---
|
| 136 |
+
|
| 137 |
+
## API Keys Required
|
| 138 |
+
|
| 139 |
+
| Key | Service | Used For |
|
| 140 |
+
|-----|---------|----------|
|
| 141 |
+
| `OPENROUTER_API_KEY` | OpenRouter | LLM access (free tier) |
|
| 142 |
+
| `BRAVE_API_KEY` | Brave Search | Web search for trending stocks and news |
|
| 143 |
+
| `FINNHUB_API_KEY` | Finnhub | Insider sentiment, company news, fundamentals |
|
| 144 |
+
| `RESEND_API_KEY_*` | Resend | Email delivery (one per team member) |
|
| 145 |
+
| `EMAIL_*` | β | Team member email addresses |
|
| 146 |
+
|
| 147 |
+
All keys are stored as GitHub Secrets for the cron job and in `.env` for local development.
|
| 148 |
+
|
| 149 |
+
---
|
| 150 |
+
|
| 151 |
+
## LLM Model Fallback
|
| 152 |
+
|
| 153 |
+
The system uses free models via OpenRouter. If one model is rate-limited (429 error), it automatically tries the next:
|
| 154 |
+
|
| 155 |
+
1. `nvidia/nemotron-3-nano-30b-a3b` (primary β fast, reliable)
|
| 156 |
+
2. `stepfun/step-3.5-flash`
|
| 157 |
+
3. `arcee-ai/trinity-large-preview`
|
| 158 |
+
4. `google/gemma-3-27b-it`
|
| 159 |
+
5. `meta-llama/llama-3.3-70b-instruct`
|
| 160 |
+
6. `mistralai/mistral-small-3.1-24b-instruct`
|
| 161 |
+
|
| 162 |
+
---
|
| 163 |
+
|
| 164 |
+
## Daily Cron Schedule
|
| 165 |
+
|
| 166 |
+
The GitHub Actions workflow (`.github/workflows/hunter.yml`) runs at **06:00 UTC daily**:
|
| 167 |
+
|
| 168 |
+
1. Hunts all 4 regions: USA, UK, Canada, Australia
|
| 169 |
+
2. Sends email reports for each region (success or failure)
|
| 170 |
+
3. Commits the updated `seen_tickers.json` memory ledger to the repo
|
| 171 |
+
4. 60-minute timeout
|
| 172 |
+
|
| 173 |
+
To trigger manually: go to **Actions > Global Hunter Cron > Run workflow** on GitHub.
|
| 174 |
+
|
| 175 |
+
---
|
| 176 |
+
|
| 177 |
+
## Paper Portfolio
|
| 178 |
+
|
| 179 |
+
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.
|
| 180 |
+
|
| 181 |
+
---
|
| 182 |
+
|
| 183 |
+
## Key Concepts
|
| 184 |
+
|
| 185 |
+
- **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.
|
| 186 |
+
- **Margin of Safety**: `(Graham Value - Price) / Graham Value` β the bigger this %, the more undervalued.
|
| 187 |
+
- **MSPR (Monthly Share Purchase Ratio)**: Finnhub's insider sentiment metric. Positive = insiders buying, negative = insiders selling.
|
| 188 |
+
- **Zombie Filter**: Rejects tech/healthcare companies burning cash with less than 6 months of runway.
|
| 189 |
+
- **Seen Tickers Memory**: A JSON ledger that prevents re-analysing the same stock within 30 days.
|