---
name: rh-model-spec
description: The buildable spec for Ben's Robinhood Chain price model v5 - every Dune query, feature definition, split rule, data trap and current out-of-sample score. Read this before touching the model, and before any scheduled session that has to rebuild it from scratch, because the container is ephemeral and nothing survives except this file. Results log lives in [[model-blind-tests]].
sources: [cowork]
aliases: [robinhood-model, price-model-spec, rh-model-v3, rh-model-v5]
---

# Robinhood Chain model, v5 spec

## RETRACTION 1 Sep 2026 — READ FIRST, IT INVALIDATES MOST SCORES BELOW
**The entry price for every return from v2 onward was a 3-DAY VWAP (days O-2 to O), and the 3-day imbalance feature is correlated with that target by construction.** Buying inside the averaging window drags the entry price below the day-O close, so the "return" to O+1 is positive mechanically. Same defect on the young cohort with a 6-hour VWAP entry against a 24-hour horizon.
Corrected close-to-close (entry = VWAP of the last 2 UTC hours of day O, >=3 trades): OLD **up 2d 0.535** (was 0.776), **up 7d 0.596** (was 0.685), **touch 7d 0.636** (was 0.777); YOUNG **up 24h 0.654** (was 0.712), **touch 0.673** (was 0.709). **Direction skill RISES with horizon, 0.508 at 1d to 0.645 at 14d** — the opposite of the "three-day half-life" in the horizon rule below.
**The entire flow term structure is dead close-to-close** (imb1 -0.052, imb3 -0.036, imbslope -0.015; dropping the family costs 0.007). Feature family 1 below is WITHDRAWN. Death scores are unaffected because death is price-independent. Full detail and the surviving feature list are in [[model-blind-tests]].
**Standing rule now: entry and exit prices are CLOSES, never multi-period VWAPs, and every feature window must end at or before the entry price's window.**

# v5 spec as originally written (audited 1 Sep 2026)

The cloud container is wiped between sessions. Everything below rebuilds from Dune alone. Dune key and gotchas are in the `ben-research-stack:research-sources` skill; standing query id 8562361, plus 8568856 and 8568857 for parallel runs.

## Hard facts and data traps
- Robinhood Chain's first real trading week is **29 Jun 2026**. Nine weeks is the entire history. One regime, no bear tape.
- `dex.trades` on `blockchain='robinhood'`, two-leg union: bought leg `isbuy=1`, sold leg `isbuy=0`, `amount_usd between 0.5 and 3000000`.
- Universe: lifetime volume >= $150,000 and >= 6 active days. Strict pre-origin re-qualification moves AUC by under 0.003.
- **ALWAYS JOIN `tokens_robinhood.erc20` FOR DECIMALS. Never assume 18.** 41 of 4,113 universe tokens are not 18-decimal (31 at 9, 5 at 6, 3 at 0, one each at 11 and 8, 3 missing). Assuming 18 corrupted 1.3% of market caps and pushed turnover p99 to 1.88e9.
- **WINSORISE EVERY MEAN AT p99 and cap outcomes.** A single young-panel print reached +2,115,491,295%.
- **`dex.pools` HAS ZERO ROBINHOOD ROWS.** Do not build on it.
- A result of exactly the row limit means the pull TRUNCATED.
- The trade-level Amihud query (lag() over every trade since 29 Jun) ran 22 minutes, cost 16 credits, cancelled. Do not retry as written; use daily/hourly bar aggregates instead.
- `information_schema` on this catalog throws `Unknown type: string`. Probe candidate tables with `select * from x limit 2` instead.

## Two cohorts, two panels
**OLD, age 5 days or more.** Daily bars. Origins every 3 days from 20 Jul to 24 Aug (12). Outcomes +2d, +7d, max over 7d. 7,096 observations, 2,745 tokens. Walk-forward on the last 6 origins = 3,013 out-of-sample rows.
**YOUNG, under 5 days.** Hourly bars, hours 0 to 216 since first trade. Observation ages 24, 36, 48, 72, 96h. Outcomes +24h, +48h, +72h, max over 72h. 6,511 observations. **Split by LAUNCH WEEK, never by date.** Folds: 27 Jul to 3 Aug, 3 to 10, 10 to 17, 17 to 24 Aug = 2,023 out-of-sample rows.

Model: GradientBoostingClassifier, n_estimators 150, max_depth 3, learning_rate 0.06, subsample 0.8.

