File size: 8,611 Bytes
4e5d4fb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# 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](https://langchain-ai.github.io/langgraph/):

```
SCOUT  ──>  GATEKEEPER  ──>  ANALYST  ──>  EMAIL
```

### Step 1: Scout (Discovery)

The Scout uses a **two-pronged approach** to find candidates:

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.
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.

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:

1. **Quantitative Base** β€” Price vs calculated intrinsic value, margin of safety math
2. **Lynch Pitch** β€” What insiders are doing + the one catalyst that could move the stock
3. **Munger Invert** β€” How you could lose money, what metric proves the bear case
4. **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:

1. `nvidia/nemotron-3-nano-30b-a3b` (primary β€” fast, reliable)
2. `stepfun/step-3.5-flash`
3. `arcee-ai/trinity-large-preview`
4. `google/gemma-3-27b-it`
5. `meta-llama/llama-3.3-70b-instruct`
6. `mistralai/mistral-small-3.1-24b-instruct`

---

## Daily Cron Schedule

The GitHub Actions workflow (`.github/workflows/hunter.yml`) runs at **06:00 UTC daily**:

1. Hunts all 4 regions: USA, UK, Canada, Australia
2. Sends email reports for each region (success or failure)
3. Commits the updated `seen_tickers.json` memory ledger to the repo
4. 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.