Programmierte Trader-Leistung: Inkrementelle Aktualisierung Algorithmen Berechnung von Mittelwerten und Differenzen

Schriftsteller:Das Gras, Erstellt: 2023-11-08 16:28:36, aktualisiert: 2023-11-09 20:46:17

img

Lebenslauf

Bei programmierter Handel ist es häufig notwendig, Mittelwerte und Differenzen zu berechnen, wie bei der Berechnung von Indikatoren wie Ebenen und Volatilitäten. Wenn wir hohe Frequenzen und langfristige Berechnungen benötigen, ist es notwendig, lange Zeit mit historischen Daten zu verbringen, was unnötig und ressourcenbedürftig ist. In diesem Artikel wird ein Online-Update-Algorithmus für die Berechnung von gewichteten Mittelwerten und Differenzen vorgestellt, der besonders wichtig ist, um mit Echtzeitdatenströmen und dynamisch angepassten Handelsstrategien, insbesondere mit Hochfrequenzstrategien, umzugehen.

Einfache Mittel und Quadratunterschiede

Wenn wir den Durchschnitt des $\mu_n$ Datensatzes mit $\mu_n$ darstellen, nehmen wir an, dass wir die Durchschnittszahl der ${n-1}$ Datensätze $\mu_{n-1}$ berechnet haben, und jetzt erhalten wir einen neuen Datensatz $x_{n}$. Wir wollen den neuen Durchschnittswert $\mu_{n}$ berechnen, der diesen neuen Datensatz enthält.

$\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$ Das ist der Punkt, an dem wir uns befinden. $\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 Prozess der Differenz-Aktualisierung kann in folgende Schritte unterteilt 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}) $S_n = S_{n-1} + (x_n - \mu_{n-1}) $\sigma_n^2 = \frac{S_n}{n}$

Wie aus den beiden oben genannten Formeln zu sehen ist, erlaubt uns dieser Prozess, bei jedem neuen Datenpunkt $x_n$, bei dem wir nur die Mittelwerte und Differenzen der ersten Daten erhalten, neue Mittelwerte und Differenzen zu aktualisieren, ohne dass die historischen Daten gespeichert werden müssen, und die Berechnung ist schneller.

Exponentiell gewichtete Mittel

Die Index-gewichtete Durchschnittszahl kann durch folgende Recurrence-Beziehung definiert werden:

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

Hierbei ist $\mu_t$ das Index-gewichtete Durchschnitt von $t$, $x_t$ das Beobachtungswert von $t$, $\alpha$ der Gewichtungsfaktor und $\mu_{t-1}$ das Index-gewichtete Durchschnitt von $t$.

Die exponentiell gewichtete Varianz

Für die Differenz müssen wir den Index-Gewähren-Durchschnitt der Quadratdifferenz für jeden Zeitpunkt berechnen.

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

$\sigma_t^2$ ist die exponentielle Quadratdifferenz von $\sigma_t^2$ und $\sigma_{t-1}^2$ ist die exponentielle Quadratdifferenz von $\sigma_t^2$.

Beobachtungsindex mit Gewichtungsdurchschnitt und Quadrat, deren inhaltlich intuitiv erweiterte Form einen Teil des vergangenen Wertes beibehält, mit neuen Veränderungen verbunden. Ein konkreter Herangehensprozess kann auf diese Arbeit verwiesen werden:https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf

Einfacher beweglicher Durchschnitt (SMA) und Index-Beweglicher Durchschnitt (EMA)

Einfache Durchschnitte (auch Arithmetische Durchschnitte genannt) und Indexgewichtete Durchschnitte sind zwei häufige statistische Messungen, die jeweils unterschiedliche Eigenschaften und Zwecke haben. Einfache Durchschnitte geben jedem Beobachtungswert die gleiche Gewichtung, da sie die zentrale Position des Datensatzes widerspiegeln. Einfache Gewichtete Durchschnitte sind eine regressive Berechnung, die dem jüngsten Beobachtungswert eine höhere Gewichtung gibt.

  • GewichtsverteilungEin einfaches Durchschnitt gibt jedem Datenpunkt das gleiche Gewicht, während ein Index-gewichtetes Durchschnitt dem nächsten Datenpunkt ein höheres Gewicht gibt.
  • Sensibilität für neue InformationenEinfache Durchschnitte sind nicht empfindlich genug für neu hinzugefügte Daten, da sie eine Umrechnung aller Datenpunkte beinhalten. Indikatorgewichtete Durchschnitte können Veränderungen der neuesten Daten schneller widerspiegeln.
  • Komplexität der Berechnung: Die Berechnung von einfachen Durchschnitten ist relativ einfach, aber mit zunehmender Anzahl von Datenpunkten steigt auch die Berechnungskosten. Die Berechnung von Index-gewichteten Durchschnitten ist komplexer, aber aufgrund ihrer rekursiven Natur kann sie kontinuierliche Datenströme effizienter verarbeiten.

