A Telegram alert that fires when top cohort traders EXIT a bet. It reads the existing pmv2_position_events EXITED feed (logged each cycle by the position watcher), runs as a non-fatal scheduled step after the trending alert, and shows the trader plus the position’s last-seen P/L. Shipped 2026-06-04.
For Agents
- Source of EXITED events: the first-mover-overlap-watcher position watcher (
run_pmv2_positions→ append-onlypmv2_position_events, kind'EXITED'). The exit-alert step is a read over that feed — it does not detect exits itself.- Module:
crates/polymarket-fetch/src/pmv2/exits.rs.- Cursor key
pmv2_exit_alertinpm_detection_cursors(dedup).- Runs as a non-fatal scheduled step right after the trending alert — a failure here never aborts the scheduled run.
pmv2-exitsCLI = read-only 24h preview (no alerts sent).
What Shipped
When a top-tier cohort trader leaves a position, the bot pushes a 🔴 TRADE EXITED Telegram alert showing:
- Trader name, score / band / rank
- Market + outcome
- P/L (last seen) — the position’s last-snapshot
cash_pnl
Gating + filters
- Top-trader gated — only traders with live
score > copy thresholdqualify (same threshold as the rest of the pmv2 alerting). - Cursor-deduped —
pm_detection_cursorsdetector keypmv2_exit_alert, so each EXITED event alerts at most once. - Dust-filtered — ≥ $50 stake.
- Telegram-budget capped — bounded number of alerts per cycle.
P/L caveat
Exit P/L is the LAST-SEEN unrealized cash_pnl, not a real fill
Exits are snapshot-detected (the position is simply gone from the next fetch), so the actual exit fill price is unknown. The displayed “P/L (last seen)” is the position’s last-snapshot
cash_pnl— its last observed unrealized cash P/L before it disappeared. It is labeled(last seen)precisely because it is not a realized fill. Treat it as “where the position stood when last seen,” not “what the trader booked.”
Migration 20260604000000_pmv2_event_pnl.sql
Added P/L-context columns to pmv2_position_events:
cash_pnlinitial_valuecurrent_valuecur_priceoutcometitle
These are captured in insert_position_event from the prior PositionRow at log time — no call-site change was needed; the event-logging function reads them off the position it’s already handling. This denormalizes the P/L context onto the event so the exit alert can render P/L without a re-join (same denormalize-at-log-time pattern the first-mover-overlap-watcher uses for trader_score).
CLI
pmv2-exits — read-only 24h preview of cohort exits. Sends no alerts; for eyeballing what the live alert would have fired on over the last day.
Related
- first-mover-overlap-watcher — documents the
EXITEDevent kind + the append-onlypmv2_position_eventsfeed this reads - pmv2-trending-bets — same alert / cooldown pattern; the exit-alert step runs right after the trending alert
- pmv2-two-tier-trader-scoring — source of the trader score / band / rank shown in the alert
- pmv2-bot-startup-ping
- polymarket-fetch