Generische Klassenbibliothek - Bugs, Beschreibung, Fragen, Nutzungsmöglichkeiten und Vorschläge - Seite 28

 
Alexey Volchanskiy:

Was zum Teufel ist hier los? Sie löschen vollkommen gute LinkedList-Beiträge. Ich kann mir gerade vorstellen, wie ein anonymer Moderator irgendwo in Europa sitzt und Beiträge von verhassten Russen löscht und dabei bösartig kichert. Es ist so ein Müll, dass man keine Lust hat zu schreiben.

Hören Sie auf, gegen Windmühlen zu kämpfen - es gibt keine gelöschten Beiträge in diesem Thread.

 
Artyom Trishkin:

Hören Sie auf, gegen Windmühlen zu kämpfen - es gibt keine gelöschten Beiträge in diesem Thread.

Artem, ich bin weder betrunken, noch stehe ich unter Einfluss. Ich schrieb eine kurze Antwort vor einer halben Stunde, dass in MQL LinkedList als Ringpuffer implementiert ist und das beschriebene Verhalten ist nur normal. Und ich habe einen Ringpuffer in meinen Filtern mit einem Array implementiert. Dann ging ich zu den .NET-Quellen, um mir die Implementierung anzusehen, und nach einer halben Stunde wurde meine Nachricht gelöscht. Es war das erste Mal, dass ich das gemacht habe.

An die russischen Moderatoren glaube ich einfach nicht.

Hier ist die Filterklasse mit der Funktion FIR, watch double FilterTick(double tick). Es gibt zwei Ringpuffer - Eingangszecken und gefilterte Ausgangswerte. Der Unterschied zur verknüpften Liste ist, dass es weniger möglich ist, aber es ist um eine Größenordnung schneller, was für mich wichtig ist.

#ifndef  Filter
#define  Filter

//+------------------------------------------------------------------+
//|                                                       Filter.mqh |
//|                                               Alexey Volchanskiy |
//|                                      https://mql4.wordpress.com/ |
//+------------------------------------------------------------------+
#property copyright "Alexey Volchanskiy"
#property link      "https://mql4.wordpress.com/"
#property version   "1.04"
#property strict
#include <Object.mqh>
#include <AvLib-4-5\coeff.mqh>
#include <AvLib-4-5\Errors.mqh>

/*
Формат массива или файла коэффициентов фильтра
double coeff[] = {FiltersCount, FilterAddr, FilterLen, FilterAddr, FilterLen..., coeff1, coeff2, coeff3...};
*/
enum EErrors {EOk, ENumFilterOutOfRange};

class CFilter : CObject
{
#define  TICK_BUF_SIZE       0x1000              // 4096
#define  TICK_BUF_MAX_IDX    (TICK_BUF_SIZE - 1) // 0xFFF
#define  OUT_BUF_SIZE        0x10000             // 65536
#define  OUT_BUF_MAX_IDX     (OUT_BUF_SIZE - 1)  // 0xFFFF   

private:
    double  TickBuf[TICK_BUF_SIZE]; // промежуточный кольцевой буфер для хранения тиков
    double  OutBuf[OUT_BUF_SIZE];   // выходной кольцевой буфер
    double  Coeff[];                // массив коэффициентов
    int     TickBufIdx;             // индекс для нового входящего тика в TickBuf
    int     OutBufIdx;              // индекс для выходного буфера 
public:
    enum Errors {OK, NUM_FILTER_OUT_OF_RANGE };  
public:
    CFilter() {}
    ~CFilter() 
    {
        ArrayFree(Coeff);
    }
    
    double  GetOutBuf(const int idx)
    {
        int tmp = OutBufIdx-idx-1;
        double out = tmp >= 0 ? OutBuf[tmp] : OutBuf[OUT_BUF_SIZE+(tmp)]; 
        return out;
    }

    void    Init()
    {
        TickBufIdx = TICK_BUF_MAX_IDX;
        OutBufIdx = 0;
        for(int n = 0; n < TICK_BUF_SIZE; n++)
            TickBuf[n] = 0;
        for(int n = 0; n < OUT_BUF_SIZE; n++)
            OutBuf[n] = 0;
    }        

    EErrors  LoadCoeffFromArray(int numFilter, double &coeffArray[])
    {
        if(numFilter >= coeffArray[0])  // количество фильтров в массиве
            return ENumFilterOutOfRange;
        uint addr = (uint)coeffArray[1 + numFilter * 2];
        uint len = (uint)coeffArray[2 + numFilter * 2];   
        ArrayResize(Coeff, len);
        for(uint n = 0; n < len; n++)
            Coeff[n] = coeffArray[addr++];
        Init();    
        return EOk;
    }

    void    LoadCoeffFromArray(double &coeffArray[])
    {
        int len = ArraySize(coeffArray); 
        ArrayResize(Coeff, len);
        for(int n = 0; n < len; n++)
            Coeff[n] = coeffArray[n];
        Init();    
    }
    
