
En el trading programático, a menudo es necesario calcular el promedio y la varianza, como cuando se calculan indicadores como los promedios móviles y la volatilidad. Cuando necesitamos cálculos de alta frecuencia y de largo plazo, necesitamos conservar datos históricos de largo plazo, lo cual es innecesario y consume mucho tiempo y recursos. Este artículo presenta un algoritmo de actualización en línea para calcular promedios ponderados y varianzas, lo cual es particularmente importante para procesar flujos de datos en tiempo real y ajustar dinámicamente estrategias comerciales, especialmente estrategias de alta frecuencia. El artículo también proporciona la implementación del código Python correspondiente para ayudar a los comerciantes a implementar y aplicar rápidamente este algoritmo en transacciones reales.
Si usamos \(\mu_n\) para representar el promedio del \(n\)ésimo punto de datos, asumiendo que ya hemos calculado el promedio de \(\mu_{n-1}\) del \({n-1}\)ésimo punto de datos , ahora se recibe un nuevo punto de datos \(x_{n}\). Queremos calcular la nueva media \(\mu_{n}\) que incluye este nuevo punto de datos. La siguiente es una derivación detallada.
\(\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})\)
El proceso de actualización de varianza se puede descomponer en los siguientes pasos:
\(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}\)
Como se puede ver en las dos fórmulas anteriores, este proceso nos permite actualizar la nueva media y varianza conservando solo la media y varianza de los datos anteriores al recibir cada nuevo punto de datos \(x_n\), sin guardar los datos históricos. El cálculo es más rápido. Pero el problema es que lo que se calcula de esta manera es la media y la varianza de toda la muestra, mientras que en la estrategia real necesitamos considerar un cierto período fijo. Al observar la actualización de la media anterior, podemos ver que la nueva cantidad de actualización de la media es la desviación de los nuevos datos respecto de la media anterior multiplicada por una razón. Si esta razón es fija, obtendremos la media ponderada exponencial que analizaremos a continuación.
El promedio ponderado exponencial se puede definir mediante la siguiente relación recursiva:
\(\mu_t = \alpha x_t + (1 - \alpha) \mu_{t-1}\)
donde \(\mu_t\) es la media ponderada exponencialmente en el punto de tiempo \(t\), \(x_t\) es el valor observado en el punto de tiempo \(t\), \(\alpha\) es el factor de ponderación y \(\mu_{t-1}\) es el Es el promedio ponderado exponencialmente del punto de tiempo anterior.
Para la varianza, necesitamos calcular el promedio ponderado exponencial de las desviaciones al cuadrado en cada punto temporal. Esto se puede lograr mediante la siguiente relación de recurrencia:
\(S_n = \alpha S_{n-1} + (1 - \alpha)(x_n - \mu_n)(x_n - \mu_{n-1})\)
donde \(\sigma_t^2\) es la varianza ponderada exponencialmente en el punto de tiempo \(t\), y \(\sigma_{t-1}^2\) es la varianza ponderada exponencialmente en el punto de tiempo anterior.
Observe la media y la varianza ponderadas exponencialmente. Sus formas de actualización incremental están en línea con la intuición. Ambas conservan parte del valor pasado y agregan el nuevo cambio. El proceso de derivación específico se puede consultar en este artículo: https://fanf2.user .srcf.net/hermes/doc/antiforgery/estadisticas.pdf
El promedio simple (también conocido como media aritmética) y el promedio ponderado exponencial son dos medidas estadísticas comunes, cada una con diferentes características y usos. La media simple otorga el mismo peso a cada observación y refleja la ubicación central del conjunto de datos. El promedio ponderado exponencial es un cálculo recursivo que otorga más peso a las observaciones más recientes. El peso disminuye exponencialmente a medida que la observación se aleja del tiempo actual.
Aunque el promedio simple y el promedio ponderado exponencial son conceptualmente diferentes, podemos hacer que el promedio ponderado exponencial se aproxime a un promedio simple para un número específico de observaciones eligiendo un valor apropiado de \(\alpha\). Esta relación aproximada se puede describir mediante el tamaño efectivo de la muestra, que es una función del factor de ponderación \(\alpha\) en el promedio ponderado exponencial.
La media móvil simple (SMA) es la media aritmética de todos los precios dentro de una ventana de tiempo determinada. Para una ventana de tiempo \(N\), el centroide de la SMA (donde está la media) puede considerarse como:
\(\text{Centroide SMA} = \frac{1 + N}{2}\)
La media móvil exponencial (EMA) es una media ponderada donde los puntos de datos más recientes tienen mayor peso. El peso de la EMA disminuye exponencialmente con el tiempo. El centroide de la EMA se puede obtener sumando las siguientes series:
\(\text{centroide EMA} = \alpha \times \left[1 + 2(1 - \alpha) + 3(1 - \alpha)^2 + \cdots \right] = \frac{1}{\alpha}\)
Cuando asumimos que SMA y EMA tienen el mismo centro de masa, obtenemos:
\(\frac{1 + N}{2} = \frac{1}{\alpha}\)
Resolviendo esta ecuación, podemos obtener la relación entre \(\alpha\) y \(N\):
\(\alpha = \frac{2}{N + 1}\)
Esto significa que, para una media móvil simple (SMA) de \(N\) días dada, el valor \(\alpha\) correspondiente se puede utilizar para calcular una EMA “equivalente” de modo que ambos tengan el mismo centro de masa y los resultados sean muy similares.
Supongamos que tenemos una EMA que se actualiza cada segundo con un factor de ponderación de \(\alpha_1\). Esto significa que cada segundo, se agrega un nuevo punto de datos a la EMA con un peso de \(\alpha_1\), mientras que el impacto de los puntos de datos antiguos se multiplica por \(1 - \alpha_1\).
Si cambiamos la frecuencia de actualización, digamos para actualizar cada \(f\) segundos, queremos encontrar un nuevo factor de peso \(\alpha_2\) tal que el impacto total de un punto de datos dentro de \(f\) segundos sea el mismo que cuando se actualiza cada segundo. .
Durante \(f\) segundos, si no se realizan actualizaciones, la influencia de los puntos de datos antiguos decaerá continuamente \(f\) veces, cada vez multiplicada por \(1 - \alpha_1\). Por lo tanto, el factor de decaimiento total después de \(f\) segundos es \((1 - \alpha_1)^f\).
Para que la EMA actualizada cada \(f\) segundos tenga el mismo efecto de decaimiento en un ciclo de actualización que la EMA actualizada una vez por segundo, establecemos el factor de decaimiento total después de \(f\) segundos para que sea igual al factor de decaimiento en una actualización. ciclo:
\((1 - \alpha_1)^f = 1 - \alpha_2\)
Resolviendo esta ecuación, obtenemos el nuevo factor de peso \(\alpha_2\):
\(\alpha_2 = 1 - (1 - \alpha_1)^f\)
Esta fórmula proporciona una aproximación para el nuevo factor de peso \(\alpha_2\) que mantiene constante el efecto de suavizado de la EMA cuando cambia la frecuencia de actualización. Por ejemplo, calculamos el precio medio \(\alpha_1\) como 0,001 y actualizamos el último precio cada 10 segundos. Si lo cambiamos a 1 segundo, el equivalente \(\alpha_2\) es aproximadamente 0,01.
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)
En el trading programático de alta frecuencia, el procesamiento rápido de datos en tiempo real es crucial. Para mejorar la eficiencia computacional y reducir el consumo de recursos, este artículo presenta un algoritmo de actualización en línea para calcular continuamente la media ponderada y la varianza de un flujo de datos. El cálculo de actualizaciones incrementales en tiempo real también se puede utilizar para calcular diversos datos estadísticos e indicadores, como la correlación entre dos precios de activos, ajuste lineal, etc., lo que tiene un gran potencial. Las actualizaciones incrementales tratan los datos como un sistema de señales, lo que supone una evolución del pensamiento en comparación con los cálculos de período fijo. Si su estrategia también tiene una parte que guarda los cálculos de datos históricos, también podría modificarla de acuerdo con esta idea, solo registrar la estimación del estado del sistema y, cuando lleguen nuevos datos, actualizar el estado del sistema, y así sucesivamente.