agentleFS
blueskynexusblueskynexus/claude-skills/rsi-screener/SKILL.md

rsi-screener

Skill1 starsChanged 3 months agoMITView on GitHub

Builds a single-file HTML momentum board that ranks a watchlist by RSI-14 and shows where every name sits on the oscillator, powered by viaNexus CORE/STOCK_STATS_US. One batched API call at build time, no polling, no backend, no client-side math. Use whenever the user wants an RSI screen, momentum screener, overbought/oversold view, relative strength ranking, or a "which of my stocks are stretched" answer — even if they don't say RSI (e.g. "which names are oversold", "screen my watchlist for momentum", "what's overbought right now", "rank these by relative strength").

The file

We split this skill into the rules it gives an agent

9 rules. About 0 are common, 7 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈7

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read references/dataset.md before writing any fetch code.

    line 37
  2. Distinctive:

    Ask for (or extract from the conversation) the tickers.

    line 46
  3. Distinctive:

    Only exchange-listed US equities and ETFs are in this dataset.

    line 51
  4. Distinctive:

    Do not loop per symbol. Sixty symbols in one request is ~28 KB and about a second.

    line 63
  5. Very specific:

    One date value: All rows should carry the same date.

    line 73
  6. Distinctive:

    Color never carries meaning alone: Every dot's value is also its x position.

    line 158
  7. Distinctive:

    Render API values verbatim: No rounding beyond display, no interpolation, no filling a null.

    line 166
  8. Distinctive:

    Do not end by handing over a file path.

    line 180
  9. Distinctive:

    no horizontal scroll on the page body at 1200px wide.

    line 196

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

RSI Screener

Generate a single HTML file the user opens in any browser: a momentum board that ranks a watchlist by RSI-14 and plots the whole universe on one 0–100 oscillator axis.

This skill differs from live-market-dashboard in one important way: the page is a snapshot, not a poller. You make one API call at build time and embed the result. The finished page makes zero network requests, contains no token, and can therefore be shipped as a hosted artifact, emailed, or committed — none of which are safe for a polling dashboard.

The other core idea: RSI-14 is a stored field, not something the page computes. rsi14 ships on the same STOCK_STATS_US record as the 50-day and 200-day moving averages. Never pull price history and never implement Wilder's smoothing in the generated page. If you find yourself writing an RSI function, you have taken the wrong path.

Read references/dataset.md before writing any fetch code. The finished reference implementation is assets/example-screener.html — this is the layout to reproduce, not merely a source of ideas.


Step 1 — Get the watchlist

Ask for (or extract from the conversation) the tickers. If the user has no list and just wants to see the thing work, use the default universe in references/dataset.md (60 US large caps) and say that is what you used.

Only exchange-listed US equities and ETFs are in this dataset. Mutual funds (5-letter tickers ending in X, e.g. FZROX) return nothing — name them to the user and offer ETF analogs rather than dropping them silently.

Step 2 — One call, then verify

A single request with all symbols comma-separated and filter= applied:

GET /v1/data/CORE/STOCK_STATS_US/{sym1,sym2,...}?token={pk_}&filter=symbol,issuerName,date,rsi14,day50MovingAverage,day200MovingAverage

Do not loop per symbol. Sixty symbols in one request is ~28 KB and about a second; that measurement is the story the page tells, so keep it true.

Then check three things before you build:

  • Missing symbols. Any ticker absent from the response did not resolve. Report those to the user by name.
  • Null rsi14. Legitimate for names with fewer than 15 trading days of history. Keep the row, render it as "insufficient history", and never substitute a number.
  • One date value. All rows should carry the same date. If they don't, say so in the page footer rather than implying a single as-of moment.

Record the payload size and elapsed time of that one call. They go in the masthead.

Step 3 — Build the page

One HTML file, no external dependencies. Inline all CSS and JS, no CDN scripts, no webfonts, no frameworks. Sections in this order, because the board is scanned, not read:

  1. Masthead — dataset identity (viaNexus · CORE / STOCK_STATS_US), the headline, and a right-aligned provenance block: as-of date, symbol count, payload size, elapsed time.
  2. Four tiles — universe size, oversold count, neutral count, overbought count. Each tile is a button that filters the rest of the page.
  3. The oscillator — the hero. All symbols as dots on one 0–100 axis (see Step 4). This is the view that makes the point in a screenshot.
  4. The table — every symbol, sorted weakest to strongest by default, with an inline RSI bar, both moving averages, and a trend chip. Sortable columns. This doubles as the accessible view of the chart.
  5. Provenance — the exact curl that produced the page, and one unedited record. Users trust a screen they can reproduce.
  6. Footer — how RSI is calculated, what nulls mean, and the not-advice line.

