3
konzentrieren Sie sich auf
1444
Anhänger

Ein leistungsstarkes Tool für programmatische Händler: Inkrementeller Update-Algorithmus zur Berechnung von Mittelwert und Varianz

Erstellt in: 2023-11-08 16:28:36, aktualisiert am: 2024-11-08 09:13:54
comments   0
hits   1735

Ein leistungsstarkes Tool für programmatische Händler: Inkrementeller Update-Algorithmus zur Berechnung von Mittelwert und Varianz

Einführung

Beim programmatischen Handel ist häufig die Berechnung von Durchschnitt und Varianz erforderlich, beispielsweise bei der Berechnung von Indikatoren wie gleitenden Durchschnitten und Volatilität. Wenn wir hochfrequente und langfristige Berechnungen benötigen, müssen wir historische Daten langfristig aufbewahren, was unnötig und zeit- und ressourcenintensiv ist. In diesem Dokument wird ein Online-Aktualisierungsalgorithmus zur Berechnung gewichteter Durchschnittswerte und Varianzen vorgestellt, der insbesondere für die Verarbeitung von Echtzeit-Datenströmen und die dynamische Anpassung von Handelsstrategien, insbesondere Hochfrequenzstrategien, wichtig ist. Der Artikel bietet auch eine entsprechende Python-Codeimplementierung, um Händlern zu helfen, diesen Algorithmus schnell bereitzustellen und in tatsächlichen Transaktionen anzuwenden.

Einfacher Mittelwert und Varianz

Wenn wir \(\mu_n\) verwenden, um den Durchschnitt des \(n\)ten Datenpunkts darzustellen, vorausgesetzt, dass wir bereits den Durchschnitt von \(\mu_{n-1}\) des \({n-1}\)ten Datenpunkts berechnet haben , jetzt wird ein neuer Datenpunkt \(x_{n}\) empfangen. Wir möchten den neuen Mittelwert \(\mu_{n}\) berechnen, der diesen neuen Datenpunkt enthält. Es folgt eine detaillierte Herleitung.

\(\mu_n = \frac{1}{n} \sum_{i=1}^{n} x_i\) \(\mu_n = \frac{1}{n} \left( x_n + \sum_{i=1}^{n-1} x_i \right)\) \(\mu_{n-1} = \frac{1}{n-1} \sum_{i=1}^{n-1} x_i\) \((n-1)\mu_{n-1} = \sum_{i=1}^{n-1} x_i\) \(\mu_n = \frac{1}{n} \left( x_n + (n-1)\mu_{n-1} \right)\) \(\mu_n = \mu_{n-1} + \frac{1}{n} (x_n - \mu_{n-1})\)

Der Varianzaktualisierungsprozess kann in die folgenden Schritte zerlegt werden:

\(S_n = \sum_{i=1}^{n} (x_i - \mu_n)^2\) \(S_n = \sum_{i=1}^{n} x_i^2 - n\mu_n^2\) \(S_n - S_{n-1} = x_n^2 - n\mu_n^2 + (n - 1)\mu_{n-1}^2\) \(S_n - S_{n-1} = (x_n - \mu_{n-1})(x_n - \mu_n)\) \(S_n = S_{n-1} + (x_n - \mu_{n-1})(x_n - \mu_n)\) \(\sigma_n^2 = \frac{S_n}{n}\)

Wie aus den beiden obigen Formeln ersichtlich ist, ermöglicht uns dieser Prozess, den neuen Mittelwert und die Varianz zu aktualisieren, indem wir beim Empfang jedes neuen Datenpunkts \(x_n\) nur den Mittelwert und die Varianz der vorherigen Daten beibehalten, ohne historische Daten zu speichern. und die Die Berechnung ist schneller. Das Problem besteht jedoch darin, dass auf diese Weise der Mittelwert und die Varianz der gesamten Stichprobe berechnet werden, während wir bei der tatsächlichen Strategie einen bestimmten festen Zeitraum berücksichtigen müssen. Wenn wir die Mittelwertaktualisierung oben beobachten, können wir sehen, dass der neue Mittelwertaktualisierungsbetrag die Abweichung der neuen Daten vom bisherigen Mittelwert multipliziert mit einem Verhältnis ist. Wenn dieses Verhältnis festgelegt ist, erhalten wir den exponentiell gewichteten Durchschnitt, den wir als Nächstes besprechen werden.

Exponentiell gewichteter Mittelwert

Der exponentiell gewichtete Durchschnitt kann durch die folgende rekursive Beziehung definiert werden:

\(\mu_t = \alpha x_t + (1 - \alpha) \mu_{t-1}\)

