Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 186

 
подскажите пожалуйста самы лучший индикатор сигналов на этом сайте...разумеется пока бесплатны!
 
barabashkakvn:
А  "довольно много вычислений на основе истории" складываете в динамический массив?

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

И насчет разбить пополам - не похоже, чтобы была существенная разница, какой именно отрезок брать и сколько в нем входов. В среднем день обрабатывается за  2500-3500 ms, но неделю приходится ждать несколько минут. Сейчас нет под рукой подходящего лога, не могу сколько точно. Но на порядок больше чем 5х по дню, и большая часть времени уйдет на последний день-два. Месяц же можно оставить на ночь и к утру он скорее всего все еще будет висеть >.>  

 
Lone_Irbis:


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

Включите форвардный тест с соотношением 1 / 2. Он автоматом разобьет историю на периоды. К тому же ещё и узнаете, стоит ли овчинка выделки.
 
Lone_Irbis:
Интересно, существует ли где-нибудь статья типа "самые распространенные причины тормознутости экспертов"? Я тут пытаюсь между делом понять, почему советник в тестере в начале просто летает, но чем дальше, тем сильнее замедляется. Пока он еще не на той стадии разработки, чтобы это было так уж критично (для разработки основных механизмов и инструментов скорости хватает). Но все равно неудобно, что отрезки больше недели брать нет смысла, т.к. после скорость уже стремится к нулю.

Попробуйте бочку с краской поставить на колёсики и по мере надобности сдвигать следом за собой.

https://www.mql5.com/ru/forum/14041/page3#comment_605412

Линейное торможение - ошибка программиста или особенность работы MT4?
Линейное торможение - ошибка программиста или особенность работы MT4?
  • www.mql5.com
Такая работа просто убивает возможность оперативной настройки советника.
 
MetaDriver:

Попробуйте бочку с краской поставить на колёсики и по мере надобности сдвигать следом за собой.

https://www.mql5.com/ru/forum/14041/page3#comment_605412

Притча занятная :) Спасибо за совет. Осталось только найти ту самую бочку... или скорее бочки. Впрочем, уже есть смутные подозрения на обработчики новостей и уровней сопротивления...
 
Lone_Irbis:
Притча занятная :) Спасибо за совет. Осталось только найти ту самую бочку... или скорее бочки. Впрочем, уже есть смутные подозрения на обработчики новостей и уровней сопротивления...
Чаще всего такой бочкой является "начало времён" - собственную торговую историю (или ещё какую-то накапливаемую информацию) советник пытается заново полностью проанализировать на каждом баре (тике).
 
Недавно переориентировался на создание панелей, поэтому вопрос. Создаю две метки OBJ_RECTANGLE_LABEL и OBJ_LABEL и не знаю как сделать так чтобы перетаскивая OBJ_RECTANGLE_LABEL по графику чтоб и OBJ_LABEL перетаскивался точно также как единое целое. Может есть какой-то механизм привязки их друг к другу и действие по одному вызывает такое же по другому (всем другим)?
 
MetaDriver:
Чаще всего такой бочкой является "начало времён" - собственную торговую историю (или ещё какой-то накапливаемую информацию) советник пытается заново полностью проанализировать на каждом баре (тике).

О! Как ни удивительно, проблема нашлась и устранилась буквально в считанные минуты. Действительно, дело было в торговой истории, перебиравшейся на каждом тике. В функции, доставшейся "по наследству" от кода а-ля "самый простой советник под mql5", который был взят за основу в самом начале. Что с тех пор как-то совершенно выпало из головы. Ну вроде работает и ладно, думаю - зачем его трогать... Видимо, стоит все же перебрать огрызки того кода :) На всякий случай, вдруг кто-то сюда нагуглит с похожими тормозами, выложу проблемный кусок и мой креатив на тему в попытке решить данную проблему. Уж не знаю, насколько мой вариант "правильнее" относительно исходника. Скорее всего это точно такой же говнокод как и все, что я пишу. [Мне-то, само-собой, без разницы. Я это к тому, что если вдруг кто-то подумает заюзать нижний кусок: учтите, что автор - говнокодер-самоучка. ^^] Но у меня по крайней мере вроде ничего не сломалось, а робот теперь летает как реактивный :) Ну, по сравнению с тем, что было, по крайней мере. Пробные два месяца прогнались примерно за минуту, что все же неплохой контраст с исходными 6+ часами %)

 Было:

