Come usare
- Copia il comando e controlla il pacchetto prima di installarlo nel tuo ambiente agente.
- Controlla strumenti, credenziali e ambienti richiesti nel documento originale.
- Descrivi input e risultato desiderato; confronta l’output con le fonti.
npx skills add https://github.com/eli-alvarado/us-watchlist-alerts --skill price-alertsPrima di iniziare
- L’installazione non include abbonamenti, quote API o accesso ai file.
- Stelle e installazioni indicano attività, non un test indipendente di qualità o sicurezza.
Contenuto dal repository con titoli, esempi, codice, tabelle, link e immagini preservati.
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
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 sessionOutput: 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
| type | value | fires when | kind |
|---|---|---|---|
price_above / price_below | price | last >= / <= value | level |
stop_hit | price (default: ticker stop) | long: last <= stop; short: last >= stop | level (implicit if stop set) |
target_hit | - | last crosses any targets entry | level (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 fire | daily |
gap_up / gap_down | % (default 2) | open vs prior close | daily |
new_52w_high / new_52w_low | - | last beyond prior 252-session range | daily |
near_52w_high / near_52w_low | % (default settings.near52wpct) | within value% of 52w extreme | daily-ish (level latch) |
golden_cross / death_cross | fast, slow (50/200) | SMA fast crosses slow on latest bar | daily |
cross_above_ma / cross_below_ma | MA length (default 50) | last close crosses its SMA | daily |
rsi_above / rsi_below | RSI level; optional period (14) | Wilder RSI on daily closes | level |
iv_above / iv_below | IV percent | unofficial Yahoo ATM IV (nearest expiry); skip if missing/0 | level |
volume_spike | multiple (default 2.0) | today's volume >= value x 20-day avg | daily |
earnings_within | days (default 3) | next earnings date within N days | daily |
intraday_range_pct | % | (day_high-day_low)/prev_close; skip if high/low missing | daily |
intraday_low_pct / intraday_high_pct | % | opt-in session low/high vs prior close. Catches a −3% low that recovered into the close | daily |
intraday_extreme_pct | % | alias: expands to both intraday_low_pct and intraday_high_pct | daily |
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 latchedtarget_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.sessionscontrols 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 labelslast_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)
--fixturepath, if given (tests/demos only).- Alpaca snapshot + daily bars, if
ALPACA_API_KEY_IDandALPACA_API_SECRET_KEYare set (official US feed). yfinanceif installed (pip install yfinance).- Yahoo public chart API (stdlib, unofficial, best-effort):
query1.finance.yahoo.com, thenquery2.prev_closeispreviousCloseor the prior aligned daily bar — after ~20:00 ET a today-row withclose: Noneis dropped, not treated as yesterday. - Finnhub quote + candles, if
FINNHUB_API_KEYis set. - Alpha Vantage daily, if
ALPHAVANTAGE_API_KEYis 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.


