What broke
Every Wednesday was missing from the five-day measurement
The stock app measures how its signals do after five and ten days. No signal from a Wednesday ever got a five-day result. Claude's cut-off rule assumed price bars sit at midnight, but they sit at the exchange's opening time, and the tests could not see it: one test set had midnight bars, the other had no weekends.
The short version
What went wrongThe five-day result looked for the last price bar before midnight on day five. Bars are stamped with the exchange's opening time, so day five itself was always excluded. For a Wednesday signal that left Friday's bar, two days out, which was too short to count, so the result was never written.
How we found itHenning asked Claude to check the app on 3 October. Counting five-day results per signal day showed 0 on every Wednesday.
The rule nowSynthetic time series in tests need real timestamps and a real calendar, with weekends and holidays. When you check a measurement, count it per day or per weekday: a gap that repeats on a fixed period is a calendar bug, not missing data.
This post documents something Claude got wrong. The claim rests on a commit or a file, not on memory. All of Claude's mistakes
The stock app keeps score on itself. When one of its signal sources flags a stock, the app later checks what the price did over the following 30 and 90 days and compares it with the rest of the market. On 23 September 2026 Claude added two shorter horizons, 5 and 10 days, as a plain measurement, so the app would get a first reading weeks before the 30-day results were in. According to the project notes, no trading path reads the five-day value.
The five-day measurement had a hole in it. No signal from a Wednesday ever got a result, from the day the measurement was added until the bug was found on 3 October.
The commit messages and notes are in Norwegian. The quotes below are our translations.
The cut-off that skipped the last day
To find a signal’s five-day result, the code looks for the last daily price bar at or before a cut-off: the signal day plus five days, at 00:00 UTC.
That would be fine if each daily bar were stamped at midnight. They are not. A bar carries the time the exchange opens: 13:30 UTC in the US, 07:00 in Europe. So day five’s own bar always falls after the cut-off, and the exit is the bar from day four or earlier.
For 30 and 90 days that is a small, even shift. It hits the signal and the comparison group the same way, so the commit keeps that definition as it is: all earlier verdicts rest on it.
For five days it met two other things: the weekend, and a guard. A result only counts if the exit bar is at least three days after the signal. For a Wednesday signal, plus five days is Monday at 00:00. The last bar before that is Friday’s, two days out. Two is less than three, so the result was discarded. The note in the project’s error-class catalogue puts it plainly: “Every Wednesday was missing its 5-day outcome for ever.” The job tried those rows again on every run and never got anywhere.
The other weekdays got a result, but a shorter one than the name says. In practice “5 days” meant two to four trading days, depending on the weekday.
How it was found
On 3 October Henning asked Claude to give the app a check. In that sweep, Claude counted the five-day results per signal day. Every Wednesday stood at zero: 26 August, 2, 9, 16 and 23 September. The catalogue puts the loss at about 4,300 rows over those five Wednesdays.
The pattern gave it away. Missing data is scattered. A gap that comes back on the same weekday every week is the calendar.
Why no test caught it
There were tests, and they passed. The catalogue entry explains why they could not have failed:
- The unit test for the return calculation used bars stamped at 00:00. With midnight bars, the cut-off includes day five, so the bug does not exist.
- The reference database, built to check results against known answers, had bars at 13:30, but one on every calendar day. With a Saturday and Sunday bar, a Wednesday signal still finds a bar more than three days out.
“One without the time offset, the other without the weekend — the bug needs both.” The reference test even recorded the day-before exit as the definition, so it described the behaviour instead of questioning it.
The fix
- Day five is included. For the 5- and 10-day horizons, the cut-off is now the end of the target day. The 30- and 90-day horizons are unchanged.
- The history was recalculated. A new tool ran over all the short-horizon history: 97,956 values. The number of five-day results with a value went from 42,699 to 49,381. Changed values got a new timestamp rather than pretending they had always been there, and the old rows are kept in the row history. Running the tool again changes nothing.
- Tests with a real week. New tests use bars at the exchange’s opening time and a week with no weekend bars. They check that a Wednesday signal never matured with the old cut-off, that it now exits on Monday’s bar, and that every weekday matures.
Holidays still leave real gaps. For signals from Wednesday 2 September, whose fifth day was the US Labor Day holiday, only 216 of 859 got a five-day result. The commit treats that as correct: with no trading day there is nothing to measure, and the honest answer is “don’t know”.
The rule
Test data for anything with dates needs real timestamps and a real calendar, with weekends and holidays. Midnight bars on every calendar day are easy to write and they hide exactly this kind of bug.
And when you check a measurement, count it per day or per weekday, not just in total. A total that is a few percent low looks like noise. A zero that returns every Wednesday is a bug.