πŸ“– How It Works β€” Stock Watch Guide

Plain-language guide to the research pipeline, scoring logic, and what every pick means

← Back to Reports
πŸ—ΊοΈ

The Big Picture β€” What Happens Every Hour

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.

Skill 1
πŸ” Discovery
Find candidates
β–Ά
Skill 2
πŸ“Š Research & Score
Rank candidates
β–Ά
Skill 3
πŸ“¬ Publish Report
Email + GitHub + Log
PhaseSkill / SectionWhat it doesFrequency
1 β€” INITSTEP 0ALoad watchlist.json + etoro-instruments.json from GitHub; fetch eToro live prices via Chrome MCPEvery run
2 β€” GEOSTEP 0A-GEO3 searches β†’ Geopolitical Briefing above Macro SnapshotEvery run
3 β€” DISCOVERasx-global-discoveryHomepage scrapes + keyword searches β†’ candidate poolEvery run
4 β€” PRICE DATASTEP 0, 0B, 0CLive prices, AUD/USD, BTC/VIX risk signal, RSI/SMAEvery run
5 β€” ENRICHSTEP 0B-ii, 0B-iii, 0FFundamentals, advanced technicals, global news β€” daily cacheOnce/day (cached)
5 β€” FEEDSSTEP 0D (tiered T1/T2/T3)T1 always Β· T2 if pool thin Β· T3 if pool very thinEvery run
6 β€” SCORESTEP 0E + 0IScore all candidates β†’ ranked ASX + Global poolsEvery run
7 β€” PICK + REPORTSTEP 1, 2, 3Select 3 ASX + 3 Global picks, write reportEvery run
8 β€” PUBLISHpublish-report skillemail-builder.py β†’ Gmail β†’ GitHub Pages β†’ watchlist-status.jsonEvery run
30+ sources scanned
All markets, all signals
β–Ό
~20–30 candidates found
Signal-triggered only
β–Ό
Scored & ranked
0–7+ weighted model
β–Ό
6 picks selected
3 ASX Β· 3 Global
πŸ”

Skill 1 β€” Discovery: Finding Candidates

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.

πŸ“° ASX News
StockheadSmall CapsMotley Fool AUDiscovery Alert
🩳 Short Interest
shorted.com.aufintel.ioCBOE AU (daily)
⚑ Breakout Scanners
SwingTradeBot ASXMarketIndex breakoutsRSI oversold scans
πŸ“Š Analyst Upgrades
BenzingaMarketBeatTipRanksGoldman / MS / UBS
πŸ—£οΈ Community
HotCopper (ASX forum)Reddit r/ASXbetsReddit r/stocks
🌏 US / Global
Yahoo Finance gainersBenzinga upgradesfinviz.com news
πŸ”’ Pro Signals (daily)
Unusual Whales (options)OpenInsider (cluster buys)Capitol Trades (Congress)
πŸ“‘ RSS Feeds
Stockhead feedMotley Fool AU feedReuters Business
Why no company names in search queries? Searching for a stock you already know only confirms what you already believe. Signal-first discovery finds what you don't know yet β€” the stocks about to move before you heard about them.
Tiered news feeds (T1 / T2 / T3): The 32 news feeds now run in priority order. T1 (Stockhead, SDU, Discovery Alert, ASX Announcements) always runs. T2 runs only if the candidate pool is thin (<10 ASX or <4 Global). T3 runs only if the pool is very thin. This skips unnecessary fetches on busy market days.
πŸ“Š

Skill 2 β€” The Scoring Model (0 to 7+)

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

5
Major catalyst TODAY β€” stock hasn't moved yet
Best entry: ASX announcement just filed, deal signed this morning, upgrade just published. Market hasn't priced it in.
4
Strong catalyst β€” upgrade, deal, or earnings beat
Fresh analyst upgrade, new contract announced, earnings above expectations. Confirmed, not speculative.
3
Volume-backed move with supporting news
Unusual volume spike AND a reason for it β€” sector news, macro tailwind, small ANN. Both signals together.
2
News only β€” no volume confirmation
Interesting catalyst but nobody is buying yet. Wait for volume to confirm before entering.
1
Volume only β€” no catalyst found
Something is happening but we can't explain it. Possible pre-announcement leak. Flag as ❓ INVESTIGATE.

βœ… Bonuses (up to +2.0 total)

