← Zurück zu den Artikeln
August 15, 2026
5 min read

Multi-Task Learning for Simultaneous Price, Volume, and Volatility Prediction

Multi-Task Learning for Simultaneous Price, Volume, and Volatility Prediction
#deep-learning
#multi-task
#shared-representation
#prediction
#auxiliary

Multitasking-Lernen (MTL) wird normalerweise mit der Behauptung verkauft: Teilen Sie einen Encoder über korrelierte Ziele hinweg und die primäre Aufgabe wird besser. Beim Handel sind die korrelierten Ziele offensichtlich – Rendite, Volumen und realisierte Volatilität fallen alle aus demselben Auftragsfluss – und diese Behauptung wird fast nie überprüft. Die interessante Frage ist nicht, ob die Aufgaben miteinander zusammenhängen. Es geht darum, ob die gemeinsamen Farbverläufe übereinstimmen und was an den Falten passiert, wo sie nicht übereinstimmen.

In diesem Artikel stehen zwei Dinge im Mittelpunkt, die in den meisten MTL-Aufsätzen als Fußnoten behandelt werden:

  1. Verlustausgleich ist ein Experiment, kein Detail. Feste Gewichte, Kendall-Unsicherheitsgewichtung und GradNorm sind drei verschiedene Modelle. Führen Sie alle drei auf den gleichen Falten aus und geben Sie die gelernten Gewichtungen zusammen mit der Metrik für die primäre Aufgabe für jede an.
  2. Negative Übertragung ist messbar, bevor Sie die Metrik sehen. Die Kosinusähnlichkeit zwischen Aufgabengradienten auf dem gemeinsam genutzten Encoder sagt Ihnen während des Trainings, ob die Hilfsaufgaben die Darstellung dorthin ziehen, wohin die primäre Aufgabe gehen möchte. Unterzeichnen Sie den Kosinus und prüfen Sie dann, ob das Vorzeichen das Ergebnis dieser Falte vorhersagte.

Alles andere in der Pipeline – der Volatilitätsprozess, die Trainingsschleife, die Leckkontrollen, das Validierungsprotokoll – wird bereits an anderer Stelle in diesem Blog behandelt und verlinkt, anstatt erneut abgeleitet zu werden.

Einrichtung

Drei Marktziele, die aus einer gemeinsamen latenten Darstellung hervorgehen

Gegebene Eingabefunktionen xRd\mathbf{x} \in \mathbb{R}^d (OHLCV, technische Indikatoren, Auftragsfluss), drei Ziele:

  • Aufgabe 1 (primär): Rückkehr in die nächste Periode y(1)=rt+1y^{(1)} = r_{t+1}
  • Aufgabe 2 (Hilfsaufgabe): Protokollvolumen der nächsten Periode y(2)=logVt+1y^{(2)} = \log V_{t+1}
  • Aufgabe 3 (Hilfsaufgabe): Realisierte Volatilität der nächsten Periode y(3)=σt+1y^{(3)} = \sigma_{t+1}

Ein Multitask-Modell erzeugt alle drei gleichzeitig, y^=fθ(x)\hat{\mathbf{y}} = f_\theta(\mathbf{x}), und das Multitask-Risiko ist eine gewichtete Summe der Risiken pro Task:

RMTL(θ)=k=1KwkE[(k)(fθ(k)(x),y(k))]\mathcal{R}_{\text{MTL}}(\theta) = \sum_{k=1}^{K} w_k \cdot \mathbb{E}\bigl[\ell^{(k)}(f_\theta^{(k)}(\mathbf{x}), y^{(k)})\bigr]

Im ganzen Artikel geht es um die wkw_k und darüber, was die Farbverläufe pro Aufgabe miteinander machen.

Warum gemeinsames Training hilfreich sein könnte, in einem Absatz. Hilfsaufgaben schränken die gemeinsame Darstellung ein, um mehr als ein Marktphänomen zu erklären, das gleichzeitig eine Kapazitätskontrolle und eine induktive Verzerrung darstellt; Und da Volumen und Volatilität direkt beobachtet werden, die „erwartete Rendite“ jedoch nicht, liefern die Hilfsköpfe ein klareres Gradientensignal als der Primärkopf. Der Fall, dass ein Modell viele Ausgaben aussendet, wird – mit der angeschlossenen Interpretierbarkeitsmaschinerie – ausführlich in Temporal Fusion Transformers for Multi-Horizon Forecasting dargelegt, was das gleiche Shared-Encoder-Many-Heads-Argument für Multi-Horizon-Quantile vorschlägt.