Step 4 — The oscillator, exactly

The hero is a dot plot stacked upward from the baseline, not a bar chart and not a gauge. Position on the x-axis carries the RSI value; the stack height where dots collide reveals the distribution for free.

Bands are fixed at the conventional thresholds. Do not invent your own:

BandRangeMeaning
OversoldRSI < 30selling pressure exhausted
Neutral30 – 70no momentum signal
OverboughtRSI > 70extended after a run

Shade 0–30 and 70–100, draw hairline rules at 30, 50 and 70, and label the 30 and 70 rules in the plot.

Layout algorithm — lanes, so dots never overlap:

const dot = 11, gapY = 2, minGapX = dot + 2;
const sorted = [...DATA].sort((a, b) => a.rsi14 - b.rsi14);
const lanes = [];                    // lanes[i] = rightmost x used in that lane
sorted.forEach(d => {
  const x = (d.rsi14 / 100) * plotWidth;
  let lane = 0;
  while (lanes[lane] != null && x - lanes[lane] < minGapX) lane++;
  lanes[lane] = x;
  d._x = x; d._lane = lane;          // bottom = 4 + lane * (dot + gapY)
});

Direct-label only the two extremes (lowest and highest RSI) with value and ticker. Everything else gets a hover tooltip carrying symbol, company, RSI, and both moving averages. Never print a number on every dot.

Step 5 — Color, fixed

These hexes are validated (lightness band, chroma floor, colorblind separation, normal-vision separation, and contrast against their own surface, in both modes). Use them as given. If the user asks for their own brand colors, re-validate rather than swapping by eye.

RoleLightDark
Oversold pole#0d7fc4#2b96d6
Overbought pole#a35f00#c07d18
Neutral midpoint#6f7885#7d8794
Page / surface#eceff3 / #f7f9fb#080d10 / #0c1317
Primary / secondary ink#0e1620 / #4b5a6c#f2f6f8 / #a8b4c0
Chrome accent (never on a data mark)#0b7f70#12b39c

The scale is diverging: a cool pole, a warm pole, and a neutral gray at the middle. Rules that follow from that:

  • Never red/green. It reads as good/bad, and oversold is not "bad".
  • The two pole hues encode the RSI band and nothing else. Trend chips, status, and links use ink and glyphs (▲ / ▼), never the pole colors, or blue starts meaning two different things on one page.
  • Color never carries meaning alone. Every dot's value is also its x position; every row prints its number; every band is named in the legend.
  • Define these as CSS custom properties and redefine them under both @media (prefers-color-scheme: dark) and :root[data-theme="dark"] so a viewer's explicit toggle wins over the OS setting.

Step 6 — Integrity rules

  • Render API values verbatim. No rounding beyond display, no interpolation, no filling a null.
  • RSI is one reading on one day. The page states this. It never says buy, sell, cheap, expensive, or "due for a bounce".
  • No signals. Crossing 30 is not a recommendation, and neither is a golden cross. Report the level and the trend relationship; stop there.
  • Same-record claim must stay true. The page's whole argument is that momentum and trend arrive together. If you end up making a second call for anything on the board, either drop that element or correct the masthead.
  • No token in the file. The page makes no requests, so it needs none. Grep the output for pk_ and sk_ before delivering.

Step 7 — Verify, then launch it

Do not end by handing over a file path. Open it:

  1. Browser pane / preview tool (Claude Code desktop, Cowork). Note that preview panes may render files outside the project folder as static snapshots with scripts disabled — if the tiles and dots come up empty, that is why; write the file inside the project folder and reopen.
  2. Desktop shell: open (macOS), xdg-open (Linux), start (Windows).
  3. No visible browser: present the file for download, and say which rung you used.

Then confirm, in the rendered page:

  • tile counts sum to the symbol count;
  • the dot count equals the number of symbols with a non-null rsi14;
  • the lowest and highest RSI names are the ones direct-labeled;
  • both themes render (toggle the OS/preview color scheme, don't assume);
  • no horizontal scroll on the page body at 1200px wide.

For a LinkedIn or deck screenshot, a 1200×660 viewport in dark mode crops the masthead, tiles, and oscillator into one image.

Unlike live-market-dashboard, this page is safe to deliver as a hosted artifact — it is a static snapshot with no outbound calls and no credential.


Example triggers

  • "Which of my holdings are overbought? AAPL MSFT NVDA TSLA"
  • "Build me an RSI screen for the S&P mega caps"
  • "Show me what's oversold right now"
  • "Rank these tickers by relative strength"
  • "Momentum board for my watchlist"

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.