Biblioteca de classes genéricas - bugs, descrição, perguntas, recursos de uso e sugestões - página 28

 
Alexey Volchanskiy:

Que porra se passa aqui outra vez? Eles estão a apagar perfeitamente bons posts da LinkedList. Posso apenas imaginar um moderador anónimo sentado algures na Europa e a apagar postos de russos odiados, a rir-se maliciosamente. É uma lixeira tão grande, que faz com que não se queira escrever.

Parar de lutar contra os moinhos de vento - não há postes apagados deste fio.

 
Artyom Trishkin:

Parar de lutar contra moinhos de vento - não há postes apagados deste tópico.

Artem, não estou bêbado nem sob a influência. Escrevi uma breve resposta há meia hora que na MQL LinkedList é implementada como um tampão de anel e o comportamento descrito é apenas normal. E implementei um tampão de anel nos meus filtros utilizando uma matriz. Depois fui às fontes .NET para analisar a implementação, e após meia hora a minha mensagem foi apagada. Foi a primeira vez que o fiz.

Sobre os moderadores russos, não penso.

Aqui está a classe de filtragem com FIR, relógio com dupla função FilterTick(duplo tick). Existem dois anéis tampão - tiquetaques de entrada e valores filtrados de saída. A diferença com a lista ligada é que é menos possível, mas é uma ordem de magnitude mais rápida, o que é importante para mim.

#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, eu não estou bêbado e não estou drogado. Escrevi uma breve resposta há meia hora atrás que a MQL LinkedList é implementada como um buffer de anel e que o comportamento descrito é apenas normal. E implementei um tampão de anel nos meus filtros utilizando uma matriz. Depois fui às fontes .NET para ver a implementação, e após meia hora a minha mensagem foi apagada. Foi a primeira vez que o fiz.

Sobre os moderadores russos, não penso.

Aqui está a classe de filtragem com FIR, relógio com dupla função FilterTick(duplo tick). Existem dois anéis tampão - tiquetaques de entrada e valores filtrados de saída. A diferença com a lista ligada é menos possibilidades, mas é muito mais rápida, o que é importante para mim.

Não sei - procurei em posts apagados - nada deste tópico. Shaitan ...

Também me parece lógico que uma "lista ligada" seja uma lista ligada. Uma lista simples não tem looping e funciona como disse Alexey Navoikov: "O Próximo do último nó é zero, tal como oAnterior do primeiro nó", enquanto que uma lista ligada funciona, e funciona como um buffer de anéis. O que, para mim, é conveniente.

 
Artyom Trishkin:

Não sei - procurei nas mensagens eliminadas - nada deste tópico. Shaitan...

Também me parece lógico que uma "lista ligada" seja uma lista ligada. Uma lista simples não tem looping e funciona como Alexey Navoikov disse: "O próximo do último nó é igual a zero e o anterior do primeiro nó também" enquanto que uma lista ligada tem e funciona como um buffer de anel. O que, para mim, é conveniente.

Ah, essa é uma possibilidade, não sabia. Bem, posso assumir que me distraí e, sem enviar uma mensagem, fui directamente daquela página para algum lado. Mas tais queixas ocorrem regularmente, e eu não sou o único. Ok, não vamos falar mais sobre isso.

 
Alexey Volchanskiy:

Ah, essa é uma possibilidade, eu não sabia. Bem, posso assumir que me distraí e fui directamente daquela página sem enviar uma mensagem. Mas tais queixas ocorrem regularmente, e eu não sou o único. Muito bem, não falemos mais sobre isso.

Aqui, aqui, é preciso estar mais atento, todos os botões bem apertados.

 
Artyom Trishkin:

Também me parece lógico que uma "lista ligada" seja uma lista ligada. Uma lista simples não tem looping e funciona como Alexey Navoikov disse: "O último nó seguinte é zero, assim como o primeiro anterior", enquanto que uma lista ligada tem e funciona como um buffer de anéis. O que, para mim, é conveniente.

Uma lista ligada é uma lista que armazena apontadores para os itens seguintes e anteriores. "O Anel não tem nada a ver com isso. De qualquer modo, isto é algo novo. Onde foi visto?

Alexey Volchanskiy:
Aqui está a classe de filtragem com FIR, relógio com dupla função FilterTick(duplo tick). Há apenas dois anéis tampão - tiquetaques de entrada e valores filtrados de saída. A diferença com a lista ligada é menos possibilidades, mas é muito mais rápida, o que é importante para mim.

Não tem nada a ver com uma classe de filtros... Estamos a falar especificamente de uma lista ligada. É um recipiente padrão que tem certas propriedades. A iteração através da lista é unidireccional. Não pode haver qualquer toque; nem em C# (a classe idêntica LinkedList), nem em C++ (a classe std::list).

Além disso, esta biblioteca é portada de .Net, o que implica compatibilidade com C#, caso contrário porque diabos precisamos de outra bicicleta caseira? Não temos tido o suficiente de bicicletas MQ migalhas? Tudo o que precisávamos era de portar uma biblioteca pronta (mesmo que com restrições específicas de linguagem, mas pelo menos para preservar a lógica do trabalho). Mas não... Mãos travessas também interferiram aqui )

Muito provavelmente, quem quer que tenha portado essas classes decidiu simplificar a sua vida, tendo simplificado o código. Em vez de dois m_primeiro e m_último apontadores, fez um m_ponteiro de cabeça...

É claro que corrigi tudo como devia ser, mas mesmo assim...

 
Alexey Navoykov:

Uma lista ligada é uma lista que armazena apontadores para os itens seguintes e anteriores. "O Anel não tem nada a ver com isso. De qualquer modo, isto é algo novo. Onde foi visto?

Não tem nada a ver com uma classe de filtros... Estamos a falar especificamente de uma lista ligada. É um recipiente padrão que tem certas propriedades. A iteração através da lista é unidireccional. Não há nenhuma em C# (a classe idêntica LinkedList) ou C++ (a classe std::list).

Além disso, esta biblioteca é portada de .Net, o que implica compatibilidade com C#, caso contrário porque diabos precisamos de outra bicicleta caseira? Não temos tido o suficiente de bicicletas MQ migalhas? Tudo o que precisávamos era de portar uma biblioteca pronta (mesmo que com restrições específicas de linguagem, mas pelo menos para preservar a lógica do trabalho). Mas não... Mãos travessas também interferiram aqui )

Muito provavelmente, quem quer que tenha portado essas classes decidiu simplificar a sua vida, tendo simplificado o código. Em vez de dois m_primeiro e m_último apontadores, fez um m_ponteiro de cabeça...

É claro que consertei tudo como devia, mas mesmo assim...

A MSDN chama-lhe um tampão de anel, ainda não inventei o nome.

O principal é não o corrigir na pasta Incluir, caso contrário será apagado quando se actualiza para a nova construção do MT5.

 
Vladimir Karputov:

Aí, aí, é preciso ter mais cuidado e carregar cuidadosamente em todos os botões certos.

A probabilidade de isso acontecer é próxima de zero. Mas é um facto que o meu ramo no fio da língua inglesa foi anonimamente morto. ***

 
Alexey Volchanskiy:

A probabilidade de isso acontecer é muito baixa. Mas é um facto que o meu ramo no fio da língua inglesa foi anonimamente morto. ***

Já chega de falar desse ramo. Voltas a falar nisso e eu dou-te uma vassoura de bétula. Estou farto disto.

 
Alexey Volchanskiy:

Mais importante, não edite na pasta Incluir, ou esta será sobrescrita quando actualizar para uma nova compilação do MT5.

Tenho-o numa pasta separada Generic_. De facto, tive de fazer muitas alterações lá, começando com const const para métodos (os criadores não o consideraram necessário), e terminando com um redesenho para argumentos por referência, e não apenas por valor.