earnings-company endpoint, pulled daily.
Thesis Alerts — count of tickers with active concerns. Combines two sources: (1) client-side threshold checks run on every page load (price above PT consensus, consensus at Hold or Sell), and (2) AI-evaluated alerts from the daily Claude Opus analysis routine (PT declining, revenue decelerating, cash runway short, filing red flags, etc.).
(PT consensus - current price) / current price × 100.
benzinga_scraper.py pulls that day's analyst ratings from Benzinga. New analysts with ≥70% Benzinga accuracy get their full history scraped by benzinga_discover.py.
Step 2 — Scoring: Every two weeks, analyst_rankings.py evaluates every analyst's track record using historical price data. A "Buy" is correct if the stock rose ≥10% within 12 months; a "Sell" is correct if it dropped ≥10%. Recent calls (last 12 months) are weighted 2× more than older ones.
Each analyst gets a composite score (0–100) from four components: buy accuracy (40% of score — how often their Buy calls are right, recency-weighted), directional accuracy (25% — all calls), portfolio ticker coverage (20% — how many of your 14 tickers they cover), and statistical confidence (15% — penalizes thin sample sizes, scales linearly to 100 rated calls).
Step 3 — Qualification: Analysts with a composite score ≥ 45 enter the qualified pool (adaptive size, 20–60 analysts). They must stay above the quality floor for 2 consecutive biweekly evaluations to reach "qualified" tier, and 5 evaluations with a buy accuracy ≥ 50% to reach "veteran." Demotion is slow — qualified analysts get a 2-evaluation watch-list buffer before dropping.
The daily collector (a scheduled GitHub Actions workflow) reads the latest vetted analyst data and writes it into daily.json. This is why you see specific analyst names, ranks, and accuracy scores rather than anonymous aggregates.
save.js. Analyst ratings and price targets are NOT re-fetched — those come from the Benzinga pipeline and only update nightly. 60-second cooldown between refreshes.
daily.yml) runs the daily collector: it reads companies.json for the ticker list, pulls quotes, earnings, and insider trades from FMP plus vetted Benzinga analyst data, builds pipeline health, and commits public/daily.json to the repository. Separate scheduled workflows refresh macro data, SEC filings, and the weekly financials. On page load the browser fetches daily.json, weekly.json, and analysis.json from the Cloudflare Pages site and renders everything. Persistent state (the SQLite databases) lives in a Cloudflare R2 bucket that the workflows sync at the start and end of each run.
earnings-company endpoint, pulled daily.
Analyst Upgrades / Downgrades — rating changes from vetted Benzinga analysts in the last 30 days. Each card shows the analyst's name, firm, rank in the composite scoring system, their historical accuracy percentage, the action taken (upgrade/downgrade/initiation), the new rating, and the price target if one was issued. Source: the nightly Benzinga scraper pipeline.
Thesis Alerts — tickers trading more than 10% above their price target consensus. This is a simple client-side calculation: (price - ptConsensus) / price. These cards flag stocks where the market has outrun analyst expectations.
companies.json and represent the investment theses behind your portfolio — the reasons you own each stock. The health grades help you monitor whether those reasons are still valid.
analysis.yml) runs the AI analysis. It reads the merged daily.json and weekly.json and analyzes every company in the portfolio. It uses Claude Opus specifically because reasoning quality matters here — this is where the system draws conclusions, not just collects data.
Daily thesis validation powered by Claude Opus. Evaluates all collected data to identify what's changed, what matters, and whether each investment thesis is intact. Not financial advice.
since date persists across runs so you can see how long a condition has been active.
Standing conditions that threaten investment theses. AI-evaluated alerts (marked AI) are generated daily by Claude Opus using cross-cutting analysis across all data sources. Auto alerts are real-time threshold checks.
Company discovery signals from SEC filings, transcripts, and institutional data are shown on the Discovery tab →
search-stock-news endpoint, requesting the 8 most recent articles per company. The calls go through the Cloudflare proxy at rhinomarket.pages.dev/api/fmp, which adds your FMP API key server-side.
Articles from all 14 tickers are combined into a single feed, deduplicated (by title + publisher to avoid the same story appearing under multiple tickers), and sorted newest-first. The feed shows 20 articles at a time with a "Load More" button to see older ones.
search-stock-news endpoint. This is a financial news aggregator that pulls from major business publications, wire services, and financial media. The data is proxied through functions/api/fmp.js on Cloudflare Pages to keep the API key server-side.
Latest news across all tracked companies. Pulls live from FMP when you open this tab.
Companies surfaced from portfolio company filings, transcripts, and institutional data. Dismiss signals you're not interested in, or watch companies to investigate further.
Companies you're watching. Investigate to pull real-time FMP data, or promote to add to your tracked portfolio on the next pipeline run.
Non-portfolio companies with the strongest buy consensus from your vetted analyst pool. Updated nightly.