# ONCHAIN-1 Family B: DEVIATION-001 (data source) and pre-run amendments **Status:** written 2026-09-25 (UTC) and sealed with RFC 3161 timestamps (`holdout-audit seal-doc`) **before any Family B metric value was computed** and before any Family B test was run. Up to sealing, the only contact with the on-chain dataset was schema inspection and BigQuery *dry runs*, which return byte estimates and no data. No realized cap, MVRV, NUPL, SOPR, CDD, Reserve Risk or STH value has been computed or loaded by this study. **Governs:** the run of Family B (B1 to B6) of the sealed preregistration `prereg/preregistration.json` (SHA-256 `aafe3c37f5bbf83bc6e4b9a986ef1c936c3b74a927c253b833a5a7626482de40`, sealed 2026-09-25T18:22:38Z). Everything not changed here is exactly as sealed: common definitions, circular-shift null (2,000 draws, seed 20260925), testability rule (at least 5 episodes), 30-day episode merge gap, horizons, end date 2026-09-24, separate Holm family for Family B (m = 6, alpha 0.05), rubric v1.1 for the one strategy audit (B5). --- ## Part 1: DEVIATION-001, data source **Sealed text:** Family B is "run only once a written commercial licence exists or a self-computed UTXO pipeline is built". `LICENCE-DECISION.md` assumed that self-computing meant a full-chain replay of ~650 GB of raw blocks on our own node. **What we do instead:** we compute every Family B metric ourselves from the public Bitcoin blockchain as indexed in Google BigQuery's public dataset `bigquery-public-data.crypto_bitcoin` (tables `inputs`, `outputs`, `transactions`; blockchain-etl schema; values in satoshi). This is the blockchain itself (public consensus data), parsed into tables by a third party; no vendor metric is used as an input. It is a deviation in *how* the UTXO history is obtained (a public indexed copy instead of our own node), not in what is measured. Risk: an ETL error in the public dataset. Mitigation: the supply and cross-checks in Part 4. **Queries (kept in `samples/onchain1/bq/*.sql`, each dry-run first, byte-capped, logged in `bq/QUERY-LOG.md`):** 1. `spent_pairs`: every spending input joined to its funding transaction (`inputs.spent_transaction_hash = transactions.hash`; the two historical duplicate coinbase txids are de-duplicated by keeping one `transactions` row per hash, the later block), aggregated by (created UTC date, spent UTC date): sum of value (sat), sum of value x exact lifespan in seconds, count. Coinbase inputs (no spent reference) are excluded. 2. `created_by_type`: all outputs aggregated by (created UTC date, output `type`): sum of value, count. 3. `coinbase`: coinbase output value per UTC date (for the issuance cross-check). Dates: an output's created date is the UTC calendar date of its block's timestamp; its spent date is the UTC date of the spending block's timestamp (miner-set; can be off by ~2 hours, as for Family A's issuance). Results are exported (daily and date-pair aggregates only) to `bq/`; all valuation is done locally in Python, so no price data is uploaded to the cloud. ### Price series - **2015-07-20 to 2026-09-24:** the sealed Coinbase file `samples/data/raw/btc_daily.csv` (SHA-256 `064d2d18...5c17`), missing days forward-filled, exactly as Family A. It is the only series used for forward returns, zones and the strategy audit. - **2011-08-18 to 2015-07-19:** Bitstamp BTC/USD daily closes from Bitstamp's public OHLC API (`/api/v2/ohlc/btcusd/`, step 86400), used **only** to value outputs created, and market cap, before the Coinbase file starts. Fetched after this seal; SHA-256 recorded in `MANIFEST.json`; missing days forward-filled; derived statistics only, never raw prices, same basis as the Coinbase data. - **Before 2011-08-18:** price = 0. Outputs created then carry zero realized value (they were worth at most tens of dollars per BTC; the effect on realized cap from 2018 onward is below 0.1%). Market cap is undefined before 2011-08-18 and is excluded from the MVRV-Z standard deviation. ### Metric definitions (daily, UTC; all BTC amounts from satoshi / 1e8) Let V(c, s) = value created on day c and spent on day s; C(c) = value created on day c excluding outputs of type `nulldata` (OP_RETURN, provably unspendable); U(c, d) = C(c) - sum over s <= d of V(c, s) = value created on c still unspent at the end of day d; p(c) = close of day c (as above); P(d) = close of day d. - **Supply** S(d) = sum over c <= d of U(c, d). - **Realized cap** RC(d) = sum over c <= d of U(c, d) x p(c). **Realized price** = RC / S. - **Market cap** MC(d) = S(d) x P(d). - **MVRV** = MC / RC. **MVRV-Z (B1, as sealed: "standard deviation of market cap over all history up to t")** Z(d) = (MC(d) - RC(d)) / sd(d), sd(d) = population standard deviation (ddof = 0) of MC over every day from 2011-08-18 to d inclusive (expanding window, no look-ahead). The conventional full-history chart version (one standard deviation over the whole sample, which uses future data) is computed for comparison only and is never used in a test. - **NUPL (B2)** = (MC - RC) / MC. - **SOPR (B3, unadjusted, as first published: "all spent outputs combined, aggregated by the day in which they were spent")** SOPR(s) = [sum over c of V(c, s) x P(s)] / [sum over c of V(c, s) x p(c)], over all outputs spent on day s, including outputs created the same day (ratio 1 at daily resolution). Outputs created before 2011-08-18 (p = 0) are excluded from numerator and denominator. The sealed smoothing is the 7-day SMA of daily SOPR. - **Coin-days destroyed** CDD(s) = sum of value x lifespan (exact block-timestamp difference in days) over outputs spent on day s. - **Reserve Risk (B4), per the creator's primary source (Part 2):** VOCD(s) = P(s) x CDD(s) / S(s); MVOCD(s) = median of VOCD over the 30 days ending s; HODL Bank(d) = cumulative sum from 2011-08-18 to d of (P(s) - MVOCD(s)) (MVOCD over available days during the first 29); Reserve Risk(d) = P(d) / HODL Bank(d). - **STH cost basis (B5):** coin age a = d - c in days. Short-term weight w(a) = 1 / (1 + exp((a - 155) / 10)) (Glassnode's logistic function, "midpoint of 155 days and a transition width of 10 days", Nov 2020; ages above 400 days get weight 0, below 1e-10). STH realized cap = sum over c of U(c, d) x p(c) x w(d - c); STH supply = sum over c of U(c, d) x w(d - c); STH cost basis = STH realized cap / STH supply. Not entity-adjusted (entity clustering is proprietary). - **Realized price (B6)** as above. ### Judgement calls declared now - `nulldata` outputs are excluded from supply and realized cap. No other outputs are treated as lost (no "lost coins" adjustment: e.g. the genesis-era coins stay in supply at zero cost, which is standard for realized cap). - Daily granularity for creation price (close of the creation day), as in the Coin Metrics realized-cap convention using daily reference prices. - SOPR is unadjusted (Glassnode's aSOPR, which drops outputs younger than one hour, is a later variant, not the one first published). --- ## Part 2: pre-run amendments required by the sealed Family B clause The sealed Family B text says: "Thresholds marked UNVERIFIED must be checked against the creator's primary source before any data access; if the primary source differs, the primary source wins and the change is sealed as a pre-run amendment before data access." We checked on 2026-09-25, before any data access: | ID | Sealed (UNVERIFIED) | Creator's primary source (retrieved 2026-09-25) | Amendment | |---|---|---|---| | B1 MVRV-Z | Top Z >= 7; bottom Z < 0; published Nov 2018; OOS start 2018-12-01 | Awe & Wonder, "Introducing ... The Bitcoin 'MVRV Z' Metric That Predicts Market Tops with 90%+ Accuracy", Medium, **2018-10-09** (web.archive.org copy; the original is deleted): "Weekly closes above z-score value of 5 occurred 5.64% of the time. Loosely speaking, a 94.36% chance of reversal can be attached to any observation above this value. Similarly, weekly closes below realized value [Z < 0] occurred 12.78% of the time." | **Top zone Z > 5** (was >= 7). Bottom Z < 0 confirmed. **OOS start 2018-10-10** (first day after publication). Evaluated on daily closes (common definitions), not weekly. The "within two weeks" top_hit claim (W = 14, 30, 90) stays. | | B3 SOPR | "2019 (month UNVERIFIED; OOS start 2020-01-01)" | Renato Shirakashi, "Introducing SOPR: spent outputs to predict bitcoin lows and tops", Medium, **2019-04-25** (web.archive.org copy): "during a bull market values of SOPR below 1 are rejected". Charts use an SMA 10. | **OOS start 2019-04-26.** The sealed 7-day SMA was not marked UNVERIFIED and stays primary; the creator's 10-day SMA is reported as an exploratory sensitivity only. The bull-regime filter (close > 200-day SMA) stays as sealed. | | B4 Reserve Risk | "2019 (month UNVERIFIED; OOS start 2020-01-01)"; bands < 0.0026 / > 0.02 "UNVERIFIED against creator" | Hans Hauge, "Introducing Binary Adjusted BDD, VOCD and Reserve Risk", Kana & Katana (Ikigai), **2019-05-30**: VOCD = sum(daily price x adjusted BDD), adjusted BDD = BDD / circulating supply; MVOCD = "median of VOCD over 30 days"; HODL Bank = cumulative (price - MVOCD); Reserve Risk = price / HODL Bank. The article gives **no numeric bands** ("purchasing Bitcoin when the Reserve Risk is the lowest ... has produced outsized returns"). | **OOS start 2019-05-31.** Definition as in Part 1 (the creator's). No primary-source band exists, so nothing differs: the sealed Glassnode bands (< 0.0026 bottom primary, > 0.02 top secondary) stand. | | B5 STH cost basis | Glassnode, date UNVERIFIED; OOS start 2021-07-01 "unless the primary source shows an earlier date, in which case the later date still binds" | Glassnode Insights: STH = UTXOs younger than 155 days (2020-03-03); logistic weighting "midpoint of 155 days and a transition width of 10 days" (2020-11-17) | Weighting as in Part 1. OOS start **2021-07-01** stands (the later date binds). | | B2 NUPL, B6 Realized price | not marked UNVERIFIED | not re-checked | none | The MVRV-Z threshold change (7 to 5) is required by the sealed clause and is made before any MVRV-Z value is seen. We did not choose it: it is the only numeric band in the creator's article. --- ## Part 3: tests (unchanged from the seal except Part 2) Primary tests (Family B Holm family, m = 6, one-sided p in the claimed direction; descriptive-only tests enter with p = 1): | ID | Zone | Claimed direction | Primary | OOS window | |---|---|---|---|---| | B1 | MVRV-Z > 5 (top) | negative | D_365 | 2018-10-10 to 2026-09-24 | | B2 | NUPL < 0 (bottom) | positive | D_365 | 2019-03-01 to 2026-09-24 | | B3 | close > SMA200(close) and SOPR 7-day SMA <= 1 (bull-regime reset) | positive | D_90 | 2019-04-26 to 2026-09-24 | | B4 | Reserve Risk < 0.0026 (bottom) | positive | D_365 | 2019-05-31 to 2026-09-24 | | B5 | close > STH cost basis (bull regime) | positive | D_90 | 2021-07-01 to 2026-09-24 | | B6 | close < realized price (bottom) | positive | D_365 | 2018-11-01 to 2026-09-24 | Each window starts at the later of the date shown and the first day the metric is computable. Secondary (exploratory, raw p only, no correction): the other horizons of each primary zone; B1 bottom Z < 0 and top_hit at W = 14, 30, 90; B2 top NUPL >= 0.75; B4 top > 0.02; B5 bear regime (close < STH cost basis); B3 with the 10-day SMA. B5 strategy audit: hold BTC (1) when close(t) > STH cost basis(t), cash (0) otherwise, decided at close t and held to close t+1; rubric v1.1, objective (a) beat buy-and-hold BTC, 10 bps per unit turnover, N = 1, default holdout, audit period 2021-07-01 to 2026-09-24. Code: the same `zone_test`, `episodes`, `hits` and `holm` functions as Family A (`run.py`), reused unchanged. --- ## Part 4: cross-check (declared before any metric is computed) 1. **Supply vs the consensus issuance schedule** (P2P headers, Family A) at each year-end: our UTXO supply must be within 0.1% of cumulative subsidy, after known exceptions (unclaimed subsidy, the two overwritten duplicate coinbases, the genesis coinbase). 2. **Realized cap / realized price / MVRV vs independent published values**: point values quoted in public prose sources (research notes and articles; no vendor data files are downloaded) at dates spread over 2018 to 2026. Tolerance: if MVRV or realized price differs by more than 5% on the median of the comparison dates, we investigate before any test (typical causes: unspendable outputs, price splice, timestamp or join errors). STH cost basis and SOPR are compared at plus or minus 10%, because vendor figures are often entity-adjusted or use aSOPR. 3. Only **data-correctness fixes** (pipeline bugs, mis-parsed outputs, price splice errors) are allowed in response to the cross-check. No zone, threshold, horizon, window or definition in Parts 1 to 3 may change because of it. Any such fix is described in `bq/METHOD.md` and sealed as `DEVIATION-002` before the tests run. The comparison table and all % differences are published in `bq/METHOD.md` whatever they show. ## Part 5: order of work (commitment) Seal this document; run the BigQuery jobs; build the daily metric series (`bq/metrics_daily.csv`); run the cross-checks and write `bq/METHOD.md`; seal DEVIATION-002 only if a data fix was needed; then run the Family B tests **once**, apply Holm (m = 6), and publish every result in `results.json`, `SUMMARY.md` and `reports/`, supported or not. **Exposure disclosure.** As for Family A, this is not a blind test: we have seen the BTC price path through 2026, and it is widely reported that MVRV-type metrics peaked in early 2021 and that BTC traded below its realized price in 2022. We have not computed or looked up any Family B series for this study. A helper process was, in parallel with writing this document, collecting a handful of public point values (realized price, MVRV) from prose sources for the Part 4 cross-check; those are public spot values, not test outcomes, and they have not been read by the author of this document at the time of sealing. Statistical analysis of past data only; not investment advice.