Тайм-серия в cplusplus

 

Кто знает подскажите.
Когда перекидываешь тайм-серию в С++, на самых старых барах происходят ошибки при различных сортировках. При чем выявил эту закономерность на барах свыше 64900. В прикрепленном файле видна эта закономерность, С++ просто не видит их.
Пытался уже делать с использованием unsignet int но результат один и тот же. При чем если просто сравнивать бары, то С++ их видит, кино начинается когда делаешь какую ни будь сортировку. У меня это проявилось при создании аналогии функции iLowest в С++. Может кто подскажет знающий в чем дело?

Файлы:
level.txt  1 kb
 
Barbarian:

Кто знает подскажите.
Когда перекидываешь тайм-серию в С++, на самых старых барах происходят ошибки при различных сортировках. При чем выявил эту закономерность на барах свыше 64900. В прикрепленном файле видна эта закономерность, С++ просто не видит их.
Пытался уже делать с использованием unsignet int но результат один и тот же. При чем если просто сравнивать бары, то С++ их видит, кино начинается когда делаешь какую ни будь сортировку. У меня это проявилось при создании аналогии функции iLowest в С++. Может кто подскажет знающий в чем дело?

Скорее всего ошибка в той функции.
 
Zhunko:
Скорее всего ошибка в той функции.
Да функция в принципе стандартная, уже все пересмотрел, что самое интересное, аналог функции iHighest отрабатывает без ошибок.
 
Barbarian:
Да функция в принципе стандартная, уже все пересмотрел, что самое интересное, аналог функции iHighest отрабатывает без ошибок.

Значит будем гадать...

Если одна работает и она стандартная, то с историей всё в порядке. Стало быть, что-то не в порядке с Вашей iLowest().

 

Вот iLowest d C++:

//+----------------------------------------------------------------------------+
//| Описание: Возвращает индекс найденного наименьшего значения                |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                                                                            |
//|     ts - массив тайм-серии                          |       count - диапазон поиска от shift   |
//|     row - размер по строкам(число баров)|   shift - индекс начального бара     |
//|     nrate - тип цены, дата, объем           |                                                                          |
//+----------------------------------------------------------------------------+
int iLowestMT4(double* ts,unsigned row,int nrate,int count,int shift)
        {
        double idx;int n=shift;
        CTimeSeries<double> *dts = new CTimeSeries<double>();
        if(dts==NULL)
                {
                cout << "Требуемая память не выделена!" << endl;
                _getch();
                }

        for(int i=shift;i<count+shift;i++)
                {
                if(dts->dRatesTS(reinterpret_cast<CTimeSeries<double>::Sts*>(ts),row,i,nrate) < 
                        dts->dRatesTS(reinterpret_cast<CTimeSeries<double>::Sts*>(ts),row,n,nrate))
                        {
                        idx=dts->dRatesTS(reinterpret_cast<CTimeSeries<double>::Sts*>(ts),row,i,nrate);         //искомое значение для тестов
                        n=i;
                        }
                }
        delete dts;
        return(n);
        }

Вот класс тайм-серий:

template<typename T>
class CTimeSeries
        {
        public:
#pragma pack (push, 1)
                struct Sts                                      //СТРУКТУРА ТАЙМ-СЕРИИ
                        {
                        unsigned int      m_ctm;
                        double            m_open;
                        double            m_low;
                        double            m_high;
                        double            m_close;
                        double            m_vol;
                        };
#pragma pack (pop)

        public:
                CTimeSeries(void) {}
                        
                virtual ~CTimeSeries(void){}

                double dRatesTS(const Sts* m_rates,const unsigned m_sizex,const unsigned m_shift,const int m_nrate)
                        {
                        if(m_rates == NULL)                                             //адрес массива тайм-серии
                                {
                                cout << "dRatesTS: NULL array\n" << endl;
                                return(0.0);
                                }
                        if(m_sizex < 0)                                                 //кол-во баров в массиве
                                {
                                cout << "dRatesTS: wrong rates_total number (%d)\n" << m_sizex << endl;
                                return(0.0);
                                }
                        if(m_shift < 0 || m_shift >= m_sizex)   //номер бара
                                {
                                cout << "dRatesTS: wrong shift number (%d)\n" << m_shift << endl;
                                return(0.0);
                                }
                        if(m_nrate < 0 || m_nrate > 5)                  //тип цены, объем или время бара
                                {
                                cout << "dRatesTS: wrong rate index (%d)\n" << m_nrate << endl;
                                return(0.0);
                                }
                        int nitem = m_sizex - 1 - m_shift;
                        switch(m_nrate)
                                {
                        case 0: return double(m_rates[nitem].m_ctm);
                        case 1: return m_rates[nitem].m_open;
                        case 2: return m_rates[nitem].m_low;
                        case 3: return m_rates[nitem].m_high;
                        case 4: return m_rates[nitem].m_close;
                        case 5: return m_rates[nitem].m_vol;
                                }
                        return(0.0);
                        }
        };
 

Два замечания по коду.

1. Для того чтобы работать по указателю с историей класс не нужен. Тем более не надо явно выделять память. Надо пользоваться STL (умные указатели) или своими.


int iLowestMT4(Sts* ts,unsigned row,int nrate,int count,int shift)
 {
  ...
  return(n);
 }

2. Структура бара неправильная. Из МТ4 передаётся всё в double.

 
Zhunko:

Два замечания по коду.

1. Для того чтобы работать по указателю с историей класс не нужен. Тем более не надо явно выделять память. Надо пользоваться STL (умные указатели) или своими.

2. Структура бара неправильная. Из МТ4 передаётся всё в double.

Мне класс нужен для другого, поэтому его и создал. С памятью понятно, а вот по п. 2 не понял. Что именно передается в double, структура бара? Она у меня и так вроде double, а если передать тип структуры то лезут ошибки.
 
Barbarian:
Мне класс нужен для другого, поэтому его и создал. С памятью понятно, а вот по п. 2 не понял. Что именно передается в double, структура бара? Она у меня и так вроде double, а если передать тип структуры то лезут ошибки.

Судя по коду, класс нужен Вам для контроля выхода за пределы истории. Это можно сделать, ограничив обращение к истории в условиях цикла.

Все члены структуры DOUBLE.

Конечно, у Вас ошибки при объявлении указателя на структуру! Вместо многоточия надо совсем другой код вставлять чтобы работало.

Примерно так:

struct Sts
 {
  double m_ctm;
  double m_open;
  double m_low;
  double m_high;
  double m_close;
  double m_vol;
 };

int iLowestMT4(Sts* ts, unsigned uiSize, int nrate, int count, int shift)
 {
  double dMin = DBL_MAX;
  int n = 0;
  for(int i = shift; i < (count + shift) && i < uiSize; i++)
   {
    double dTemp = 0;
    switch(nrate)
     {
      case 0: dTemp = ts[i].m_ctm; break;
      case 1: dTemp = ts[i].m_open; break;
      case 2: dTemp = ts[i].m_low; break;
      case 3: dTemp = ts[i].m_high; break;
      case 4: dTemp = ts[i].m_close; break;
      case 5: dTemp = ts[i].m_vol; break;
      default: return(0);
     }
    if (dTemp < dMin)
     {
      dMin = dTemp;
      n = i;
     }
   }
  return(n);
 }
 
Zhunko:

Судя по коду, класс нужен Вам для контроля выхода за пределы истории. Это можно сделать, ограничив обращение к истории в условиях цикла.

Все члены структуры DOUBLE.

Конечно, у Вас ошибки при объявлении указателя на структуру! Вместо многоточия надо совсем другой код вставлять чтобы работало.

Примерно так:


Спасибо за помощь, но класс мне нужен для других целей. Вот где была моя ошибка
for(int i = shift; i < (count + shift) && i < uiSize; i++)
забыл сделать проверку на выход за пределы массива :) Все остальное оставляю как есть. Кроме конечно явного выделения памяти. Пока использую "умные указатели" из STL auto_ptr, но все равно прихожу к выводу, что лучше писать свой менеджер памяти т.к. происходят потери по времени из-за большой стоимости выделения-очистки памяти. Будем соображать дальше. Еще раз большое спасибо за помощь :) Про "умные указатели" раньше только слышал, но внимания им не предавал, теперь опробовал - удобнее.
 

Структура неправильная у вас! Поправил код, а то после правки структура исчезла.

Всё же, зачем класс? Он же не используется. Как лишний код.

 
Zhunko:

Структура неправильная у вас! Поправил код, а то после правки структура исчезла.

Всё же, зачем класс? Он же не используется. Как лишний код.

Класс нужен для обработки свечных паттернов нейросетью :) Без класса этого не сделать, код будет сильно разбухать, т.к. методов планируется много.
Причина обращения: