Bibliothèque de classes génériques - bogues, description, questions, caractéristiques d'utilisation et suggestions - page 28

 
Alexey Volchanskiy:

Qu'est-ce qui se passe encore ici ? Ils suppriment des messages parfaitement valides de LinkedList. Je peux imaginer un modérateur anonyme assis quelque part en Europe et supprimant les messages de Russes détestés, en ricanant malicieusement. C'est un tel dépotoir, ça te donne pas envie d'écrire.

Arrêtez de vous battre contre les moulins à vent - il n'y a pas de messages supprimés de ce fil de discussion.

 
Artyom Trishkin:

Arrêtez de vous battre contre des moulins à vent - il n'y a pas de messages supprimés de ce fil de discussion.

Artem, je ne suis ni ivre ni sous influence. J'ai écrit une brève réponse il y a une demi-heure : dans MQL, LinkedList est implémentée comme un tampon en anneau et le comportement décrit est tout à fait normal. Et j'ai implémenté un tampon circulaire dans mes filtres en utilisant un tableau. J'ai ensuite consulté les sources .NET pour voir l'implémentation, et après une demi-heure, mon message a été supprimé. C'était la première fois que je le faisais.

En ce qui concerne les modérateurs russes, je ne pense pas.

Voici la classe de filtre avec FIR, regardez la fonction double FilterTick(double tick). Il y a deux tampons en anneau - les ticks d'entrée et les valeurs filtrées de sortie. La différence avec la liste chaînée est que c'est moins possible, mais c'est un ordre de grandeur plus rapide, ce qui est important pour moi.

#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, je ne suis pas ivre et je ne suis pas drogué. J'ai écrit une courte réponse il y a une demi-heure, indiquant que la liste de liens MQL est mise en œuvre comme un tampon en anneau et que le comportement décrit est tout à fait normal. Et j'ai implémenté un tampon circulaire dans mes filtres en utilisant un tableau. Je me suis ensuite rendu dans les sources .NET pour examiner l'implémentation, et après une demi-heure, mon message a été supprimé. C'était la première fois que je le faisais.

En ce qui concerne les modérateurs russes, je ne pense pas.

Voici la classe de filtre avec FIR, regardez la fonction double FilterTick(double tick). Il y a deux tampons en anneau - les ticks d'entrée et les valeurs filtrées de sortie. La différence avec la liste liée est moins de possibilités, mais c'est beaucoup plus rapide, ce qui est important pour moi.

Je ne sais pas - j'ai regardé les messages supprimés - rien dans ce fil. Shaitan...

Il me semble également logique qu'une "liste liée" soit une liste liée. Une liste simple ne comporte pas de boucles et fonctionne comme l'a dit Alexey Navoikov : "Le suivant du dernier nœud est égal à zéro, tout comme leprécédent du premier nœud", alors qu'une liste liée en comporte et fonctionne comme un tampon en anneau. Ce qui pour moi est pratique.

 
Artyom Trishkin:

Je ne sais pas - j'ai regardé dans les messages supprimés - rien dans ce fil. Shaitan...

Il me semble également logique qu'une "liste liée" soit une liste liée. Une liste simple n'a pas de boucle et fonctionne comme Alexey Navoikov l'a dit : "Le suivant du dernier nœud est égal à zéro et le précédent du premier nœud l'est aussi", tandis qu'une liste liée a et fonctionne comme un tampon en anneau. Ce qui pour moi est pratique.

Ah, c'est une possibilité, je ne le savais pas. Eh bien, je peux supposer que j'ai été distrait et que, sans envoyer de message, je suis allé directement de cette page quelque part. Mais de telles plaintes se produisent régulièrement, et je ne suis pas le seul. Ok, ne parlons plus de ça.

 
Alexey Volchanskiy:

Ah, c'est une possibilité, je ne le savais pas. Eh bien, je peux supposer que j'ai été distrait et que je suis allé directement de cette page sans envoyer de message. Mais de telles plaintes se produisent régulièrement, et je ne suis pas le seul. Très bien, ne parlons plus de ça.

Ici, ici, il faut être plus attentif, tous les boutons sont soigneusement pressés.

 
Artyom Trishkin:

Il me semble également logique qu'une "liste liée" soit une liste liée. Une liste simple n'a pas de boucle et fonctionne comme Alexey Navoikov l'a dit : "Le suivant du dernier noeud est zéro, ainsi que le précédent du premier", tandis qu'une liste liée a et fonctionne comme un tampon en anneau. Ce qui pour moi est pratique.

Une liste liée est une liste qui stocke des pointeurs vers les éléments suivants et précédents. "La sonnerie n'a rien à voir avec ça. Quoi qu'il en soit, c'est quelque chose de nouveau. Où l'a-t-on vu ?

Alexey Volchanskiy:
Voici la classe de filtre avec FIR, regardez la fonction FilterTick(double tick). Il y a juste deux tampons en anneau - les ticks d'entrée et les valeurs filtrées de sortie. La différence avec la liste liée est moins de possibilités, mais c'est beaucoup plus rapide, ce qui est important pour moi.

Cela n'a rien à voir avec une classe de filtre... Nous parlons spécifiquement d'une liste liée. Il s'agit d'un conteneur standard qui possède certaines propriétés. L'itération dans la liste est unidirectionnelle. Il ne peut y avoir de sonnerie. Il n'y en a pas en C# (la classe identique LinkedList) ou en C++ (la classe std::list).

De plus, cette bibliothèque est portée depuis .Net, ce qui implique une compatibilité avec C#, sinon pourquoi diable avons-nous besoin d'un autre vélo fait maison ? N'en avons-nous pas assez des vélos MQ minables ? Tout ce dont nous avions besoin était de porter une bibliothèque prête à l'emploi (même si elle comporte des restrictions spécifiques au langage, mais au moins pour préserver la logique du travail). Mais non... De vilaines mains sont intervenues ici aussi).

Il est fort probable que celui qui a porté ces classes a décidé de se simplifier la vie, après avoir simplifié le code. Au lieu de deux pointeurs m_first et m_last, il a fait un pointeur m_head...

Bien sûr, j'ai tout arrangé comme il faut, mais néanmoins...

 
Alexey Navoykov:

Une liste liée est une liste qui stocke des pointeurs vers les éléments suivants et précédents. "La sonnerie n'a rien à voir avec ça. Quoi qu'il en soit, c'est quelque chose de nouveau. Où l'a-t-on vu ?

Cela n'a rien à voir avec une classe de filtre... Nous parlons spécifiquement d'une liste liée. Il s'agit d'un conteneur standard qui possède certaines propriétés. L'itération dans la liste est unidirectionnelle. Il ne peut y avoir de sonnerie. Il n'y en a pas en C# (la classe identique LinkedList) ou en C++ (la classe std::list).

De plus, cette bibliothèque est portée depuis .Net, ce qui implique une compatibilité avec C#, sinon pourquoi diable avons-nous besoin d'un autre vélo fait maison ? N'en avons-nous pas assez des vélos MQ minables ? Tout ce dont nous avions besoin était de porter une bibliothèque prête à l'emploi (même avec des restrictions spécifiques au langage, mais au moins pour préserver la logique du travail). Mais non... De vilaines mains sont intervenues ici aussi).

Il est fort probable que celui qui a porté ces classes a décidé de se simplifier la vie, après avoir simplifié le code. Au lieu de deux pointeurs m_first et m_last, il a fait un pointeur m_head...

Bien sûr, j'ai tout réparé comme il se doit, mais néanmoins...

MSDN l'appelle un tampon circulaire, je n'ai pas inventé ce nom.

L'essentiel est de ne pas le fixer dans le dossier Include, sinon il sera effacé lors de la mise à niveau vers la nouvelle version de MT5.

 
Vladimir Karputov:

Là, là, vous devez être plus prudent et appuyer sur tous les bons boutons avec précaution.

La probabilité que cela se produise est proche de zéro. Mais c'est un fait que ma branche sur le fil de discussion en anglais a été anonymement tuée. ***

 
Alexey Volchanskiy:

La probabilité que cela se produise est très faible. Mais le fait que ma branche dans le fil de la langue anglaise a été tuée anonymement est un fait. ***

Assez parlé de cette branche. Tu en reparles et je te donne un balai de bouleau. J'en ai marre.

 
Alexey Volchanskiy:

Surtout, ne modifiez pas le dossier Include, car il sera écrasé lors de la mise à niveau vers une nouvelle version de MT5.

Je l'ai placé dans un dossier séparé Generic_. En fait, j'ai dû y apporter beaucoup de changements, en commençant par les const pour les méthodes (les développeurs ne le jugeaient pas nécessaire), et en terminant par la refonte pour les arguments par référence, et pas seulement par valeur.