Tuesday, February 14, 2017

Gewichtet Gleitender Durchschnitt

Ich versuche, den gleitenden Durchschnitt eines Signals zu berechnen. Der Signalwert (ein Doppel) wird zu beliebigen Zeiten aktualisiert. Ich bin auf der Suche nach einem effizienten Weg, um seine Zeit gewichteten Durchschnitt über ein Zeitfenster, in Echtzeit zu berechnen. Ich könnte es selbst tun, aber es ist schwieriger als ich dachte. Die meisten der Ressourcen Ive gefunden über das Internet berechnen gleitenden Durchschnitt des periodischen Signals, aber Mine Updates zu beliebigen Zeit. Wer weiß, gute Ressourcen für die Der Trick ist die folgende: Sie erhalten Updates zu beliebigen Zeiten über void update (int Zeit, float-Wert). Allerdings müssen Sie auch nachverfolgen, wenn ein Update fällt aus dem Zeitfenster, so dass Sie einen Alarm, der bei der Zeit N, die die vorherige Aktualisierung entfernt wird immer wieder in der Berechnung berücksichtigt. Wenn dies in Echtzeit geschieht, können Sie das Betriebssystem anfordern, einen Aufruf einer Methode void dropoffoldestupdate (int time) aufzurufen, die zum Zeitpunkt N aufgerufen werden soll. Wenn es sich um eine Simulation handelt, können Sie keine Hilfe vom Betriebssystem bekommen und müssen dies tun Tun Sie es manuell. In einer Simulation würden Sie Methoden mit der angegebenen Zeit als Argument aufrufen (was nicht mit der Echtzeit korreliert). Eine vernünftige Annahme ist jedoch, dass die Anrufe so gewartet werden, dass die Zeitargumente zunehmen. In diesem Fall müssen Sie eine sortierte Liste der Alarmzeitwerte pflegen und bei jedem Aktualisierungs - und Leseaufruf überprüfen, ob das Zeitargument größer ist als der Kopf der Alarmliste. Während es größer ist, tun Sie die alarmbezogene Verarbeitung (Drop off der ältesten Aktualisierung), entfernen Sie den Kopf und überprüfen Sie erneut, bis alle Alarme vor der angegebenen Zeit verarbeitet werden. Anschließend den Update-Aufruf durchführen. Ich habe bis jetzt angenommen, dass es offensichtlich ist, was Sie für die tatsächliche Berechnung tun würden, aber ich erarbeiten gerade für den Fall. Ich nehme an, Sie haben eine Methode float read (int Zeit), die Sie verwenden, um die Werte zu lesen. Das Ziel ist, diesen Anruf so effizient wie möglich zu machen. So berechnen Sie den gleitenden Durchschnitt nicht jedes Mal, wenn die Lesemethode aufgerufen wird. Stattdessen müssen Sie den Wert der letzten Aktualisierung oder des letzten Alarms vorberechnen und diesen Wert durch ein paar Gleitkommaoperationen anpassen, um die Zeit seit der letzten Aktualisierung zu berücksichtigen. (D. h. eine konstante Anzahl von Operationen, außer dass möglicherweise eine Liste von aufgestauten Alarmen verarbeitet wird). Hoffentlich ist dies klar - das sollte ein ganz einfacher Algorithmus und sehr effizient sein. Weitere Optimierung. Einer der verbleibenden Probleme ist, wenn eine große Anzahl von Updates innerhalb des Zeitfensters auftreten, dann gibt es eine lange Zeit, für die es weder liest noch Updates, und dann ein Lesen oder Update kommt entlang. In diesem Fall ist der obige Algorithmus ineffizient, wenn der Wert für jedes der Aktualisierungen, die herunterfallen, inkremental aktualisiert wird. Dies ist nicht notwendig, weil wir nur kümmern uns um die letzte Aktualisierung über das Zeitfenster so, wenn es einen Weg, um effizient drop off alle älteren Updates, würde es helfen. Um dies zu tun, können wir den Algorithmus ändern, um eine binäre Suche nach Updates durchzuführen, um das neueste Update vor dem Zeitfenster zu finden. Wenn es relativ wenige Updates gibt, die gelöscht werden müssen, kann man den Wert für jede heruntergelassene Aktualisierung inkremental aktualisieren. Aber, wenn es viele Updates gibt, die gelöscht werden müssen, dann kann man den Wert vom Kratzer neu berechnen, nachdem er weg von den alten Updates. Anhang auf Inkrementelle Berechnung: Ich sollte klären, was ich meine durch inkrementelle Berechnung oben in den Satz zwicken diesen Wert durch ein paar Gleitkomma-Operationen, um für den Ablauf der Zeit seit dem letzten Update. Initiale nicht-inkrementelle Berechnung: dann über die relevanten Aktualisierungen in der Reihenfolge der zunehmenden Zeit iterieren: movingaverage (sum lastupdate timesincelastupdate) windowlength. Nun, wenn genau ein Update fällt aus dem Fenster, aber keine neuen Aktualisierungen ankommen, stellen Sie die Summe als: (beachten Sie, es ist Priorupdate, deren Timestamp geändert, um den Beginn der letzten Fenster beginnt). Und wenn genau ein Update in das Fenster eintritt, aber keine neuen Updates abfallen, passen Sie die Summe als an: Wie offensichtlich sein sollte, ist dies eine grobe Skizze, aber hoffentlich zeigt es, wie Sie den Durchschnitt so halten können, dass es O (1) Operationen pro Update ist Auf amortisierte Basis. Aber beachten Sie weitere Optimierung im vorherigen Absatz. Beachten Sie auch Stabilitätsprobleme, auf die in einer älteren Antwort hingewiesen wird, was bedeutet, dass Gleitkomma-Fehler über eine große Anzahl derartiger Inkrementierungsoperationen akkumulieren können, so dass es eine Abweichung von dem Ergebnis der Vollberechnung gibt, die für die Anwendung signifikant ist. Wenn eine Annäherung OK und theres eine minimale Zeit zwischen Proben ist, könnten Sie versuchen, Super-Sampling. Sie haben ein Array, das gleichmäßig beabstandete Zeitintervalle repräsentiert, die kürzer als das Minimum sind, und zu jedem Zeitpunkt die letzte empfangene Probe speichern. Je kürzer das Intervall, desto näher ist der Mittelwert auf den wahren Wert. Der Zeitraum sollte nicht größer als die Hälfte des Minimums sein, oder es besteht die Möglichkeit, eine Stichprobe zu fehlen. Antwortete Dec 15 11 at 18:12 antwortete 15 Dez, um 22:38 Uhr Danke für die Antwort. Eine Verbesserung, die erforderlich wäre, um tatsächlich Quotecachequot den Wert des Gesamtdurchschnitts, so dass wir don39t Schleife die ganze Zeit. Auch kann es ein kleiner Punkt sein, aber wäre es nicht effizienter, ein deque oder eine Liste zu verwenden, um den Wert zu speichern, da wir davon ausgehen, dass die Aktualisierung in der richtigen Reihenfolge kommen wird. Einfügen wäre schneller als in der Karte. Ndash Arthur Ja, Sie könnten den Wert der Summe zwischenspeichern. Subtrahieren Sie die Werte der Proben, die Sie löschen, fügen Sie die Werte der Proben, die Sie einfügen. Auch, ja, ein dequeltpairltSample, Dategtgt könnte effizienter sein. Ich wählte Karte für Lesbarkeit, und die Leichtigkeit der Aufruf der Karte :: upperbound. Wie immer, schreiben Sie den richtigen Code zuerst, dann Profil und messen inkrementelle Änderungen. Ndash Rob Dez 16 11 um 15:00 Hinweis: Anscheinend ist dies nicht der Weg, um dies zu nähern. Lassen Sie es hier als Referenz auf, was ist falsch mit diesem Ansatz. Überprüfen Sie die Kommentare. AKTUALISIERT - basierend auf Olis Kommentar. Nicht sicher über die Instabilität, dass er aber reden. Verwenden Sie eine sortierte Karte der Ankunftszeiten mit Werten. Bei der Ankunft eines Wertes addieren Sie die Ankunftszeit zur sortierten Karte zusammen mit ihrem Wert und aktualisieren Sie den gleitenden Durchschnitt. Warnung dies ist Pseudocode: Dort. Nicht vollständig ausgefuellt, aber Sie bekommen die Idee. Dinge zu beachten. Wie ich schon sagte ist Pseudocode. Youll Notwendigkeit, eine passende Karte zu wählen. Entfernen Sie nicht die Paare, während Sie iterieren durch, wie Sie den Iterator ungültig machen und müssen wieder neu starten. Siehe Olis Kommentar unten auch. Antwort # 2 am: Dezember 15, 2010, um 12:22 Uhr Dies doesn39t Arbeit: es doesn39t berücksichtigen, welcher Anteil der Fensterlänge jeder Wert für vorhanden ist. Auch dieser Ansatz der Addition und dann Subtraktion ist nur stabil für Ganzzahl-Typen, nicht Floaten. Ndash Oliver Charlesworth OliCharlesworth - sorry Ich habe einige wichtige Punkte in der Beschreibung (doppelt und zeitgewichtet) verpasst. Ich werde aktualisieren. Vielen Dank. Ndash Dennis Dec 15 11 at 12:33 Die Zeitgewichtung ist ein weiteres Problem. Aber das ist nicht das, worüber ich rede. Ich bezog sich auf die Tatsache, dass, wenn ein neuer Wert zuerst das Zeitfenster betritt, sein Beitrag zum Durchschnitt minimal ist. Ihr Beitrag steigt, bis ein neuer Wert eintritt. Ndash Oliver Charlesworth Dez 15 11 at 12: 35net. sourceforge. openforecast. models Klasse WeightedMovingAverageModel Ein gewichtetes gleitendes Durchschnittsprognosemodell basiert auf einer künstlich konstruierten Zeitreihe, in der der Wert für einen bestimmten Zeitraum durch den gewichteten Mittelwert dieses Werts ersetzt wird Und die Werte für eine gewisse Anzahl von vorhergehenden Zeitperioden. Wie Sie vielleicht aus der Beschreibung erraten haben, ist dieses Modell am besten für Zeitreihendaten, d. H. Daten, die sich über die Zeit ändern, geeignet. Da der Prognosewert für einen gegebenen Zeitraum ein gewichteter Durchschnitt der vorangegangenen Perioden ist, wird die Prognose immer scheinbar zurückbleiben, entweder bei der Erhöhung oder Verminderung der beobachteten (abhängigen) Werte. Wenn beispielsweise eine Datenreihe einen merkbaren Aufwärtstrend aufweist, wird eine gewichtete gleitende Durchschnittsprognose generell eine Unterbewertung der Werte der abhängigen Variablen liefern. Das gewichtete gleitende Durchschnittmodell, wie das gleitende Durchschnittsmodell, hat gegenüber anderen Prognosemodellen einen Vorteil, dass es in einer Reihe von Beobachtungen Gipfel und Mulden (oder Täler) glättet. Jedoch, wie das gleitende Durchschnittmodell, hat es auch einige Nachteile. Insbesondere erzeugt dieses Modell keine tatsächliche Gleichung. Daher ist es nicht alles, was nützlich, da ein Mittel-Langstrecken-Prognose-Tool. Es kann nur zuverlässig genutzt werden, um ein paar Perioden in die Zukunft zu prognostizieren. Seit: 0.4 Autor: Steven R. Gould Felder geerbt aus der Klasse net. sourceforge. openforecast. models. AbstractForecastingModel WeightedMovingAverageModel () Erstellt ein neues gewichtetes gleitendes Durchschnittsprognosemodell. WeightedMovingAverageModel (Doppelgewichte) Erstellt ein neues gewichtetes gleitendes Durchschnittsprognosemodell unter Verwendung der angegebenen Gewichte. Prognose (double timeValue) Gibt den Prognosewert der abhängigen Variablen für den gegebenen Wert der unabhängigen Zeitvariablen zurück. GetForecastType () Gibt einen oder zwei Wortnamen dieser Art von Prognosemodell zurück. GetNumberOfPeriods () Gibt die aktuelle Anzahl von Perioden zurück, die in diesem Modell verwendet werden. GetNumberOfPredictors () Gibt die Anzahl der Prädiktoren zurück, die vom zugrunde liegenden Modell verwendet werden. SetWeights (Doppelgewichte) Setzt die Gewichte dieses gewichteten gleitenden Durchschnittsprognosemodells auf die angegebenen Gewichte. ToString () Dies sollte überschrieben werden, um eine textuelle Beschreibung des aktuellen Prognosemodells zu liefern, einschließlich, wenn möglich, alle abgeleiteten Parameter. Von der Klasse geerbte Methoden network. sourceforge. openforecast. models. AbstractTimeBasedModel WeightedMovingAverageModel Erstellt ein neues gewichtetes gleitendes Durchschnittsprognosemodell unter Verwendung der angegebenen Gewichte. Für ein gültiges zu konstruierendes Modell sollten Sie init aufrufen und einen Datensatz mit einer Reihe von Datenpunkten übergeben, wobei die Zeitvariable initialisiert wird, um die unabhängige Variable zu identifizieren. Die Größe des Gewichts-Arrays wird verwendet, um die Anzahl der Beobachtungen zu bestimmen, die verwendet werden, um den gewichteten gleitenden Durchschnitt zu berechnen. Zusätzlich wird der letzten Periode das Gewicht gegeben, das durch das erste Element des Arrays, d. H. Gewichte, definiert ist. Die Größe des Gewichts-Arrays wird auch verwendet, um die Menge zukünftiger Perioden zu bestimmen, die effektiv prognostiziert werden können. Mit einem 50-Tage-gewichteten gleitenden Durchschnitt können wir mit einer Genauigkeit nicht mehr als 50 Tage über den letzten Zeitraum, für den Daten verfügbar sind, prognostizieren. Selbst Prognosen in der Nähe des Endes dieses Bereichs sind wahrscheinlich unzuverlässig. Hinweis zu Gewichten Im Allgemeinen sollten die Gewichte, die an diesen Konstruktor übergeben werden, bis zu 1,0 addieren. Wenn jedoch die Summe der Gewichte nicht bis zu 1,0 addiert, skaliert diese Implementierung alle Gewichte proportional, so dass sie auf 1,0 addieren. Parameter: Gewichte - ein Array von Gewichten, um den historischen Beobachtungen bei der Berechnung des gewichteten gleitenden Durchschnitts zuzuordnen. WeightedMovingAverageModel Erstellt ein neues gewichtetes gleitendes Durchschnittsprognosemodell, wobei die benannte Variable als unabhängige Variable und die angegebenen Gewichte verwendet wird. Parameter: independentVariable - der Name der unabhängigen Variablen, die in diesem Modell verwendet werden soll. Gewichte - ein Array von Gewichten, um den historischen Beobachtungen bei der Berechnung des gewichteten gleitenden Durchschnitts zuzuordnen. WeightedMovingAverageModel Erstellt ein neues gewichtetes gleitendes Durchschnittsprognosemodell. Dieser Konstruktor soll nur von Unterklassen (also geschützt) verwendet werden. Jede Unterklasse, die diesen Konstruktor verwendet, muss anschließend die (geschützte) setWeights-Methode aufrufen, um die von diesem Modell zu verwendenden Gewichte zu initialisieren. WeightedMovingAverageModel Konstruiert ein neues gewichtetes gleitendes Durchschnittsprognosemodell unter Verwendung der angegebenen unabhängigen Variablen. Parameter: independentVariable - der Name der unabhängigen Variablen, die in diesem Modell verwendet werden soll. SetWeights Setzt die Gewichte dieses gewichteten gleitenden Durchschnittsprognosemodells auf die angegebenen Gewichte. Dieses Verfahren soll nur von Unterklassen (also geschützt) und nur in Verbindung mit dem (geschützten) Ein-Argument-Konstruktor verwendet werden. Jede Unterklasse, die den Ein-Argument-Konstruktor verwendet, muss anschließend setWeights aufrufen, bevor die Methode AbstractTimeBasedModel. init (net. sourceforge. openforecast. DataSet) aufgerufen wird, um das Modell zu initialisieren. Anmerkung zu Gewichten Im allgemeinen sollten die an diese Methode übergebenen Gewichte bis zu 1,0 addieren. Wenn jedoch die Summe der Gewichte nicht bis zu 1,0 addiert, skaliert diese Implementierung alle Gewichte proportional, so dass sie auf 1,0 addieren. Parameter: Gewichte - ein Array von Gewichten, um den historischen Beobachtungen bei der Berechnung des gewichteten gleitenden Durchschnitts zuzuordnen. Gibt den Prognosewert der abhängigen Variablen für den gegebenen Wert der unabhängigen Zeitvariablen zurück. Unterklassen müssen diese Methode in einer Weise implementieren, die mit dem von ihnen implementierten Prognosemodell übereinstimmt. Unterklassen können die Methoden getForecastValue und getObservedValue verwenden, um frühere Prognosen und Beobachtungen zu erhalten. Gegeben durch: Prognose in Klasse AbstractTimeBasedModel Parameter: timeValue - der Wert der Zeitvariablen, für die ein Prognosewert erforderlich ist. Gibt den Prognosewert der abhängigen Variablen für die angegebene Zeit zurück. Throws: IllegalArgumentException - Wenn es unzureichende historische Daten gibt - Beobachtungen, die an init übergeben werden -, um eine Prognose für den gegebenen Zeitwert zu generieren. GetNumberOfPredictors Gibt die Anzahl der Prädiktoren zurück, die vom zugrunde liegenden Modell verwendet werden. Rückgabewerte: die Anzahl der Prädiktoren, die das zugrunde liegende Modell verwendet. GetNumberOfPeriods Gibt die aktuelle Anzahl von Perioden zurück, die in diesem Modell verwendet werden. Angegeben durch: getNumberOfPeriods in der Klasse AbstractTimeBasedModel Gibt die aktuelle Anzahl der in diesem Modell verwendeten Perioden zurück. GetForecastType Gibt einen oder zwei Wortnamen dieser Art von Prognosemodell zurück. Halten Sie diese kurz. Eine längere Beschreibung sollte in der Methode toString implementiert werden. Dies sollte überschrieben werden, um eine textuelle Beschreibung des aktuellen Prognosemodells zu liefern, wobei nach Möglichkeit alle abgeleiteten Parameter verwendet werden. Bestimmt durch: toString in der Schnittstelle ForecastingModel Overrides: toString in der Klasse AbstractTimeBasedModel Gibt eine Stringdarstellung des aktuellen Prognosemodells und seiner Parameter zurück. Exponential Moving Average (EMA) Die klassische EMA-Formel lautet: Anders als Simple Moving Average. Wo das Gewicht aller vorherigen Balken gleich ist, macht der Exponential Moving Average die letzte Balke wichtiger. Das Gewicht jedes älteren Stabes verringert das exponentiell. Unten ist ein Gewichtsdiagramm für N 10 (1 ist der aktuelle Preis, 2 der vorherige und so weiter): Die Gewichtsformel ist, wo i eine Distanz zum letzten Balken ist. 0 bedeutet die letzte, 1 die vorherige Leiste und so weiter. First Value Die Formel bezieht sich auf den vorherigen Wert und es gibt keine Standardvereinbarung, was der erste (älteste) Wert ist. Unterschiedliche Implementierung von EMA verwendet: Der erste Preis (MT4, Marketscope) oder Der Einfache Moving Average der ersten N Preise (Stockcharts). An Stelle von einfachem gleitendem Mittelwert Der exponentielle gleitende Durchschnitt kann genau als einfacher gleitender Durchschnitt verwendet werden. Insbesondere in der Situation, in der die Inertheit von Simple Moving Average nicht ignoriert werden kann. Vergleichen Sie EMA (10) und MVA (10), die zu denselben Preisen angewendet werden: Einschränkungen Der Exponential Moving Average basiert auf allen vorherigen Werten, so dass das Indikatorergebnis für einen bestimmten Balken davon abhängt, wie viel historische Daten berücksichtigt werden. In dem Fall, in dem mehr historische Daten geladen werden, kann sich der Wert des Indikators von dem zuvor berechneten Wert unterscheiden. Indikatoren Dieser Artikel in anderen Sprachen


No comments:

Post a Comment