// Эта функция вызывалась дважды за каждый тик. С ее помощью записывались две глобальные переменные: 
// с ценой последнего ордера и числом открытых ордеров (да, взятый за исходник код был примером самого простейшего мартина). 
double History(bool LastPrice = false){
   long Ticket, OldTicket = 0, PosID, Magic, Dir;
   double PriceOpen = 0, Count = 0;
   ENUM_DEAL_TYPE CheckDir;
   if(Sell) CheckDir = DEAL_TYPE_SELL; 
   else if(Buy) CheckDir = DEAL_TYPE_BUY;
   
   HistorySelect(0, Now);
   int HistoryTotal = HistoryDealsTotal();
   // Проблемное место было тут: в цикле перебиралась вся история торговли, что в начале немного. 
   // Но даже за сутки счетчик доходил до сотни (не рискну предположить, сколько там набиралось за месяц). 
   // И этот бессмысленный и беспощадный процесс повторялся на каждом тике вообще без всякой на то причины.
   for (int i=0; i < HistoryTotal; i++){ 
      Ticket = (int)HistoryDealGetTicket(i);
      PosID  = HistoryDealGetInteger(Ticket, DEAL_POSITION_ID);
      Magic  = HistoryDealGetInteger(Ticket, DEAL_MAGIC);
      Dir    = HistoryDealGetInteger(Ticket, DEAL_TYPE);
      
      if(LastPrice) { // Этой частью добывалась цена
         if(PosID == PositionID && Magic == MagicNumber && Dir == CheckDir) {
            if(Ticket > OldTicket) {
               PriceOpen = HistoryDealGetDouble(Ticket, DEAL_PRICE);
               OldTicket = Ticket;
            }
         }
      }
      
      else { // А тут оно считало ордера
         if(PosID == PositionID && Magic == MagicNumber) Count++;
      }                              
   }
   
   if(LastPrice) return(PriceOpen);
   else return(Count);
}

 Стало:

// Вызывается она теперь только в конце функций создания/изменения/закрытия позиций. Если открытых нет - глобальные переменные просто обнуляются.
// Хотя в принципе, если вызывать ее не каждый тик, а только на изменениях, вероятно и старая версия не тормозила бы так уж сильно
void History(){
   long Ticket, PosID, Magic, Dir;
   bool GotPrice = false;
   Total = 0;
   HistorySelect(0, Now);
   int HistoryTotal = HistoryDealsTotal();
   
   // Похоже, что быстрее будет считать с обратного конца
   for(int i=HistoryTotal;i>=0;i--){
      Ticket = (int)HistoryDealGetTicket(i);
      PosID  = HistoryDealGetInteger(Ticket, DEAL_POSITION_ID);
      Magic  = HistoryDealGetInteger(Ticket, DEAL_MAGIC);
      Dir    = HistoryDealGetInteger(Ticket, DEAL_TYPE);
      
      if(PosID == PositionID && Magic == MagicNumber) {
         // Корявую конструкцию заменяем на... другую корявую конструкцию... но она хотя бы компактнее :)
         Total++; 
         if(!GotPrice){
            LastOrderPrice = HistoryDealGetDouble(Ticket, DEAL_PRICE);
            GotPrice = true; // Раз уж нужная цена всегда в начале списка, на ней и остановимся
         }
      }
      // Чтобы не перепахивать всю торговую историю, если номер позиции уже меньше нашего (но больше ноля) - прерываем цикл
      else if(PosID > 0 && PosID < PositionID) break; 
   }
}

 В общем, спасибо за помощь :) Без наводки мне бы, наверно, еще долго не пришло бы в голову заглянуть в эти дальние пыльные углы кода...

 
Lone_Irbis:

О! Как ни удивительно, проблема нашлась и устранилась буквально в считанные минуты. Действительно, дело было в торговой истории, перебиравшейся на каждом тике. В функции, доставшейся "по наследству" от кода а-ля "самый простой советник под mql5", который был взят за основу в самом начале. Что с тех пор как-то совершенно выпало из головы. Ну вроде работает и ладно, думаю - зачем его трогать... Видимо, стоит все же перебрать огрызки того кода :) На всякий случай, вдруг кто-то сюда нагуглит с похожими тормозами, выложу проблемный кусок и мой креатив на тему в попытке решить данную проблему. Уж не знаю, насколько мой вариант "правильнее" относительно исходника. Скорее всего это точно такой же говнокод как и все, что я пишу. [Мне-то, само-собой, без разницы. Я это к тому, что если вдруг кто-то подумает заюзать нижний кусок: учтите, что автор - говнокодер-самоучка. ^^] Но у меня по крайней мере вроде ничего не сломалось, а робот теперь летает как реактивный :) Ну, по сравнению с тем, что было, по крайней мере. Пробные два месяца прогнались примерно за минуту, что все же неплохой контраст с исходными 6+ часами %)

 Было:

 Стало:

 В общем, спасибо за помощь :) Без наводки мне бы, наверно, еще долго не пришло бы в голову заглянуть в эти дальние пыльные углы кода...

ок.
 
paladin800:
Недавно переориентировался на создание панелей, поэтому вопрос. Создаю две метки OBJ_RECTANGLE_LABEL и OBJ_LABEL и не знаю как сделать так чтобы перетаскивая OBJ_RECTANGLE_LABEL по графику чтоб и OBJ_LABEL перетаскивался точно также как единое целое. Может есть какой-то механизм привязки их друг к другу и действие по одному вызывает такое же по другому (всем другим)?

Готового механизма нет.  Придётся прописывать самостоятельно.  К счастью это не очень-то и сложно. Но немного поработать придётся.

Успехов.

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