+1.0
ASX announcement today and price not yet moved 5%+
+1.0
Analyst upgrade or initiation published today
+0.5
Earnings within 5 days with bullish prior history
+0.5
Mentioned in 3+ independent sources in 24h
+0.5
Tier-1 bank upgrade (Goldman, MS, UBS)
+0.5
Unusual options sweep (bullish β€” big bets placed)
+0.5
Director / insider confirmed buying on market
+0.5
Above both SMA50 and SMA200 (healthy uptrend)
+0.5
5-day RSI rising + price above SMA50
+0.5
Sector commodity rising (iron ore, copper, gold…)

❌ Penalties

βˆ’1.0
Already up >15% today β€” chasing is dangerous
βˆ’1.0
Analyst downgrade or profit warning issued
βˆ’0.5
RSI >70 AND still rising β€” overbought
βˆ’0.5
RSI falling + price below SMA50 β€” deteriorating
βˆ’0.5
Supertrend signal = DOWN
βˆ’0.5
Analyst target already achieved β€” thesis is stale
βˆ’0.5
VIX >25 β€” broad market fear, reduce conviction
πŸ“ˆ

Technical Indicators β€” Plain Language

RSI (Relative Strength Index)
Measures momentum on a 0–100 scale. Think of it as a speedometer β€” how fast is the stock moving?
40–65 rising βœ“ >70 overbought <30 falling
SMA 50 (50-day Average)
The average share price over the past 50 days. Being above it means the medium-term trend is up.
Price above βœ“ Price below βœ—
SMA 200 (200-day Average)
The long-term average. Above = confirmed uptrend. Below = bear territory. The "golden cross" (SMA50 crossing SMA200 upward) is a major bull signal.
Above = uptrend βœ“ Below = bear zone
Supertrend
A single UP or DOWN signal based on price + volatility bands. Simpler than RSI β€” it just tells you the trend direction.
UP + ADX>25 βœ“ DOWN = avoid
ADX (Average Directional Index)
Measures trend strength, not direction. A weak trend in either direction means choppy trading β€” hard to profit from.
>25 strong trend <20 = no trend
Volume Ratio
Today's volume vs the 20-day average. 3Γ— means 3 times the normal amount of shares are changing hands β€” something is happening.
>3Γ— unusual βœ“ <0.5Γ— quiet

How Entry / Target / Stop are set

FieldHow it's calculatedWhy it matters
Entry ZoneCurrent price Β±1–2% (limit order range)Set a limit order β€” never chase with a market order
TargetAnalyst consensus price target or next resistanceWhere to sell when right
Stop LossBelow 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.
🌍

Macro Layer β€” What Shapes Every Run

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.

β›” BTC Risk-Off Signal

  • BTC drops >3% in 24h β†’
  • RISK-OFF banner fires
  • Reduce all positions 25–30%
  • Tighten stops to entry
  • Avoid crypto-correlated names
  • Prefer gold, healthcare, defensives

🏭 Commodity Basket (checked every run)

  • Iron ore >$120/t β†’ BHP, RIO, FMG ↑
  • Copper >$9,500/t β†’ copper miners ↑
  • Gold >$3,500/oz β†’ EVN, NST, NCM ↑
  • Oil >$75/bbl β†’ WDS, STO ↑
  • Uranium >$85/lb β†’ PDN, BOE, LOT ↑

πŸ“‰ ASX Sector ETFs

  • XMJ β€” Materials (iron ore, copper)
  • XEJ β€” Energy (oil, LNG, coal)
  • XFJ β€” Financials (rate sensitive)
  • XHJ β€” Healthcare (approvals)
  • XTEK β€” Technology (AI/cloud)
Rising sector β†’ +0.3 bonus to all stocks in it. Falling sector β†’ βˆ’0.3 penalty.

🌐 Geopolitical & Policy

  • China tension ↑ β†’ AUD, iron ore risk
  • RBA rate cut β†’ REITs, financials ↑
  • US Fed hawkish β†’ AUD falls, risk-off
  • AUKUS deal β†’ EOS, MEI, DRO ↑
  • Trade tariffs β†’ supply chain exposure
⚑ Daily API cache: Alpha Vantage (25 calls/day), Mediastack (100 calls/month), and Twelve Data (800 credits/month) are called once per day only. The first run writes results to /tmp/daily-cache-YYYY-MM-DD.json. All subsequent hourly runs read from cache β€” no wasted quota.
🎯