Architektur, kurz

Harte Parameterfreigabe: ein gemeinsam genutzter Encoder gϕg_\phi füttert KK aufgabenspezifische Köpfe hψkh_{\psi_k}, Also y^(k)=hψk(gϕ(x))\hat{y}^{(k)} = h_{\psi_k}(g_\phi(\mathbf{x})). Dies ist die hier gemessene Version, da es sich um die Version handelt, bei der ein Farbverlaufskonflikt auftritt ϕ\phi ist wohldefiniert.

Soft Parameter Sharing gibt jeder Aufgabe einen eigenen Encoder mit einer Kopplungsstrafe λkjϕkϕj2\lambda \sum_{k \neq j} \|\phi_k - \phi_j\|^2 – mehr Parameter, mehr Flexibilität und kein einzelner gemeinsamer Parametervektor, an dem Konflikte gemessen werden könnten. Kreuzstichnetzwerke liegen dazwischen und mischen Funktionen pro Aufgabe durch eine erlernte Matrix αkj\alpha_{kj} auf jeder Ebene. Es lohnt sich, beides auszuprobieren, wenn beim Hard Sharing Konflikte auftreten, und beide außerhalb des Rahmens der folgenden Messung liegen.

Das Experiment, das zählt: Drei Verlustausgleichssysteme

Konkurrierende Aufgabengradienten, die um einen gemeinsamen neuronalen Kern herum ausgeglichen werden

Der naive Verlust L=kwkL(k)\mathcal{L} = \sum_k w_k \mathcal{L}^{(k)} ist maßstabsabhängig. Wenn die Rückflussdämpfung in der Nähe ist 0.010.01 und Volumenverlust herum 1.01.0, das Volumen besitzt den Gradienten und die Rückförderhöhe verhungert. Drei Antworten:

Feste Gewichte. Set wk=1w_k = 1 nach der Standardisierung jedes Ziels. Die ehrliche Grundlinie – wenn sie gewinnt, sind die adaptiven Schemata eine Zeremonie.

Unsicherheitsgewichtung (Kendall et al., 2018). Lernen Sie eine homoskedastische Rauschskala σk\sigma_k pro Aufgabe:

LMTL=k=1K12σk2L(k)+logσk\mathcal{L}_{\text{MTL}} = \sum_{k=1}^{K} \frac{1}{2\sigma_k^2} \mathcal{L}^{(k)} + \log \sigma_k

Aufgaben mit hoher Unsicherheit werden automatisch herabgestuft; Die logσk\log \sigma_k Begriff blockiert das Triviale σk\sigma_k \to \infty Lösung. Beachten Sie dies σk\sigma_k ist ein Verlustgewichtungsgerät für die Trainingszeit, kein Vorhersageintervall – Informationen zur Unsicherheit, mit der Sie tatsächlich eine Position dimensionieren können, finden Sie unter konforme Vorhersage.

GradNorm (Chen et al., 2018). Gleichgewichtsgradienten Größen statt Verlustskalen. Jeder Schritt: Berechnen Gk=ϕwkL(k)2G_k = \|\nabla_\phi w_k \mathcal{L}^{(k)}\|_2 und der Mittelwert Gˉ\bar{G}, berechnen Sie die relative Trainingsrate r~k=L(k)(t)/L(k)(0)rˉ\tilde{r}_k = \frac{\mathcal{L}^{(k)}(t)/\mathcal{L}^{(k)}(0)}{\bar{r}}, und aktualisieren wkwkηwwkkGkGˉr~kαw_k \leftarrow w_k - \eta_w \nabla_{w_k} \sum_k |G_k - \bar{G} \cdot \tilde{r}_k^\alpha|. Alle Aufgaben werden dann unabhängig vom Verlustumfang mit vergleichbaren Raten trainiert.

Der MTL-spezifische Code besteht aus den Köpfen, dem List-Return-Forward und der Verlustaggregation. Der Linear/BatchNorm/ReLU/Dropout-Stack, die Adam/Cosine/Clip-Boilerplate und die Epochenschleife sind die in DeepLOB gezeigten Standardmuster und werden hier weggelassen.

import torch
import torch.nn as nn


class MultiTaskTradingModel(nn.Module):
    """Hard parameter sharing: one encoder, K heads."""

    def __init__(self, encoder: nn.Module, repr_dim: int, n_tasks: int = 3):
        super().__init__()
        self.shared_encoder = encoder          # any MLP/CNN/GRU trunk
        self.task_heads = nn.ModuleList(
            nn.Linear(repr_dim, 1) for _ in range(n_tasks)
        )

    def forward(self, x):
        h = self.shared_encoder(x)
        return [head(h).squeeze(-1) for head in self.task_heads]

    def shared_repr(self, x):
        return self.shared_encoder(x)


class UncertaintyWeightedLoss(nn.Module):
    """Kendall et al. (2018) homoscedastic weighting."""

    def __init__(self, n_tasks: int = 3):
        super().__init__()
        self.log_vars = nn.Parameter(torch.zeros(n_tasks))  # log(sigma^2)

    def forward(self, losses: list) -> torch.Tensor:
        return sum(
            torch.exp(-self.log_vars[i]) * loss + self.log_vars[i]
            for i, loss in enumerate(losses)
        )

    def get_weights(self) -> list:
        with torch.no_grad():
            return [torch.exp(-lv).item() for lv in self.log_vars]

UncertaintyWeightedLoss verfügt über Parameter und muss daher zusammen mit dem Modell in den Optimierer eingefügt werden: optim.Adam(list(model.parameters()) + list(uw.parameters()), ...). Dies zu vergessen ist die häufigste Methode, „Unsicherheitsgewichtungen durchzuführen“ und stattdessen stillschweigend feste Gewichtungen auszuführen.

Was zu melden ist

Für jedes Schema, auf jeder Falte: die erlernten Gewichtungen der endgültigen Aufgabe, die Metrik der primären Aufgabe und – da es sich bei einem Gewichtungsschema um eine Modellauswahl handelt – wie viele Schemata verglichen wurden, bevor eines ausgewählt wurde.

Schema wreturnw_{\text{return}} wvolumew_{\text{volume}} wvolw_{\text{vol}} Metrik für primäre Aufgabe vs. Einzelaufgabe
Behoben (wk=1w_k = 1) 1,00 1,00 1,00
Unsicherheitsgewichtung
GradNorm

Drei Schemata mal mehrere Falten ist schon eine kleine Modellsuche. Jede hier gemeldete Verbesserung muss die in deflated Sharpe und multiple Tests beschriebene Korrektur mehrerer Tests überstehen, bevor sie etwas bedeutet.

Negative Übertragung: Signieren Sie die Farbverläufe

Ausgerichtete und widersprüchliche Aufgabengradienten bei einer gemeinsamen Darstellung

Das ist der Teil, den es wert ist, behalten zu werden. Von einer negativen Übertragung spricht man, wenn Hilfsaufgaben die Hauptaufgabe verschlechtern, und es gibt eine direkte Diagnose: den Winkel zwischen Aufgabengradienten im gemeinsamen Parameterraum.

cos(ϕL(k),ϕL(j))<0    conflicting tasks\cos\bigl(\nabla_\phi \mathcal{L}^{(k)}, \nabla_\phi \mathcal{L}^{(j)}\bigr) < 0 \implies \text{conflicting tasks}

Nur am gemeinsamen Encoder gemessen – die Köpfe sind konstruktionsbedingt aufgabenspezifisch und „stimmen“ immer trivial überein.

import torch.nn.functional as F


def shared_grad(model, x, y, task_idx, criterion=nn.MSELoss()):
    """Gradient of task `task_idx` w.r.t. the shared encoder, flattened."""
    model.zero_grad(set_to_none=True)
    loss = criterion(model(x)[task_idx], y)
    loss.backward()
    return torch.cat([
        p.grad.detach().flatten()
        for p in model.shared_encoder.parameters()
        if p.grad is not None
    ])


def task_conflict(model, x, y_by_task, task_names):
    """Pairwise cosine similarity between per-task shared-encoder gradients."""
    grads = {
        name: shared_grad(model, x, y_by_task[name], i)
        for i, name in enumerate(task_names)
    }
    return {
        (a, b): F.cosine_similarity(
            grads[a].unsqueeze(0), grads[b].unsqueeze(0)
        ).item()
        for i, a in enumerate(task_names)
        for b in task_names[i + 1:]
    }

Rufen Sie dies während des Trainings in einer durchgehaltenen Gruppe mit einer festen Kadenz auf, nicht einmal am Ende. Ein Paar kann zunächst ausgerichtet sein und auseinanderlaufen, wenn sich der Encoder spezialisiert; Eine einzelne Abschlussnummer verbirgt dies.

Der Befund, nach dem man suchen und den man so oder so veröffentlichen sollte:

Paar cos sim, frühes Training cos sim, spätes Training MTL hat bei der Hauptaufgabe geholfen?
zurück ↔ Volumen
Rendite ↔ Volatilität
Volumen ↔ Volatilität

Wenn Volumen- und Volatilitätsgradienten miteinander übereinstimmen, während beide mit dem Rückgabegradienten in Konflikt stehen, ist die richtige Schlussfolgerung, dass die beiden Hilfsaufgaben einen kohärenten Block bilden, zu dem die Rückgabeaufgabe nicht gehört – und die Lösung ist die Aufgabengruppierung, nicht mehr Kapazität. Wenn ein Konflikt real ist, sind die Standardlösungen PCGrad (Yu et al., 2020), das jeden widersprüchlichen Gradienten auf die Normalebene des anderen projiziert; CAGrad (Liu et al., 2021), das nach einer Abstiegsrichtung sucht, die keiner Aufgabe schadet; oder die Hilfsaufgabe ganz fallen lassen.

Beachten Sie, was bewusst fehlt: ein t-SNE-Diagramm der gemeinsamen Darstellung, gefärbt nach Zielwert. Es ist dekorativ – die Kosinuszahlen oben sagen alles aus, worauf die Einbettung hinweisen würde, und sie sagen es als Zahlen.

Validierungsprotokoll

Getrennte Walk-Forward-Validierungsfenster über einen Forschungszeitraum hinweg

Die obige Messung ist unter einem schlampigen Protokoll wertlos, und MTL macht die üblichen Fallen noch schlimmer, weil es drei Ziele gibt, die durchgesickert sind, statt eines.

Echte Daten, kein Simulator. Die Ziele müssen aus tatsächlichen OHLCV-/Handelsdaten stammen. Ein fest codiertes GARCH-Spielzeug erzeugt Volatilität, die konstruktionsbedingt mit Renditen korreliert, was genau das ist, was getestet wird – das Experiment würde seinen eigenen Generator messen. Wenn Sie einen angepassten Volatilitätsprozess wünschen, passt GARCH-Volatilitätsprognose für Krypto GARCH(1,1) nach maximaler Wahrscheinlichkeit an reale BTC/ETH an und validiert die standardisierten Residuen, und asymmetrisches GARCH und der Leverage-Effekt erläutert, warum eine Gaußsche Funktion verwendet wird Der Symmetry-Response-Simulator gibt die Kryptovolatilität von vornherein falsch an. Synthetische Daten sind nur dann vertretbar, wenn sie eine kontrollierte Grundwahrheit liefern – eine bekannte, vom Autor festgelegte Aufgabenkorrelation, die Sie wiederherzustellen versuchen –, was ein anderes Experiment als das hier ist.

Skalierer passen nur auf den Zug. Platzieren Sie den Feature-Skalierer und alle drei Ziel-Skalierer in jeder Trainingsfalte und wenden Sie sie auf die Validierung an; ein globaler fit_transform Bevor Sie Lecks aufteilen, testen Sie Momente in das Training. Dieser genaue Fehler ist in der Look-Ahead-Bias-Taxonomie katalogisiert.

Gelöschte, mit einem Embargo belegte Walk-Forward-Falten. Eine 80/20-chronologische Aufteilung kann eine MTL-Verbesserung nicht von einem Fold-Effekt unterscheiden – das ist das gesamte Argument der Walk-Forward-Optimierung, das zeigt, dass drei Aufteilungen zu drei Schlussfolgerungen führen. Verwenden Sie das Erweiterungsfenster erneut purged_walk_forward Generator von Spread-Modellierung mit maschinellem Lernen: Es schließt eine Lücke von horizon Zeilen auf beiden Seiten jeder Grenze, was hier wichtig ist, da überlappende Fenster der realisierten Volatilität über die Grenze hinweg auslaufen, selbst wenn das Renditeziel dies nicht tut.

Eine klassische Grundlinie. Ein MTL-Netz, das drei Einzelaufgabennetze übertrifft, hat nichts bewiesen, wenn ein Gradientenverstärkungs- oder Ridge-Modell pro Ziel alle vier übertrifft. Passen Sie ein Modell pro Ziel mit LightGBM oder Grat an denselben Falten und denselben Merkmalen an und geben Sie es in derselben Tabelle an.

Modell Primäre Aufgabenmetrik Notizen
Grat, pro Ziel Klassische Grundlinie
LightGBM, pro Ziel Klassische Grundlinie
Einzeltask-MLP, pro Ziel Drei separate Netze
MTL, bestes Verlustschema Ein Netz, drei Köpfe

Was würde MTL hier lohnenswert machen?

Eine gemessene Entscheidungsschwelle für die Komplexität von Multitask-Modellen

Bedingungen, unter denen MTL gewinnen sollte, angegeben als Hypothesen zur Überprüfung anhand der oben genannten Falten und nicht als Checkliste:

  • Hilfsetiketten sind sauberer als das Primäretikett. Das Volumen wird direkt beobachtet; „erwartete Rendite“ ist es nicht. Wenn der Rücklaufkopf größtenteils aus passendem Rauschen besteht, ist das Gradientensignal von den Hilfsköpfen der einzige gut positionierte Teil des Objektivs.
  • Trainingsdaten sind im Verhältnis zur Encoderkapazität begrenzt, sodass die Hilfsbeschränkung echte Regularisierungsarbeit leistet und nicht nur um Parameter konkurriert. – Die Inferenzlatenz ist wichtig und ein Vorwärtspass schlägt drei.

Und der Fall dagegen, ebenso prüfbar: wenn das gemessen wird cos_sim(return, ·) Die Werte sind dauerhaft negativ, der gemeinsame Encoder wird von der primären Aufgabe abgezogen und die Hilfsköpfe sind eine Steuer, kein Regularisierer.

Fazit

Harmonisierte Vorhersageströme, die sich in einer Multitask-Schlussfolgerung auflösen

Renditen, Volumen und Volatilität stammen aus derselben Mikrostruktur, daher ist eine gemeinsame Darstellung ein vernünftiger Prior – aber ein Prior ist kein Ergebnis. Die beiden Dinge, die dieses Setup tatsächlich feststellen kann, sind, welches Verlustausgleichsschema die Daten bevorzugen (mit den erlernten Gewichtungen werden berichtet, nicht nur der Gewinner genannt) und ob die Aufgabengradienten auf dem gemeinsam genutzten Encoder übereinstimmen, gemessen über das Training und nicht aufgrund der Tatsache, dass die Ziele korrelieren.

Wenn die bereinigten Walk-Forward-Falten zeigen, dass das MTL-Netz ein Gradienten-verstärkendes Modell pro Ziel nicht schlagen kann, ist das das Ergebnis und wird als solches veröffentlicht – die Vorlage ist das ehrliche Negativ. Ein negatives Ergebnis einer negativen Übertragung ist immer noch ein Ergebnis einer negativen Übertragung.

blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Dem Markt einen Schritt voraus

Abonniere unseren Newsletter für exklusive KI-Trading-Einblicke, Marktanalysen und Plattform-Updates.

Wir respektieren deine Privatsphäre. Jederzeit abbestellbar.