К вопросу о мультивалютности и синхронизации - страница 6

 
Renat:

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

Хотя функцию "Быстро заполните указанные массивы синхронизированными данными с дозаполнением пустых полей" сделать можем. Это позволит упростить жизнь трейдерам.

Тем кто занимается мультивалютниками очень упростит.

Renat:
Вообще-то такую функцию можно и на MQL5 легко написать самостоятельно.

...

Urain:

На MQL5 будет медленнее это раз, и при изменениях в новом билде вы не будете это учитывать, это два.

А дав стандартную функцию, вы при каждом новом билде будете тестировать корректность в том числе и этого функционала.

Так всё же, в планах будет такой функционал или нет?

Главное в таком функционале чтоб к синхронизированным данным можно было применить стандартные индикаторы,

в этом вся суть,

без этого действительно можно и самому написать.

 
Urain:

Тем кто занимается мультивалютниками очень упростит.

Так всё же, в планах будет такой функционал или нет?

Главное в таком функционале чтоб к синхронизированным данным можно было применить стандартные индикаторы,

в этом вся суть,

без этого действительно можно и самому написать.


!! Полностью согласен.
 
MetaDriver:
!! Полностью согласен.

Ну раз интерактивчив всё же работает, то поделюсь своими размышлениями по этому вопросу.

С моей колокольни мультивалютность держится на двух слонах (в отличии от матушки земли, которая держится на 3-х слонах, а они покоятся на черепахе :)

1 событие МультиТик

2 синхронизация чартов

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

По 1: Народ уже пытался создать МультиТик (и ты Владимир в том числе) пользовательским путём, сам видишь получалось громоздко и корявенько. Что же в вашей концепции не хватало? вы создали кучу шпионов что отсылают сообщения с одним шифром в общую копилку, таким образом если отслеживать МультиТик на многих парах то появляются ситуации когда по одному тику приходит шквал событий и очередь быстро переполняется. Я же вижу хоть и похожую но несколько отличную схему.

Я рассматриваю реализацию МультиТика как приёмо-передатчик с фильтром. Приёмник получает событие тика от любого (выбранного в списке) инструмента и тут же генерирует событие МультиТик, после чего впадает в спячку на секунду (1 сек взята потому что это меньше средней частоты тиков по любому инструменту и соответствует минимальному таймеру), все тиковые события пришедшие в эту секунду игнорируются. По прошествии секунды от отправки сообщения МультиТик приёмник снова готов принимать сообщения тик.

Такая схема позволит не переполнять очередь и не частить с событиями, схема гибридная и переделана мной как более экономное событие чем 1 секундный таймер (который часто используют в мультивалютниках вместо отсутствующего события МультиТик). В данной схеме есть слабое место, будут происходить редкие случаи потери сигнала на обработку, когда событие тик пришло во время сна приёмника и следующего тика нет по причине например выходных, тогда получится что МультиТик сработает до того момента когда по инструменту придёт тик, но сам последний тик по инструменту не обработается до понедельника. Ну и конечно же (если замечаний нет) хотелось бы видеть данное событие как стандартное от которого срабатывает OnCalculate(), а то ведь копировать внутренние массивы open,close,time,volume в Event не очень гуд (трата ресурсов на копирование того что уже и так есть).

По 2: Теперь о синхронизаниции, Ренат советовал написать синхронизацию самому, опустим момент замедления расчётов, опустим момент что для запуска на стандартных индикаторах придётся пользовать библиотеки Integer'a XXXonArray (которые так же будут работать медленнее),

задам лишь один вопрос: Renat, а как отобразить индикатор, данные которого рассчитаны на дополненных синхронизированных барах,

на не синхронизированном графике?

