mcpField
P
price-alerts

price-alerts

github.com/eli-alvaradoOther310 installsUpdated 6d ago
Repository

About price-alerts

A skill for evaluating US-market watchlist rules against fresh quotes and reporting only new price alerts. It includes cooldown and anti-spam state handling, market-session checks, and optional notification delivery; it does not place or change orders.

Key features

  1. 01Evaluates price and indicator rules
  2. 02Reports only new alerts
  3. 03Applies latches and cooldowns
  4. 04Checks market sessions and stale quotes
  5. 05Supports text and JSON output
  6. 06Optional notification sinks

Use cases

  1. 01Monitor watchlist levels and stop or target prices
  2. 02Check daily moves, indicators, and earnings timing
  3. 03Send configured alert notifications
  4. 04Review conditions without updating cooldown state

MCP support

It can use connected Alpaca or TradingView MCP servers for read-only quotes or indicators instead of its scripts. The same alert rules and anti-spam state handling still apply.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/eli-alvarado/us-watchlist-alerts --skill price-alerts

After installing, type/price-alertsin Claude Code to confirm it loaded.

Details

From the project README

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.

Run it

python scripts/alerts.py --watchlist watchlist.json --state .alert_state.json            # text output
python scripts/alerts.py --format json                                                    # machine-readable
python scripts/alerts.py --force-session                                                  # evaluate even when market closed
python scripts/alerts.py --dry-run                                                        # don't update cooldown state
python scripts/alerts.py --notify                                                         # also deliver via WATCHLIST_NOTIFY sinks
python scripts/market_calendar.py                                                         # current ET session

Output: ALERT <message> lines, or no new alerts, or a "outside alert sessions" note. Data errors go to stderr as WARN. 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%change vs prior close >= valuedaily
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.near_52w_pct)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

Any rule may set cooldown_minutes to override settings.cooldown_minutes.

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/New_York, handled by scripts/market_calendar.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 alerts run; default ["regular"]. Add "pre"/"after" for extended hours - note extended-hours 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.
  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 (no key) → Finnhub earnings calendar → Alpha Vantage EARNINGS_CALENDAR. earnings_source on the quote says which layer won.

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, nearest expiration, ATM call/put average as percent. Not IV rank. python 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.

Comments

Markdown supported