← Alle Insights

Data Versioning mit DVC: reproduzierbare Backtests auf Wochen-Skala.

„Können Sie den Backtest von vor sechs Wochen noch einmal laufen lassen?" — eine harmlose Frage, die in vielen Quant-Setups ein halber Albtraum ist. Code ist versioniert. Daten meistens nicht. Und beides ohne Verknüpfung ist halbe Reproduzierbarkeit. DVC, lakeFS und Pachyderm lösen genau diesen Spalt.

Warum Git nicht reicht.

Git ist auf Text-Diffs ausgelegt. Eine 12 GB Parquet-Datei mit Tick-Daten lässt sich nicht sinnvoll diffen, sie sprengt jedes Repo und macht git clone zur Stunden-Operation. Git LFS ist ein Pflaster, kein Heilmittel — das LFS-Backend wird schnell zur Kostenfalle, und große Branches sind eine Tortur.

Was wir wirklich wollen:

DVC, lakeFS, Pachyderm im Vergleich.

Für 90 % der Mandanten — ein bis fünf Quants, Backtest-orientiert — ist DVC die richtige Wahl. Geringer Overhead, läuft auf jedem CI-Runner, kein zusätzlicher Server.

DVC-Setup in 5 Minuten.

# Repo initialisieren
cd quant-research/
git init
dvc init
git commit -m "init dvc"

# Remote konfigurieren (S3 als Beispiel)
dvc remote add -d s3remote s3://my-quant-bucket/dvc
dvc remote modify s3remote region eu-central-1
git add .dvc/config
git commit -m "configure dvc remote"

# Daten tracken
dvc add data/raw/ticks_msft_2031.parquet
# erzeugt: data/raw/ticks_msft_2031.parquet.dvc  (kleine YAML)
# und schreibt: .gitignore mit Pfad-Ausschluss
git add data/raw/ticks_msft_2031.parquet.dvc data/raw/.gitignore
git commit -m "add MSFT 2031 tick data"

# Daten ins Remote pushen
dvc push

# Auf anderem Rechner / im CI:
git clone <repo>
dvc pull           # holt nur die Daten zum aktuellen Commit

Das war's. Der entscheidende Punkt: die .dvc-Datei enthält einen MD5- oder SHA-Hash der echten Daten. Wer einen alten Git-Commit auscheckt und dvc pull macht, bekommt byte-genau die Daten zurück, mit denen damals gearbeitet wurde.

Remote Storage — was wirklich zählt.

Eines vorab: das Remote sollte versioniert werden. S3 Object Versioning oder GCS Object Versioning ist ein Klick und schützt vor versehentlichem Überschreiben. DVC selbst verlässt sich auf Content-Hashes — wer einen alten Hash hat, holt die Daten zurück. Wer ihn nicht hat, ist abhängig vom Storage-Backend.

Pipelines mit dvc.yaml.

DVC kann mehr als nur Dateien tracken. Mit dvc.yaml wird der ganze Backtest deklarativ:

stages:
  ingest:
    cmd: python src/ingest.py
    deps:
      - src/ingest.py
      - data/raw/ticks_msft_2031.parquet
    outs:
      - data/interim/clean_msft.parquet

  features:
    cmd: python src/features.py
    deps:
      - src/features.py
      - data/interim/clean_msft.parquet
    params:
      - features.vol_window
      - features.flow_lookback
    outs:
      - data/processed/features_msft.parquet

  backtest:
    cmd: python src/backtest.py
    deps:
      - src/backtest.py
      - data/processed/features_msft.parquet
    params:
      - strategy.threshold
      - strategy.position_size
    metrics:
      - metrics/backtest.json
    plots:
      - plots/equity_curve.csv

dvc repro führt nur die Stages aus, deren Inputs oder Parameter sich geändert haben — wie make, nur mit Datenabhängigkeiten. dvc metrics show und dvc plots diff vergleichen Backtest-Ergebnisse zwischen Commits.

Code-Hash und Daten-Hash verknüpfen.

Ein reproduzierbarer Backtest ist erst dann reproduzierbar, wenn der Run einen eindeutigen Fingerprint hat. Ich schreibe in jeden Backtest-Output:

{
  "run_id": "2032-07-30T14:21:09Z_a8f3c9d",
  "git_commit":     "a8f3c9d7e4b2a1...",
  "git_dirty":      false,
  "dvc_lock_hash":  "f4c2b3a8...",
  "params": {
    "features.vol_window": 5,
    "strategy.threshold": 0.0042,
    "strategy.position_size": 0.02
  },
  "data_inputs": [
    {"path": "data/raw/ticks_msft_2031.parquet",
     "md5":  "d41d8cd98f00b204..."}
  ],
  "metrics": { "sharpe": 1.87, "max_dd": -0.092 }
}

Mit diesem Block lässt sich jeder Run Monate später byte-genau wiederherstellen: Git-Commit auschecken, dvc pull, dvc repro. Wenn das nicht geht, ist die Pipeline kaputt — und das ist eine Information, die man früh haben will, nicht nach drei Monaten Live-Trading.

Praktisches Beispiel: ein Strategie-Backtest mit Code, Daten, Ergebnis.

Letztes Mandantenprojekt, vereinfacht: eine Volatilitäts-Carry-Strategie auf VIX-Futures. Inputs: 4 Jahre tägliche Settlement-Daten (~12 MB), 18 Monate Intraday-Ticks (~6 GB), zwei Macro-Reihen aus FRED. Code: Python, ein paar hundert Zeilen plus Backtest-Loop.

Setup:

Wirkung: jeder Pull-Request zeigt, wie sich Sharpe, Max Drawdown und Trade-Count verändern, wenn ich an einem Feature schraube. Diskussion mit dem Mandanten läuft entlang konkreter Zahlen statt entlang von Eindrücken. Und sechs Wochen später eine Frage beantworten zu können „mit welchen Daten lief der Backtest vom 14. Juni?" ist eine Minute Arbeit, nicht ein halber Tag.

Meine Praxis.

Für ernsthafte Mandanten-Backtests ist DVC für mich Pflicht. Nicht weil ich Tools sammle, sondern weil ohne ein solches System bei jeder Diskussion „aber bei mir kam etwas anderes raus" der Beweis fehlt, dass beide Seiten von denselben Daten reden. Mit DVC ist die Frage in zehn Sekunden geklärt: gleicher Commit, gleicher dvc pull, gleicher Hash — gleiches Ergebnis.

Für persönliche Experimente reicht oft ein lokaler Parquet-Ordner. Für alles, was länger als eine Woche lebt oder von zwei oder mehr Personen angefasst wird, kostet DVC einen Nachmittag Setup und spart in Summe Tage Detektivarbeit. Das ist eine der besten ROI-Investitionen, die ein systematischer Trader machen kann.

Sie wollen reproduzierbare Backtests etablieren, bevor das nächste „warum stimmt das nicht mehr?" auf dem Tisch liegt? Erstgespräch buchen — wir bringen Ihren Quant-Stack auf Versionierungs-Niveau.