The Three Pick Timeframes

⚑
DAY Pick
Same session or next open
Fast-moving catalyst: short squeeze, gap-and-go, pre-market announcement. Set a tight stop. Exit by end of session if not at target.
πŸ“…
WEEK Pick
1–5 trading days
Analyst upgrade, upcoming earnings, deal announced but not fully priced yet. Hold through the week and re-assess Friday.
πŸ“ˆ
LONG Pick
Weeks to months
Structural thesis: sector rotation, undervalued vs analyst consensus, AI/commodity megatrend. Patient entry, wider stop, hold through noise.

Pick badge meanings

πŸ†• NEW First time this ticker appears as a pick
HOLD Was a pick last run β€” thesis still intact
⚠️ Runner-up Promoted due to diversity rule β€” lower conviction
β›” RISK-OFF BTC triggered β€” reduce size 25–30%
PRE-MOVE Catalyst today, market hasn't priced it yet β€” best entry
SHORT-SQUEEZE High short interest + catalyst = potential sharp move
FMP+Vol Confirmed by FMP screener AND volume leaders β€” double signal
The Diversity Rule: The same ticker can never appear more than once across the 3 ASX or 3 Global slots. If the top scorer would fill all three slots, the runner-up is promoted and labelled accordingly. Concentration in a single name kills returns.
πŸ“¬

Reading the Email Report

The same locked template is filled in every single run β€” the layout never changes.

⚠️

Risk Management β€” Built In

RuleTriggerAction
BTC Risk-OffBTC drops >3% in 24hReduce all position sizes 25–30%, tighten stops, avoid crypto-correlated names
VIX SpikeVIX >25Reduce all conviction scores by 0.5 β€” fewer picks qualify
Anti-ChaseStock already up >15% todayβˆ’1.0 score penalty β€” almost always excluded
Stale CatalystCatalyst >7 days oldScore reduced β€” old news doesn't move markets
Target AchievedStock already at analyst PTMarked stale β€” upside exhausted, not selected
Diversity RuleSame ticker in 2+ slotsRunner-up promoted β€” forces diversification
Source Quality<10 live sources in a runPicks labelled with ⚠️ β€” treat entry zones as wider

Source health indicator (in the log)

  βœ… = Live data fetched this run
  ⚠️ = Fallback used (cached or web search)
  ❌ = Source unavailable β€” not used this run

15+ βœ… = high quality run. Below 10 βœ… = more fallback data β€” use wider entry zones.

πŸ”§

Under the Hood β€” Skill Architecture

The system uses four modular skills. Each handles a distinct phase of the pipeline and can be run or re-run independently.

πŸ” asx-global-discovery
Phase 3 β€” Discover: 15 homepage scrapes + 35 keyword searches β†’ candidate pool. Always runs first. Outputs ranked table + sector heat map that feeds directly into scoring. ~245 lines.
πŸ“Š hourly-global-stock-picks
Phases 2, 4, 5, 6, 7: Geopolitical briefing β†’ price data (EODHD + Finnhub + smallcaps) β†’ enrichment (AV/Mediastack/Twelve Data β€” daily cache) β†’ tiered news feeds β†’ scoring β†’ pick selection β†’ report writing. ~1,735 lines Β· report structure in report-template.md.
πŸ“¬ publish-report
Phase 8 β€” Publish: Reads /tmp/email-data.json β†’ email-builder.py fills email-template.html β†’ Gmail draft β†’ publish-report.py pushes HTML to GitHub Pages β†’ writes watchlist-status.json β†’ SMS (paused). Can be re-run independently to retry a failed send. ~148 lines.
πŸ‘οΈ watchlist-monitor
Anytime β€” Quick check: Fetches live prices, RSI, SMA position, volume, and last-researched tier for every ticker in watchlist.json + etoro-watchlist.json. No pick generation. Runs in under 3 minutes. Use when you say "how is my watchlist doing?" ~178 lines.
πŸ“² etoro-watchlist-sync-skill β€” once per day, scheduled
Scheduled Claude skill β€” runs automatically once per day. Uses Chrome MCP JS fetch to bypass the sandbox HTTPS proxy and call the eToro API with auth headers natively.

Writes two files to GitHub:
  • etoro-instruments.json β€” instrument IDs only (no prices); read by hourly skill to batch-fetch live rates
  • etoro-watchlist.json β€” full positions with prices; displayed on GitHub Pages
Does not modify SKILL.md or any skill file β€” ever.
Supporting files:  email-template.html (locked layout) Β· report-template.md (report structure, on GitHub) Β· email-builder.py (fills template from JSON) Β· publish-report.py (pushes to GitHub) Β· etoro-watchlist-sync-skill.md (daily scheduled skill) Β· watchlist.json (monitoring tickers, GitHub) Β· etoro-instruments.json (eToro IDs β€” no prices) Β· etoro-watchlist.json (eToro positions + prices) Β· watchlist-status.json (per-ticker tier/score, written each run)
Why email-builder.py? Every run that writes its own HTML produces a different layout β€” breaking formatting for recipients. One locked template, substituted each run via JSON data. The structure is physically impossible to drift between runs.
πŸ“‹

Watchlists β€” Three Layers Explained

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

1️⃣
Fixed Monitoring List β€” checked every run
watchlist.json on GitHub Β· EODHD + Finnhub + smallcaps.com.au

A curated list of tickers stored in watchlist.json in the Stock-Soup GitHub repo β€” no hardcoded tickers in the skill file. Every run, the system fetches live prices, RSI/SMA technicals, and recent news for each. They enter the scoring pool on equal footing with newly discovered candidates β€” no automatic pick priority. The watchlist is loaded fresh each run so adding/removing tickers takes effect immediately without editing the skill.

VTMPDNIELTLXEOSNTUDYLDROA2MSGHWTCPLTR
What's fetched each run
βœ… Live price via EODHD batch API
βœ… RSI + SMA50/200 via Yahoo Finance chart API
βœ… Recent news via EODHD news API
βœ… Smallcaps.com.au page (RSI, volume, narrative)
βœ… SimplyWallSt discount % (daily)
How they become picks
They compete on score β€” same 0–7+ model as every other candidate.

A watchlist stock with no catalyst scores ~2/5 and won't be picked.
A watchlist stock with a fresh upgrade scores 4.5+ and wins a slot.
To add a ticker to the fixed list: edit watchlist.json in the Stock-Soup GitHub repo. The next hourly run will pick it up automatically β€” no skill file changes needed.
2️⃣
eToro Integration β€” daily sync + live hourly prices
etoro-instruments.json + etoro-watchlist.json on GitHub Β· automatic scheduled sync

The eToro integration runs in two separate stages β€” a daily ID sync and a live price fetch every hourly run.

⏱ Stage 1 β€” Daily Sync (scheduled task)
What it does
1. Calls eToro API β†’ fetch all watchlists
2. Compare vs current JSON β†’ log changes
3. Write etoro-instruments.json (IDs only)
4. Write etoro-watchlist.json (+ prices)
5. Push both files to GitHub
Why two files?
etoro-instruments.json has IDs only β€” no prices. The hourly skill reads this to know which instruments to fetch.

etoro-watchlist.json has full data + prices β€” shown on GitHub Pages watchlist view.
Chrome MCP required β€” here's why: eToro's API requires custom auth headers (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.
πŸ”„ Stage 2 β€” Live Prices Every Hourly Run
1. Read etoro-instruments.json from GitHub
2. Batch IDs (20 per call β€” eToro API limit)
3. Fetch live rates via Chrome MCP JS fetch
4. Pass as ETORO_LIVE_PRICES to email-builder.py
5. Auto-injected into External Watchlists section
In the report
Appears as EXTERNAL WATCHLISTS section (below Watchlist Notables). Shows all 62 instruments grouped by watchlist, with live price column. Read-only β€” not editable in reports. Prices show "β€”" if eToro API is unreachable.
To update after adding/removing eToro positions: the daily scheduled sync handles this automatically. If you need an immediate update, ask Claude to "run the eToro watchlist sync" β€” it will invoke etoro-watchlist-sync-skill.md.
3️⃣
Browser Watchlist β€” personal reminder layer
Saved in browser localStorage Β· visible on the archive page Β· not read by Claude

The chip UI on the archive page lets you save tickers locally in your browser. Chips are colour-coded by the tier assigned in the last hourly run (watchlist-status.json written by publish-report.py). These are stored in localStorage β€” they persist across refreshes but are not read by Claude.

What it does
βœ… Visual reminder of tickers you're watching
βœ… Survives browser refresh and app restart
βœ… Colour-coded by exchange (ASX / US / Global)
βœ… Add / remove instantly, no login needed
What it doesn't do
❌ Not sent to Claude automatically
❌ Not fetched for prices or news
❌ Not synced across devices or browsers
❌ Won't influence pick selection
To get Claude to actually research a ticker, use the Request Ticker for Research Queue form β€” that creates a GitHub issue and gets the ticker added to the Layer 1 fixed list in SKILL.md.

Summary

LayerWhere storedFetched by Claude?Influences picks?How to update
1 β€” Fixed listwatchlist.json (GitHub)βœ… Every runβœ… Competes equallyEdit watchlist.json in GitHub repo
2 β€” eToro syncetoro-instruments.json + etoro-watchlist.json (GitHub)βœ… IDs loaded Phase 1; live prices fetched hourlyβœ… If catalyst exists + shown in External WatchlistsAutomatic daily scheduled task (or ask Claude to run sync)
3 β€” Browser chipsBrowser localStorage❌ Not read❌ NoAdd/remove on archive page
πŸ“š

Glossary

ASX
Australian Securities Exchange β€” where Australian shares trade (opens 10am AEST Mon–Fri)
NYSE / NASDAQ
US stock exchanges β€” NYSE is traditional blue-chips, NASDAQ is tech-heavy
RSI
Relative Strength Index β€” 0–100 momentum gauge. Think of it as a speedometer. 70+ = too fast (overbought), 30βˆ’ = too slow (oversold)
SMA 50 / 200
Simple Moving Average β€” average price over 50 or 200 days. Being above your SMA50 is like running faster than your usual pace β€” positive momentum
Short interest
% of shares borrowed and sold by people betting the price will fall. High short interest = many bears. When they're wrong, they all rush to buy at once β€” that's a squeeze
Short squeeze
When a stock unexpectedly rises β€” short sellers must buy to close their positions, which pushes the price even higher, fast
Catalyst
The specific event that causes a stock to move: earnings beat, new contract, analyst upgrade, FDA approval, regulatory clearance, insider buy
PRE-MOVE
A catalyst just fired but the stock price hasn't reacted yet. Best entry window β€” market is slow to price in new information
R:R (Risk:Reward)
How much you could make vs how much you risk. 2.0 = risk $1 to potentially make $2. System requires minimum 1.5 to qualify as a pick
Entry zone
The price range to buy at. Always set as a limit order β€” never chase with a market order above the zone
Stop loss
The price to exit if wrong. Non-negotiable β€” set it at the moment you enter the trade
Day pick ⚑
Trade designed to be entered and exited within the same ASX or US session
Week pick πŸ“…
Hold for 1–5 trading days β€” re-assess at end of week
Long pick πŸ“ˆ
Structural thesis β€” hold for weeks to months through normal volatility
RISK-OFF β›”
Market mood where investors sell risky assets and move to cash/gold. BTC dropping 3%+ is the system's trigger
VIX
The "fear index" β€” measures expected market volatility. Above 25 = fear. Below 15 = calm
AUD/USD
Exchange rate: how many US dollars one Australian dollar buys. Higher AUD = good for importing; lower = good for ASX export stocks
EODHD
End of Day Historical Data β€” the primary API for live ASX prices and AUD/USD each run
Finnhub
API for US/global stock quotes, analyst consensus ratings, and BTC price (risk-off signal)
FMP
Financial Modeling Prep β€” provides analyst grades, stock screener, and the economic calendar (run mandatory every session)
Supertrend
A technical indicator that gives a simple UP or DOWN direction signal based on price and volatility bands. Combined with ADX for trend strength
ADX
Average Directional Index β€” measures trend strength (not direction). Above 25 = strong trend. Below 20 = choppy market, hard to trade
etoro-instruments.json
The single source of truth for your eToro instrument IDs β€” written by the daily sync task, read by the hourly skill to batch-fetch live prices. No prices stored here (they're fetched fresh each run)
etoro-watchlist.json
Your full eToro positions including last-synced prices β€” pushed to GitHub and displayed on the GitHub Pages watchlist view
External Watchlists
Section in every report showing all your eToro positions with live prices, grouped by watchlist. Read-only β€” populated automatically by email-builder.py from etoro-instruments.json + live eToro rates
Win rate
Tracked by win-rate.py β€” the % of past picks that hit their price target vs were stopped out. Visible in Section 15B of every report