Ошибки, баги, вопросы - страница 577

 
papaklass:

...

Ок. Ваша позиция ясна.
 

Даже сложно представить себе такой советник, чтобы ему не хватало в реале мощности одного ядра. Например, если в тестере советник делает один проход на годовой истории по одному символу за одни сутки (это ужасно много! наверно, надо код переписать!), то в реале он будет загружать процессор в среднем на 1/250 мощности = 0.4%

Для советника на десяти символах - получается средняя загрузка 4%. Нет особого смысла в загрузке других ядер.  

 

Что касается идеи Константина (Lizar) то на мой взгляд она неплоха. Но для подобных решений не мешает разделить события приходящие непосредственно от чарта и те события которые генерируются кастомно. Т.е. неплохо бы иметь две очереди событий и соответственно два обработчика (для кастомных событий что-то типа - OnUserEvents).

Причем интересным дополнением к кастомным событием было бы возможность явного указания их приоритета (скажем от 0 до 9), что могло бы позволить пользователю управлять вытеснением и обработкой определенных событий. Например, такая возможность позволила бы выполнять события с меньшим значением, а удалять из очереди с большим (если очередь забита более важными событиями новые в очередь не ставятся).

papaklass:

Я никогда не занимался разработкой ПО, поэтому на техническом языке разработчиков ПО я говорить не смогу. Я опишу то, что я бы хотел получить от своего 4-х ядерного компа и МТ5. В общем виде это выглядит так:


1. Обрабатывать несколько инструментов возможно и сейчас, и тут разработчики создали вполне работоспособное решение.

2. На счет работы тестера и кучи ядер. Тут особый случай и сравнивать этот механизм с реальной торговлей в принципе не корректно. Суть решения вопроса с тестером состоит в том что имея несколько вариантов эксперта (верней один эксперт + кучу уникальных наборов параметров) вполне рационально распределить вычисления на все доступные ядра/агенты. Таким образом мы получаем асинхронность для всего набора заданий, но с точки зрения отдельно взятого агента все синхронизированно.

3. Когда же речь идет о многопоточности речь идет не о обработке нескольких инструментов одновременно, а об обработке нескольких событий в один момент времени (причем в рамках конкретного отдельно взятого эксперта). Чего не было не в одно версии терминала.

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

С другой стороны идея с событиями не доведена до логического конца. Ладно "многопоточность" реализовать накладно и проблематично, но ведь можно максимально распараллелить процессы и информационные потоки внутри самого терминала + создать набор обработчиков достаточный для решения максимального числа задач (причем с нормальным набором параметров).

 
papaklass:

Мой советник на М5 на периоде 04.01.2010 - 01.09.2011 на 12 валютах делает одиночный проход за 1436 сек (24 минуты) и при этом совершает 5687 трейдов. При этом загружено только одно ядро, а три остальных простаивают. То есть при каждом одиночном проходе я теряю 3/4 времени из-за того, что платформа не использует мощность компьютера. При отладке стратегии это существенный недостаток платформы. Ядра по полной используются только при оптимизации. Но оптимизация бывает намного реже, чем одиночные прогоны. А на одиночных прогонах теряется куча времени.

Подход "теряю 3/4 времени" указывает, что Вы считаете: использование многопоточности - это просто упущенная на ровном месте возможность и явная недоработка разработчиков.

К сожалению, многопоточность на последовательных задачах (а одиночный проход тестера является последовательной задачай) не дается бесплатно. В реальности многопоточность имеет огромные (иногда кратные) потери за синхронизации процессов. Фактически все доступы к совместно используемым ресурсам приходится обвязывать синхронизаторами.

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

Предложение "давайте в каждого эксперта засунем многозадачность" от полного непонимания стоимости (тотальное замедление) многопоточности в данном случае и последствий (замедление + снос крыши у 99% непрофессиональных разработчиков).


Мы эффективно решили вопросы применения многозадачности в терминале, тестере и включили режим практически неограниченного масштабирования мощности в режимах удаленных агентов и MQL5 Cloud Network.


Не знаю как у Вас в терминале. У меня, если я открываю 12 графиков и вешаю на них по одному индикатору, то вижу невооруженным глазом как в некоторые моменты времени терминал начинает тормозить. Судя по сообщениям на форуме, это происходит не только у меня. Так это 12 инструментов с одним индикатором. А если мне потребуется увеличить количество инструментов и индикаторов, то терминал ляжет. И при этом будет использоваться одно ядро, а остальные будут отдыхать. Так есть смысл в загрузке других ядер? При распределении процессов терминала по ядрам, т.е. полноценного использования мощности компьютера, появится возможность решать задачи другого уровня. Вот о чем я.

Если 12 разных чартов с разными символами, то значит символ каждого чарта заведомо работает в собственном потоке, не затрагивая других.

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

 

