Sunday 5 February 2017

Php Code Exponentiell Gleitenden Durchschnitt

Ich möchte den Wert EMA (Exponential Moving Average) in PHP berechnen. Ive versucht mit dem folgenden Code, aber seine geben mir 500 Fehler. PHP: EMA Berechnungsfunktion trader-ema Versucht mit langer Zeit Googeln, aber keine Hilfe zu diesem in PHP. Also, Ive keine Ahnung, was getan werden muss, um die EMA-Wert zu berechnen. Edit-1: Installierte Erweiterungen Ive installiert alle notwendigen Erweiterungen, Jetzt erhalte ich die Ausgabe. Aber es scheint nicht geben richtige Ausgabe. Ich denke, PHP-Funktion für die Berechnung von EMA funktioniert nicht richtig. Jede mögliche Hilfe in diesem würde sehr geschätzt. Ich versuche, die letzte EMA eines großen Datenbestands (15000 Werte) zurückzuholen. Es ist ein sehr ressourcenhungriger Algorithmus, da jeder Wert von der vorherigen abhängt. Hier ist mein Code: Was ich schon tat: Isolieren Sie k, so dass es nicht 10000 mal berechnet wird Halten Sie nur die neuesten Computer-EMA, und nicht alle von ihnen in einem Array verwenden für () anstelle von foreach () das Daten-Array hat keine Schlüssel Es eine grundlegende Array Dies ermöglichte mir, die Ausführungszeit von 2000ms auf ca. 500ms für 15000 Werte Was hat nicht funktioniert: Verwenden Sie SplFixedArray (), dies rasiert nur 10ms Ausführen von 1.000.000 Werten Verwenden Sie PHPTrader-Erweiterung. Gibt dies ein Array mit allen EMAs anstatt nur die neuesten, und seine langsamer Schreiben und Ausführen der gleichen Algorithmus in C und läuft es über 2.000.000 Werte dauert nur 13ms So offensichtlich, mit einer kompilierten, niedrigere Ebene scheint zu helfen, P Wo Sollte ich von hier aus gehen Der Code wird letztlich auf Ubuntu laufen, also welche Sprache sollte ich wählen Will PHP in der Lage sein, anzurufen und zu übergeben, wie ein riesiges Argument, um das Skript klar, mit einer Erweiterung gibt Ihnen ein Erhebliche Steigerung. Darüber hinaus kann die Kalkül als selbst verbessert werden und die gewinnen können Sie in welcher Sprache Sie wählen hinzufügen. Es ist leicht zu sehen, dass lastEMA wie folgt berechnet werden kann: Dies kann folgendermaßen umgeschrieben werden, um die Schleife so weit wie möglich zu entfernen: Um die Extraktion des k zu erklären, denken Sie, dass in der vorherigen Formulierung ist, als ob alle Werden die ursprünglichen Rohdaten mit k multipliziert, so dass man praktisch das Endergebnis multiplizieren kann. Beachten Sie, dass auf diese Weise umgeschrieben, haben Sie 2 Operationen innerhalb der Schleife statt 3 (genau in der Schleife gibt es auch i inkrementieren, i Vergleich mit sizedata und lastEMA Wertzuweisung) so so können Sie erwarten, um eine zusätzliche zu erreichen Beschleunigung im Bereich zwischen den 16 und 33. Weiter gibt es weitere Verbesserungen, die zumindest unter bestimmten Umständen berücksichtigt werden können: Betrachten Sie nur die letzten Werte Die ersten Werte werden mehrmals mit k1m 1 - k multipliziert, so dass ihr Beitrag wenig oder sogar gehen kann Unter der Gleitpunktpräzision (oder dem annehmbaren Fehler). Diese Idee ist besonders hilfreich, wenn Sie die Annahme machen können, dass ältere Daten in derselben Größenordnung wie die neueren sind, denn wenn Sie nur die letzten n Werte betrachten, ist der Fehler, den Sie machen, EMAofdiscardeddata (1-k) n. Wenn also die Größenordnung im Großen und Ganzen gleich ist, können wir feststellen, dass der relative Fehler, der durchgeführt wird, relerr err ist. EndEMA EMAofdiscardeddata (1-k) n lastEMA, die fast gleich einfach (1-k) n ist. Unter der Annahme, dass lastEMA fast gleich EMAofdiscardeddata: Lets sagen, dass Sie einen relativen Fehler relerr akzeptieren können Sie sicher nur die letzten n Werte berücksichtigen, wobei (1 - k) n lt relerr. Bedeutet, dass Sie (vor der Schleife) n log (relerr) log (1-k) vorberechnen und nur unter Berücksichtigung der letzten n Werte berechnen können. Wenn der Datensatz sehr groß ist, kann dies eine sinnvolle Beschleunigung ergeben. Betrachten Sie, dass für 64-Bit-Gleitkommazahlen Sie eine relative Genauigkeit (bezogen auf die Mantisse), die 2-53 (ca. 1.1e-16 und nur 2-24 5.96e-8 für 32-Bit-Gleitpunktzahlen), so dass Sie nicht erhalten können Besser als dieser relative Fehler so grundsätzlich sollten Sie nie einen Vorteil bei der Berechnung von mehr als n log (1.1e-16) log (1-k) Werte. Um ein Beispiel zu geben, wenn Bereich 2000 dann n log (1.1e-16) log (1-22001) 36746. Ich denke, das ist interessant zu wissen, dass zusätzliche Berechnungen verloren gehen würde in den Rundungen ist es nutzlos ist besser nicht zu tun. Jetzt ein Beispiel für den Fall, in dem Sie einen relativen Fehler akzeptieren können, der größer ist als Fließkomma-Genauigkeit relerr 1ppm 1e-6 0.00001 6 signifikante Nachkommastellen haben Sie log log (1-22001) 13815 Ich denke, ist ganz ein Kleine Zahl im Vergleich zu Ihren letzten Proben Zahlen, so dass in diesen Fällen die Beschleunigung offensichtlich sein könnte (Im Annahme, dass Bereich 2000 ist sinnvoll oder hoch für Ihre Anwendung, aber thi kann ich nicht wissen). Nur einige wenige Zahlen, weil ich nicht weiß, was Ihre typischen Zahlen sind: relerr 1e-3 range 2000 n 6907 relerr 1e-3 range 200 n 691 relerr 1e-3 range 20 n 69 relerr 1e-6 range 2000 n 13815 relerr 1e - 6 Bereich 200 n 1381 relerr 1e-6 Bereich 20 n 138 Wenn die Annahme lastEMA fast gleich EMAofdiscardeddata nicht genommen werden kann, sind die Dinge weniger einfach, aber da die Vorteilskurve erheblich sein kann, kann es sinnvoll sein, weiterzumachen Log (relerr) log (lastEMA EMAofdiscardeddata)) log (1-k) Der zentrale Punkt ist die Berechnung von lastEMA Ein Fall ist, wenn wir a priori wissen, dass zB EMAofdiscardeddata lastEMA lt M (zB M 1000 oder M 1e6) in diesem Fall n lt (log (relerrM)) log (1 - k) Wenn Sie keine M-Nummer angeben können, müssen Sie eine gute Idee finden, EMAofdiscardeddata zu überschätzen lastEMA eine schnelle Möglichkeit, M max (Daten) min (Daten) zu nehmen Parallelisierung Die Berechnung kann in einem Formular umgeschrieben werden Wo es sich um eine einfache Addition von unabhängigen Begriffen handelt: Wenn also die Implementierungssprache Parallelisierung unterstützt, kann der Datensatz in 4 (oder 8 oder n. Im Grunde die Anzahl der CPU-Kerne zur Verfügung) Stücke und es kann die Summe der Begriffe auf jedem Stück parallel berechnet werden zusammengefasst die einzelnen Ergebnisse am Ende. Ich gehe nicht im Detail mit diesem, da diese Antwort ist schon furchtbar lang und ich denke, das Konzept ist bereits ausgedrückt. Vielen Dank für diese I39m mit diesem auf Börsendaten, so dass die Tatsache, dass die älteren Daten in der gleichen Größenordnung wie die neueren Daten ist abhängig von der Zeitrahmen verwendet. Angenommen, ein Bereich von 200, wird es eine viel größere Variation der Preise auf einem täglichen Zeitrahmen (200 Tage) als 5 Minuten Zeitrahmen (16 Stunden). Ich werde mit verschiedenen Szenarien auf realen und simulierten Daten experimentieren. Auf neue Daten, mit einem Bereich lt 200, verwende ich eine 1000-Elemente-Dataset. Aber ich habe auch einige Back-Tests in den letzten Jahren, so muss ich noch die gesamte Datenmenge laden. Sie half für beide Situationen, danke ndash Lykegenes Erstellen Sie Ihre eigene Erweiterung definitiv verbessert die Leistung. Heres ein gutes Tutorial von der Zend-Website. Einige Leistungsdaten: Hardware: Ubuntu 14.04, PHP 5.5.9, 1-Core Intel CPU3.3Ghz, 128MB RAM (ein VPS). Vorher (nur PHP, 16.000 Werte). 500ms C Erweiterung, 16.000 Werte. 0,3 ms C Erweiterung (100 000 Werte). Erweiterung 3.7ms C (500.000 Werte). 28.0ms Aber Im Gedächtnis begrenzt an diesem Punkt, unter Verwendung 70MB. Ich werde das reparieren und die Zahlen entsprechend aktualisieren. Der exponentielle gleitende Durchschnitt ist ein Typ des IIR-Filters, der einfach in C implementiert werden kann und minimale Ressourcen verwendet. Anders als ein einfacher gleitender Durchschnitt erfordert es keinen RAM-Puffer, um vorherige Abtastwerte zu speichern. Es muss nur einen Wert (der vorherige Durchschnitt) zu speichern. Ein exponentieller gleitender Durchschnitt wird als die folgende Gleichung ausgedrückt: avgn (in alpha) avgn-1 (1-alpha). Die Implementierung dieser Gleichung mit Floating-Point-Mathematik ist einfach, aber mit festen Punkt-Variablen ist ein wenig heikel. Das Code-Snippet verwendet hier 32-Bit-signierte Ganzzahlen für die Durchschnitts - und Eingabewerte. Zwischenwerte müssen 64-Bit-Mathematik verwenden, um Überlauffehler zu vermeiden. Alpha-Werte nahe bei Null repräsentieren eine starke Mittelung, während ein Alpha-Wert von einem keine Mittelung aufweist. Auf der Zeile, wo temp0 berechnet wird, glaube ich, dass das Ende der Zeile lesen sollte (65535 - alpha) Andernfalls würde ein Alpha von 1 unsachgemäß den vorherigen Durchschnitt sowie den neuen Wert enthalten.


No comments:

Post a Comment