wobei \(\mu_t\) der exponentiell gewichtete Mittelwert zum Zeitpunkt \(t\), \(x_t\) der beobachtete Wert zum Zeitpunkt \(t\), \(\alpha\) der Gewichtungsfaktor und \(\mu_{t-1}\) ist. ist der exponentiell gewichtete Durchschnitt des vorherigen Zeitpunkts.

Exponentiell gewichtete Varianz

Für die Varianz müssen wir den exponentiell gewichteten Durchschnitt der quadrierten Abweichungen zu jedem Zeitpunkt berechnen. Dies kann durch die folgende Rekurrenzrelation erreicht werden:

\(S_n = \alpha S_{n-1} + (1 - \alpha)(x_n - \mu_n)(x_n - \mu_{n-1})\)

wobei \(\sigma_t^2\) die exponentiell gewichtete Varianz zum Zeitpunkt \(t\) und \(\sigma_{t-1}^2\) die exponentiell gewichtete Varianz zum vorherigen Zeitpunkt ist.

Beobachten Sie den exponentiell gewichteten Mittelwert und die Varianz. Ihre inkrementellen Aktualisierungsformen entsprechen der Intuition. Beide behalten einen Teil des vergangenen Werts bei und fügen die neue Änderung hinzu. Der spezifische Ableitungsprozess kann in diesem Dokument nachgelesen werden: https://fanf2.user .srcf.net/hermes/doc/antiforgery/stats.pdf

Einfacher gleitender Durchschnitt (SMA) vs. exponentieller gleitender Durchschnitt (EMA)

Der einfache Durchschnitt (auch arithmetisches Mittel genannt) und der exponentiell gewichtete Durchschnitt sind zwei gängige statistische Maße mit jeweils unterschiedlichen Eigenschaften und Verwendungszwecken. Der einfache Mittelwert gewichtet jede Beobachtung gleich und spiegelt die zentrale Lage des Datensatzes wider. Der exponentiell gewichtete Durchschnitt ist eine rekursive Berechnung, die aktuelleren Beobachtungen mehr Gewicht verleiht. Das Gewicht nimmt exponentiell ab, je weiter die Beobachtung vom aktuellen Zeitpunkt entfernt ist.

  • Gewichtsverteilung: Der einfache Durchschnitt gewichtet jeden Datenpunkt gleich, während der exponentiell gewichtete Durchschnitt den aktuellsten Datenpunkten ein höheres Gewicht zuweist.
  • Sensibilität gegenüber neuen Informationen: Der einfache Durchschnitt reagiert nicht empfindlich genug auf neu hinzugefügte Daten, da hierfür alle Datenpunkte neu berechnet werden müssen. Exponentiell gewichtete Durchschnittswerte können Änderungen in den neuesten Daten schneller widerspiegeln.
  • Rechenkomplexität: Die Berechnung des einfachen Durchschnitts ist relativ einfach, aber mit zunehmender Anzahl der Datenpunkte steigen auch die Berechnungskosten. Der exponentiell gewichtete Durchschnitt ist komplexer zu berechnen, kann aufgrund seiner rekursiven Natur jedoch bei kontinuierlichen Datenströmen effizienter sein.

EMA- und SMA-Näherungsumrechnungsmethode

Obwohl sich der einfache Durchschnitt und der exponentiell gewichtete Durchschnitt konzeptionell unterscheiden, können wir den exponentiell gewichteten Durchschnitt für eine bestimmte Anzahl von Beobachtungen an einen einfachen Durchschnitt annähern, indem wir einen geeigneten Wert für \(\alpha\) wählen. Diese ungefähre Beziehung kann durch die effektive Stichprobengröße beschrieben werden, die eine Funktion des Gewichtungsfaktors \(\alpha\) im exponentiell gewichteten Durchschnitt ist.

Der Simple Moving Average (SMA) ist das arithmetische Mittel aller Preise innerhalb eines bestimmten Zeitfensters. Für ein Zeitfenster \(N\) kann der Schwerpunkt des SMA (wo der Mittelwert ist) wie folgt betrachtet werden:

\(\text{SMA-Schwerpunkt} = \frac{1 + N}{2}\)

Der exponentielle gleitende Durchschnitt (EMA) ist ein gewichteter Durchschnitt, bei dem aktuellere Datenpunkte ein größeres Gewicht haben. Das Gewicht der EMA nimmt mit der Zeit exponentiell ab. Der Schwerpunkt der EMA kann durch Summieren der folgenden Reihen ermittelt werden:

\(\text{EMA-Schwerpunkt} = \alpha \times \left[1 + 2(1 - \alpha) + 3(1 - \alpha)^2 + \cdots \right] = \frac{1}{\alpha}\)

Wenn wir davon ausgehen, dass SMA und EMA den gleichen Schwerpunkt haben, erhalten wir:

\(\frac{1 + N}{2} = \frac{1}{\alpha}\)

Durch Lösen dieser Gleichung erhalten wir die Beziehung zwischen \(\alpha\) und \(N\):

\(\alpha = \frac{2}{N + 1}\)

Dies bedeutet, dass für einen gegebenen N-Tage-SMA der entsprechende Alpha-Wert verwendet werden kann, um einen „äquivalenten“ EMA zu berechnen, sodass beide den gleichen Schwerpunkt haben und die Ergebnisse sehr ähnlich sind.

Konvertierung von EMA mit unterschiedlichen Aktualisierungsfrequenzen

Angenommen, wir haben eine EMA, die jede Sekunde mit einem Gewichtungsfaktor von \(\alpha_1\) aktualisiert wird. Dies bedeutet, dass jede Sekunde ein neuer Datenpunkt mit einem Gewicht von \(\alpha_1\) zum EMA hinzugefügt wird, während der Einfluss alter Datenpunkte mit \(1 - \alpha_1\) multipliziert wird.

Wenn wir die Aktualisierungsfrequenz ändern, beispielsweise auf alle \(f\) Sekunden, möchten wir einen neuen Gewichtungsfaktor \(\alpha_2\) finden, sodass die Gesamtauswirkung eines Datenpunkts innerhalb von \(f\) Sekunden dieselbe ist wie bei einer Aktualisierung jede Sekunde. .

Wenn keine Aktualisierungen vorgenommen werden, nimmt der Einfluss der alten Datenpunkte über \(f\) Sekunden kontinuierlich \(f\)-mal ab, jedes Mal multipliziert mit \(1 - \alpha_1\). Daher beträgt der gesamte Abklingfaktor nach \(f\) Sekunden \((1 - \alpha_1)^f\).

Damit die alle \(f\) Sekunden aktualisierte EMA in einem Aktualisierungszyklus den gleichen Abklingeffekt hat wie die einmal pro Sekunde aktualisierte EMA, setzen wir den Gesamtabklingfaktor nach \(f\) Sekunden so, dass er dem Abklingfaktor in einer Aktualisierung entspricht. Zyklus:

\((1 - \alpha_1)^f = 1 - \alpha_2\)

Durch Lösen dieser Gleichung erhalten wir den neuen Gewichtungsfaktor \(\alpha_2\):

\(\alpha_2 = 1 - (1 - \alpha_1)^f\)

Diese Formel liefert eine Näherung für den neuen Gewichtungsfaktor \(\alpha_2\), der den EMA-Glättungseffekt konstant hält, wenn sich die Aktualisierungsfrequenz ändert. Wir berechnen beispielsweise den Preismittelwert \(\alpha_1\) als 0,001 und aktualisieren den neuesten Preis alle 10 Sekunden. Wenn wir ihn auf 1 Sekunde ändern, beträgt das Äquivalent \(\alpha_2\) etwa 0,01

Python-Code-Implementierung

class ExponentialWeightedStats:
    def __init__(self, alpha):
        self.alpha = alpha
        self.mu = 0
        self.S = 0
        self.initialized = False

    def update(self, x):
        if not self.initialized:
            self.mu = x
            self.S = 0
            self.initialized = True
        else:
            temp = x - self.mu
            new_mu = self.mu + self.alpha * temp
            self.S = self.alpha * self.S + (1 - self.alpha) * temp * (x - self.mu)
            self.mu = new_mu

    @property
    def mean(self):
        return self.mu

    @property
    def variance(self):
        return self.S

# 使用示例
alpha = 0.05  # 权重因子
stats = ExponentialWeightedStats(alpha)
data_stream = [] # 数据流
for data_point in data_stream:
    stats.update(data_point)

Zusammenfassen

Beim hochfrequenten programmatischen Handel ist die schnelle Verarbeitung von Echtzeitdaten von entscheidender Bedeutung. Um die Rechenleistung zu verbessern und den Ressourcenverbrauch zu reduzieren, stellt dieses Dokument einen Online-Aktualisierungsalgorithmus zur kontinuierlichen Berechnung des gewichteten Mittelwerts und der Varianz eines Datenstroms vor. Die Berechnung inkrementeller Aktualisierungen in Echtzeit kann auch zur Berechnung verschiedener statistischer Daten und Indikatoren verwendet werden, wie z. B. der Korrelation zwischen zwei Vermögenspreisen, der linearen Anpassung usw., was großes Potenzial birgt. Inkrementelle Aktualisierungen behandeln Daten als Signalsystem, was im Vergleich zu Berechnungen mit festem Zeitraum eine Weiterentwicklung des Denkens darstellt. Wenn Ihre Strategie auch einen Teil zum Speichern historischer Datenberechnungen enthält, können Sie ihn auch entsprechend dieser Idee modifizieren, also nur die Schätzung des Systemstatus aufzeichnen und den Systemstatus aktualisieren, wenn neue Daten eintreffen, und so weiter.