По моим поискам разсинхронизация графиков на 3-х летней истории достигает на М15 7 часов, а на М1 все 20 часов. Представьте себе арбитражную или хеджевую или кластерную стратегию у которой данные инструмента беруться с лагом в 7-20 часов :(

Поэтому я всё же предлагаю рассмотреть вопрос в свете синхронизации именно чартов. Список инструментов для синхронизации можно брать например из обзора рынка, из этого же списка брать и для МультиТика. Ну и в Тестере в таком случае ввести два режима, моновалютное тестирование и мультивалютное при котором инструменты будут синхронизироваться.

 
Для примера рассинхронизации вот скриптик запрашивающий данные по 6 мажорам, с начало выясняет по какому инструменту первая дата наибольшая, чтоб по всем инструментам была доступна одинаковая история, затем от этой даты берём количество баров до сейчас, в итоге имеем список скока баров в каком инструменте на одном и том же участке истории.
#property script_show_inputs
input ENUM_TIMEFRAMES TF=PERIOD_M15;

//---
string Symbolbuf[6]={"EURUSD","GBPUSD","AUDUSD","USDJPY","USDCHF","USDCAD"};
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime fmin(datetime value1,datetime value2)
  {
   return(value1<value2?value1:value2);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime fmax(datetime value1,datetime value2)
  {
   return(value1>value2?value1:value2);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   datetime timestart; int size=ArraySize(Symbolbuf);
   timestart=(datetime)SeriesInfoInteger(Symbolbuf[0],TF,SERIES_FIRSTDATE);
   Print(Symbolbuf[0]," = ",(datetime)SeriesInfoInteger(Symbolbuf[0],TF,SERIES_FIRSTDATE));
   for(int i=1;i<size;i++)
     {
      timestart=fmax(timestart,(datetime)SeriesInfoInteger(Symbolbuf[i],TF,SERIES_FIRSTDATE));
      Print(Symbolbuf[i]," = ",(datetime)SeriesInfoInteger(Symbolbuf[i],TF,SERIES_FIRSTDATE));
     }
   Print("-----------------   ",timestart);
   for(int i=0;i<size;i++)
     {
      Print(Symbolbuf[i]," = ",Bars(Symbolbuf[i],TF,timestart,TimeCurrent()));
     }

  }

вот результат:

//чарт(EURUSD,M15)

USDCAD = 101251
USDCHF = 101320
USDJPY = 101322
AUDUSD = 101436
GBPUSD = 101313
EURUSD = 101453
-----------------   2007.12.21 07:30:00 // дата начала запроса количества баров по всем инструментам

//первая дата по инструментам
USDCAD = 2007.11.29 06:45:00
USDCHF = 2007.12.21 07:00:00
USDJPY = 2007.12.21 07:30:00
AUDUSD = 2007.12.03 06:45:00
GBPUSD = 2007.12.21 01:00:00
EURUSD = 1971.01.04 00:00:00
EURUSD = 101453 

-

USDCAD = 101251 

=

202 бара /4 (15*4=H1) =50.5 часов

То есть в данном примере между мажорами по евро и канадцу имеется рассинхронизация в 50 часов, на глубине истории всего ~4 года.


 

Ну ладно, кто то может сказать, что первые бары не всегда с заданного ТФ, я сделал другой расчёт, ТФ H1, дата начала фиксированая D'2008.01.02' те что то около 25 тысяч баров, проверил руками все данные на такую глубину с родного H1:

//(EURUSD,H1)
        
USDCAD = 25307
USDCHF = 25290
USDJPY = 25286
AUDUSD = 25305
GBPUSD = 25287
EURUSD = 25318
-----------------   2008.01.02 00:00:00

25318 - 25290 = 28 часов рассинхронизации.

ЗЫ ну в общем мне надоело монологом портянки строчить, у кого будет что сказать милости просим высказывайтесь.


 
papaklass:
Наступили на больную мозоль. Ваш метод, метод шпионов или метод последовательного перебора символов на предмет нового тика - это задачи одного класса, которые решаются в рамках терминала. Т.е. они ограничены архитектурой терминала. Вот что по этому поводу говорил stringo: https://www.mql5.com/ru/forum/1111/page587#comment_122442. В терминал котировки приходят в одном последовательном потоке и за эти рамки не выйти. Нужно искать решение в этой области. Удастся разработчикам найти приемлемое решение доставки котировок в терминал в мильтипотоках, и многие проблемы с мультивалютностью отпадут. До тех пор пока такого решения не найдено, нам остается только штамповать костыли.

Те в принципе сам мультитик уже реализован в терминале, и лишь пользователю этот мультитик выдаётся как обособленный тик по разным символам.

Всё же задача сводится именно в изменении политики терминала.

ЗЫ Остаётся выяснить насколько пользователю это надо? стоит ли ворошить терминал из-за подобных возможностей.

 

Полностью согласен с необходимостью улучшения синхронизации истории.

У меня в процессе загрузки цен закрытия в БД получается, что цены могут быть равны нулю.

 

код скрипта:

// Generating DB structure
   table_name="Rates"+"_M"+tf2str(Period());
   string tbl="CREATE TABLE IF NOT EXISTS `"+table_name+"` ( `time` datetime NOT NULL,UNIQUE KEY `un` (`time`) USING BTREE) ENGINE=Aria DEFAULT CHARSET=cp1251;";
   mydb.Query2(tbl);// Creating DB

                    // vars
   datetime start,end;
   MqlRates rates[];

   datetime dt[];
   int copyed=CopyTime(Symbol(),Period(),0,TerminalInfoInteger(TERMINAL_MAXBARS),dt);
   start=dt[copyed-1];
   end=dt[0];
   uint scount=SymbolsTotal(true);
   for(uint i=0;i<scount;i++)
     {
      string smb=SymbolName(i,true);
      //MqlRates rates[];
      copyed=CopyRates(smb,Period(),start,end,rates);

      // Uploading to DB
      mydb.AddColumn(table_name,smb,"double NOT NULL");// adding column for current data

      string q="INSERT INTO "+table_name+" (`time`, `"+smb+"`) VALUES ";
      for(int bar=0; bar<copyed; bar++)
        {
         //if(rates[bar].time!=dt[bar]) continue;
         if(rates[bar].close==0) continue;
         q+="('"+TimeToString(rates[bar].time,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"', '"+DoubleToString(rates[bar].close,(int)SymbolInfoInteger(smb,SYMBOL_DIGITS))+"'),";
        }
      q+=" ON DUPLICATE KEY UPDATE `"+smb+"`=VALUES(`"+smb+"`);";
      StringReplace(q,"), ON",") ON"); //removing last , before ON DUPLICATE
      mydb.Query2(q);
      //gq+=q;
      //IndicatorRelease(zzh);
     }

 Результат работы скрипта Urain:

USDCAD = 49996
USDCHF = 49995
USDJPY = 49996
AUDUSD = 49997
GBPUSD = 49997
EURUSD = 49996
-----------------   2011.06.03 06:55:00
USDCAD = 1970.01.01 00:00:00
USDCHF = 1970.01.01 00:00:00
USDJPY = 1970.01.01 00:00:00
AUDUSD = 1970.01.01 00:00:00
GBPUSD = 1970.01.01 00:00:00
EURUSD = 2011.06.03 06:55:00

 ЗЫ: перед тестами вся история была закачана.

Причина обращения: