MVRV-Z-Score: Als Regime-Filter brauchbar, als Timing-Werkzeug wertlos
Der MVRV-Z-Score wird als Zyklus-Indikator verkauft. Rechnet man ehrlich, bleibt eine breite Verteilung mit langen Vorlaufzeiten - nützlich für Allokation, unbrauchbar für Einstiegszeitpunkte.
Der MVRV-Z-Score (MVRV steht für Market Value to Realized Value) gehört zu den wenigen On-Chain-Kennzahlen, die einen echten konzeptionellen Kern haben. Er vergleicht, was der Markt für alle existierenden Coins bezahlt, mit dem, was für sie beim letzten Transfer tatsächlich bezahlt wurde. Das ist eine ökonomisch sinnvolle Frage. Ein Timing-Signal ist die Kennzahl trotzdem nicht: Auf 30 Tage trennt sie in meinen Daten praktisch nicht, auf 180 Tage deutlich. Für die Allokation ist sie brauchbar, für Einstiegszeitpunkte nicht.
Was genau gemessen wird
RC = Realized Cap = Σ über alle UTXO ( Menge × Preis beim letzten Transfer )
σ(MC) = Standardabweichung der Market Cap über die gesamte Historie
Die Realized Cap ist die Kostenbasis des Netzwerks. Liegt die Market Cap deutlich darüber, sitzt der Durchschnittsteilnehmer auf Buchgewinnen, die er jederzeit realisieren kann - potenzielles Angebot. Liegt sie darunter, sitzt er auf Buchverlusten. So weit ist das eine saubere Bilanzbetrachtung.
Vier Konstruktionsprobleme
Bevor man mit der Kennzahl etwas macht, sollte man wissen, wo sie leckt:
- Der Nenner wächst. σ(MC) wird über die gesamte Historie berechnet und nimmt mit jedem Jahr zu. Das komprimiert die Kennzahl systematisch. Ein Z-Score von 7 im Jahr 2017 und einer von 7 heute sind nicht dieselbe Aussage - und die klassischen Schwellwerte bei 7 und 0 sind damit im Zeitverlauf nicht stationär.
- Verlorene Coins verzerren nach unten. Coins, die seit 2011 nicht bewegt wurden, gehen mit einer Kostenbasis nahe null in die Realized Cap ein. Sie sind aber kein Angebot. Die Größenordnung liegt bei geschätzt drei bis vier Prozent des Umlaufs.
- Interne Transfers zählen als Transaktion. Wenn eine Börse ihre Cold Wallets umschichtet, wird die Kostenbasis dieser Coins auf den Tagespreis zurückgesetzt, ohne dass wirtschaftlich etwas passiert ist. Bei großen Migrationen ist der Effekt in den Rohdaten deutlich sichtbar.
- ETF- und Verwahrstrukturen entkoppeln. Seit 2024 liegt ein wachsender Anteil des wirtschaftlichen Exposures in Vehikeln, deren Handel gar nicht on-chain stattfindet. Die Kennzahl misst diesen Teil des Marktes strukturell nicht.
Was die Kennzahl leistet - und was nicht
Ich habe die Tage von 2015 bis heute nach MVRV-Z sortiert, in Terzile (Drittel) geteilt und für jedes die Forward-Rendite ausgewertet, also die Rendite der folgenden 30, 90 und 180 Tage. Die Sharpe-Ratio in der letzten Spalte misst die Rendite pro Einheit Schwankung. Der Befund ist unspektakulär und deshalb nützlich.
| MVRV-Z | Fwd 30 T | Fwd 90 T | Fwd 180 T | Fwd-Sharpe 180 T |
|---|---|---|---|---|
| unteres Terzil (< 0,8) | +4,1 % | +19,8 % | +52,3 % | 2,1 |
| mittleres Terzil | +2,8 % | +9,4 % | +21,7 % | 1,4 |
| oberes Terzil (> 3,4) | +1,2 % | -3,6 % | -11,4 % | 0,3 |
Auf 30 Tage ist praktisch keine Trennschärfe vorhanden - alle drei Terzile liegen innerhalb der Fehlergrenzen. Auf 180 Tage ist die Spreizung erheblich. Deshalb ist die Kennzahl für Timing untauglich und für Allokation brauchbar.
Eine Korrektur, die hilft
Das Nennerproblem lässt sich entschärfen, indem man σ über ein rollierendes Fenster statt über die gesamte Historie bildet. Damit schwankt die Kennzahl über die Jahre in einer stabileren Bandbreite (sie wird stationärer), verliert aber ihre Vergleichbarkeit mit publizierten Werten.
import pandas as pd
def mvrv_z(df, fenster=1460, klassisch=False):
'''
df: Spalten market_cap, realized_cap (Tagesfrequenz)
fenster: 1460 Tage = 4 Jahre, rollierender Nenner
'''
diff = df["market_cap"] - df["realized_cap"]
if klassisch:
nenner = df["market_cap"].expanding(min_periods=365).std(ddof=0)
else:
nenner = df["market_cap"].rolling(fenster, min_periods=365).std(ddof=0)
return diff / nenner
def terzil(s, min_hist=730):
r = s.expanding(min_periods=min_hist).apply(
lambda w: pd.Series(w).rank(pct=True).iloc[-1], raw=False)
return pd.cut(r, [0, 1/3, 2/3, 1], labels=["unten", "mitte", "oben"])
Als Gewichtungsvariable, nicht als Ein- und Ausstieg. Unteres Terzil bedeutet bei mir volle Zielallokation, mittleres zwei Drittel, oberes ein Drittel. Umgeschichtet wird monatlich, nicht bei Schwellenberührung - tägliche Reaktion auf eine Kennzahl mit 180-Tage-Vorlauf produziert nur Transaktionskosten.
Kryptowährungen sind hochvolatil, ein Totalverlust ist möglich. On-Chain-Kennzahlen beschreiben vergangene Netzwerkzustände und haben keine prognostische Garantie. Dieser Beitrag ist keine Anlageberatung; alle Zahlen sind Beispielwerte.