    bool    LoadCoeffFromFile(int numFilter, string fileName)
    {
        // не реализовано
        return true;
    }
    
    // фильтрация одного тика
    double  FilterTick(double tick)
    {
        TickBuf[TickBufIdx] = tick;
        if (TickBufIdx == 0)
            TickBufIdx = TICK_BUF_MAX_IDX;
        else
            TickBufIdx--;
        int asize = ArraySize(Coeff); // вынести из функции!!!
        double acc = 0;
        int tbIdx = TickBufIdx;
        // делаем фильтрацию в цикле for
        for (int n = 0; n < asize; n++)
        {
            tbIdx++;
            /* вместо
            if(tbIdx > TICK_BUF_MAX_IDX)
            tbIdx = 0;
            */
            tbIdx &= TICK_BUF_MAX_IDX; // небольшая оптимизация вместо if
            acc += TickBuf[tbIdx] * Coeff[n];
        }
        OutBuf[OutBufIdx] = acc;
        OutBufIdx++;
        OutBufIdx &= OUT_BUF_MAX_IDX;
        return acc;
    }
    
    // фильтрация массива
    void    FilterTickSeries(double &ticks[], int count)
    {
        for(int n = 0; n < count; n++)
            ticks[n] = FilterTick(ticks[n]);
    }
};
#endif
 
Alexey Volchanskiy:

Artem, ich bin nicht betrunken und stehe nicht unter Drogen. Ich habe vor einer halben Stunde eine kurze Antwort geschrieben, dass MQL LinkedList als Ringpuffer implementiert ist und das beschriebene Verhalten ganz normal ist. Und ich habe einen Ringpuffer in meinen Filtern mit einem Array implementiert. Dann ging ich zu den .NET-Quellen, um mir die Implementierung anzusehen, und nach einer halben Stunde wurde meine Nachricht gelöscht. Es war das erste Mal, dass ich das gemacht habe.

An die russischen Moderatoren glaube ich einfach nicht.

Hier ist die Filterklasse mit der Funktion FIR, watch double FilterTick(double tick). Es gibt zwei Ringpuffer - Eingangszecken und gefilterte Ausgangswerte. Der Unterschied zur verknüpften Liste ist, dass es weniger Möglichkeiten gibt, aber es ist viel schneller, was für mich wichtig ist.

Ich weiß es nicht - ich habe die gelöschten Beiträge durchgesehen - nichts aus diesem Thread. Shaitan ...

Es erscheint mir auch logisch, dass eine "verbundene Liste" eine verbundene Liste ist. Bei einer einfachen Liste gibt es keine Schleifen und sie funktioniert so, wie Alexey Navoikov sagte: "Der Next des letzten Knotens ist Null, genau wie derPrevious des ersten Knotens", während eine verknüpfte Liste dies tut und wie ein Ringpuffer funktioniert. Das ist für mich sehr praktisch.

 
Artyom Trishkin:

Ich weiß es nicht - ich habe die gelöschten Beiträge durchgesehen - nichts von diesem Thema. Shaitan...

Es erscheint mir auch logisch, dass eine "verbundene Liste" eine verbundene Liste ist. Eine einfache Liste hat keine Schleifen und funktioniert wie Alexey Navoikov sagte: "Next of last node equals zero and so does Previous of first node", während eine verknüpfte Liste hat und wie ein Ringpuffer funktioniert. Das ist für mich sehr praktisch.

Ah, das ist eine Möglichkeit, das wusste ich nicht. Nun, ich kann davon ausgehen, dass ich abgelenkt wurde und, ohne eine Nachricht zu senden, direkt von dieser Seite irgendwohin gegangen bin. Aber solche Beschwerden kommen regelmäßig vor, und ich bin nicht der Einzige, der sich darüber beschwert. Okay, lassen Sie uns nicht mehr darüber reden.

 
Alexey Volchanskiy:

Ah, das ist eine Möglichkeit, die ich nicht kannte. Nun, ich kann davon ausgehen, dass ich abgelenkt wurde und die Seite direkt verlassen habe, ohne eine Nachricht zu senden. Aber solche Beschwerden kommen regelmäßig vor, und ich bin nicht der Einzige, der sich darüber beschwert. In Ordnung, lassen Sie uns nicht mehr darüber reden.

Hier, hier, müssen aufmerksamer sein, alle Tasten ordentlich gedrückt.

 
Artyom Trishkin:

Es erscheint mir auch logisch, dass eine "verbundene Liste" eine verbundene Liste ist. Eine einfache Liste hat keine Schleifen und funktioniert so, wie Alexey Navoikov sagte: "Der vorletzte Knoten ist Null, der vorherige auch", während eine verknüpfte Liste einen Ringpuffer hat und wie ein solcher funktioniert. Das ist für mich sehr praktisch.

Eine verknüpfte Liste ist eine Liste, die Zeiger auf das nächste und das vorherige Element speichert. "Klingeln hat damit nichts zu tun. Auf jeden Fall ist das etwas Neues. Wo wurde sie gesehen?

Alexey Volchanskiy:
Hier ist die Filterklasse mit der Funktion FIR, watch double FilterTick(double tick). Es gibt nur zwei Ringpuffer - Eingangszecken und gefilterte Ausgangswerte. Der Unterschied zur verknüpften Liste ist, dass es weniger Möglichkeiten gibt, aber es ist viel schneller, was für mich wichtig ist.

Das hat nichts mit einer Filterklasse zu tun... Wir sprechen hier speziell von einer verknüpften Liste. Es handelt sich um einen Standardcontainer, der bestimmte Eigenschaften hat. Die Iteration durch die Liste ist unidirektional. In C# (die identische LinkedList-Klasse) oder C++ (die std::list-Klasse) gibt es kein Klingeln.

Außerdem ist diese Bibliothek aus .Net portiert, was Kompatibilität mit C# impliziert, warum zum Teufel brauchen wir sonst noch ein selbstgebasteltes Fahrrad? Haben wir nicht schon genug von miesen MQ-Fahrrädern? Alles, was wir brauchten, war eine fertige Bibliothek zu portieren (wenn auch mit sprachspezifischen Einschränkungen, aber zumindest, um die Logik der Arbeit zu erhalten). Aber nein... Auch hier haben sich böse Hände eingemischt)

Wahrscheinlich hat derjenige, der diese Klassen portiert hat, beschlossen, sich das Leben zu vereinfachen, indem er den Code vereinfacht hat: Statt zwei m_first- und m_last-Zeigern hat er einen m_head-Zeiger erstellt...

Natürlich habe ich alles so repariert, wie es sein sollte, aber trotzdem...

 
Alexey Navoykov:

Eine verknüpfte Liste ist eine Liste, die Zeiger auf das nächste und das vorherige Element speichert. "Klingeln hat damit nichts zu tun. Auf jeden Fall ist das etwas Neues. Wo hat man sie gesehen?

Das hat nichts mit einer Filterklasse zu tun... Wir sprechen hier speziell von einer verknüpften Liste. Es handelt sich um einen Standardcontainer, der bestimmte Eigenschaften hat. Die Iteration durch die Liste ist unidirektional. In C# (die identische LinkedList-Klasse) oder C++ (die std::list-Klasse) gibt es kein Klingeln.

Außerdem ist diese Bibliothek aus .Net portiert, was Kompatibilität mit C# impliziert, warum zum Teufel brauchen wir sonst noch ein selbstgebasteltes Fahrrad? Haben wir nicht schon genug von miesen MQ-Fahrrädern? Alles, was wir brauchten, war eine fertige Bibliothek zu portieren (wenn auch mit sprachspezifischen Einschränkungen, aber zumindest, um die Logik der Arbeit zu erhalten). Aber nein... Auch hier haben sich böse Hände eingemischt)

Wahrscheinlich hat derjenige, der diese Klassen portiert hat, beschlossen, sich das Leben zu vereinfachen, indem er den Code vereinfacht hat: Statt zwei m_first- und m_last-Zeigern hat er einen m_head-Zeiger erstellt...

Natürlich habe ich alles so repariert, wie ich es sollte, aber trotzdem...

MSDN nennt es einen Ringpuffer, ich habe den Namen nicht erfunden.

Das Wichtigste ist, dass Sie es nicht im Ordner "Include" fixieren, da es sonst beim Upgrade auf den neuen Build von MT5 gelöscht wird.

 
Vladimir Karputov:

Da, da, da muss man vorsichtiger sein und alle richtigen Knöpfe sorgfältig drücken.

Die Wahrscheinlichkeit, dass dies geschieht, geht gegen Null. Aber es ist eine Tatsache, dass mein Zweig im englischsprachigen Thread anonym getötet wurde. ***

 
Alexey Volchanskiy:

Die Wahrscheinlichkeit, dass dies geschieht, ist sehr gering. Aber die Tatsache, dass mein Zweig im englischsprachigen Thread anonym getötet wurde, ist eine Tatsache. ***

Genug von diesem Zweig. Wenn du noch einmal damit anfängst, gebe ich dir einen Birkenbesen. Ich habe es satt.

 
Alexey Volchanskiy:

Wichtig ist, dass Sie nicht im Include-Ordner editieren, da dieser sonst bei einem Upgrade auf eine neue Version von MT5 überschrieben wird.

Ich habe es in einem separaten Ordner Generic_. Tatsächlich musste ich dort eine Menge Änderungen vornehmen, beginnend mit const für Methoden (die Entwickler hielten es nicht für notwendig), und endend mit der Umgestaltung für Argumente durch Referenz, nicht nur durch Wert.

Grund der Beschwerde: