Thursday, November 17, 2016

Promedio Móvil Ponderado C ++


Estoy tratando de calcular el promedio móvil de una señal. El valor de la señal (un doble) se actualiza al azar. Estoy buscando una manera eficiente de calcular su tiempo promedio ponderado en una ventana de tiempo, en tiempo real. Podría hacerlo yo mismo, pero es más difícil de lo que pensaba. La mayoría de los recursos que he encontrado en Internet están calculando el promedio móvil de la señal periódica, pero la mina se actualiza al azar. Alguien sabe buenos recursos para que El truco es el siguiente: Usted recibe actualizaciones en tiempos aleatorios mediante la actualización de void (tiempo int, valor de float). Sin embargo, también es necesario realizar un seguimiento cuando una actualización se cae de la ventana de tiempo, por lo que se establece una alarma que se llama en el momento N que elimina la actualización anterior de ser considerado de nuevo en el cálculo. Si esto sucede en tiempo real, puede solicitar al sistema operativo que realice una llamada a un método void dropoffoldestupdate (int time) que se llamará en el momento N Si se trata de una simulación, no puede obtener ayuda del sistema operativo y necesita Hágalo manualmente. En una simulación llamaríamos métodos con el tiempo suministrado como un argumento (que no se correlaciona con el tiempo real). Sin embargo, una suposición razonable es que las llamadas están garantizadas de tal manera que los argumentos de tiempo están aumentando. En este caso, debe mantener una lista ordenada de valores de hora de alarma y, para cada llamada de actualización y lectura, compruebe si el argumento de tiempo es mayor que el de la lista de alarmas. Mientras que es mayor que usted hace el proceso relacionado con la alarma (caiga la actualización más vieja), quite la cabeza y compruebe otra vez hasta que se procesen todas las alarmas antes del tiempo dado. A continuación, haga la llamada de actualización. Hasta ahora he asumido que es obvio lo que haría para el cálculo real, pero voy a elaborar por si acaso. Supongo que tienes un método float read (tiempo int) que usas para leer los valores. El objetivo es hacer que esta llamada sea lo más eficiente posible. Por lo tanto, no calcula el promedio móvil cada vez que se llama al método de lectura. En su lugar precompute el valor a partir de la última actualización o la última alarma y ajuste este valor por un par de operaciones de punto flotante para explicar el paso del tiempo desde la última actualización. (Es decir, un número constante de operaciones excepto para tal vez procesar una lista de alarmas acumuladas). Esperemos que esto esté claro - este debería ser un algoritmo bastante simple y bastante eficiente. Otra optimización. Uno de los problemas restantes es si un gran número de actualizaciones se producen dentro de la ventana de tiempo, entonces hay un largo tiempo para que no hay ni lecturas ni actualizaciones, y luego una lectura o actualización viene adelante. En este caso, el algoritmo anterior será ineficaz en la actualización incremental del valor para cada una de las actualizaciones que está cayendo. Esto no es necesario porque sólo nos preocupamos por la última actualización más allá de la ventana de tiempo por lo que si hay una manera de dejar de manera eficiente todas las actualizaciones anteriores, que ayudaría. Para ello, podemos modificar el algoritmo para realizar una búsqueda binaria de actualizaciones para encontrar la actualización más reciente antes de la ventana de tiempo. Si hay relativamente pocas actualizaciones que deben eliminarse, puede actualizar incrementalmente el valor de cada actualización eliminada. Pero si hay muchas actualizaciones que necesitan ser eliminados, entonces uno puede volver a calcular el valor desde cero después de dejar las antiguas actualizaciones. Apéndice sobre Cálculo Incremental: Debo aclarar lo que quiero decir con el cálculo incremental anterior en la frase ajustar este valor por un par de operaciones en coma flotante para explicar el paso del tiempo desde la última actualización. Cálculo inicial no incremental: luego iterar sobre las actualizaciones relevantes en orden creciente de tiempo: movilidad (sum latupdate timesincelastupdate) / windowlength. Ahora si exactamente una actualización cae de la ventana pero no llega ninguna nueva actualización, ajuste la suma como: (note que es priorupdate que tiene su timestamp modificado para iniciar el inicio de la última ventana). Y si exactamente una actualización entra en la ventana, pero no hay nuevas actualizaciones se caen, ajustar la suma como: Como debe ser obvio, este es un bosquejo aproximado, pero esperemos que muestra cómo se puede mantener el promedio tal que es O (1) operaciones por actualización Sobre una base amortizada. Pero tenga en cuenta la optimización adicional en el párrafo anterior. También tenga en cuenta los problemas de estabilidad aludidos en una respuesta anterior, lo que significa que los errores de coma flotante pueden acumularse en un gran número de operaciones incrementales tales que existe una divergencia con respecto al resultado del cálculo completo que es significativo para la aplicación. Si una aproximación es correcta y hay un tiempo mínimo entre las muestras, puede intentar el super-muestreo. Tenga una matriz que represente intervalos de tiempo uniformemente espaciados que son más cortos que el mínimo, y en cada período de tiempo almacene la última muestra que fue recibida. Cuanto más corto sea el intervalo, más cercano será el promedio al valor verdadero. El período no debe ser mayor de la mitad del mínimo o existe la posibilidad de que falte una muestra. Respondió Dec 15 11 at 18:12 respondió Dec 15 11 at 22:38 Gracias por la respuesta. Una mejora que se necesita para realmente quotcachequot el valor de la media total por lo que don39t lazo todo el tiempo. Además, puede ser un punto menor, pero no sería más eficiente usar un deque o una lista para almacenar el valor, ya que asumimos que la actualización vendrá en el orden correcto. La inserción sería más rápida que en el mapa. Ndash Arthur 16 de diciembre a las 8:55 Sí, podría almacenar en caché el valor de suma. Resta los valores de las muestras que borres, agrega los valores de las muestras que insertas. También, sí, un dequeltpairltSample, Dategtgt podría ser más eficiente. Elegí el mapa para la legibilidad, y la facilidad de invocar map :: upperbound. Como siempre, escriba el código correcto primero, luego el perfil y mida los cambios incrementales. Ndash Rob Dic 16 11 at 15:00 Nota: Aparentemente esta no es la manera de abordar esto. Dejándolo aquí para referencia sobre lo que está mal con este enfoque. Compruebe los comentarios. ACTUALIZADO - basado en el comentario de Olis. No estoy seguro de la inestabilidad de la que habla. Utilice un mapa ordenado de los tiempos de llegada en función de los valores. Al llegar un valor agregue la hora de llegada al mapa ordenado junto con su valor y actualice la media móvil. Advirtiendo esto es pseudo-código: Allí. No se desarrolla completamente, pero tienes la idea. Cosas a tener en cuenta. Como dije lo anterior es pseudo código. Youll necesidad de elegir un mapa adecuado. No quite los pares a medida que pasa a través de lo que va a invalidar el iterador y tendrá que empezar de nuevo. Véase Olis comentar abajo también. Respondió Dec 15 11 at 12:22 Esto no funciona: no tiene en cuenta qué proporción de la longitud de la ventana de cada valor existe para. Además, este enfoque de sumar y luego restar es sólo estable para tipos enteros, no para flotantes. Ndash Oliver Charlesworth dic 15 11 at 12:29 OliCharlesworth - lo siento perdí algunos puntos clave en la descripción (doble y tiempo de ponderación). Voy a actualizar. Gracias. Ndash Dennis dic 15 11 at 12:33 La ponderación de tiempo es otro problema. Pero eso no es de lo que estoy hablando. Me refería al hecho de que cuando un nuevo valor entra por primera vez en la ventana de tiempo, su contribución al promedio es mínima. Su contribución continúa aumentando hasta que ingresa un nuevo valor. Ndash Oliver Charlesworth dic 15 11 at 12: 35Vista general Una media móvil ponderada es un promedio de datos calculados durante un período de tiempo, donde se agrega mayor peso a los datos más recientes. La media móvil ponderada se puede utilizar con cualquier precio, incluyendo el precio de alta, baja, abierta o cierre, y se puede aplicar a otros indicadores también. La media móvil ponderada suaviza una serie de datos, lo cual es importante en un mercado volátil, ya que ayuda a identificar tendencias mucho más fácilmente. La ponderación se calcula a partir de una suma de días. Dundas Chart para Windows Forms tiene cuatro tipos de promedios móviles, incluyendo Simple. Exponencial. Triangular. Y Ponderado. La diferencia más importante entre las medias móviles anteriores es cómo pesan sus puntos de datos. Le recomendamos que lea Usando fórmulas financieras antes de continuar. El uso de fórmulas financieras proporciona una explicación detallada sobre cómo utilizar las fórmulas y también explica las diversas opciones disponibles para usted al aplicar una fórmula. Un gráfico de líneas es una buena opción cuando se muestra una media móvil ponderada. Interpretación Financiera: El promedio móvil ponderado se utiliza para comparar un valor con su promedio móvil ponderado, y da más influencia para los datos recientes y menos influencia para los datos pasados. El elemento más importante utilizado para calcular la media móvil es un período de tiempo, que debería ser igual al ciclo de mercado observado. La media móvil ponderada es el indicador de retraso, y siempre estará detrás del precio. Cuando el precio sigue una tendencia, la media móvil ponderada es muy cercana al precio. Cuando un precio está aumentando el promedio móvil ponderado probablemente se mantendrá abajo debido a la influencia de los datos históricos. Cálculo: El promedio móvil ponderado se calcula utilizando una suma de índices de períodos de tiempo (puntos de datos). El peso para cada período se calcula como índice / (número de puntos de datos). La siguiente tabla muestra cómo calcular una media móvil ponderada de 5 días: Véase tambiénMensajes móviles exponenciales para series de tiempo irregulares En el análisis de series de tiempo, a menudo existe la necesidad de funciones de suavizado que reaccionan rápidamente a los cambios en la señal. En la aplicación típica, puede estar procesando una señal de entrada en tiempo real, y desea calcular cosas como el valor promedio reciente, o obtener una pendiente instantánea para él. Pero las señales del mundo real suelen ser ruidosas. Algunas muestras ruidosas harán que el valor actual de la señal, o su pendiente, varíe ampliamente. Promedios móviles La función de suavizado más simple es una media móvil con ventana. A medida que vienen las muestras, toma un promedio de los valores de N más recientes. Esto suavizará los picos, pero introduce un retraso 8211 o latencia. Su promedio siempre será retrasado por el ancho de su promedio móvil. El ejemplo anterior es relativamente costoso de calcular. Para cada muestra tiene que iterar sobre el tamaño entero de la ventana. Pero hay maneras más baratas de mantener la suma de todas las muestras en la ventana en un búfer y ajustar la suma a medida que vienen nuevas muestras: Otro tipo de promedio móvil es la media móvil ponderada 8222 que pesa para cada posición en la ventana de muestra. Antes de promediar multiplicar cada muestra por el peso de esa posición de la ventana. Técnicamente esto se llama una 8220convolución8221. Una función de ponderación típica aplica una curva de campana a la ventana de muestra. Esto da una señal que está más afinada al centro de la ventana, y todavía algo tolerante de muestras ruidosas. En el análisis financiero, usas a menudo una función de ponderación que valora más recientemente muestras recientes, para dar una media móvil que sigue más de cerca las muestras recientes. Las muestras más viejas se dan progresivamente menos peso. Esto atenúa algo los efectos de la latencia, mientras que todavía da razonablemente buen alisamiento: Con un promedio ponderado, usted siempre tiene que iterar sobre el tamaño entero de la ventana para cada muestra (a menos que usted pueda constreñir los pesos permitidos a ciertas funciones). El promedio móvil exponencial Otro tipo de promedio es el promedio móvil exponencial, o EMA. Esto se utiliza a menudo cuando la latencia es crítica, como en el análisis financiero en tiempo real. En este promedio, los pesos disminuyen exponencialmente. Cada muestra es valorada un poco más pequeña que la siguiente muestra más reciente. Con esta limitación se puede calcular el promedio móvil muy eficientemente. Donde alpha es una constante que describe cómo los pesos de las ventanas disminuyen con el tiempo. Por ejemplo, si cada muestra se ponderara a 80 del valor de la muestra anterior, se establecería alfa 0.2. El alfa más pequeño se convierte en el más largo de su media móvil es. (Por ejemplo, se vuelve más suave, pero menos reactiva a nuevas muestras). Los pesos para una EMA con alpha0.20 Como se puede ver, para cada nueva muestra sólo es necesario que la media con el valor de la media anterior. Así que el cálculo es muy, muy rápido. En teoría, todas las muestras anteriores contribuyen al promedio actual, pero su contribución se vuelve exponencialmente menor en el tiempo. Esta es una técnica muy potente, y probablemente la mejor si quieres obtener un promedio móvil que responda rápidamente a nuevas muestras, tiene buenas propiedades de suavizado y es rápido de calcular. El código es trivial: EMA para la Serie de Tiempo Irregular La EMA estándar está muy bien cuando la muestra es muestreada a intervalos de tiempo regulares. Pero qué pasa si sus muestras vienen a intervalos irregulares Imagine una señal continua que se muestrea a intervalos irregulares. Esta es la situación habitual en el análisis financiero. En teoría hay una función continua para el valor de cualquier instrumento financiero, pero sólo puede muestrear esta señal cada vez que alguien realmente ejecuta un comercio. Así que su flujo de datos consiste en un valor, más el tiempo en el que se observó. Una forma de tratar esto es convertir la señal irregular en una señal regular, interpolando entre observaciones y remuestreo. Pero esto pierde datos, y re-introduce la latencia. Es posible calcular directamente una EMA para una serie temporal irregular: En esta función, se pasa la muestra actual de la señal, y la muestra anterior, y la cantidad de tiempo transcurrido entre los dos, y el valor anterior devuelto por esta función. Resultados Qué tan bien este trabajo para demostrar I8217ve generó una onda senoidal, a continuación, la muestra en intervalos irregulares, e introdujo alrededor de 20 ruido. Esa es la señal variará aleatoriamente - 20 de la señal de seno original 8220true8221. Qué tan bien recupera la media móvil exponencial irregular la señal La línea roja es la onda sinusoidal original 8211 muestreada a intervalos irregulares. La línea azul es la señal con el ruido añadido. La línea azul es la única señal que la EMA ve. La línea verde es la EMA suavizada. Usted puede ver que recupera la señal bastante bien. Un poco vacilante, pero qué se puede esperar de una señal de fuente tan ruidosa? Se desplaza alrededor de 15 a la derecha, porque la EMA introduce una cierta latencia. Cuanto más suave lo desee, más latencia verá. Pero a partir de esto se puede por ejemplo calcular una pendiente instantánea para una señal irregular ruidosa. Qué se puede hacer con que Hmm8230. Recursos:

No comments:

Post a Comment