Skip to content

Add S&P 500 drawdown-from-ATH alert and ATH status in close alert#20

Merged
valuecodes merged 3 commits into
mainfrom
drawdown-alert
Jul 12, 2026
Merged

Add S&P 500 drawdown-from-ATH alert and ATH status in close alert#20
valuecodes merged 3 commits into
mainfrom
drawdown-alert

Conversation

@valuecodes

Copy link
Copy Markdown
Owner

What

  • Adds a scheduled alert that fires when the S&P 500 crosses a drawdown threshold from its all-time high (10/20/30/40/50%), in both directions — dropping below and recovering above.
  • Crossings are detected statelessly by comparing the two most recent daily closes, so each is reported once with no persistence needed. Thresholds live in an adjustable DRAWDOWN_THRESHOLDS array.
  • Enriches the existing daily close alert with ATH context: flags a new all-time high, otherwise shows percent below ATH plus the ATH price and date.
  • Both alerts reuse the existing 0 8 * * * cron — no wrangler or env changes.

How to test

pnpm --filter @repo/alerts test
pnpm typecheck
pnpm lint
pnpm format:check

Security review

No security-impacting changes.

Copilot AI review requested due to automatic review settings July 12, 2026 08:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new S&P 500 (SPY) drawdown-from-all-time-high (ATH) threshold alert to the alerts worker, and enriches the existing daily SPY close alert with ATH context so recipients can see whether the latest close is a new ATH or how far below the ATH it is.

Changes:

  • Introduces a new scheduled sp500-drawdown alert that detects stateless crossings of configurable drawdown thresholds (10/20/30/40/50%) from ATH.
  • Extends the daily sp500-close alert to fetch full history and include ATH / drawdown-from-ATH details.
  • Registers the new alert in the alerts registry and adds unit tests for the drawdown alert behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
apps/alerts/src/alerts/sp500-drawdown.ts New alert that detects drawdown band crossings vs ATH and emits Telegram HTML messages.
apps/alerts/src/alerts/sp500-drawdown.test.ts Unit tests covering drawdown band crossing detection and messaging behavior.
apps/alerts/src/alerts/sp500-close.ts Enriches the daily close alert with ATH / drawdown context and switches to full history fetch.
apps/alerts/src/alerts/index.ts Registers the new drawdown alert in the alert registry.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +16 to +24
const bandFor = (drawdown: number): number => {
let band = 0;
for (const threshold of DRAWDOWN_THRESHOLDS) {
if (drawdown >= threshold) {
band = threshold;
}
}
return band;
};
Comment on lines +25 to +37
// The bar with the highest close; `latest` is at the ATH when it ties it.
const athBar = series.bars.reduce((max: DailyBar, bar: DailyBar) =>
bar.close > max.close ? bar : max
);
const isNewAth = latest.close >= athBar.close;

const head = `📈 SPY close ${latest.date}: $${latest.close.toFixed(2)}`;
if (isNewAth) {
return `${head} — 🚀 all-time high`;
}

const drawdown = (athBar.close - latest.close) / athBar.close;
return `${head} (−${(drawdown * 100).toFixed(1)}% from ATH $${athBar.close.toFixed(2)} on ${athBar.date})`;
Comment on lines +15 to +18
// `full` history is required to establish a real all-time high.
const series = await client.getDailyTimeSeries("SPY", {
outputSize: "full",
});
@valuecodes
valuecodes merged commit 7d53889 into main Jul 12, 2026
7 checks passed
@valuecodes
valuecodes deleted the drawdown-alert branch July 12, 2026 09:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants