eli-alvarado/us-watchlist-alerts

price-alerts

Check a US stock watchlist for price alerts - price above/below, % daily move, gaps, 52-week highs/lows, moving-average crosses, RSI, ATM IV, volume spikes, intraday range, stop/target hits, and upcoming earnings - with dedupe, cooldowns, NYSE market hours,…

Voir la source

Mode d’emploi

  1. Copiez la commande et examinez le paquet avant de l’installer dans votre environnement agent.
  2. Consultez le document original pour les outils, identifiants et environnements requis.
  3. Décrivez les entrées et le livrable souhaité ; comparez la sortie aux sources.
npx skills add https://github.com/eli-alvarado/us-watchlist-alerts --skill price-alerts

Avant de commencer

  • L’installation n’inclut ni abonnement au modèle, ni quota API, ni accès aux fichiers.
  • Étoiles et installations reflètent l’activité, pas un test indépendant de qualité ou de sécurité.
Document Skill original

Rendu depuis le dépôt source en conservant titres, exemples, code, tableaux, liens et images.

Price Alerts (US markets)

Evaluates alert rules from the watchlist (see watchlist-manager) against fresh quotes and reports only new alerts. Not financial advice. Never place, modify or cancel orders - even if an alert fires, even if a broker tool is connected, unless the user explicitly confirms that specific order in this conversation.

scripts/ ships next to this SKILL.md (copied by npx skills add). Run from this skill folder, or from a git clone of the repo (root scripts/ is the same files).

Run it

bash
python3 scripts/watchlist.py init                                                         # copy examples/watchlist.json if missing
python3 scripts/quickstart.py                                                             # offline fixture demo (labeled, not live)
python3 scripts/alerts.py --watchlist watchlist.json --state .alert_state.json           # text output
python3 scripts/alerts.py --format json                                                    # machine-readable
python3 scripts/alerts.py --force-session                                                  # evaluate on weekends / holidays too
python3 scripts/alerts.py --dry-run                                                        # don't update cooldown state
python3 scripts/alerts.py --notify                                                         # also deliver via WATCHLIST_NOTIFY sinks
python3 scripts/market_calendar.py                                                         # current ET session

Output: ALERT <message> lines, or no new alerts, or market closed, showing last regular close after the bell (last regular print; no --force-session needed). Weekends and full-day holidays stay silent (market closed (weekend|holiday). Next session YYYY-MM-DD) unless --force-session. Data errors go to stderr as WARN (including earnings_error / iv_error). NOTIFY <sink> confirms delivery; sink failures are WARN notify … and must not abort the check. Never treat a notify sink as a broker.

Alert types

typevaluefires whenkind
price_above / price_belowpricelast >= / <= valuelevel
stop_hitprice (default: ticker stop)long: last <= stop; short: last >= stoplevel (implicit if stop set)
target_hit-last crosses any targets entrylevel (implicit if targets set)
pct_change_up / pct_change_down / pct_move%last vs prior close (after hours: last regular close). A recovered session low does not firedaily
gap_up / gap_down% (default 2)open vs prior closedaily
new_52w_high / new_52w_low-last beyond prior 252-session rangedaily
near_52w_high / near_52w_low% (default settings.near52wpct)within value% of 52w extremedaily-ish (level latch)
golden_cross / death_crossfast, slow (50/200)SMA fast crosses slow on latest bardaily
cross_above_ma / cross_below_maMA length (default 50)last close crosses its SMAdaily
rsi_above / rsi_belowRSI level; optional period (14)Wilder RSI on daily closeslevel
iv_above / iv_belowIV percentunofficial Yahoo ATM IV (nearest expiry); skip if missing/0level
volume_spikemultiple (default 2.0)today's volume >= value x 20-day avgdaily
earnings_withindays (default 3)next earnings date within N daysdaily
intraday_range_pct%(day_high-day_low)/prev_close; skip if high/low missingdaily
intraday_low_pct / intraday_high_pct%opt-in session low/high vs prior close. Catches a −3% low that recovered into the closedaily
intraday_extreme_pct%alias: expands to both intraday_low_pct and intraday_high_pctdaily

Any rule may set cooldown_minutes to override settings.cooldown_minutes.

Default % checks use last print vs prior close (pct_change_* / pct_move). They do not look at the session high/low. If the user says “alert me if it drops 3% today” and they mean the print that traded through 3% even if it bounced, add intraday_low_pct (or intraday_extreme_pct). Do not add those unless they ask — they are opt-in.

Anti-spam rules (implemented in scripts/alerts.py, state in .alert_state.json)

  • Level alerts latch: once fired they stay silent until price moves back through the level by rearm_pct (default 0.5%). A stock hovering at $240 never pings repeatedly. iv_* rearms when ATM IV no longer breaches the threshold.
  • Daily-event alerts fire at most once per trading day per ticker/type.
  • Cooldown (cooldown_minutes, default 240) applies to every re-fire.
  • Cap of max_alerts_per_run (default 20). Alerts past the cap are not written to state, so they can fire on the next run. If many fire, summarize ("7 alerts, 4 on TSLA") rather than dumping walls of text.
  • If the state file is missing or corrupt, start fresh but warn the user that duplicates are possible on this run.
  • Each targets[] level is its own latched target_hit (T1 firing does not hide T2).

Market hours (America/NewYork, handled by `scripts/marketcalendar.py`)

  • Pre-market 04:00-09:30, regular 09:30-16:00, after-hours 16:00-20:00 ET; early-close days (day after Thanksgiving, Christmas Eve, July 3 when a weekday) close 13:00 with after-hours to 17:00.
  • NYSE holidays: New Year's (not observed when Saturday), MLK, Presidents', Good Friday, Memorial, Juneteenth, Independence, Labor, Thanksgiving, Christmas (Sat -> Fri, Sun -> Mon). Unscheduled closures: bundled data/holidays_overrides.json, NYSE_EXTRA_CLOSURES / settings.extra_closures, and (with Alpaca keys) weekdays missing from the official calendar. Mention it if quotes look stale on a weekday the calendar thinks is open.
  • settings.sessions controls when extended-hours quotes are treated as live. Default ["regular"]. After the bell (or pre-open / overnight) on a trading day, the script still evaluates the last regular close and labels last_close — you do not need --force-session. Add "pre"/"after" only if you want to treat extended-hours prints as the live session. Those quotes are thinner and free sources may lag.
  • Always state times in ET (add the user's local time if known, e.g. "10:05 ET / 9:05 CT").

Data sources (scripts/quotes.py, auto-fallback in this order)

  1. --fixture path, if given (tests/demos only).
  2. Alpaca snapshot + daily bars, if ALPACA_API_KEY_ID and ALPACA_API_SECRET_KEY are set (official US feed).
  3. yfinance if installed (pip install yfinance).
  4. Yahoo public chart API (stdlib, unofficial, best-effort): query1.finance.yahoo.com, then query2. prev_close is previousClose or the prior aligned daily bar — after ~20:00 ET a today-row with close: None is dropped, not treated as yesterday.
  5. Finnhub quote + candles, if FINNHUB_API_KEY is set.
  6. Alpha Vantage daily, if ALPHAVANTAGE_API_KEY is set.

Force one with --provider or WATCHLIST_PROVIDER. HTTP 429/5xx are retried; failures are tagged QuoteErrors (provider, HTTP status, hint). Free data can be delayed ~15 min; say so when precision matters.

Earnings dates are filled after the quote, first hit: existing field (yfinance/fixture) → Yahoo calendarEvents (cookie + crumb) → Yahoo quote HTML → Nasdaq analyst earnings-date (free, no key) → Finnhub / Alpha Vantage if keyed. earnings_source says which layer won; if none do, earnings_error prints a WARN.

Stale quotes: --stale-after / WATCHLIST_STALE_AFTER / settings.stale_after_seconds (default 900). During the regular session, warn if as_of is older than that. 0 disables.

ATM IV: only fetched for tickers with iv_above/iv_below. Unofficial Yahoo options chain (same crumb), then yfinance if installed. Nearest expiration, ATM call/put average as percent. Not IV rank. Failures set iv_error and print a WARN. python3 scripts/quotes.py AAPL --iv to inspect.

Notify (optional): WATCHLIST_NOTIFY=ntfy,slack,webhook,desktop,file and/or --notify. See README for env vars. Do not notify on empty/skipped/dry-run. Delivery errors stay warnings.

Known limits: unscheduled closures live in data/holidays_overrides.json (incomplete) plus env/settings plus an optional Alpaca official calendar overlay (day-cached). Yahoo endpoints are unofficial. See docs/LIMITATIONS.md.

MCP option: if an alpaca MCP server (alpacahq/alpaca-mcp-server) or tradingview MCP (atilaahmettaner/tradingview-mcp) is connected, you may use it for quotes/indicators instead of the scripts, then apply the exact same rules and anti-spam logic (read/write .alert_state.json in the same format). Use broker MCPs for read-only calls only.

Reporting format

🔔 3 new alerts (10:05 ET, regular session, data: yahoo, ~15m delayed)
- AAPL $241.50 is above $240.00  (thesis: services margin; stop $210, T1 $250)
- TSLA down -6.0% today, gapped down -5.0%, volume 3.0x avg
- TSLA reports earnings in 1 day (2026-10-16)

Group by ticker, include the stored thesis/stop/target for context, no recommendations. If no alerts: one short line, or stay silent when running on a heartbeat (see HEARTBEAT.md).

Creating alerts from chat

"Alert me if AAPL drops below 200" -> python scripts/watchlist.py update AAPL --alert price_below:200 --append (add the ticker first if missing). Confirm the rule back in plain English.

Tâches connexes

du même dépôt

Autres Skills

Tous les Skills