Inspiration
In a market crash, things that normally move independently start moving together. Traders call it "all correlations go to one". You can't see that on a price chart, and nobody can watch a chart all day anyway. We wanted something you could leave running in the background and hear when the market starts moving as one.
What it does
Canary replays the March 2020 currency crash as live music. Four analysts each watch a slice of the FX market and play their own part:
- fx (euro, pound): an 808 bass
- havens (yen, Swiss franc): a wobbly pad
- commodity (Australian dollar, Canadian dollar, Norwegian krone): a cowbell riff
- contrarian (bets against whatever moved most): a gritty lead
In calm markets you hear four separate parts. As correlation rises, the parts drift together, and at the peak every part plays one note. Risk speeds up a Geiger-style ticking.
When risk stays high for two days, the code proposes an action ("cut commodity by 30%") on an approval card. Each analyst votes for or against it, the replay pauses, and a named human approves or vetoes. Every decision is logged with who made it, why and how long it took.
You can kill an analyst mid-replay. Its neighbour notices within 3 seconds and takes over its part, and you can hear the handover.
A blind test blacks out the screen and asks you to guess "calm or crash" by ear alone.
How we built it
- Data: daily exchange rates for 7 currencies from the Federal Reserve (H.10), cached so the demo needs no internet.
- Signals: pure Python functions. Correlation is the average over all 21 currency pairs of daily returns over 10 days. It maps to a single number that drives the music:
$$u = \operatorname{clip}\left(\frac{\bar\rho - 0.25}{0.40},\ 0,\ 1\right)$$
- Risk: combines a "flight to safety" signal (havens rising while commodity currencies fall) with unison and the drawdown:
$$\text{risk} = \min\left(1,\ 0.8\cdot\max(\text{divergence},\ u) + 0.2\cdot\frac{\text{fall}}{10\%}\right)$$
- Card rule: fires when risk is at least 0.50 for two days in a row.
- No hub: seven OS processes share one UDP multicast bus on localhost. Every analyst computes risk itself, and there's no coordinator. A thin relay forwards messages to the browser over server-sent events. Killing it changes nothing for the analysts.
- Music: Tone.js in the browser. Every part shares one scale (D minor pentatonic), so convergence always sounds musical. Each note's scale degree is pulled toward D as unison rises:
$$\text{degree} = \operatorname{round}\big(\text{pattern} \times (1 - u)\big)$$
- Tooling: standard-library Python only at runtime, 105 pytest tests, mypy in strict mode.
Challenges we ran into
- Being honest about results. We tuned the thresholds on 2020, so 2020 working proves little. We ran 2008, 2022 and 2024 with the same thresholds. You can hear the correlation in all of them, but the early warning didn't repeat: no lead in 2008, no card at all in 2022, and in 2024 the card came 13 days after the low. We report all of it.
- Takeover changes the numbers. When an analyst covers a dead neighbour, it reads that slice with its own temperament, so risk comes out differently. Killing fx leaves the 2 March card unchanged. Killing commodity loses it.
- One card, not four. Four analysts raise the same alert independently, so the relay dedupes by ID, pauses the replay and resumes only when the last open card is decided.
- Making calm sound calm. Early versions were tiring to listen to. Now calm markets are soft and muffled, and stress opens the sound up.
Accomplishments that we're proud of
- The blind test works: you can tell calm from crash by ear.
- Kill any analyst and the band keeps playing.
- We show where it fails, not just where it works.
What we learned
The correlation signal generalises across crises, and the early warning doesn't. That distinction is the whole honest claim of the project: Canary doesn't predict anything. It makes correlation audible. In 2020 the card fired 14 trading days before the low, 8 days ahead of a 10% stop-loss but 3 days behind a tight 5% one.
We also learned that peer-to-peer systems are easy to describe and fiddly to get right, especially deciding who covers whom without an election.
What's next
- AI-written one-line explanations for each analyst. The design keeps them strictly after the numbers are final, so they can never change a decision. Right now they're templates.
- A live mode on today's markets.
- Testing the card and the chart with a screen reader.
Historical replay of a hypothetical portfolio, for demonstration only. Built with (one tag each): python, javascript, html5, css3, tone.js, web-audio-api, udp, multicast, server-sent-events, pytest, mypy, black, federal-reserve-data, fred, git, github