Сортировка тиков (CopyTicks) по минуткам

 

Привет!

Кто-нибудь делал подобную сортировку?

 
Так а в чем основная проблема?
 
Dmitriy Skub:
Так а в чем основная проблема?

Как лучше организовать сортировку

Добавлено

Пока я себе так это представляю

Загружаем все бары (минутки)

Загружаем все нужные тики

А дальше? Как лучше?

Чтобы быстрее было.

 

Не совсем понял общую задачу - тики и так отсортированы.

Вот, у меня сделано так - формирование из тиков минутного файла с значениями Action Balance.

Возможно поможет.

//      Откроем файл для записи баров:
        csv_bar_file_handle = FileOpen( csv_bar_file_name, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_WRITE | FILE_CSV | FILE_ANSI, ',' );
        if( csv_bar_file_handle == INVALID_HANDLE )
        {
                Message( "Ошибка открытия файла - " + csv_bar_file_name );
                return( INIT_FAILED );
        }

//---------------------------------------------------------------------
//      Цикл сохранения тиковых данных и формирования 1М - баров:
        datetime        curr_start_dt = DateStart;
        string          flags;
        ulong                   buy_total_volume = 0, sell_total_volume = 0;
        double          open_price;
        datetime        curr_dt, prev_dt;
        datetime        end_data_dt, next_start_dt;
        while(true)
        {
//      Копируем очередную порцию тиков:
                copied = CopyTicks( _Symbol, ticks_Arr, COPY_TICKS_TRADE, curr_start_dt * 1000, StepCount );
                if( copied < 0 )
                {
                        Message( "Ошибка копирования данных - CopyTicks" );
                        return( INIT_FAILED );
                }
//              Print("Copied : ", copied, " ticks, from ", TimeToString(ticks_Arr[ 0 ].time, TIME_DATE | TIME_MINUTES | TIME_SECONDS ), " to ", TimeToString(ticks_Arr[ ArraySize( ticks_Arr ) - 1 ].time, TIME_DATE | TIME_MINUTES | TIME_SECONDS ));
                if( copied == 0 )
                {
                        break;
                }

                //      Время для последнего тика в массиве:
                end_data_dt = ticks_Arr[ ArraySize( ticks_Arr ) - 1 ].time;

                curr_dt = ( ticks_Arr[ 0 ].time / PeriodSeconds(PERIOD_M1)) * PeriodSeconds(PERIOD_M1);
                prev_dt = curr_dt;
                open_price = ticks_Arr[ 0 ].last;

                //      Cоздаем минутные бары:
                for( int i = 0; i < copied; i++ )
                {
                        if(( ticks_Arr[ i ].flags & TICK_FLAG_BUY ) > 0 )
                        {
                                buy_total_volume += ticks_Arr[ i ].volume;
                                flags = "BUY";
                        }
                        else if(( ticks_Arr[ i ].flags & TICK_FLAG_SELL ) > 0 )
                        {
                                sell_total_volume += ticks_Arr[ i ].volume;
                                flags = "SELL";
                        }
                        else
                        {
                                flags = "####";
                        }

                        curr_dt = ( ticks_Arr[ i ].time / PeriodSeconds(PERIOD_M1)) * PeriodSeconds(PERIOD_M1);
                
                        //      Если началась новая минута:
                        if( curr_dt > prev_dt )
                        {
                                curr_start_dt = curr_dt + ( curr_dt - prev_dt );

                                if(( ticks_Arr[ i ].flags & TICK_FLAG_BUY ) > 0 )
                                {
                                        buy_total_volume -= ticks_Arr[ i ].volume;
                                }
                                else if(( ticks_Arr[ i ].flags & TICK_FLAG_SELL ) > 0 )
                                {
                                        sell_total_volume -= ticks_Arr[ i ].volume;
                                }

                                FileWrite( csv_bar_file_handle, TimeToString( prev_dt, TIME_DATE ) + " " + TimeToString( prev_dt, TIME_MINUTES ),
                                                                         DoubleToString( open_price, _Digits ),
                                                                         DoubleToString( ticks_Arr[ i - 1 ].last, _Digits ),
                                                                         IntegerToString( buy_total_volume ),
                                                                         IntegerToString( sell_total_volume ));

                                open_price = ticks_Arr[ i ].last;
                                if(( ticks_Arr[ i ].flags & TICK_FLAG_BUY ) > 0 )
                                {
                                        buy_total_volume = ticks_Arr[ i ].volume;
                                        sell_total_volume = 0;
                                }
                                else if(( ticks_Arr[ i ].flags & TICK_FLAG_SELL ) > 0 )
                                {
                                        buy_total_volume = 0;
                                        sell_total_volume = ticks_Arr[ i ].volume;
                                }

                                prev_dt = curr_dt;

                                //      Если текущая минута не заполнена тиками до конца, то ее не записываем:
                                next_start_dt = curr_start_dt + PeriodSeconds(PERIOD_M1);
                                if( next_start_dt > end_data_dt )
                                {
////                                    break;
                                }
                        }

                        FileWrite( csv_tick_file_handle, TimeToString( ticks_Arr[ i ].time, TIME_DATE ) + " " + TimeToString( ticks_Arr[ i ].time, TIME_SECONDS ) + "." + IntegerToString( ticks_Arr[ i ].time_msc - ( ticks_Arr[ i ].time_msc / 1000 ) * 1000, 3, '0' ),
                                                                 DoubleToString( ticks_Arr[ i ].bid, _Digits),
                                                                 DoubleToString( ticks_Arr[ i ].ask, _Digits),
                                                                 DoubleToString( ticks_Arr[ i ].last, _Digits),
                                                                 IntegerToString( ticks_Arr[ i ].volume),
                                                                 flags );
                }

                if(copied < (int)StepCount)
                {
                        break;
                }
                curr_start_dt = (end_data_dt / PeriodSeconds(PERIOD_M1)) * PeriodSeconds(PERIOD_M1);
        }
 
Dmitriy Skub:

Не совсем понял общую задачу - тики и так отсортированы.

Вот, у меня сделано так - формирование из тиков минутного файла с значениями Action Balance.

Возможно поможет.

Проблема в том, что как раз тики не отсортированы.

Например бар начался 10:00:25 (т.е не ровно с нулевой секунды)

А тики с асками и бидами идут с 10:00:00 

Как в индикаторе их выводить?

И еще проблема, что делать с тиками, если бара нет, куда их "пристраивать"

 
prostotrader:

Какая реальная задача стоит?

 
Alexey Kozitsyn:

Какая реальная задача стоит?

Построить индикатор из тиков (ask bid среднее значение), но по существующим минутным барам

 
prostotrader:

Построить индикатор из тиков (ask bid среднее значение), но по существующим минутным барам

Лучше не пытайся, погрязнеш в этом *** надолго.

У терминала закрытый очень глючный формат хранения тиков. Почитай тему, баги не исправляются годами.

Можешь сказать мне не нужны кастомные символы, мне нужны тики - это всё связано. Хранилище тиков глючное, не сможешь нормальный индикатор сделать, только такой же глючный как и хранилище тиков.

Лучше бы писали тики как есть и помещали в обычную сжатую выньдосом папку, намного быстрее работало бы и без глюков. 

Пользовательские символы. Ошибки, баги, вопросы, предложения.
Пользовательские символы. Ошибки, баги, вопросы, предложения.
  • 2019.02.23
  • www.mql5.com
Так как тема достаточна обширна, решил, что стоит выделить её в отдельное обсуждение...
 
prostotrader:

Проблема в том, что как раз тики не отсортированы.

Например бар начался 10:00:25 (т.е не ровно с нулевой секунды)

А тики с асками и бидами идут с 10:00:00 

Как в индикаторе их выводить?

И еще проблема, что делать с тиками, если бара нет, куда их "пристраивать"

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

 
Stanislav Korotky:

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

Тики в МТ5 идут двумя потоками,

 - это тики информационные из стакана (bid,ask)

 - и торговые из ленты (last).

Естественно два потока не могут быть синхронизированы. Сервер MQ эти потоки синхронизирует по своим скрытым алгоритмам.

Бары на ФОРТС строятся по Last-ам, попробуйте построить кастомный символ по Bid на основе любого символа с RTS. Всю жизнь будете писать в ветку упомянутую выше.

 
Sergey Chalyshev:

Тики в МТ5 идут двумя потоками,

 - это тики информационные из стакана (bid,ask)

 - и торговые из ленты (last).

Естественно два потока не могут быть синхронизированы. Сервер MQ эти потоки синхронизирует по своим скрытым алгоритмам.

Бары на ФОРТС строятся по Last-ам, попробуйте построить кастомный символ по Bid на основе любого символа с RTS. Всю жизнь будете писать в ветку упомянутую выше.

Красное и зеленое противоречат друг другу. В принципе, когда есть разные источники информации, то в отсутствии синхронизированного времени между ними, можно лишь достоверно указывать время получения данных на серверах MQ, а это время точно будет упорядочено.

На ФОРТСе не был, но по какому бы типу цен бары ни строились, они строятся из тиков и не могут друг другу противоречить - я так пока считаю, потому что не знаю примеров, когда это не работает (кроме глюков).