EMA und SMA werden in etwa umgerechnet

Obwohl einfache Mittelwerte und Index-gewichtete Mittelwerte konzeptionell unterschiedlich sind, können wir die Index-gewichtete Mittelwerte annähernd einem einfachen Mittelwert ähnlich machen, der bestimmte quantitative Beobachtungswerte enthält. Diese Annäherung kann durch die effektiven Stichprobengröße beschrieben werden, die eine Funktion des Gewichtungsfaktors $\alpha$ in den Index-gewichteten Mittelwerten ist.

Ein einfacher gleitender Durchschnitt (SMA) ist der arithmetische Durchschnitt aller Preise in einem bestimmten Zeitfenster. Für ein Zeitfenster von $N$ kann der Mittelpunkt des SMA (d. h. der Ort, an dem sich die Durchschnittszahlen befinden) als:

$\text{SMA} ist gleich \frac{1 + N}{2} $

Ein EMA ist ein gewogenes Durchschnitt, bei dem die nächsten Datenpunkte ein größeres Gewicht haben. Das Gewicht der EMA sinkt mit der Zeitindexstufe.

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

Wenn wir annehmen, dass die SMA und die EMA die gleiche Masse haben, erhalten wir:

$\frac{1 + N}{2} = \frac{1}{\alpha}$

Wenn wir diese Gleichung lösen, bekommen wir die Beziehung zwischen $\alpha$ und $N$:

$\alpha = \frac{2}{N + 1}$

Dies bedeutet, dass für eine gegebene SMA von $N$ Tage der entsprechende $\alpha$-Wert verwendet werden kann, um eine EMA mit einem Anschluss zu berechnen, so dass beide die gleiche Masse haben und die Ergebnisse sehr nahe sind.

Wechsel von unterschiedlichen EMA-Aktualisierungsfrequenzen

Angenommen, wir haben eine EMA, die sich pro Sekunde aktualisiert, und deren Gewichtungsfaktor $\alpha_1$ ist. Das bedeutet, dass jede Sekunde neue Datenpunkte mit einem Gewicht von $\alpha_1$ in die EMA hinzugefügt werden, während die Auswirkungen der alten Datenpunkte mit $1 - \alpha_1$ multipliziert werden.

Wenn wir die Frequenz der Aktualisierungen ändern, z. B. einmal pro $f$ Sekunde, wollen wir einen neuen Gewichtungsfaktor $\alpha_2$ finden, so dass die Gesamtwirkung der Datenpunkte in $f$ Sekunden die gleiche ist wie bei der Aktualisierung pro Sekunde.

In $f$ Sekunden wird der Einfluss des alten Datensatzes $f$ mal in Folge verringert, wenn keine Aktualisierung durchgeführt wird, jedes Mal mit $1 - \alpha_1$. Daher ist der Gesamtverfallfaktor nach $f$ Sekunden $(1 - \alpha_1) ^f$.

Um zu erreichen, dass eine EMA, die einmal $f$ Sekunden aktualisiert wird, die gleiche Abnahmewirkung in einem Updatezyklus hat wie eine EMA, die einmal pro Sekunde aktualisiert wird, setzen wir den Gesamtabfallfaktor nach $f$ Sekunden auf den Abfallfaktor in einem Updatezyklus:

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

Wenn wir diese Gleichung lösen, bekommen wir den neuen Gewichtungsfaktor $\alpha_2$:

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

Diese Formel gibt einen Annäherungswert für den neuen Gewichtungsfaktor $\alpha_2$, der bei der Frequenzänderung die EMA-Glanzwirkung unverändert hält.

Implementierung des Python-Codes

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)

Zusammenfassung

Die schnelle Verarbeitung von Echtzeitdaten ist in der Hochfrequenz-Programmierung von entscheidender Bedeutung. Um die Rechenleistung zu steigern und den Ressourcenverbrauch zu reduzieren, wird in diesem Artikel ein Online-Aktualisierungs-Algorithmus vorgestellt, mit dem die Gewichtungs- und Differenzquoten der Datenströme kontinuierlich berechnet werden. Echtzeit-Inkrementelle Aktualisierungen können auch für die Berechnung verschiedener Statistiken und Indikatoren verwendet werden, wie z. B. der Preisverknüpfung von zwei Vermögenswerten, der linearen Passform usw.


Mehr