barabashkakvn: А "довольно много вычислений на основе истории" складываете в динамический массив?
Есть такое дело, да :) Ну, точнее, несколько динамических массивов используются, но они по идее не должны разрастаться до слишком больших размеров.
И насчет разбить пополам - не похоже, чтобы была существенная разница, какой именно отрезок брать и сколько в нем входов. В среднем день обрабатывается за 2500-3500 ms, но неделю приходится ждать несколько минут. Сейчас нет под рукой подходящего лога, не могу сколько точно. Но на порядок больше чем 5х по дню, и большая часть времени уйдет на последний день-два. Месяц же можно оставить на ночь и к утру он скорее всего все еще будет висеть >.>
Lone_Irbis: Интересно, существует ли где-нибудь статья типа "самые распространенные причины тормознутости экспертов"? Я тут пытаюсь между делом понять, почему советник в тестере в начале просто летает, но чем дальше, тем сильнее замедляется. Пока он еще не на той стадии разработки, чтобы это было так уж критично (для разработки основных механизмов и инструментов скорости хватает). Но все равно неудобно, что отрезки больше недели брать нет смысла, т.к. после скорость уже стремится к нулю.
Попробуйте бочку с краской поставить на колёсики и по мере надобности сдвигать следом за собой.
Притча занятная :) Спасибо за совет. Осталось только найти ту самую бочку... или скорее бочки. Впрочем, уже есть смутные подозрения на обработчики новостей и уровней сопротивления...
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;
elseif(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);
elsereturn(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; // Раз уж нужная цена всегда в начале списка, на ней и остановимся
}
}
// Чтобы не перепахивать всю торговую историю, если номер позиции уже меньше нашего (но больше ноля) - прерываем циклelseif(PosID > 0 && PosID < PositionID) break;
}
}
В общем, спасибо за помощь :) Без наводки мне бы, наверно, еще долго не пришло бы в голову заглянуть в эти дальние пыльные углы кода...
О! Как ни удивительно, проблема нашлась и устранилась буквально в считанные минуты. Действительно, дело было в торговой истории, перебиравшейся на каждом тике. В функции, доставшейся "по наследству" от кода а-ля "самый простой советник под mql5", который был взят за основу в самом начале. Что с тех пор как-то совершенно выпало из головы. Ну вроде работает и ладно, думаю - зачем его трогать... Видимо, стоит все же перебрать огрызки того кода :) На всякий случай, вдруг кто-то сюда нагуглит с похожими тормозами, выложу проблемный кусок и мой креатив на тему в попытке решить данную проблему. Уж не знаю, насколько мой вариант "правильнее" относительно исходника. Скорее всего это точно такой же говнокод как и все, что я пишу. [Мне-то, само-собой, без разницы. Я это к тому, что если вдруг кто-то подумает заюзать нижний кусок: учтите, что автор - говнокодер-самоучка. ^^] Но у меня по крайней мере вроде ничего не сломалось, а робот теперь летает как реактивный :) Ну, по сравнению с тем, что было, по крайней мере. Пробные два месяца прогнались примерно за минуту, что все же неплохой контраст с исходными 6+ часами %)
Было:
Стало:
В общем, спасибо за помощь :) Без наводки мне бы, наверно, еще долго не пришло бы в голову заглянуть в эти дальние пыльные углы кода...
paladin800: Недавно переориентировался на создание панелей, поэтому вопрос. Создаю две метки OBJ_RECTANGLE_LABEL и OBJ_LABEL и не знаю как сделать так чтобы перетаскивая OBJ_RECTANGLE_LABEL по графику чтоб и OBJ_LABEL перетаскивался точно также как единое целое. Может есть какой-то механизм привязки их друг к другу и действие по одному вызывает такое же по другому (всем другим)?
Готового механизма нет. Придётся прописывать самостоятельно. К счастью это не очень-то и сложно. Но немного поработать придётся.
А "довольно много вычислений на основе истории" складываете в динамический массив?
Есть такое дело, да :) Ну, точнее, несколько динамических массивов используются, но они по идее не должны разрастаться до слишком больших размеров.
И насчет разбить пополам - не похоже, чтобы была существенная разница, какой именно отрезок брать и сколько в нем входов. В среднем день обрабатывается за 2500-3500 ms, но неделю приходится ждать несколько минут. Сейчас нет под рукой подходящего лога, не могу сколько точно. Но на порядок больше чем 5х по дню, и большая часть времени уйдет на последний день-два. Месяц же можно оставить на ночь и к утру он скорее всего все еще будет висеть >.>
И насчет разбить пополам - не похоже, чтобы была существенная разница, какой именно отрезок брать и сколько в нем входов.
Интересно, существует ли где-нибудь статья типа "самые распространенные причины тормознутости экспертов"? Я тут пытаюсь между делом понять, почему советник в тестере в начале просто летает, но чем дальше, тем сильнее замедляется. Пока он еще не на той стадии разработки, чтобы это было так уж критично (для разработки основных механизмов и инструментов скорости хватает). Но все равно неудобно, что отрезки больше недели брать нет смысла, т.к. после скорость уже стремится к нулю.
Попробуйте бочку с краской поставить на колёсики и по мере надобности сдвигать следом за собой.
https://www.mql5.com/ru/forum/14041/page3#comment_605412
Попробуйте бочку с краской поставить на колёсики и по мере надобности сдвигать следом за собой.
https://www.mql5.com/ru/forum/14041/page3#comment_605412
Притча занятная :) Спасибо за совет. Осталось только найти ту самую бочку... или скорее бочки. Впрочем, уже есть смутные подозрения на обработчики новостей и уровней сопротивления...
Чаще всего такой бочкой является "начало времён" - собственную торговую историю (или ещё какой-то накапливаемую информацию) советник пытается заново полностью проанализировать на каждом баре (тике).
О! Как ни удивительно, проблема нашлась и устранилась буквально в считанные минуты. Действительно, дело было в торговой истории, перебиравшейся на каждом тике. В функции, доставшейся "по наследству" от кода а-ля "самый простой советник под mql5", который был взят за основу в самом начале. Что с тех пор как-то совершенно выпало из головы. Ну вроде работает и ладно, думаю - зачем его трогать... Видимо, стоит все же перебрать огрызки того кода :) На всякий случай, вдруг кто-то сюда нагуглит с похожими тормозами, выложу проблемный кусок и мой креатив на тему в попытке решить данную проблему. Уж не знаю, насколько мой вариант "правильнее" относительно исходника. Скорее всего это точно такой же говнокод как и все, что я пишу. [Мне-то, само-собой, без разницы. Я это к тому, что если вдруг кто-то подумает заюзать нижний кусок: учтите, что автор - говнокодер-самоучка. ^^] Но у меня по крайней мере вроде ничего не сломалось, а робот теперь летает как реактивный :) Ну, по сравнению с тем, что было, по крайней мере. Пробные два месяца прогнались примерно за минуту, что все же неплохой контраст с исходными 6+ часами %)
Было:
Стало:
В общем, спасибо за помощь :) Без наводки мне бы, наверно, еще долго не пришло бы в голову заглянуть в эти дальние пыльные углы кода...
О! Как ни удивительно, проблема нашлась и устранилась буквально в считанные минуты. Действительно, дело было в торговой истории, перебиравшейся на каждом тике. В функции, доставшейся "по наследству" от кода а-ля "самый простой советник под mql5", который был взят за основу в самом начале. Что с тех пор как-то совершенно выпало из головы. Ну вроде работает и ладно, думаю - зачем его трогать... Видимо, стоит все же перебрать огрызки того кода :) На всякий случай, вдруг кто-то сюда нагуглит с похожими тормозами, выложу проблемный кусок и мой креатив на тему в попытке решить данную проблему. Уж не знаю, насколько мой вариант "правильнее" относительно исходника. Скорее всего это точно такой же говнокод как и все, что я пишу. [Мне-то, само-собой, без разницы. Я это к тому, что если вдруг кто-то подумает заюзать нижний кусок: учтите, что автор - говнокодер-самоучка. ^^] Но у меня по крайней мере вроде ничего не сломалось, а робот теперь летает как реактивный :) Ну, по сравнению с тем, что было, по крайней мере. Пробные два месяца прогнались примерно за минуту, что все же неплохой контраст с исходными 6+ часами %)
Было:
Стало:
В общем, спасибо за помощь :) Без наводки мне бы, наверно, еще долго не пришло бы в голову заглянуть в эти дальние пыльные углы кода...
Недавно переориентировался на создание панелей, поэтому вопрос. Создаю две метки OBJ_RECTANGLE_LABEL и OBJ_LABEL и не знаю как сделать так чтобы перетаскивая OBJ_RECTANGLE_LABEL по графику чтоб и OBJ_LABEL перетаскивался точно также как единое целое. Может есть какой-то механизм привязки их друг к другу и действие по одному вызывает такое же по другому (всем другим)?
Готового механизма нет. Придётся прописывать самостоятельно. К счастью это не очень-то и сложно. Но немного поработать придётся.
Успехов.