通用类库 - 错误、说明、问题、使用功能和建议 - 页 28

 
Alexey Volchanskiy:

这里又他妈的发生了什么事?他们正在删除完美的LinkedList帖子。我可以想象一个匿名版主坐在欧洲的某个地方,删除来自可恨的俄罗斯人的帖子,恶意地傻笑着。这是一个垃圾场,它使你不想写。

不要再打风车了--这个主题中没有被删除的帖子。

 
Artyom Trishkin:

不要再打风车了--这个主题中没有被删除的帖子。

Artem,我没有喝醉,也没有受到影响。我在半小时前写了一个简短的回复,在MQL中LinkedList被实现为一个环形缓冲器,所描述的行为只是正常的。而我已经在我的过滤器中用数组实现了一个环形缓冲器。然后我到.NET的源头去看实现,半小时后我的信息已经被删除了。这是我第一次这样做。

关于俄罗斯版主,我只是不认为。

这里是带有FIR的过滤器类,观看双FilterTick(double tick)函数。有两个环形缓冲器--输入刻度线和输出过滤值。与链表的区别是,它的可能性较小,但它的速度要快一个数量级,这对我来说很重要。

#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,我没有喝醉,也没有吸毒。我在半小时前写了一个简短的回复,MQL LinkedList被实现为一个环形缓冲器,所描述的行为只是正常的。而我已经在我的过滤器中用数组实现了一个环形缓冲器。然后我到.NET的源头去看实现,半小时后,我的信息已经被删除。这是我第一次这样做。

关于俄罗斯版主,我只是不认为。

这里是带有FIR的过滤器类,观看双FilterTick(double tick)函数。有两个环形缓冲器--输入刻度线和输出过滤值。与链接列表的区别是可能性更小,但速度更快,这对我来说很重要。

我不知道--查看了被删除的帖子--没有这个主题的内容。谢坦...

在我看来,"链表 "就是一个链表,这也是符合逻辑的。一个简单的列表没有循环,就像Alexey Navoikov说的那样:"最后一个节点的Next是0,就像第一个节点的Previous 一样",而一个链接列表则是这样,它的工作原理就像一个环形缓冲器。对我来说,这很方便。

 
Artyom Trishkin:

我不知道--查看了被删除的帖子--这个主题中没有任何内容。谢坦...

在我看来,"链表 "也是符合逻辑的,它是一个链表。一个简单的列表没有循环,就像Alexey Navoikov说的那样:"最后一个节点的下一个等于0,第一个节点的上一个 也等于0",而一个链接列表有,并且像一个环形缓冲器一样工作。对我来说,这很方便。

啊,这是个可能性,不知道。好吧,我可以认为是我分心了,没有发信息,就直接从那页的某个地方走了。但这样的抱怨经常发生,而且我不是唯一的一个。好了,我们不要再谈这个了。

 
Alexey Volchanskiy:

啊,这是个可能性,我不知道。好吧,我可以认为是我分心了,没有发信息就直接从那一页走了。但这样的抱怨经常发生,而且我不是唯一的一个。好了,我们不要再谈这个了。

这里,这里,需要更加用心,所有的按钮都整齐地按下。

 
Artyom Trishkin:

在我看来,"链表 "也是符合逻辑的,它是一个链表。一个简单的列表没有循环,就像Alexey Navoikov说的那样:"最后一个节点的下一个是0,第一个节点的上一个 也是0",而一个链接列表有,并且像一个环形缓冲器一样工作。对我来说,这很方便。

链接列表是一个存储指向下一个和上一个 项目的指针的列表。"铃声与此无关。总之,这是新的东西。在哪里看到过?

Alexey Volchanskiy:
这里是带有FIR的过滤器类,看双FilterTick(double tick)函数。这里只有两个环形缓冲器--输入刻度线和输出过滤值。与链接列表的区别是可能性更小,但速度更快,这对我来说很重要。

这与过滤器类没有关系......我们具体谈论的是一个链接列表。它是一个标准的容器,具有某些特性。通过列表的迭代是单向的。不能有任何铃声。 在C#(相同的LinkedList类)或C++(std::list类)中没有。

此外,这个库是从.Net移植过来的,意味着与C#兼容,否则我们到底为什么需要另一个自制的自行车? 难道我们还没有受够蹩脚的MQ自行车吗? 我们需要的是移植一个现成的库(即使有特定语言的限制,但至少要保留工作的逻辑)。 但是没有...顽皮的手在这里也干涉了 )

最有可能的是,移植这些类的人决定简化他的生活,因为他已经简化了代码。 他没有用两个m_first和m_last指针,而是用一个m_head指针。

当然,我已经把所有的东西都修复好了,但尽管如此......

 
Alexey Navoykov:

链接列表是一个存储指向下一个和上一个 项目的指针的列表。"铃声与此无关。总之,这是新的东西。在哪里看到过?

这与过滤器类没有关系......我们具体谈论的是一个链接列表。它是一个标准的容器,具有某些特性。通过列表的迭代是单向的。不可能有任何铃声;在C#(相同的LinkedList类)和C++(std::list类)中都没有。

此外,这个库是从.Net移植过来的,意味着与C#兼容,否则我们到底为什么需要另一个自制的自行车? 难道我们还没有受够蹩脚的MQ自行车吗? 我们需要的是移植一个现成的库(即使有特定语言的限制,但至少要保留工作的逻辑)。 但是没有...顽皮的手在这里也干涉了 )

最有可能的是,移植这些类的人决定简化他的生活,因为他已经简化了代码。 他没有用两个m_first和m_last指针,而是用一个m_head指针...

当然,我把所有的东西都修好了,但尽管如此......。

MSDN称它为环形缓冲器,我还没有发明这个名字。

最主要的是不要把它固定在Include文件夹里,否则当你升级到MT5的新版本时,它将被删除。

 
Vladimir Karputov:

在那里,在那里,你必须更加小心,仔细按下所有正确的按钮。

这种情况发生的概率接近于零。但我在英语线的分支被匿名杀害是事实。***

 
Alexey Volchanskiy:

发生这种情况的可能性非常低。但是,我在英语线的分支被匿名杀害是一个事实。***

关于这个分支,已经说得够多了。你再提这个问题,我就给你一把白桦树扫帚。我已经厌烦了。

 
Alexey Volchanskiy:

最重要的是,不要在Include文件夹中编辑,否则当你升级到MT5的新版本时,它将被覆盖。

事实上,我不得不在那里做了很多修改,从方法的const开始(开发者认为没有必要),到重新设计参数的引用,而不仅仅是值。