How this report is built
Reading each tab
- Strategies — one table per A1/A2/B0/B1/B2. Click a header to sort, type in the filter box to narrow, and click any row to reveal two foldables for that stock: a 1-year track (open it for the daily price/MA table) and Fundamentals (sector-relative verdicts). Fundamentals are no longer a separate tab.
- Sector rotation — score heatmap (A/B/C/D + trend), Continuity analysis (autocorrelation/persistence), and Rotation events (⬆ breakouts / ⬇ breakdowns across 50).
- ETF — BUY-signal ETFs first, then daily & weekly momentum treemaps (tile area ∝ |momentum|, banded colour: deep→light by strength).
The 5 strategies
| What it selects | Family | |
|---|---|---|
| A1 | BUY back at support — price returned to a level that was oversold (RSI<30) on an earlier day; the BUY-day RSI can be anything | value |
| A2 | buy the correction — pullback to a fan WMA (or deep flush held by the weekly) | value |
| B0 | reclaim breakout — price back above all WMAs (early reversal) | trend |
| B1 | WMA-fan breakout — W20<W50<W100<W200 stacked, recent | trend |
| B2 | clean uptrend — real uptrend, few WMA violations | trend |
★ week-confirmed: the same signal also fires on the weekly chart (the weekly log is re-classified with the identical rules) — higher conviction.
Fundamentals — sector-relative
Each metric (valuation, quality, health, growth, income) is compared to the median of that stock's sector in your universe. GOOD beats peers · NEUTRAL in line · POOR lags. Source: yfinance + data/sector_fundamentals.json.
| Flag | Severity | Meaning |
|---|---|---|
| value-trap | red | cheap vs sector BUT earnings shrinking + weak ROE — possible trap |
| dividend-risk | red | high yield BUT payout uncovered / earnings falling |
| over-leveraged | red | high debt vs sector + current ratio < 1 |
| quality-compounder | green | above-sector ROE & margins with positive growth |
| turnaround | amber | trailing earnings down but forward P/E ≪ trailing + analyst upside |
| expensive-growth | amber | rich valuation backed by strong growth |
Ranking & selection
Pure, fixed-band function of the artifacts. Weights + per-strategy quality are auto-calibrated from the strategy backtest (config/ranking.yaml is generated by scripts/analysis/calibrate_weights.py — see the calibration doc in docs/):
score = 6.0·Σ quality(strategy) + 0.0·sector_norm·value_share + 2.0·(GOOD−POOR clamped) + 2.0·(upside clamped, ≥3 analysts) + 1.5·(week-confirmed)
− penalties: value-trap 3.0, dividend-risk 2.0, over-leveraged 2.0, expensive-growth 0.5strat quality (from long-horizon excess-vs-index): A1 0.0 · A2 0.319 · B0 0.255 · B1 ? · B2 1.0. B2 (only durable alpha) anchors at 1.0; weakest floors at 0.2. The sector term is soft and applies only in proportion to a candidate's value-strategy (A1/A2/B0) share — never to the trend strategies (the backtest shows a sector gate hurts B2). analyst_upside is clamped and analyst-count-gated so a single stale target can't float a thin name.
Top by score → shortlist (8) → sentiment → final top-5. Sentiment can demote a name (e.g. a guidance cut), which is why the shortlist is wider than 5.
Sentiment score
Weighted: analyst 30% · 2-week price 25% · news 25% · community 20% → 🟢 ≥0.5 bullish · ⚪ −0.5…0.5 neutral · 🔴 ≤−0.5 bearish. WebSearch-based.
Colour legend
+2.1%/-3.4% price-vs-MA · 28 RSI oversold · 74 overbought · GOODNEUTRALPOOR verdicts · A1B1 strategy family · ★ wk = weekly-confirmed.