Ich habe mit CRingBuffer eine eigene MQL5-Bibliothek entwickelt, die speziell für effiziente Rolling-Window-Analysen im Trading ausgelegt ist. Mein Fokus lag dabei klar auf Performance: Die Statistik-Berechnungen sind so optimiert, dass nach jedem Einfügevorgang sofort aktualisierte Ergebnisse vorliegen – bei möglichst geringem CPU-Verbrauch.
Die Bibliothek liefert in Echtzeit Kennzahlen wie Mittelwert, Varianz, Standardabweichung, Perzentile, Z-Scores sowie Min-/Max-Tracking und normalisierte Werte. Je nach Operation bewege ich mich dabei in Laufzeiten von O(1) bis O(n log n), was sie besonders für performanzkritische Strategien interessant macht.
CRingBuffer speichert numerische Werte in zeitlicher Reihenfolge und stellt nach jedem Einfügevorgang sofort nutzbare statistische Kennzahlen bereit. Die Klasse ist auf schnelle Rolling-Window-Analysen und robuste Signalaufbereitung ausgelegt.
Typische Einsatzgebiete:
Preise, Spreads und Volumen fortlaufend beobachten
Rolling-Window-Analysen mit fester oder variabler Länge
Signalnormalisierung auf [0,1]
Min/Max-Tracking mit virtuellem Positionsindex
Z-Score-basierte Ausreißererkennung
Historienbasierte Perzentilberechnung
Numerisch stabile Online-Statistik
2. Datenmodell: Virtueller Index
Alle Public-Methoden arbeiten mit einem virtuellen Index. Dadurch bleibt die interne Speicheranordnung verborgen und die Nutzung für Anwender klar und konsistent.
3. Konstruktion: Statischer vs. dynamischer Buffer
CRingBuffer(const int buf_size, const bool is_dynamic = false)
Statischer Buffer
Feste Größe, unveränderlich nach Konstruktion
Bei voller Kapazität wird der älteste Wert überschrieben
removeValue() und setMaxTotal() sind nicht erlaubt
Sinnvoll für feste Rolling Windows, z. B. ATR-14
Dynamischer Buffer
Größe kann angepasst werden
Wachsen über setMaxTotal() und setDynBufferTotal()
Schrumpfen über shrinkBuffer()
Einzelne Werte können mit removeValue() entfernt werden
clear() setzt zusätzlich die Kapazität auf 0 zurück
Hinweis: Nach clear() muss ein dynamischer Buffer neu aufgebaut werden, z. B. über addValue() oder setMaxTotal().
4. Platzhalter und gültige Werte
CRingBuffer unterscheidet zwischen statistisch gültigen Werten und Platzhaltern. Das schützt Kennzahlen vor Verzerrungen.
Ein Platzhalter liegt vor, wenn:
der Wert NaN oder Inf ist
der Wert EMPTY_VALUE (1e+308) ist
|value| ≥ 1e100 ist
Folgen:
Wird gespeichert und belegt einen Slot
Wird nicht für Summe, Mittelwert, Varianz oder Standardabweichung genutzt
Wird nicht für Min/Max, Perzentile oder Z-Score-Fenster genutzt
getTotal() zählt alle Slots, getValidCount() nur gültige Werte
fill_rate = valid_count / total_count
5. Statistikfunktionen im Überblick
CRingBuffer aktualisiert seine Kennzahlen direkt nach jedem addValue()-Aufruf. Dadurch stehen wichtige Zustands- und Analysewerte sofort bereit, ohne dass der komplette Buffer jedes Mal neu berechnet werden muss.
Die Tabelle fasst die wichtigsten Statistikgruppen zusammen und zeigt, wofür die jeweiligen Methoden typischerweise verwendet werden.
Beschreibt Extremwerte, deren Positionen und die aktuelle Spannweite des Buffers für schnelle Zustandsbewertungen.
Range-Historie
getAverageRange(), getRangeHistory()
Zeigt, wie sich die Spannweite im Zeitverlauf entwickelt und unterstützt Volatilitätsanalysen.
Änderung
getAverageDiff()
Misst die durchschnittliche absolute Änderung zwischen aufeinanderfolgenden gültigen Werten und hilft bei der Beurteilung der Dynamik.
Empfehlung: Für robuste Analysen mit großen Preisniveaus sind die Welford-Methoden oft die bessere Wahl, während die Basisstatistik für kompakte Echtzeitabfragen ideal ist.
6. Erweiterung durch Vererbung
Abgeleitete Klassen können Hooks überschreiben. Diese Hooks werden erst nach vollständiger Aktualisierung der Statistiken aufgerufen.
void OnAddValue(constdoublevalue)
Wird nach dem erfolgreichen Einfuegen eines neuen Wertes gerufen.
Alle Statistiken sind zu diesem Zeitpunkt bereits aktuell.
void OnRemoveValue(constdoublevalue)
Wird aufgerufen wenn ein Wert aus dem Buffer entfernt oder
ueberschrieben wird.
void OnChangeValue(constint vIndexID,
constdouble prev_value,
constdouble new_value)
Wird nach replaceValue() gerufen.
Alle Statistiken sind zu diesem Zeitpunkt bereits aktuell.
void OnChangeArray()
Wird nach jeder strukturellen Aenderung gerufen (addValue,
replaceValue, removeValue, clear, shrinkBuffer, setMaxTotal).
void OnSetMaxTotal(constint max_total)
Wird nach setMaxTotal() gerufen (nur dynamische Buffer).
void OnShrink()
Wird nach shrinkBuffer() gerufen.
7. Codebeispiele
Die folgenden Beispiele zeigen typische Einsatzmuster der Klasse. Hervorgehoben wird jeweils nur der eigentliche Codeblock.
getLastZScore() beschreibt den aktuellen Zustand. getZScoreAt() eignet sich für Backtests, weil der bewertete Wert nicht Teil seiner eigenen Statistik ist.
Beispiel 5 · Dynamischer Buffer: Entfernen und Verkleinern
removeValue() arbeitet mit virtuellen Indizes. shrinkBuffer() behält immer die neuesten Werte und ist ideal für flexible Historienfenster.
8. Wichtige Verhaltensdetails und Fallstricke
ToArray(): count > 0 exportiert die neuesten count Werte, nicht die ältesten.
Z-Score: getZScoreAt() und getZScores(arr, 0) sind look-ahead-frei.
clear() bei dynamisch: Nach clear() ist die Kapazität 0.
Min/Max-Index: Vor Zugriff immer auf -1 prüfen.
getTotal() vs. getValidCount(): Platzhalter werden nur von getTotal() vollständig erfasst.
9. Struct RBufStats
RBufStats ist eine Snapshot-Struct für den aktuellen Bufferzustand. Sie bündelt Kennzahlen in einer transportfähigen Form und eignet sich für Logging, Weitergabe an andere Klassen oder den Vergleich mehrerer Zustände.
Hilft bei Signalbewertung, Vergleich auf einheitlicher Skala und Änderungserkennung.
Typischer Einsatz: Snapshot befüllen, mit Validate() prüfen und anschließend gesammelt protokollieren oder an andere Verarbeitungsschritte weitergeben.
10. Praktische Hinweise
Statischer Buffer für feste Rolling Windows, dynamischer Buffer für variable Historien.
Welford bevorzugen bei großen Preisniveaus und langen Laufzeiten.
Für Backtesting getZScoreAt() oder getZScores(arr, 0) verwenden.
getMinIndex() und getMaxIndex() immer auf -1 prüfen.
getPercentiles() ist effizienter als mehrfach getPercentile().
11. Public-API-Referenz
Legende: [S] statisch und dynamisch · [D] nur dynamisch · O(1) konstante Laufzeit · O(n) lineare Laufzeit
11.1 Konstruktion
Methode: CRingBuffer(const int buf_size, const bool is_dynamic = false)
Typ: [S/D]
Laufzeit: Initialisierung
Beschreibung: Erstellt einen statischen oder dynamischen Buffer mit definierter Startkapazität.
Hinweis: Der Modus bestimmt, ob Werte später entfernt oder die Kapazität geändert werden dürfen.
Methode: ~CRingBuffer()
Typ: [S/D]
Laufzeit: Freigabe
Beschreibung: Gibt die belegten Ressourcen nach der Nutzung frei.
Hinweis: Relevant beim sauberen Lifecycle-Management in längeren Analyseläufen.
11.2 Werte hinzufügen und ändern
Methode: addValue(long|int|double)
Typ: [S/D]
Laufzeit: O(1)
Beschreibung: Fügt einen neuen Wert hinzu und aktualisiert die Statistiken unmittelbar.
Hinweis: Im statischen Modus wird bei voller Kapazität der älteste Wert überschrieben.
Methode: replaceValue(vIndexID, value)
Typ: [S/D]
Laufzeit: O(1)
Beschreibung: Ersetzt einen vorhandenen Wert gezielt am virtuellen Index.
Hinweis: Sinnvoll für Korrekturen einzelner Datenpunkte ohne kompletten Neuaufbau.
Methode: removeValue(vIndexID)
Typ: [D]
Laufzeit: O(n)
Beschreibung: Entfernt einen Eintrag aus einem dynamischen Buffer.
Hinweis: Danach verschieben sich die virtuellen Indizes der nachfolgenden Werte.
11.3 Direkter Datenzugriff
Methode: getValue(vIndexID)
Typ: [S/D]
Laufzeit: O(1)
Beschreibung: Liest einen bestimmten Wert anhand des virtuellen Index aus.
Hinweis: Eignet sich für gezielten Zugriff auf historische Positionen.
Methode: getLast(), getPrevious(), getOldest()
Typ: [S/D]
Laufzeit: O(1)
Beschreibung: Liefert die wichtigsten Positionswerte direkt aus dem Buffer.
Hinweis: Besonders nützlich für aktuelle Signale und Vergleiche mit dem ältesten Wert.
Wenn Sie kein Benutzerkonto haben, registrieren Sie sich
Erlauben Sie die Verwendung von Cookies, um sich auf der Website MQL5.com anzumelden.
Bitte aktivieren Sie die notwendige Einstellung in Ihrem Browser, da Sie sich sonst nicht einloggen können.
Sie sind angemeldet. Die Zwei-Faktor-Authentifizierung wurde deaktiviert. Richten Sie sie erneut ein und scannen Sie einen neuen QR-Code oder fahren Sie mit deaktivierter Zwei-Faktor-Authentifizierung fort.
Hallo zusammen,
Ich habe mit CRingBuffer eine eigene MQL5-Bibliothek entwickelt, die speziell für effiziente Rolling-Window-Analysen im Trading ausgelegt ist. Mein Fokus lag dabei klar auf Performance: Die Statistik-Berechnungen sind so optimiert, dass nach jedem Einfügevorgang sofort aktualisierte Ergebnisse vorliegen – bei möglichst geringem CPU-Verbrauch.
Die Bibliothek liefert in Echtzeit Kennzahlen wie Mittelwert, Varianz, Standardabweichung, Perzentile, Z-Scores sowie Min-/Max-Tracking und normalisierte Werte. Je nach Operation bewege ich mich dabei in Laufzeiten von O(1) bis O(n log n), was sie besonders für performanzkritische Strategien interessant macht.
Wenn ihr interesse habt, dann könnt ihr sie hier downloaden: https://www.mql5.com/de/market/product/174460
1. Zweck und Einsatzgebiete
CRingBuffer speichert numerische Werte in zeitlicher Reihenfolge und stellt nach jedem Einfügevorgang sofort nutzbare statistische Kennzahlen bereit. Die Klasse ist auf schnelle Rolling-Window-Analysen und robuste Signalaufbereitung ausgelegt.
2. Datenmodell: Virtueller Index
0 = ältester gespeicherter Wert getTotal() - 1 = neuester, zuletzt hinzugefügter Wert
3. Konstruktion: Statischer vs. dynamischer Buffer
CRingBuffer(const int buf_size, const bool is_dynamic = false)
4. Platzhalter und gültige Werte
fill_rate = valid_count / total_count
5. Statistikfunktionen im Überblick
6. Erweiterung durch Vererbung
7. Codebeispiele
getLastZScore() beschreibt den aktuellen Zustand. getZScoreAt() eignet sich für Backtests, weil der bewertete Wert nicht Teil seiner eigenen Statistik ist.
Beispiel 5 · Dynamischer Buffer: Entfernen und Verkleinern
8. Wichtige Verhaltensdetails und Fallstricke
9. Struct RBufStats
10. Praktische Hinweise
11. Public-API-Referenz
11.1 Konstruktion
11.2 Werte hinzufügen und ändern
11.3 Direkter Datenzugriff
11.4 Buffergröße und Zustand
11.5 Index- und Arrayoperationen
11.6 Basisstatistik
11.7 Z-Score-Methoden
11.8 Min/Max und Range
11.9 Welford-Statistik
11.10 Normalisierung
11.11 Debugging
Hinweis: Hilfreich bei Entwicklung, Test und Validierung des Bufferverhaltens.