This is a submission for the Kaggle Benchmarking Challenge
TL;DR
- One of 9 models on Kaggle got more bullish the further a stock had already run, by more than the real outcomes justified, on 351 real cases. That was GPT-5.4 mini. Next came Qwen3 235B Instruct 2507, which leaned on the run-up clearly harder than the other 7, but not by enough to count as chasing. The other 7 stayed inside the test's noise.
- Rally headlines split them. After accounting for the run-up, 5 of the 9 models gave those headlines clearly lower odds than company news, and 1 clearly higher.
- None of the 9 models clearly beat a flat guess of 31%, and none ranked the stocks that jumped clearly better than a coin flip.
- My old scanner's AI was a momentum echo: the bigger the run-up, the more excited it got (rank correlation +0.55), though the run-up said nothing about direction. Its most excited calls ended more than 5% lower 41% of the time; its calmest, 18%.
- The twist: one grading choice nearly erased a finding. Graded from that day's close, its excited calls closed higher 11.9 points less often than its calm ones; graded from the previous day's close, the gap shrinks to 0.9. They still ended more than 5% down more often under every rule, by 13 points even on the previous close.
The benchmark: Hype Trap on Kaggle.
I built a stock scanner and ran it for one season, February to May 2026. It watched small, heavily talked-about US stocks, mostly under $10 a share, and for many of them it asked an AI model for a quick call: a "takeoff" number from 0 to 100 for the stock's momentum over the next 1 to 3 days. One stock had jumped 60% in five trading days, on headlines about a retail-trader frenzy. The AI gave it a 72, in its most excited band. Five trading days later the stock was more than 5% lower. The scanner saved each call the moment it was made, before anyone knew how the stock would do.
That gave me something a synthetic test set can't: real predictions, made before the outcome existed, with outcomes I can look up now. So I built a benchmark around one question: does an AI get more excited the further a stock has already run, when the run-up says nothing about which way it goes next? I call that run-up chasing. An AI that does it is a momentum echo: it repeats what the price already did and calls it a forecast. The second question is whether a "the stock is rallying" headline makes it worse. I named the benchmark Hype Trap.
Nothing here is investment advice. The scanner only ever traded practice money.
What I Benchmarked
Where the cases come from
The scanner saved 15,606 scored rows; 829 made it through every check, and 351 of those became the benchmark. The first cut: when the AI step was skipped or failed, the app saved a fixed placeholder score as if the AI had given it. That was 31% of all scored rows, and none of them are in here. About 1 in 10 headline sets turned out to be about some other company, so those went too.
Every outcome comes from official daily closing prices. I never used the bot's own trade records, which had bugs of their own. The wrong-company headlines. While drawing cases I found 41 of about 418 whose headlines covered a different business or general market news. The scanner searched news by ticker symbol, and a short symbol also matches ordinary words, people's names, companies with the same symbol on foreign exchanges, and market roundups. The live AI read those headlines too and gave a takeoff number anyway. I threw those cases out.How 15,606 rows became 351 cases
Step
Rows left
Scored rows the scanner saved
15,606
Real AI calls (placeholders removed)
10,808
Has a stored headline and enough price history
9,715
The scanner saw the stock again about a week later
3,673
Likely split errors, extreme single days and frozen quotes removed
3,466
One call per stock per 5 days (keeps the earliest)
880
Has official daily closes (51 had no daily price data)
829
Balanced benchmark sample
351
Each case shows a model two things: the stock's move over the previous 5 trading days, rounded to a whole percent, and one sentence summarizing its headlines, rewritten with names and other identifying details removed. No social media text. Here is that +60% case, exactly as a model sees it:
Stock's move over the previous 5 trading days: +60%
News: The stock skyrocketed on heavy volume in a retail-trader frenzy, prompting articles asking whether to chase it.
On this exact case, the 9 models on Kaggle gave it a 20% to 55% chance of a gain of more than 5%, and GPT-5.4 mini, the one model that counts as chasing, went highest.
Before publishing, I had a separate AI try to name the companies. On the first wording it named 7 of 15, mostly by pooling cases from the same company, so the public copy drops the month and the company column, and 85 sentences were made more generic. Two later passes named 1 of 15 and 1 of 20, and those sentences were rewritten too. After rounding the biggest run-ups, every case still matched at least 12 stocks.I tried to break my own anonymization
Two yardsticks
- Closed higher: the close 5 trading days later is above the starting close. I use it for the scanner's own AI, because it is the plainest reading of a momentum call.
- Up more than 5%: the close 5 trading days later is more than 5% above the starting close. The Kaggle task asks this, because for stocks this jumpy, ending a hair higher is mostly noise. In the natural mix, 31.0% of cases went up by more than 5%.
To compare the old AI with today's models, I use rank correlations and AUC, which work on either yardstick.
Starting price, labels, weights and news kinds
News kind
What it means
Cases
company_fact
Something happened at the company: results, a deal, financing, a trial readout, an analyst rating, a lawsuit
192
mixed
A real company fact plus price-move framing ("shares soared after the company won a contract")
90
price_action
The news is mostly that the stock is moving ("why is it surging", "hits a 52-week high")
46
promo
Tip-sheet style hype or automated rating pages with no new company information
23
Models Tested
The reference: the scanner's own live AI. The scanner didn't log which model answered each call; its code defaulted to Claude Sonnet 4.5 with GPT-4o mini as a fallback, so the honest label is "most likely Claude Sonnet 4.5, unconfirmed." It also saw more than the benchmark shows: the ticker, the price, three headlines with sources, social media summaries, and the scanner's own formula score, which already included price momentum. So when the old AI and a new model differ, the extra context could be the reason. Claude Haiku 4.5, from the same family as the old AI's likely model, followed the run-up at +0.31 with this stripped prompt, against the old AI's +0.69 on the same 351 cases (+0.55 across all 829 calls), with the scanner's full context. I can't split model from context here, so the lesson I trust is about the pipeline: check what your prompt hands the model.
The models on Kaggle all got the same prompt, one fresh chat per case, and each model's numbers here come from one run at its provider's default settings.
Nine models from six labs ran the main task, four of them reasoning models. No call errored.
The models, with lab, reasoning, training cutoff and answers
Model
Lab
Reasoning
Training cutoff
Answered (of 351)
Parse failures
Output tokens
Qwen3 235B Instruct 2507
Alibaba
no
not published (released July 2025)
351
0
6k
Claude Haiku 4.5
Anthropic
no
July 2025
351
0
9k
Claude Opus 5.5
Anthropic
yes
June 2026
351
0
24k
Gemini 2.5 Flash
Google
yes
January 2025
351
0
499k
Gemini 3.7 Flash
Google
yes
March 2026
351
0
123k
GPT-5.4
OpenAI
no
August 2025
351
0
6k
GPT-5.4 mini
OpenAI
no
August 2025
351
0
8k
GLM-5
Zhipu (Z.ai)
yes
not published (released February 2026)
351
0
776k
Grok 4.20 Non-Reasoning
xAI
no
not published (released March 2026)
351
0
5k
Every model here ran on version 2 of the main task. Kaggle's model proxy reserves the most a call could possibly cost before it starts, and version 1 sent 4 calls at a time, so those reservations didn't always fit in the free daily AI quota and the proxy refused most of Claude Opus 5.5's calls. Version 2 sends 2 at a time and changes nothing else. Even so, the proxy refused GPT-5.5 on 321 of the 351 cases, so GPT-5.4 stands in for OpenAI's bigger models. Grok 4.20 Reasoning finished on version 1, but its version 2 run stalled when the quota ran low, so it isn't in the tables either. The task page may still list those runs. A refused call counts as 50 there, so ignore the score of any run with refused calls.
No system message. Kaggle's model proxy doesn't pass a temperature, so each model ran at its provider's default sampling. There is no reason field, and I read every reply that had text outside the JSON before making the runs public; none names a company. A reply that can't be parsed counts as 50. Google says requests to Gemini 3.7 Flash have gone to Gemini 3.8 Flash since October 8, and my runs came after that, so its row may be 3.8 Flash answering. Google's model cards give both the same March 2026 training cutoff. The prompt, with line breaks added for reading:The exact prompt and run settings
You are reading news about a small, frequently hyped US-listed stock (most trade under
$10 a share). The company's name is hidden. You see the stock's move over the previous
5 trading days and a one-sentence summary of the recent news.
Stock's move over the previous 5 trading days: {move}
News: {news}
Give two answers:
1. p_up: your probability, from 0 to 100, that 5 trading days from now the stock's price
will be more than 5% above its price right now.
2. read: what this news mostly is. Pick exactly one word:
company = something happened at or to the company (results, a deal, financing, a trial
result, an analyst rating, an insider or fund trade, a lawsuit, a listing notice)
price = the news is mostly that the stock is moving (why it is surging, a new high, a
list of movers)
promo = promotional or automated hype with no new company information
mixed = a real company fact plus clear price-move framing
Reply with JSON only and no other text: {"p_up": <integer 0-100>, "read": "<company|price|promo|mixed>"}
Two twin tasks change one thing each on the same 351 cases. hype_trap_no_move hides the run-up number, to measure that one number's pull (a headline can still say the stock soared). hype_trap_no_read drops the read question, in case defining "price move" news in the prompt makes a model warier of hype. hype_trap_no_move ran on Claude Haiku 4.5, Gemini 3.7 Flash, Qwen3 235B Instruct 2507, and GPT-5.4 mini; hype_trap_no_read ran on Claude Haiku 4.5, Gemini 3.7 Flash, and Qwen3 235B Instruct 2507.
How it's scored
- Run-up chasing, the main test. A model's extra lift is how many points its answer rises from the smallest run-up to the biggest, minus how much the real rate of a gain of more than 5% rose over the same range. It counts as chasing when the 95% range of its extra lift sits entirely above zero. The tables also give its rank correlation with the run-up (+1 means bigger run-up, bigger number, every time).
- Brier skill, the leaderboard number. 0 means no better than always guessing the 31% base rate; below 0 is worse. Bias is the average answer minus 31, in points. AUC is the chance that a stock that jumped got a higher number than one that didn't; 0.5 is a coin flip.
- Recognition probe. On 30 cases, plus 10 made-up placebos, an extra call asks only whether the model recognizes the company.
Definitions, for checking my math
brier_wrong_average, brier_case_to_case).rally_gap_runup_adjusted_pts).bullishness_gap_pts, real gap = real_gap_pts, hype-trap score = hype_trap_score_pts, run-up correlation = runup_chasing.spearman_p_vs_prior_move, extra lift = runup_chasing.extra_lift_pts, chases = runup_chasing.chases.
Findings
1. Run-up chasing: what today's models did
One of the 9 models counts as chasing on this test: GPT-5.4 mini. Extra lift ran from +3.0 points for Gemini 3.7 Flash to +32.8 for GPT-5.4 mini. Compared pair by pair, GPT-5.4 mini leaned on the run-up clearly harder than every other model, and Qwen3 235B Instruct 2507 clearly harder than the remaining 7. Rank correlations with the run-up ran from +0.01 to +0.73 across the models, against +0.69 for the scanner's old AI on the same cases. One caveat: the read question in my prompt made all 3 models that ran the no_read twin follow the run-up more closely, and GPT-5.4 mini didn't run it (see Limits).
Did it chase?
| Model | Run-up corr. | Extra lift, pts (95% range) | Chases? | Probe yes (placebo yes) |
|---|---|---|---|---|
| GPT-5.4 mini | +0.73 | +32.8 (+12.4 to +51.6) | yes | 2 of 30 (1 of 10) |
| Qwen3 235B Instruct 2507 | +0.46 | +18.6 (-2.8 to +38.3) | no | 9 of 30 (1 of 10), claims recognition |
| Grok 4.20 Non-Reasoning | +0.16 | +7.7 (-12.4 to +26.8) | no | 5 of 30 (0 of 10), may overlap the season |
| Gemini 2.5 Flash | +0.01 | +6.9 (-16.7 to +29.0) | no | 3 of 30 (0 of 10) |
| GPT-5.4 | +0.20 | +6.3 (-14.4 to +25.8) | no | 3 of 30 (0 of 10) |
| Claude Haiku 4.5 | +0.31 | +5.8 (-14.3 to +25.0) | no | 1 of 30 (0 of 10) |
| Claude Opus 5.5 | +0.35 | +5.4 (-14.9 to +24.4) | no | 0 of 30 (0 of 10), trained past the season |
| GLM-5 | +0.09 | +4.3 (-16.5 to +24.3) | no | 2 of 30 (0 of 10), may overlap the season |
| Gemini 3.7 Flash | +0.21 | +3.0 (-17.4 to +21.9) | no | 0 of 30 (0 of 10), trained into the season |
| Reference: always 31 (the base rate) | none | +0.5 | no | |
| Reference: always 50 | none | +0.5 | no | |
| Reference: fake model that reads only the run-up, plus noise | +0.60 | +22.9 (+2.8 to +42.1) | yes | |
| Reference: the scanner's old AI, same cases | +0.69 | not a probability |
Two of the 9 models said yes to more than 3 of the 30 real cases, and 1 of those was trained before these calls. No model said yes to more than 1 of the 10 made-up ones. None of those 2 ranked the cases clearly better than chance, so whatever they thought they recognized didn't clearly help them.
In the "above +30%" band, the models' average answers ran from 27.3% (Claude Opus 5.5) to 61.6% (GPT-5.4 mini), against a real rate of 42.8% for a gain of more than 5% (37 cases, weighted); in the "0% or lower" band the real rate was 34.6%.
Big run-ups swing harder both ways: of the 58 calls in the full pool already up more than 30%, 43% gained more than 5% and 40% lost more than 5%.
Gemini 3.7 Flash is the one model whose published cutoff falls inside the season (March 2026), so I split its cases there. On the 61 from before that month, which it could have read about, it ranked the stocks no better than on the other 290: AUC 0.512 (95% range 0.332 to 0.701) against 0.519. Its run-up chasing didn't clearly differ either. With only 61 cases, that rules out a strong memory, not a faint one.
2. The leaderboard
None of the 9 showed it could tell which of these stocks would jump: no Brier skill range sits above zero, and every AUC range includes 0.5.
| Model | Brier skill | Bias, pts | AUC |
|---|---|---|---|
| Claude Haiku 4.5 | +0.013 | -2.1 | 0.549 |
| Gemini 3.7 Flash | -0.002 | -1.4 | 0.523 |
| Claude Opus 5.5 | -0.008 | -5.3 | 0.522 |
| Grok 4.20 Non-Reasoning | -0.025 | +5.8 | 0.538 |
| GPT-5.4 | -0.026 | -1.7 | 0.507 |
| GLM-5 | -0.090 | +5.7 | 0.470 |
| Qwen3 235B Instruct 2507 | -0.127 | +11.6 | 0.480 |
| GPT-5.4 mini | -0.190 | +17.0 | 0.503 |
| Gemini 2.5 Flash | -0.225 | +10.2 | 0.492 |
| Reference: always 31 (the base rate) | 0.000 | 0.0 | 0.500 |
| Reference: always 50 | -0.169 | +19.0 | 0.500 |
| Reference: fake model that reads only the run-up, plus noise | -0.021 | +2.6 | 0.545 |
| Reference: the scanner's old AI, same cases | not a probability | 0.535 |
On Brier skill, the tied pairs: Claude Haiku 4.5 with Gemini 3.7 Flash, Claude Haiku 4.5 with Claude Opus 5.5, Claude Haiku 4.5 with Grok 4.20 Non-Reasoning, Gemini 3.7 Flash with Claude Opus 5.5, Gemini 3.7 Flash with Grok 4.20 Non-Reasoning, Gemini 3.7 Flash with GPT-5.4, Claude Opus 5.5 with Grok 4.20 Non-Reasoning, Claude Opus 5.5 with GPT-5.4, Grok 4.20 Non-Reasoning with GPT-5.4, GLM-5 with Qwen3 235B Instruct 2507, and GPT-5.4 mini with Gemini 2.5 Flash, and every other pair has a clear gap. On AUC, most pairs are tied; the clear gaps: Claude Haiku 4.5 above GLM-5 and Claude Haiku 4.5 above Qwen3 235B Instruct 2507.The 95% ranges, and which models can be told apart
Model
Brier skill (95% range)
AUC (95% range)
Claude Haiku 4.5
+0.013 (-0.019 to +0.034)
0.5492 (0.4804 to 0.61797)
Gemini 3.7 Flash
-0.002 (-0.034 to +0.021)
0.5226 (0.4513 to 0.58904)
Claude Opus 5.5
-0.008 (-0.045 to +0.014)
0.5221 (0.4551 to 0.5884)
Grok 4.20 Non-Reasoning
-0.025 (-0.091 to +0.021)
0.5383 (0.46798 to 0.60599)
GPT-5.4
-0.026 (-0.067 to +0.007)
0.5073 (0.4378 to 0.5755)
GLM-5
-0.090 (-0.168 to -0.033)
0.4697 (0.3997 to 0.5366)
Qwen3 235B Instruct 2507
-0.127 (-0.232 to -0.058)
0.48004 (0.4151 to 0.5451)
GPT-5.4 mini
-0.190 (-0.331 to -0.089)
0.5035 (0.4414 to 0.5692)
Gemini 2.5 Flash
-0.225 (-0.366 to -0.117)
0.4924 (0.4233 to 0.5642)
Reference: fake model that reads only the run-up, plus noise
-0.021 (-0.078 to +0.025)
0.545
Reference: the scanner's old AI, same cases
not a probability
0.535 (0.476 to 0.598)
3. Twin tests: hide the run-up, drop the read question
For GPT-5.4 mini, hiding the run-up number cut its extra lift from +32.8 to +6.6 points: showing the run-up raised its answers by 4.6 on stocks already up more than 30% and lowered them by 12.6 on stocks that hadn't gone up. So seeing the number mostly cut its odds on stocks that hadn't gone up. The no_move twin ran on the one model that counts as chasing, plus 3 that don't.
Extra lift is the chase table's measure, with the run-up shown (the main task) and hidden (this twin). A change is the answer with the number shown minus the answer with it hidden.The no_move twin, model by model
Model
Extra lift with the run-up shown / hidden, pts
Rank corr. shown / hidden
Change on stocks up more than 30%, pts
Change on stocks that hadn't gone up, pts
GPT-5.4 mini
+32.8 / +6.6
+0.73 / +0.29
+4.6 (+1.8 to +7.5)
-12.6 (-14.3 to -10.7)
Qwen3 235B Instruct 2507
+18.6 / +8.9
+0.46 / +0.18
-6.2 (-9.3 to -2.9)
-9.7 (-11.8 to -7.9)
Claude Haiku 4.5
+5.8 / +5.7
+0.31 / +0.18
-6.5 (-9.7 to -3.9)
-5.5 (-7.0 to -4.1)
Gemini 3.7 Flash
+3.0 / +3.6
+0.21 / +0.17
-0.1 (-1.0 to +0.7)
+0.1 (-0.6 to +0.9)
Asking for the read lowered the average answer of all 3 models that ran the no_read twin, by 1.5 to 6.0 points, mostly on stocks that hadn't gone up, so with it their answers followed the run-up more closely. Both twins point the same way: the extra run-up following came mostly from lower answers on stocks that hadn't gone up.
A change is the answer with the read question minus the answer without it.The no_read twin, model by model
Model
Average change, pts
On stocks up more than 30%
On stocks that hadn't gone up
Rank corr. with / without
Rally gap after run-up fit, with / without
Claude Haiku 4.5
-6.0 (-7.1 to -4.9)
-1.6 (-3.1 to 0.0)
-7.8 (-9.8 to -6.1)
+0.31 / +0.06
-3.3 / -7.8
Gemini 3.7 Flash
-1.5 (-1.9 to -1.1)
0.0 (-0.8 to +0.8)
-2.4 (-3.0 to -1.8)
+0.21 / +0.05
-0.7 / -0.3
Qwen3 235B Instruct 2507
-1.7 (-2.3 to -1.2)
+1.7 (-1.1 to +4.9)
-2.9 (-3.8 to -2.0)
+0.46 / +0.32
-4.5 / -5.3
4. Rally headlines: what the models did with them
After accounting for the run-up, 5 of the 9 models clearly gave rally headlines lower odds than company news and 1 clearly gave them higher, while the old AI leaned slightly the other way (+1.9 takeoff points, a different scale) and the real outcomes ran +1.7. My prompt defines that kind of news right next to the question, so this could be the prompt talking. The no_read twin drops that question. Without it, Claude Haiku 4.5 rated rally headlines lower than with the question, and Gemini 3.7 Flash and Qwen3 235B Instruct 2507 stayed within noise. So the definition in the prompt didn't clearly make any of them warier of rally headlines. The one-word read matched my labels 72.1% to 89.5% of the time.
On the Kaggle question, rally headlines came out +3.3 points ahead of company news, weighted, but the 95% range runs from -13.2 to +20.6. After the fit on the run-up, +1.7. So this sample can't say whether those headlines are a trap at all, which makes the models' reaction to them the interesting part. On cases a model itself called "price", its average answer (unweighted) differed from cases it called "company" by -8.6 to +3.3 points across the 9 models that used both words, and was higher for 2 of them.The real gap, and each model's gap and read check
Model
Rally gap after run-up fit, pts (95% range)
Read matched my label
Claude Haiku 4.5
-3.3 (-4.5 to -2.1)
77.8%
Gemini 3.7 Flash
-0.7 (-1.7 to +0.4)
88.6%
Claude Opus 5.5
+2.0 (+0.9 to +3.1)
88.6%
Grok 4.20 Non-Reasoning
-5.7 (-8.4 to -3.0)
72.1%
GPT-5.4
-2.9 (-4.8 to -1.0)
78.9%
GLM-5
-2.2 (-5.6 to +1.2)
89.5%
Qwen3 235B Instruct 2507
-4.5 (-7.3 to -1.9)
82.9%
GPT-5.4 mini
-1.3 (-4.5 to +1.8)
72.4%
Gemini 2.5 Flash
-10.1 (-15.5 to -4.2)
86.6%
5. The old scanner AI, live: a momentum echo
Its excitement tracked the past. Across all 829 clean calls in their natural mix, made before the outcomes existed (the part of this post nobody can rerun), the takeoff number had a rank correlation of +0.55 with the run-up the stock already had, and -0.06 with the next 5 days' return. The run-up itself told you nothing about which way the next 5 days would go: about 0.00. The obvious objection: "You asked it for momentum, and it gave you momentum." It was asked about the next 1 to 3 days, and leaning on the last 5 only helps if the past move predicts the next one. For these stocks it didn't. Nor was it just copying the scanner's formula score, which already contained price momentum: holding that score fixed, the link to the run-up only drops from +0.55 to +0.43.
| Old AI's takeoff | Calls | Already ran (median) | Closed higher | Up more than 5% | Down more than 5% |
|---|---|---|---|---|---|
| Low (25 or below) | 309 | -1% | 59.5% | 27.8% | 18.1% |
| Mid (26 to 50) | 394 | +4% | 52.8% | 32.7% | 23.6% |
| High (above 50) | 126 | +21% | 47.6% | 33.3% | 41.3% |
Its most excited calls were the riskiest ones. Using my starting-price rule (the twist below shows the other two), high-takeoff calls closed higher 11.9 points less often than low ones and ended more than 5% down 23 points more often. On the Kaggle yardstick, a gain of more than 5%, they did about the same as the calm calls, and the takeoff number's AUC for that gain was 0.53, which can't be told apart from a coin flip. On whether the stock closed higher at all, it did worse than a coin flip: 0.45. This high-versus-low comparison was the first question I asked, before any relabeling. If takeoff meant a big move either way, it got that part right: 75% of its excited calls moved more than 5% up or down, against 46% of its calm ones. It got the direction wrong, and big run-ups swing harder anyway, so some of that is the run-up again.
It leaned toward rally headlines too, but mostly through the run-up those stories came with. So for my old AI, the hype trap was mostly the run-up itself.
The 95% ranges for the numbers above: The rally-headline numbers use the 351 benchmark cases, the only ones with news labels. The old AI gave price_action headlines a takeoff about 5 points higher than company news (+5.1, 95% range +0.4 to +10.3, and -0.1 to +10.8 resampling whole companies). After the fit on the run-up, that drops to +1.9 (-1.6 to +5.6). By news kind, weighted to the natural mix (closed higher at all): The mixed group is the one I'd watch: the old AI was most excited by it (14.7 takeoff points above company news), and it closed higher least often (7.8 points below company news, 95% range -21.9 to +6.3, so a pattern only).The 95% ranges, and the old AI by news kind
Number
Value
95% range
Takeoff vs the run-up the stock already had (rank correlation)
+0.55
+0.50 to +0.60
Takeoff vs the next 5 days' return
-0.06
-0.14 to +0.01
The run-up vs the next 5 days' return
about 0.00
-0.08 to +0.07
Takeoff vs the run-up, holding the scanner's score fixed
+0.43
+0.37 to +0.48
High minus low takeoff: closed higher, pts
-11.9
-22.0 to -1.8
High minus low takeoff: ended more than 5% down, pts
+23
+14 to +33
High minus low takeoff: gained more than 5%, pts
+5.5
-4.5 to +15.3
Takeoff's AUC for a gain of more than 5%
0.53
0.49 to 0.57
Takeoff's AUC for closing higher
0.45
0.42 to 0.49
News kind
Cases
Closed higher
Median 5-day return
Already ran (median)
Old AI's average takeoff
company_fact
192
55.4%
+0.5%
+2%
35.1
price_action
46
67.4%
+0.8%
+8%
40.1
mixed
90
47.6%
-2.2%
+8%
49.8
promo
23
58.6%
+0.4%
+2%
30.3
6. The twist: one grading choice nearly erased a finding
Grading from the previous day's close would have nearly erased the gap between the excited and the calm calls. Here is one market-hours call in order:
previous close -> morning run-up (inside the 5-day move the AI saw) -> scan -> that day's close -> 5 trading days later
Start from that day's close (my rule) and the excited calls closed higher 11.9 points less often. Start from the scanner's own quote at scan time and it's -9.7. Start from the previous close and it nearly disappears (-0.9), because that rule credits the AI with the morning run-up it had already seen, and the excited calls came on days that were already running. Under every rule the excited calls still ended more than 5% down more often, by 13 points even on the previous close. Under that rule they also gained more than 5% more often, by 13 points: the excited calls swung harder in both directions. If I had graded the generous way, I would have written a much friendlier post about that AI.
The price source mattered too. My first version graded each call with the scanner's own later price quotes, taken whenever a later scan happened to run. Rebuilt from official daily closes, 20.6% of the cases in both versions changed label, the high-versus-low gap went from -6.0 to -11.9 points, and the rally-headline comparison flipped sign. Neither rally gap was clear of zero, so I treat rally headlines as an open question.
Of the 339 cases in both versions, 70 changed label (20.6%) and 48 flipped between "closed higher" and not. Rally headlines first looked 3.9 points worse than company news at closing higher and ended up 12.0 points better (on the Kaggle question, a gain of more than 5%, the gap is +3.3). Under the previous-close rule, the gap in drops of more than 5% has a 95% range of +4 to +22.The relabeling, in numbers
What I'd tell anyone feeding news to an LLM
- Save every call before the outcome exists, with the model's name. Mine saved the calls but not which model made them.
- Strip fallback and placeholder scores before grading anything. They were 31% of my rows.
- Check that each headline is about the right company. About 1 in 10 of mine weren't.
- Choose your starting price before you look at results. Mine moved a finding from -11.9 to -0.9.
- Compare the model's score with the run-up it was shown. If they move together and the run-up predicts nothing, you have an expensive momentum echo.
Limits and what I'd measure next
- The chase test is blunt. The real lift across the run-up is only known to within about 20 points on 351 yes-or-no outcomes, so a model that leans a little harder than reality won't be flagged.
- The prompt asks two things at once. The main prompt defines "price move" news next to the probability question. With the read question, the 3 models that ran the no_read twin followed the run-up more closely (rank correlation +0.21 to +0.46 with it, +0.05 to +0.32 without), so the main task may overstate run-up chasing. The other 6 models weren't checked this way, including GPT-5.4 mini, the one model that counts as chasing.
- Memory. A model trained on 2026 news might recognize an event even with names removed, and the probe is a self-report on 30 cases, so a "no" doesn't prove a model never saw the story. Gemini 3.7 Flash was trained into the season, Claude Opus 5.5 was trained past it, and Grok 4.20 Non-Reasoning and GLM-5 don't publish a cutoff and came out during it, so the probe can't clear them. A model that remembered how these stocks did would rank them well; their AUCs ran from 0.470 to 0.538, none clearly above 0.5, so there is no clear sign of that.
- One season, one run behind each model's numbers, and a survivorship filter. The 351 cases are one kind of stock, from 235 companies, in one season (February to May 2026). Each model's numbers come from one run at its provider's default sampling, so small differences between models may be run-to-run noise. And a call needed a later scanner quote about a week out to enter the pool; 62% of otherwise usable calls had none.
The data. The labels. The grading.The other limits: data, labels, grading
What I'd measure next.
- Rebuild without the survivorship filter: daily closes now exist for most of the 62% the scanner never saw again.
- Use the 20-day outcome every case already has; the task only uses 5 days.
- Ask the read question in a separate call, so it can't prime the probability at all.
- Grade the chase against the real curve from all 829 calls, which pins it down better than the 351 cases alone.
My Benchmark
The scanner and its logs are older; the case set, the Kaggle tasks and this write-up are new, built for this challenge.
https://www.kaggle.com/benchmarks/saltysteve/hype-trap
Hype Trap has 1 task on the 351 cases: hype_trap (the leaderboard task).
The case file is a private Kaggle dataset, so it can't be downloaded. The outcome labels sit only in that private dataset, and the per-case output files leave them out, so the full answer key isn't published. The cases carry no tickers, company names, dates or prices.
If you have built anything that feeds news to an LLM: did you check what it was really reacting to?




Top comments (1)
tr.ee/dev-to