не могу добиться обратного графика, что- то не допонимаю, на этом варианте глючит новый бар

оригинальный индикатор, над которым я изголялся, прилагаю 

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---- проверка количества баров на достаточность для расчета
   for(int numb=0; numb<8; numb++) if(BarsCalculated(RSI_Handle[numb])<rates_total) return(RESET);
   if(rates_total<min_rates_total) return(RESET);

//---- объявления локальных переменных 
   int to_copy;

//---- расчеты необходимого количества копируемых данных
   if(prev_calculated>rates_total || prev_calculated<=0)// проверка на первый старт расчета индикатора
      to_copy=rates_total-1;                   // стартовый номер для расчета всех баров
   else to_copy=rates_total-prev_calculated+1; // стартовый номер для расчета новых баров
   
//---- копируем вновь появившиеся данные в массивы
   if(CopyBuffer(RSI_Handle[0],0,0,to_copy,Buffer1)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[1],0,0,to_copy,Buffer2)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[2],0,0,to_copy,Buffer3)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[3],0,0,to_copy,Buffer4)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[4],0,0,to_copy,Buffer5)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[5],0,0,to_copy,Buffer6)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[6],0,0,to_copy,Buffer7)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[7],0,0,to_copy,Buffer8)<=0) return(RESET);
   
   //мой кусок отсель   
   if (Reverse)
      {
         int start=prev_calculated;
         for(int i=start;i<rates_total;i++)
            {
               Buffer1[i]=100-Buffer1[i];
               Buffer2[i]=100-Buffer2[i];
               Buffer3[i]=100-Buffer3[i];
               Buffer4[i]=100-Buffer4[i];
               Buffer5[i]=100-Buffer5[i];
               Buffer6[i]=100-Buffer6[i];
            }
         Buffer1[0]=100-Buffer1[0];
         Buffer2[0]=100-Buffer2[0];
         Buffer3[0]=100-Buffer3[0];
         Buffer4[0]=100-Buffer4[0];
         Buffer5[0]=100-Buffer5[0];
         Buffer6[0]=100-Buffer6[0];
       }  
   //досель    

//----     
   return(rates_total);
  }
//+------------------------------------------------------------------+

Файлы:
Multi_RSI.mq5  15 kb
 

подскажите в чем проблемма

пишу мультивалютник

получаю хэндл индикатора MA

maHandle_EURUSD=iMA("EURUSD",PERIOD_H1,MA_Period_EURUSD,MA_Shift_EURUSD,MODE_SMA,PRICE_CLOSE);

maHandle_GBPUSD=iMA("GBPUSD",PERIOD_H1,MA_Period_GBPUSD,MA_Shift_GBPUSD,MODE_SMA,PRICE_CLOSE); 

аналогичным образом делаю для остальных 10 валют разрешенных на чемпионате, но при тестировании сразу выкидывает ошибку 4801, все 12 валют есть в истории(вроде) 

тест провожу на граффике EURUSD 

советник тестирует пару GBPUSD (так в настройках поставил, чтоб оптимизировать) 

 
Lazarev:

подскажите в чем проблемма

пишу мультивалютник

получаю хэндл индикатора MA

аналогичным образом делаю для остальных 10 валют разрешенных на чемпионате, но при тестировании сразу выкидывает ошибку 4801, все 12 валют есть в истории(вроде) 

тест провожу на граффике EURUSD 

советник тестирует пару GBPUSD (так в настройках поставил, чтоб оптимизировать) 

Нужно добавить символы в "Обзор рынка"  SymbolSelect
 

papaklass:

Теперь ответьте мне на такой простой вопрос ....

Отвечу еще более просто, пусть даже не вежливо.

К сожалению, Вы абсолютно не в теме и делаете заявления, которые показывают исключительно поверхностные представления о процессах.

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

зы: делать запросы "а вы расскажите по доводы, а мы порассуждаем" не нужно, ситуация абсолютно понятна

 

Подскажите новичку так и не нашел ответы на эти вопросы:

1) При добавлении очередного элемента в динамический массив, его обязательно необходимо расширять с помощью ArrayResize?

2) Есть ли функция в MQL5, чтоб удалить из динамического массива i элемент (один из - например в середине массива) ? Если нет, как лучше средствами языка это сделать?

Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
  • www.mql5.com
Основы языка / Типы данных / Объект динамического массива - Документация по MQL5
 
Fia:

Подскажите новичку так и не нашел ответы на эти вопросы:

1) При добавлении очередного элемента в динамический массив, его обязательно необходимо расширять с помощью ArrayResize?

Делаете размера массива с некоторым запасом, при подходе к пределу увеливаете размер. Автотического увеличения размера и добавления в конец не сушествует. Посмотрите пример к функции ArrayInitialize()
Причина обращения: