Wednesday, 5 July 2017

Php Code Exponentiell Gleitender Durchschnitt


Ich möchte den EMA (Exponential Moving Average) Wert in PHP berechnen. Ive versucht mit dem folgenden Code, aber es gibt mir 500 Fehler. PHP: EMA-Berechnungsfunktion Trader-Ema Versucht mit langer Zeit Googeln aber keine Hilfe dazu in PHP. Also, Ive keine Ahnung, was getan werden muss, um den EMA-Wert zu berechnen. Edit-1: Installierte Erweiterungen Ive installiert alle notwendigen Erweiterungen, jetzt bekomme ich die Ausgabe. Aber es scheint nicht richtige Ausgabe zu geben. Ich denke, PHP-Funktion für die Berechnung EMA funktioniert nicht richtig. Jede Hilfe in diesem wäre sehr dankbar. Im versuchen, die letzte EMA eines großen Datensatzes (15000 Werte) abzurufen. Es ist ein sehr ressourcenhungriger Algorithmus, da jeder Wert vom vorherigen abhängt. Hier ist mein Code: Was ich schon tat: Isoliere k also ist es nicht 10000 mal berechnet 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 ist ein Grund-Array Dies erlaubte mir, die Ausführungszeit von 2000ms auf etwa 500ms für 15000 Werte zu reduzieren Was funktionierte nicht: Verwenden Sie SplFixedArray (), diese rasierte nur 10ms, die 1.000.000 Werte ausführen Verwenden Sie PHPTrader-Erweiterung. Dies gibt 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, untergeordneten Sprache 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 ein solches riesiges Argument an das Drehbuch zu geben, fragte Jul 11 ​​14 um 19:21 Klar implementiert mit einer Erweiterung gibt dir ein Signifikanter Aufschwung Darüber hinaus kann das Kalkül als sich selbst verbessert werden und das Sie gewinnen können, können Sie in welcher Sprache Sie wählen. Es ist leicht zu sehen, dass lastEMA wie folgt berechnet werden kann: Dies kann wie folgt umgeschrieben werden, um so viel wie möglich aus der Schleife herauszunehmen: Um die Extraktion der k zu erklären, denken wir, dass in der vorherigen Formulierung wie bei allen ist Original-Rohdaten werden mit K so vervielfacht, dass man stattdessen das Endergebnis multiplizieren kann. Beachten Sie, dass Sie auf diese Weise umgeschrieben haben, haben Sie 2 Operationen innerhalb der Schleife anstelle von 3 (genau in der Schleife gibt es auch ich inkrementieren, ich Vergleich mit sizedata und lastEMA Wert Zuweisung) so können Sie erwarten, um eine zusätzliche zu erreichen Beschleunigung im Bereich zwischen 16 und 33. Weiterhin gibt es noch andere Verbesserungen, die zumindest in einigen Fällen berücksichtigt werden können: Betrachten Sie nur die letzten Werte Die ersten Werte werden mehrmals um k1m 1 - k multipliziert, so dass sie dazu beitragen können Unter der Fließkomma-Präzision (oder dem annehmbaren Fehler). Diese Idee ist besonders hilfreich, wenn man die Annahme ausführen kann, dass ältere Daten von der gleichen Größenordnung sind wie die neuere, denn wenn man nur die letzten n Werte betrachtet, ist der Fehler, den du machst, irregedeDiscardeddata (1-k) n. Wenn also die Größenordnung weitgehend gleich ist, können wir feststellen, dass der relative Fehler, der erledigt ist, reerr err ist, letzteren EMAofdiscardeddata (1-k) n lastEMA, die fast gleich einfach (1-k) n ist. Unter der Annahme, dass lastEMA fast gleich EMAofdiscardeddata ist: Lasst uns sagen, dass ihr einen relativen Fehler relerr akzeptieren könnt, könnt ihr nur die letzten n Werte betrachten, wo (1 - k) n lt relerr ist. Bedeutet, dass Sie vor der Schleife vorberechnen können (vor der Schleife) n log (relerr) log (1-k) und berechnen Sie alle nur unter Berücksichtigung der letzten n Werte. Wenn der Datensatz sehr groß ist, kann dies eine vernünftige Beschleunigung geben. Betrachten Sie, dass für 64-Bit-Gleitkommazahlen Sie eine relative Präzision (bezogen auf die Mantisse), die 2-53 (ca. 1.1e-16 und nur 2-24 5.96e-8 für 32-Bit-Gleitkommazahlen) ist, so dass Sie nicht erhalten können Besser als dieser relative Fehler also grundsätzlich sollten Sie nie einen Vorteil bei der Berechnung von mehr als n log (1.1e-16) log (1-k) Werte haben. 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 in den Rundungen verloren gehen, ist es nutzlos ist besser nicht zu tun. Jetzt ein Beispiel für den Fall, wo man einen relativen Fehler akzeptieren kann, der größer ist als die Gleitkomma-Präzision relerr 1ppm 1e-6 0.00001 6 signifikante Dezimalstellen Sie haben n log (1.1e-16) log (1-22001) 13815 Ich denke, ist ganz ein Kleine Zahl im Vergleich zu Ihren letzten Stichproben Zahlen so in diesem Fall die Beschleunigung könnte offensichtlich sein (Ich vermute, dass Bereich 2000 ist sinnvoll oder hoch für Ihre Anwendung, aber ich kann nicht wissen). Nur noch wenige wenige, weil ich nicht weiß, was sind deine typischen Figuren: relerr 1e-3 range 2000 n 6907 relerr 1e-3 range 200 n 691 relerr 1e-3 reihe 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 der Vorteil cam signifikant ist, kann es sinnvoll sein, weiterzumachen: Wir müssen das wieder betrachten Vollständige Formel: relerr EMAofdiscardeddata (1-k) n lastEMA so n log (relerr lastEMA EMAofdiscardeddata) log (1-k) (log (relerr) log (lastEMA EMAofdiscardeddata)) log (1-k) der zentrale Punkt ist, lastEMA zu berechnen EMAofdiscardeddata (ohne tatsächliche Berechnung von lastEMA noch EMAofdiscardeddata natürlich) Ein Fall ist, wenn wir a-priori wissen, dass zum Beispiel EMAofdiscardeddata lastEMA lt M (zB M 1000 oder M 1e6) in diesem Fall n lt (log (relerrM)) log (1 - k) Wenn du keine M-Nummer geben kannst, musst du eine gute Idee finden, die EMAofdiscardeddata zu überschätzen. LastEMA eine schnelle Möglichkeit könnte sein, M max (Daten) min zu nehmen (Daten) Parallelisierung Die Berechnung kann in einem Formular umgeschrieben werden Wo es eine einfache Hinzufügung von unabhängigen Begriffen ist: Wenn also die Implementierungssprache die Parallelisierung unterstützt, kann der Datensatz in 4 (oder 8 oder n. Grundsätzlich die Anzahl der CPU-Kerne zur Verfügung) Chunks und es kann berechnet werden, die Summe der Begriffe auf jedem Stück in parallel summieren die einzelnen Ergebnisse am Ende. Ich gehe nicht ins Detail, denn diese Antwort ist schon schrecklich lang und ich denke, das Konzept ist bereits ausgedrückt. Vielen Dank für diese I39m mit diesem auf Börsen-Daten, so dass die Tatsache, dass die älteren Daten in der gleichen Größenordnung wie die neueren Daten hängt 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. Bei neuen Daten, mit einem Bereich lt 200, benutze ich einen 1000-Elemente-Datensatz. Aber ich mache auch einige Rückenversuche in den letzten Jahren, also muss ich noch den ganzen Datensatz laden. Sie haben für beide Situationen geholfen, danke ndash Lykegenes Jul 16 14 um 15:11 Aufbau Ihrer eigenen Erweiterung definitiv verbessert die Leistung. Heres ein gutes Tutorium von der Zend Website. Einige Leistungszahlen: Hardware: Ubuntu 14.04, PHP 5.5.9, 1-Core Intel CPU3.3Ghz, 128MB RAM (seine VPS). Vorher (nur PHP, 16.000 Werte). 500ms C Erweiterung, 16.000 Werte. 0,3ms C Erweiterung (100.000 Werte). 3,7ms C Erweiterung (500.000 Werte). 28.0ms Aber Im Gedächtnis begrenzt an diesem Punkt, unter Verwendung von 70MB. Ich werde das beheben und die Nummern entsprechend aktualisieren. traderema die traderema () Funktion funktioniert nicht richtig. Es berechnet nur durchschnittlich der letzten Periodeneinträge. Folgen Sie dem folgenden Code für traderema: function EMACalculator (limit, array) EMApreviousday array0 printr (array) multiplier1 (2limit1) EMAarray () EMA array0 Schließen Sie array1 while (limit) echoEMA ist EMAn EMA (Close - EMApreviousday) Multiplikator1 EMApreviousday EMApreviousday EMA limit - - Rückkehr EMA wo Grenze den Zeitraum von ema und Array akzeptieren. Akzeptiere Array von Daten für ema Berechnung. Leider hat der gezeigte Code zwei große Bugs, aufgrund der Art und Weise der Durchschnitt wird als eine ganze Zahl gespeichert. Um dies zu sehen, wählt man alpha zu 1024. Wir beginnen mit adcvalue 0, dann wird dspemai32 0 wie erwartet zurückgeben. Dann heben adcvalue auf 1. tmp0 in dspemai32 wird: tmp0 (int64t) 1 (1024) (int64t) 0 (65536 - 1024) 1024 0 64512 1024 so ist der zurückgegebene Wert: (int32t) ((tmp0 32768) 65536) ( 1024 32768) 65536 33792 65536 0 Also dspemai32 wird weiter zurückkehren 0, während es (nach lang genug Filterzeit) am Ende zurückkehren muss 1. Der Code implementiert effektiv einen Filter mit einer toten Zone und ändert sich nicht, bis der Eingang von der Durchschnittlich um 32768alpha oder mehr, oder unterscheidet sich durch - (32768alpha) oder weniger. Nach dem obigen Beispiel, erhöhen Sie den Wert auf 31 (das ist weniger als 32768alpha). Tmp0 in dspemai32 ist: tmp0 (int64t) 31 (1024) (int64t) 0 (65536 - 1024) 31744 0 64512 31744 so ist der zurückgegebene Wert: (int32t) ((tmp0 32768) 65536) (31744 32768) 65536 64512 65536 0 Also dspemai32 wird weiter zurückkehren 0. Beim Anlegen von adcvalue auf 32 stattdessen wird tmp0 in dspemai32: tmp0 (int64t) 32 (1024) (int64t) 0 (65536 - 1024) 32768 0 64512 32768 so ist der zurückgegebene Wert: ( Int32t) ((tmp0 32768) 65536) (32768 32768) 65536 65536 65536 1 Mindestens der Durchschnitt bewegt sich auf den Eingangswert um 1. Das ist gut. Aber dann: tmp0 (int64t) 32 (1024) (int64t) 1 (65536 - 1024) 32768 1 64512 97280 so ist der zurückgegebene Wert: (int32t) ((tmp0 97280) 65536) (97280 32768) 65536 130048 65536 1 So dspemai32 Wird bei der Rückkehr 1, nie erreichen den Eingangswert von 32. Nicht gut. Der zweite Fehler ist die Integer-Division (tmp0 32768) 65536. In C C wird die Integer-Division um 0 herum, also in dieser Situation ist die tote Zone noch größer. Viel besser (und viel einfacher) ist der Algorithmus, wie von david. prentice auf avrfreakscomment824765comment-824765 gezeigt: long total 0 int durchschnittlich 0 int N 0 Arbeitszahl der Proben. Total ADCW add to running total, wenn (N gt MAXSAMPLES) genug Samples total - durchschnittlich einen anderen entfernen N durchschnittliche Gesamtmenge N integer

No comments:

Post a Comment