Plain-language guide to the research pipeline, scoring logic, and what every pick means
Three skills run in sequence every hour across 8 phases. Think of it as a three-stage funnel: cast wide, score everything, deliver the best.
| Phase | Skill / Section | What it does | Frequency |
|---|---|---|---|
| 1 β INIT | STEP 0A | Load watchlist.json + etoro-instruments.json from GitHub; fetch eToro live prices via Chrome MCP | Every run |
| 2 β GEO | STEP 0A-GEO | 3 searches β Geopolitical Briefing above Macro Snapshot | Every run |
| 3 β DISCOVER | asx-global-discovery | Homepage scrapes + keyword searches β candidate pool | Every run |
| 4 β PRICE DATA | STEP 0, 0B, 0C | Live prices, AUD/USD, BTC/VIX risk signal, RSI/SMA | Every run |
| 5 β ENRICH | STEP 0B-ii, 0B-iii, 0F | Fundamentals, advanced technicals, global news β daily cache | Once/day (cached) |
| 5 β FEEDS | STEP 0D (tiered T1/T2/T3) | T1 always Β· T2 if pool thin Β· T3 if pool very thin | Every run |
| 6 β SCORE | STEP 0E + 0I | Score all candidates β ranked ASX + Global pools | Every run |
| 7 β PICK + REPORT | STEP 1, 2, 3 | Select 3 ASX + 3 Global picks, write report | Every run |
| 8 β PUBLISH | publish-report skill | email-builder.py β Gmail β GitHub Pages β watchlist-status.json | Every run |
Before picking anything, the system casts a wide net across 30+ sources. It never searches for specific companies β it searches for signals and lets candidates emerge. This prevents confirmation bias.
Every candidate gets a Base Score (1β5) based on catalyst strength, then Bonuses and Penalties adjust it. Minimum score of 3.5 required to become a pick.
Base Score β Catalyst Strength
β Bonuses (up to +2.0 total)
β Penalties
How Entry / Target / Stop are set
| Field | How it's calculated | Why it matters |
|---|---|---|
| Entry Zone | Current price Β±1β2% (limit order range) | Set a limit order β never chase with a market order |
| Target | Analyst consensus price target or next resistance | Where to sell when right |
| Stop Loss | Below key support (recent swing low or SMA50) | Where to exit when wrong β non-negotiable |
| R:R Ratio | (Target β Entry) Γ· (Entry β Stop) | Must be β₯1.5 to qualify as a pick. 2.0 = risk $1 to make $2. |
Before individual stocks are scored, the system reads the macro environment. Commodity prices, sector ETFs, and geopolitical signals all feed into score bonuses and penalties.
/tmp/daily-cache-YYYY-MM-DD.json. All subsequent hourly runs read from cache β no wasted quota.
Pick badge meanings
The same locked template is filled in every single run β the layout never changes.
| Rule | Trigger | Action |
|---|---|---|
| BTC Risk-Off | BTC drops >3% in 24h | Reduce all position sizes 25β30%, tighten stops, avoid crypto-correlated names |
| VIX Spike | VIX >25 | Reduce all conviction scores by 0.5 β fewer picks qualify |
| Anti-Chase | Stock already up >15% today | β1.0 score penalty β almost always excluded |
| Stale Catalyst | Catalyst >7 days old | Score reduced β old news doesn't move markets |
| Target Achieved | Stock already at analyst PT | Marked stale β upside exhausted, not selected |
| Diversity Rule | Same ticker in 2+ slots | Runner-up promoted β forces diversification |
| Source Quality | <10 live sources in a run | Picks labelled with β οΈ β treat entry zones as wider |
Source health indicator (in the log)
15+ β = high quality run. Below 10 β = more fallback data β use wider entry zones.
The system uses four modular skills. Each handles a distinct phase of the pipeline and can be run or re-run independently.
etoro-instruments.json β instrument IDs only (no prices); read by hourly skill to batch-fetch live ratesetoro-watchlist.json β full positions with prices; displayed on GitHub PagesThe system uses three separate watchlist layers. They serve different purposes and are fetched in different ways β none of them automatically override the signal-first discovery process.
The eToro integration runs in two separate stages β a daily ID sync and a live price fetch every hourly run.
etoro-instruments.json (IDs only)etoro-watchlist.json (+ prices)x-api-key, x-user-key). Python/curl can't send them through the sandbox proxy. Chrome's JS fetch() sends them natively β no proxy involved.
etoro-instruments.json from GitHubETORO_LIVE_PRICES to email-builder.pyetoro-watchlist-sync-skill.md.
Summary
| Layer | Where stored | Fetched by Claude? | Influences picks? | How to update |
|---|---|---|---|---|
| 1 β Fixed list | watchlist.json (GitHub) | β Every run | β Competes equally | Edit watchlist.json in GitHub repo |
| 2 β eToro sync | etoro-instruments.json + etoro-watchlist.json (GitHub) | β IDs loaded Phase 1; live prices fetched hourly | β If catalyst exists + shown in External Watchlists | Automatic daily scheduled task (or ask Claude to run sync) |
| 3 β Browser chips | Browser localStorage | β Not read | β No | Add/remove on archive page |