## Feature families, in order of what they are worth
1. **FLOW TERM STRUCTURE. Still the core.** Imbalance = (buy_usd - sell_usd)/(buy_usd + sell_usd). A single window is nearly worthless; the information is in the CHANGE. OLD: 1d, 2d, 3d, 5d, 7d plus lag (days 3 to 6) and acceleration (1d minus 3d). YOUNG: 3h, 6h, 12h, 24h plus whole-life, lag and acceleration.
2. **TRUE POOL DEPTH. The biggest win, and it lands hardest on the young cohort (+0.058 direction, +0.042 touch).** Route: `uniswap_v4_robinhood.PoolManager_evt_Initialize` (id, currency0, currency1) joined to `PoolManager_evt_Swap`, plus `uniswap_v3_robinhood.UniswapV3Factory_evt_PoolCreated` joined to `UniswapV3Pool_evt_Swap`. Last swap per pool per day. sqrtP = sqrtPriceX96 / 2^96; base virtual reserve = L/sqrtP if the token is token0 else L*sqrtP; divide by 10^decimals; multiply by USD price. Features: log depth, **depth_to_mc (rho -0.246, t -11.2 vs touch, the strongest number in the project, CLIP AT 3.0)**, vol_to_depth, pool_conc, npools, v4share, depth_chg, has_depth. Validates at a median 0.71 ratio to DexScreener liquidity where 0.50 is exact.
3. **PRICE IMPACT PROXY.** Amihud = mean |ln(p_t/p_t-1)| / volume_t, times 1e6, log10, at 3d and 7d (OLD) or 6h and 12h (YOUNG), plus the change. **Realised volatility is the strongest of these**: OLD rho -0.272, YOUNG -0.204. High recent vol predicts LOWER forward return.
4. **TAKER GRAPH and TRADE-SIZE MIX.** log takers, new-taker share, repeat share, taker growth; share of volume in trades >= $2,000 and under $200; log average trade size.
5. **HOLDERS.** +0.001 to +0.005. Cheap, keep, do not expect much.
6. **CROSS-SECTIONAL DEMEANING: for the DEATH model only.** Within-origin rank-z plus chain regime descriptors takes death 0.872 to 0.897, and takes direction DOWN 0.776 to 0.760. Fit death on rank-z, fit direction and touch on raw levels.
7. **DEPLOYER GRAPH. Track record does NOT predict** (dep_hit rho -0.024, t -0.3). +0.001 to +0.004 AUC. Keep it as a repeat-operator and fraud flag, not a return feature.
8. **WALLET QUALITY. DEAD.** Failed standalone, as a weight, and as class shares. Do not rebuild.
9. **SUB-HOUR BARS. DEAD, tested 1 Sep (Test 4). Do not rebuild.** 5-minute bars over minutes 0-1440, with 15m and 30m imbalance / realised-vol / Amihud / taker / trade-size windows added on top of the hourly set: **twelve paired out-of-sample cells across ages 3h, 6h, 12h, 24h, zero gains, one significant loss.** The single significant win (touch at age 3h, +0.015) disappears once log market cap is in the model. Untested only on top of true pool depth.
10. **FIRST-30-MINUTE SNIPER BLOCK. DEAD, same test. Do not rebuild.** Top-1/top-5 share of first-30m buy volume, temporal HHI, sniper count and average buy, and the share of first-30m buying already SOLD at the observation. Univariate it is strong (`sn_exit_flag` t -8.08 at 3h, t -9.88 at 6h; `sn_sold_share` t -6.38) and multivariate it is negative: **-0.011 direction and -0.012 touch at age 3h**, while consuming 11.7% of model importance.

## Observation ages under 24h (Test 4, 1 Sep)
An age-3h observation is scorable, but only on the TAIL. Measured on a FIXED window (price at h96 vs h24) so the target is identical at every age: direction 0.600 at 3h rising to 0.664 at 24h (+0.064 [+0.025,+0.104]); death 0.788 to 0.855 (+0.067 [+0.022,+0.111]); **touch 0.697 at 3h against 0.704 at 24h, +0.007 [-0.023,+0.038], i.e. no gain from waiting.**
**Rule: the tail call can be made at hour 3. The direction and death calls cannot and need the full 24 hours.** Ranking at hour 3 by P(touch) gives 42.6% touch in Q1 vs a 24.7% universe and a +65.5% capped mean; hour 24 gives 46.0% and +68.8%.
Two sign traps at this age, both opposite to the mature cohort: **share of volume in trades under $200 is the strongest POSITIVE feature** (rho +0.268, t 14.85 at 3h), and **Amihud's sign FLIPS to +0.328** - illiquid low-volume launches outperform in the first hours, the reverse of the old-cohort prior. Also, the best P(up) quintile at age 3h DIES MORE, not less, so death must be ranked by its own model here.
Strict pre-observation re-qualification was re-checked on identical rows at ages 3h to 24h: leak <=0.006 everywhere, so the "<0.003" rule holds down to hour 3.

## Current out-of-sample scores, v5 (audited)
OLD: up in 2d **0.776** | touch +50% in 7d **0.779** | dies in 7d **0.895**
YOUNG: up in 24h **0.718** | touch +50% in 72h **0.707** | dies in 72h **0.878**
OLD top decile by P(touch): 53.8% touched +50% against a 22.0% universe, died 0.0%.

## 11. CATEGORY BY NAME. Real standalone, dead as a feature. CLOSED 1 Sep (Test 6).
- **`tokens_robinhood.erc20` has a `name` column, not just `symbol`.** Names resolve for 100% of panel tokens. That is what unblocked this.
- **`rwa_stock_factory_robinhood.factory_deployer_call_deploy`** = the definitive 203 tokenised stocks (`output_0`, `name_`, `symbol_`, `uid_`). `rwa_robinhood` holds only balances tables. `information_schema` is broken on this catalog; use `show tables from <schema>`.
- Payout-word tokens beat infrastructure-word tokens by **+25.8pp on the 7-day up-rate (57.0% vs 31.2%), permutation p 0.0009, 6 of 6 origins.** Medians +3.8% vs -16.1%. The radar's hand-read 27-token finding survives at n=3,013.
- Factory stocks: 58.6% up at 7d, median +0.6%, **zero touched +50%, zero died.**
- **Adds nothing to the model**: v5 0.775/0.779/0.884 to v6 0.774/0.778/0.890. Use it to decide what to LOOK AT, never as a feature.
- Equity-pairing is NOT a category: only 0.8% of observations have any equity-quoted pair.

## THIRD OBSERVATION WINDOW: EARLY, age 3 to 12 hours (built 1 Sep, Test 6)
Hourly bars are enough. Fixed outcome window h24 to h96, depth from the launch-day pool reading, 90% coverage.
| age | direction base / +depth | touch base / +depth | death base / +depth |
|---|---|---|---|
| 3h | 0.633 / 0.616 | 0.659 / **0.669** | 0.805 / **0.834** |
| 24h | 0.680 / 0.676 | 0.686 / 0.692 | 0.857 / 0.857 |
**Depth is worth +0.029 on death and +0.010 on touch at hour 3, and costs 0.017 on direction.** Age-3h Q1 by P(touch): 33.7% touch and 7.8% died against a 22.5% and 17.2% universe; Q5 8.6% and 38.3%.
Sign flip: `v4share` +0.194 at age 3h versus -0.098 in the old cohort. **Uniswap v4 pools outperform in the first hours and underperform later.**

## THE RECURRING LESSON
Four strong univariate stories have now added nothing once flow and depth are in: wallet quality, the sniper block, the deployer graph, and name category. **Treat a real univariate rho as no evidence until it survives the walk-forward ablation.**

## THE HORIZON RULE, measured 1 Sep 2026 (Test 7). This governs how the model may be used.
**Accuracy DECAYS with holding period. It does not improve. Highest at ONE day.**

| hold | chain direction | chain tail | the 42 direction | the 42 tail |
|---|---|---|---|---|
| 1d | 0.803 | 0.832 | **0.772** | 0.685 |
| 3d | 0.709 | 0.782 | 0.574 | 0.639 |
| 7d | 0.679 | 0.760 | **0.481** | 0.538 |
| 14d | 0.672 | 0.754 | **0.428** | 0.496 |

- **On large, liquid, well-known utility tokens the model is a 1-to-5-day instrument only.** By day 7 it is below a coin flip on that list.
- The whole chain degrades gently (0.803 to 0.679); a curated large-cap list collapses (0.772 to 0.428). Size dilutes the flow imbalance the model runs on.
- **The TAIL call decays far less than direction everywhere** (chain 0.832 to 0.754). For any hold longer than a week, rank by P(touch), never by P(up).
- Top half minus bottom half median return on the 42: +14.9pp at 1d, +16.4pp at 3d, +2.8pp at 7d, **-30.7pp at 10d, -35.5pp at 14d. The ranking INVERTS.** Both halves were up in this tape (+76% and +111% at 14d), so this is a separation failure, not a loss.
- Accuracy vs token AGE runs the other way: 0.669 at 3h, 0.692 at 1d, 0.707 at 1-4d, 0.740 at 5-8d, **0.790 at 8-12d, then flat** (0.717 to 0.777 out to 70 days). Age helps until about day eight and then stops.
- Artifact: "Signal Half-Life" https://claude.ai/code/artifact/d907143b-8992-4b86-b938-b03bc82efeb8

## Open gaps
- No bear tape exists in nine weeks of chain history. Every number here is one regime.
- A second chain has never been tested, so nothing is known about transfer.
- Direction at hour 3 remains uncallable (0.616 to 0.633). If that is ever wanted it needs information that is not in trade flow or pool state.

## Standing rules
- Report the AUC for the target actually being claimed. Direction, touch and death are three different problems with three different numbers.
- Absolute base rates are universe-dependent. Only the RANKING transfers.
- Always show median next to mean; the means are tail-driven.
- Freeze any forward call to a file before reading post-cutoff data.
