Уважаемые разработчики, могли бы Вы сообщить, как вычисляется MQL_MEMORY_USED?
Сделал расчет памяти, что занимают все переменные советника.
Это меньше 10%. Если правильно понимаю, то в MQL_MEMORY_USED входит History-кеш и CopyTicks-кеш. Но это все равно значительно меньше должно занимать.
При этом параллельный советник кушает в несколько раз меньше. Хотя принцип тот же.
В общем, что входит в это значение?
ЗЫ Сохранил шаблон с советником и к этому же чарту применил, вызвав перезагрузку. Стало так.
Потребление памяти изменилось почти на порядок. Сложно пока объяснить, что это обозначает.
Накопительный эффект пользования памяти есть у многих прог. Этим браузеры грешат, тот же ворд, иногда может. Терминал тоже грешит. К тому же логи по дефолту пишут все и если много действий то в гиг за неделю легко улететь. Это зло, которым надо управлять. Правда не понятно как.
Сделать тривиальный Маркет-продукт в виде Маркет-скринера - фактически, не посильная задача для MT5 из-за чрезмерного расхода памяти.
Терминал после запуска съедает столько памяти.
После выполнение скринера стал съедать 2 гига (TERMINAL_MEMORY_USED и не уменьшалось со временем). Это при только одном открытом чарте на 5000 M1-баров.
Скрин не сохранил. Но решил накидать пример, показывающий, выжирание памяти Терминалом не в себя там, где это просто глупо.
// Создание копий оригинальных символов из Обзора рынка в виде пользовательских.#property script_show_inputsinputdatetime inStartTime = D'2020.06.01'; // С какого времени закачивать тикиvoidOnStart()
{
for (int i = SymbolsTotal(true) - 1; !IsStopped() && (i >= 0); i--)
{
conststring Symb = SymbolName(i, true);
if (!SymbolInfoInteger(Symb, SYMBOL_CUSTOM)) // Если символ не кастомный.
{
Alert(Symb + " - Start.");
MqlTick Ticks[];
if (CopyTicksRange(Symb, Ticks, COPY_TICKS_ALL, (long)inStartTime * 1000) > 0) // Взяли с него тики.
{
conststring CustomSymb = "CUSTOM_" + Symb;
if (SymbolInfoInteger(CustomSymb, SYMBOL_EXIST) || CustomSymbolCreate(CustomSymb, AccountInfoString(ACCOUNT_SERVER), Symb)) // Содали кастомный.
{
Alert((string)i + ": " + Symb + " - " + (string)CustomTicksReplace(CustomSymb, 0, LONG_MAX, Ticks)); // Поместили в него тики.SymbolSelect(CustomSymb, true);
}
}
}
}
}
Скрипт просто делает копии оригинальных символов из Обзора рынка. Предполагалось, что на MQ-Demo добавлю все символы и запущу этот скрипт первый раз на холодную, а потом повторно - на горячую.
И после горячего (когда тики уже на SSD в виде tkc-файлов) запуска буду наблюдать дикое выжирание памяти там, где это совсем не нужно при должной реализации.
Однако, запустив скрипт, столкнулся с тем, что он подвисает на MQ-Demo. Снимается только через Abnormal termination, после чего Терминал не высвобождает больше 1 Гб памяти.
Простите, не уверен баг это или фича. Самостоятельно ответа не нашел. Но вопрос связан по поводу производительности и полагаю, что лучше этот вопрос задать тут.
Если в пустой индикатор добавить, скажем, 22 буфера с типом DRAW_SECTION, то при запуске такого индикатора на одном чарте, в котором находится 1000000 баров и выше, то терминал начинает достаточно сильно тормозить (так же идет заметная нагрузка на ЦП) и съедать заметное количество оперативной памяти, даже если индикатор ничего не вычисляет.
Мой интерес вызвал тот факт, что если использовать буферы с другими типами, то все работает без проблем и подобного замедления не наблюдается.
К примеру, я запускал следующий код индикатора на единственном чарте в котором содержится 1000000 баров и терминал съедал около 500 МБайт и заметно лагал, особенно сам чарт.
Но если поменять тип буфферов на, скажем, DRAW_LINE, то нагрузка на процессор резко понижается, лагов не наблюдается, а оперативка съедается в 5 раз меньше (потребляется около 100 МБайт).
Отдельный гражданин достализ широких штаниндубликатом бесценного груза MQL-код, который показал, что в одних и тех же условиях костыль работает быстрее штатной функции.
Очень простой тест:
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnTick()
{
TestSymbolInfoTick();
TestPositionSelectByTicket();
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+void TestSymbolInfoTick()
{
MqlTick Tick;
//---ulong start,end,max_time=0,avr_time=0,counter=0;
int count=100000;
for(int i=0; i<count; i++)
{
start=GetMicrosecondCount();
SymbolInfoTick(_Symbol, Tick);
end=GetMicrosecondCount()-start;
//---if(end>max_time)
max_time=end;
if(end>100)
{
avr_time+=end;
counter++;
}
}
Print("SymbolInfoTick max bad time: ",DoubleToString(max_time/1000.0,3)," ms; avr bad time: ",counter ? DoubleToString(avr_time/1000.0/counter,3):"0"," ms; bad iterations: ",counter," total iterations: ",count);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+void TestPositionSelectByTicket()
{
//---ulong start,end,max_time=0,avr_time=0,counter=0;
int count=100000;
for(int i=0; i<count; i++)
{
start=GetMicrosecondCount();
GetBid();
end=GetMicrosecondCount()-start;
//---if(end>max_time)
max_time=end;
if(end>100)
{
avr_time+=end;
counter++;
}
}
Print("GetBid max bad time: ",DoubleToString(max_time/1000.0,3)," ms; avr bad time: ",counter ? DoubleToString(avr_time/1000.0/counter,3):"0"," ms; bad iterations: ",counter," total iterations: ",count);
}
20 экспертов на EURUSD, т.е. все OnTick процессим одновременно. Билд терминала 2664. Запускать тест без оптимизации, компиляции и проч. доп.загрузки на 100% цпу - вы же не собираетесь запускать реальную "hft" торговлю на таком фоне?
Типичный лога теста:
2020.10.2911:10:49.133SymbolInfoTick (EURUSD,M15) GetBid max bad time: 28.004 ms; avr bad time: 0.393 ms; bad iterations: 1569 total iterations: 1000002020.10.2911:10:49.136SymbolInfoTick (EURUSD,H1) GetBid max bad time: 4.795 ms; avr bad time: 0.361 ms; bad iterations: 1783 total iterations: 1000002020.10.2911:10:49.137SymbolInfoTick (EURUSD,M15) GetBid max bad time: 25.367 ms; avr bad time: 0.425 ms; bad iterations: 1496 total iterations: 1000002020.10.2911:10:49.138SymbolInfoTick (EURUSD,M15) GetBid max bad time: 2.681 ms; avr bad time: 0.352 ms; bad iterations: 1804 total iterations: 1000002020.10.2911:10:49.139SymbolInfoTick (EURUSD,M15) GetBid max bad time: 4.264 ms; avr bad time: 0.370 ms; bad iterations: 1734 total iterations: 1000002020.10.2911:10:49.142SymbolInfoTick (EURUSD,H1) GetBid max bad time: 7.049 ms; avr bad time: 0.362 ms; bad iterations: 1803 total iterations: 1000002020.10.2911:10:49.142SymbolInfoTick (EURUSD,M15) GetBid max bad time: 13.376 ms; avr bad time: 0.365 ms; bad iterations: 1754 total iterations: 1000002020.10.2911:10:49.144SymbolInfoTick (EURUSD,H1) GetBid max bad time: 18.048 ms; avr bad time: 0.417 ms; bad iterations: 1516 total iterations: 1000002020.10.2911:10:49.144SymbolInfoTick (EURUSD,M15) GetBid max bad time: 21.280 ms; avr bad time: 0.372 ms; bad iterations: 1769 total iterations: 1000002020.10.2911:10:53.837SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.631 ms; avr bad time: 0.143 ms; bad iterations: 205 total iterations: 1000002020.10.2911:10:53.837SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.517 ms; avr bad time: 0.134 ms; bad iterations: 170 total iterations: 1000002020.10.2911:10:53.837SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.483 ms; avr bad time: 0.144 ms; bad iterations: 178 total iterations: 1000002020.10.2911:10:53.838SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.517 ms; avr bad time: 0.147 ms; bad iterations: 182 total iterations: 1000002020.10.2911:10:53.844SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 0.582 ms; avr bad time: 0.134 ms; bad iterations: 165 total iterations: 1000002020.10.2911:10:53.845SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 0.518 ms; avr bad time: 0.137 ms; bad iterations: 195 total iterations: 1000002020.10.2911:10:53.845SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.530 ms; avr bad time: 0.139 ms; bad iterations: 160 total iterations: 1000002020.10.2911:10:53.846SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.575 ms; avr bad time: 0.138 ms; bad iterations: 143 total iterations: 1000002020.10.2911:10:53.848SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.593 ms; avr bad time: 0.143 ms; bad iterations: 206 total iterations: 1000002020.10.2911:10:53.849SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.446 ms; avr bad time: 0.138 ms; bad iterations: 147 total iterations: 1000002020.10.2911:10:53.850SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.661 ms; avr bad time: 0.146 ms; bad iterations: 191 total iterations: 1000002020.10.2911:10:53.850SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 0.471 ms; avr bad time: 0.141 ms; bad iterations: 219 total iterations: 1000002020.10.2911:10:53.851SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.442 ms; avr bad time: 0.137 ms; bad iterations: 198 total iterations: 1000002020.10.2911:10:53.851SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.574 ms; avr bad time: 0.140 ms; bad iterations: 215 total iterations: 1000002020.10.2911:10:53.853SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 0.507 ms; avr bad time: 0.140 ms; bad iterations: 222 total iterations: 1000002020.10.2911:10:53.857SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 0.776 ms; avr bad time: 0.165 ms; bad iterations: 341 total iterations: 1000002020.10.2911:10:53.858SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.568 ms; avr bad time: 0.156 ms; bad iterations: 381 total iterations: 1000002020.10.2911:10:53.860SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.896 ms; avr bad time: 0.164 ms; bad iterations: 293 total iterations: 1000002020.10.2911:10:53.861SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 6.124 ms; avr bad time: 0.178 ms; bad iterations: 219 total iterations: 1000002020.10.2911:10:53.862SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.794 ms; avr bad time: 0.164 ms; bad iterations: 356 total iterations: 1000002020.10.2911:10:54.686SymbolInfoTick (EURUSD,M15) GetBid max bad time: 4.870 ms; avr bad time: 0.339 ms; bad iterations: 1575 total iterations: 1000002020.10.2911:10:54.728SymbolInfoTick (EURUSD,M15) GetBid max bad time: 6.442 ms; avr bad time: 0.343 ms; bad iterations: 1691 total iterations: 1000002020.10.2911:10:54.732SymbolInfoTick (EURUSD,M15) GetBid max bad time: 7.568 ms; avr bad time: 0.349 ms; bad iterations: 1671 total iterations: 1000002020.10.2911:10:54.755SymbolInfoTick (EURUSD,M15) GetBid max bad time: 13.354 ms; avr bad time: 0.365 ms; bad iterations: 1634 total iterations: 1000002020.10.2911:10:54.773SymbolInfoTick (EURUSD,M15) GetBid max bad time: 9.385 ms; avr bad time: 0.352 ms; bad iterations: 1734 total iterations: 1000002020.10.2911:10:54.778SymbolInfoTick (EURUSD,M15) GetBid max bad time: 2.526 ms; avr bad time: 0.342 ms; bad iterations: 1748 total iterations: 1000002020.10.2911:10:54.785SymbolInfoTick (EURUSD,M15) GetBid max bad time: 15.195 ms; avr bad time: 0.356 ms; bad iterations: 1708 total iterations: 1000002020.10.2911:10:54.790SymbolInfoTick (EURUSD,H1) GetBid max bad time: 5.180 ms; avr bad time: 0.347 ms; bad iterations: 1796 total iterations: 100000
20 экспертов на EURUSD, т.е. все OnTick процессим одновременно. Билд терминала 2664. Запускать тест без оптимизации, компиляции и проч. доп.загрузки на 100% цпу - вы же не собираетесь запускать реальную "hft" торговлю на таком фоне?
Типичный лога теста:
Вы создаете тепличные условия, делая 100К итераций в течение 1.5 секунд на одном и том же тике. Я же специально дожидался тиков, которые не породили OnTick.
Просматривая логи своей торговли, замечаю исполнение SymbolInfoTick в течение нескольких миллисекунд. При этом на 100% знаю, что в этот момент был полный Idle CPU.
Все очень просто. В сутки условно 1 млн тиков. Даже тормоза в 0.01% тиков - 100 тиков в сутки с лагами. Вы скажете, что это ерунда. Я - плохо. Если нарвусь на лаг, когда нужно делать приказ, то это потенциальные денежные потери.
Очень благодарен, что эта ветка не остается незамеченной, и по этой функции, в частности, сделана большая работа по ускорению. Однако, для меня было несколько неожиданным, что ужасный костыль в определенных ситуациях может опережать штатную функцию. И, возможно, если бы Вы разобрались и устранили это отставание, то 100 потенциальных лагов в сутки превратились бы в 10.
Говорю, что стало много лучше, чем в начале ветки. Но факт остается фактом - есть моменты, когда нехорошо. И вижу, что Вы не хотите в этом разбираться. Уважаю Ваш выбор.
Выше приводил снепшотовый вариант получения текущих цен. Он меня бы полностью устроил, если бы не ловил на Idle-CPU машине миллисекундные лаги.
Меня также волнует вопрос не только скорости SymbolInfoTick, но и актуальности отданных ею цен. Вижу, что Вы этот вопрос не поднимаете. Видимо, решили позже посмотреть.
Вы создаете тепличные условия, делая 100К итераций в течение 1.5 секунд на одном и том же тике. Я же специально дожидался тиков, которые не породили OnTick.
Просматривая логи своей торговли, замечаю исполнение SymbolInfoTick в течение нескольких миллисекунд. При этом на 100% знаю, что в этот момент был полный Idle CPU.
Все очень просто. В сутки условно 1 млн тиков. Даже тормоза в 0.01% тиков - 100 тиков в сутки с лагами. Вы скажете, что это ерунда. Я - плохо. Если нарвусь на лаг, когда нужно делать приказ, то это потенциальные денежные потери.
Очень благодарен, что эта ветка не остается незамеченной, и по этой функции, в частности, сделана большая работа по ускорению. Однако, для меня было несколько неожиданным, что ужасный костыль в определенных ситуациях может опережать штатную функцию. И, возможно, если бы Вы разобрались и устранили это отставание, то 100 потенциальных лагов в сутки превратились бы в 10.
Говорю, что стало много лучше, чем в начале ветки. Но факт остается фактом - есть моменты, когда нехорошо. И вижу, что Вы не хотите в этом разбираться. Уважаю Ваш выбор.
Выше приводил снепшотовый вариант получения текущих цен. Он меня бы полностью устроил, если бы не ловил на Idle-CPU машине миллисекундные лаги.
Меня также волнует вопрос не только скорости SymbolInfoTick, но и актуальности отданных ею цен. Вижу, что Вы этот вопрос не поднимаете. Видимо, решили позже посмотреть.
Это совершенно не тепличные условия. Цикл на 100000 запросов цены без Sleep() и тому подобного и в 20 потоков одновременно - очевидный стресс тест. Ничего подобного в реальных условиях даже близко быть не должно.
Если вы думаете, что за 1.5 секунды не приходят другие тики - ок, сделайте 10 миллионов запросов, это ничего не поменяет, ваш "костыль" работает хуже:
NG 010:26:22.903SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 2.223 ms; avr bad time: 0.146 ms; bad iterations: 22369 total iterations: 10000000
OK 010:26:22.934SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 1.759 ms; avr bad time: 0.144 ms; bad iterations: 22462 total iterations: 10000000
KO 010:26:22.944SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 4.587 ms; avr bad time: 0.145 ms; bad iterations: 22620 total iterations: 10000000
RS 010:26:23.443SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 8.433 ms; avr bad time: 0.162 ms; bad iterations: 36242 total iterations: 10000000
LG 010:26:23.487SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 9.660 ms; avr bad time: 0.163 ms; bad iterations: 36378 total iterations: 10000000
KH 010:26:23.492SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 8.433 ms; avr bad time: 0.163 ms; bad iterations: 36208 total iterations: 10000000
HK 010:26:23.505SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 14.355 ms; avr bad time: 0.164 ms; bad iterations: 36292 total iterations: 10000000
QN 010:27:26.728SymbolInfoTick (EURUSD,M15) GetBid max bad time: 18.589 ms; avr bad time: 0.373 ms; bad iterations: 122026 total iterations: 10000000
HQ 010:27:27.042SymbolInfoTick (EURUSD,H1) GetBid max bad time: 15.544 ms; avr bad time: 0.371 ms; bad iterations: 123026 total iterations: 10000000
RD 010:27:29.190SymbolInfoTick (EURUSD,H1) GetBid max bad time: 16.207 ms; avr bad time: 0.370 ms; bad iterations: 127228 total iterations: 10000000
QJ 010:27:32.661SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 7.465 ms; avr bad time: 0.495 ms; bad iterations: 994 total iterations: 10000000
CL 010:27:32.799SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 16.999 ms; avr bad time: 0.585 ms; bad iterations: 1081 total iterations: 10000000
EP 010:27:33.056SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 11.774 ms; avr bad time: 0.515 ms; bad iterations: 1122 total iterations: 10000000
EE 010:27:33.555SymbolInfoTick (EURUSD,M15) GetBid max bad time: 17.385 ms; avr bad time: 0.368 ms; bad iterations: 134761 total iterations: 10000000
FG 010:27:35.581SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 10.428 ms; avr bad time: 0.502 ms; bad iterations: 373 total iterations: 10000000
CJ 010:27:46.372SymbolInfoTick (EURUSD,M15) GetBid max bad time: 14.278 ms; avr bad time: 0.360 ms; bad iterations: 153668 total iterations: 10000000
QO 010:27:46.819SymbolInfoTick (EURUSD,M15) GetBid max bad time: 12.494 ms; avr bad time: 0.361 ms; bad iterations: 154170 total iterations: 10000000
KP 010:27:46.897SymbolInfoTick (EURUSD,M15) GetBid max bad time: 17.176 ms; avr bad time: 0.362 ms; bad iterations: 154258 total iterations: 10000000
PE 010:27:47.560SymbolInfoTick (EURUSD,M15) GetBid max bad time: 14.090 ms; avr bad time: 0.362 ms; bad iterations: 156325 total iterations: 10000000
LF 010:27:47.946SymbolInfoTick (EURUSD,M15) GetBid max bad time: 16.794 ms; avr bad time: 0.367 ms; bad iterations: 160557 total iterations: 10000000
IH 010:27:47.970SymbolInfoTick (EURUSD,H1) GetBid max bad time: 11.241 ms; avr bad time: 0.366 ms; bad iterations: 160307 total iterations: 10000000
KN 010:27:51.026SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 4.961 ms; avr bad time: 0.333 ms; bad iterations: 687 total iterations: 10000000
FP 010:27:51.517SymbolInfoTick (EURUSD,M15) GetBid max bad time: 19.844 ms; avr bad time: 0.372 ms; bad iterations: 165266 total iterations: 10000000
LE 010:27:51.574SymbolInfoTick (EURUSD,M15) GetBid max bad time: 15.435 ms; avr bad time: 0.371 ms; bad iterations: 165785 total iterations: 10000000
QE 010:27:51.686SymbolInfoTick (EURUSD,H1) GetBid max bad time: 13.601 ms; avr bad time: 0.371 ms; bad iterations: 166278 total iterations: 10000000
CK 010:27:52.204SymbolInfoTick (EURUSD,M15) GetBid max bad time: 15.480 ms; avr bad time: 0.374 ms; bad iterations: 161441 total iterations: 10000000
FL 010:27:52.262SymbolInfoTick (EURUSD,M15) GetBid max bad time: 19.503 ms; avr bad time: 0.374 ms; bad iterations: 161363 total iterations: 10000000
FQ 010:27:52.504SymbolInfoTick (EURUSD,M15) GetBid max bad time: 15.440 ms; avr bad time: 0.375 ms; bad iterations: 161927 total iterations: 10000000
KQ 010:27:52.507SymbolInfoTick (EURUSD,H1) GetBid max bad time: 20.155 ms; avr bad time: 0.375 ms; bad iterations: 161670 total iterations: 10000000
EG 010:27:52.558SymbolInfoTick (EURUSD,M15) GetBid max bad time: 15.634 ms; avr bad time: 0.371 ms; bad iterations: 167511 total iterations: 10000000
OK 010:27:52.751SymbolInfoTick (EURUSD,M15) GetBid max bad time: 14.698 ms; avr bad time: 0.368 ms; bad iterations: 168482 total iterations: 10000000
LL 010:27:53.941SymbolInfoTick (EURUSD,M15) GetBid max bad time: 16.659 ms; avr bad time: 0.364 ms; bad iterations: 171194 total iterations: 10000000
JP 010:27:58.244SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 12.019 ms; avr bad time: 0.308 ms; bad iterations: 970 total iterations: 10000000
OD 010:27:58.879SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 7.972 ms; avr bad time: 0.299 ms; bad iterations: 1094 total iterations: 10000000
CE 010:28:06.402SymbolInfoTick (EURUSD,M15) GetBid max bad time: 14.140 ms; avr bad time: 0.342 ms; bad iterations: 56289 total iterations: 10000000
EK 010:28:06.860SymbolInfoTick (EURUSD,H1) GetBid max bad time: 14.013 ms; avr bad time: 0.344 ms; bad iterations: 56008 total iterations: 10000000
QL 010:28:06.922SymbolInfoTick (EURUSD,H1) GetBid max bad time: 11.626 ms; avr bad time: 0.343 ms; bad iterations: 56676 total iterations: 10000000
ER 010:28:07.010SymbolInfoTick (EURUSD,M15) GetBid max bad time: 13.021 ms; avr bad time: 0.340 ms; bad iterations: 51610 total iterations: 10000000
ER 010:28:08.708SymbolInfoTick (EURUSD,M15) GetBid max bad time: 2.970 ms; avr bad time: 0.317 ms; bad iterations: 24083 total iterations: 10000000
Вот это ваше утверждение на 100% ложное:
Просматривая логи своей торговли, замечаю исполнение SymbolInfoTick в течение нескольких миллисекунд. При этом на 100% знаю, что в этот момент был полный Idle CPU.
Как и вот это ваше предыдущее утверждение:
Уверен, что могу доказать, что получение текущих цен у Вас реализовано очень медленно. И CPU-нагрузка создает такие тормоза только из-за неправильной реализации Вами самой главной функции в MQL5.
Доступ к ценам через SymbolInfoTick сейчас очень быстрый и он полностью отвязан от процессинга потока тиков. Вы работаете с готовым кэшем цен, который обновляется очень экономно и быстро.
Все "тормоза в 0.01% тиков" проявляются только в условиях стресс-теста, и это отличный результат. В нормальных условиях доступ гарантированно очень быстрый.
Если вы признаёте, что "сделана большая работа по ускорению" SymbolInfoTick, то вам следуют мне поверить, что "костыль" с получением цен через PositionSelectByTicket не может быть лучшим решением.
По одной простой причине - реализация PositionSelectByTicket полностью идентична первоначальной "медленной" реализации SymbolInfoTick.
Как я писал выше, эта реализация не является медленной в прямом смысле этого слова, но при большой нагрузке на цпу, имеет более высокую вероятность выбросов по времени выполнения (что хорошо видно в моем последнем тесте).
Тут тайминги сильно зависят от работы планировщика задач системы под нагрузкой, т.е. могут быть различия в разных ОС и даже их версиях.
И чем больше нагрузка, тем больше вы тестируете эффективность работы планировщика задач, а не терминала.
На этом тему быстродействия SymbolInfoTick закрываю.
Если ваши эксперты создают нагрузку на уровне синтетических стресс-тестов, то решение одно: "железо должно соответствовать задачам".
Уважаемые разработчики, могли бы Вы сообщить, как вычисляется MQL_MEMORY_USED?
Сделал расчет памяти, что занимают все переменные советника.
Это меньше 10%. Если правильно понимаю, то в MQL_MEMORY_USED входит History-кеш и CopyTicks-кеш. Но это все равно значительно меньше должно занимать.
При этом параллельный советник кушает в несколько раз меньше. Хотя принцип тот же.
В общем, что входит в это значение?
ЗЫ Сохранил шаблон с советником и к этому же чарту применил, вызвав перезагрузку. Стало так.
Потребление памяти изменилось почти на порядок. Сложно пока объяснить, что это обозначает.
Накопительный эффект пользования памяти есть у многих прог. Этим браузеры грешат, тот же ворд, иногда может. Терминал тоже грешит. К тому же логи по дефолту пишут все и если много действий то в гиг за неделю легко улететь. Это зло, которым надо управлять. Правда не понятно как.
Может быть Вы знаете как программно выбрать финансовый инструмент и не зависнуть на века ?
Через индикатор
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
MT5 и скорость в боевом исполнении
Renat Fatkhullin, 2020.10.14 04:15
Для массовой работы с тиками ставьте больше памяти.
4 гб (цена 20 евро) - это никуда не годится в 2020 году, если речь идет об аналитике и исследованиях.
Для Маркет-продуктов такой подход никуда не годится. Приходится обходить 10-ти секундное удержание в памяти ненужных данных через такой костыль.
Сделать тривиальный Маркет-продукт в виде Маркет-скринера - фактически, не посильная задача для MT5 из-за чрезмерного расхода памяти.
Сделать тривиальный Маркет-продукт в виде Маркет-скринера - фактически, не посильная задача для MT5 из-за чрезмерного расхода памяти.
Терминал после запуска съедает столько памяти.
После выполнение скринера стал съедать 2 гига (TERMINAL_MEMORY_USED и не уменьшалось со временем). Это при только одном открытом чарте на 5000 M1-баров.
Скрин не сохранил. Но решил накидать пример, показывающий, выжирание памяти Терминалом не в себя там, где это просто глупо.
Скрипт просто делает копии оригинальных символов из Обзора рынка. Предполагалось, что на MQ-Demo добавлю все символы и запущу этот скрипт первый раз на холодную, а потом повторно - на горячую.
И после горячего (когда тики уже на SSD в виде tkc-файлов) запуска буду наблюдать дикое выжирание памяти там, где это совсем не нужно при должной реализации.
Однако, запустив скрипт, столкнулся с тем, что он подвисает на MQ-Demo. Снимается только через Abnormal termination, после чего Терминал не высвобождает больше 1 Гб памяти.
Легко сравнить этот скрин с тем, что в начале.
Простите, не уверен баг это или фича. Самостоятельно ответа не нашел. Но вопрос связан по поводу производительности и полагаю, что лучше этот вопрос задать тут.
Если в пустой индикатор добавить, скажем, 22 буфера с типом DRAW_SECTION, то при запуске такого индикатора на одном чарте, в котором находится 1000000 баров и выше, то терминал начинает достаточно сильно тормозить (так же идет заметная нагрузка на ЦП) и съедать заметное количество оперативной памяти, даже если индикатор ничего не вычисляет.
Мой интерес вызвал тот факт, что если использовать буферы с другими типами, то все работает без проблем и подобного замедления не наблюдается.
К примеру, я запускал следующий код индикатора на единственном чарте в котором содержится 1000000 баров и терминал съедал около 500 МБайт и заметно лагал, особенно сам чарт.
Но если поменять тип буфферов на, скажем, DRAW_LINE, то нагрузка на процессор резко понижается, лагов не наблюдается, а оперативка съедается в 5 раз меньше (потребляется около 100 МБайт).
Подобные тесты проводил на разных билдах, вплоть до билдов 2019 года и ситуация одинаковая.
Отдельный гражданин достал из широких штанин дубликатом бесценного груза MQL-код, который показал, что в одних и тех же условиях костыль работает быстрее штатной функции.
Очень простой тест:
20 экспертов на EURUSD, т.е. все OnTick процессим одновременно. Билд терминала 2664. Запускать тест без оптимизации, компиляции и проч. доп.загрузки на 100% цпу - вы же не собираетесь запускать реальную "hft" торговлю на таком фоне?
Типичный лога теста:
Очень простой тест:
20 экспертов на EURUSD, т.е. все OnTick процессим одновременно. Билд терминала 2664. Запускать тест без оптимизации, компиляции и проч. доп.загрузки на 100% цпу - вы же не собираетесь запускать реальную "hft" торговлю на таком фоне?
Типичный лога теста:
Вы создаете тепличные условия, делая 100К итераций в течение 1.5 секунд на одном и том же тике. Я же специально дожидался тиков, которые не породили OnTick.
Просматривая логи своей торговли, замечаю исполнение SymbolInfoTick в течение нескольких миллисекунд. При этом на 100% знаю, что в этот момент был полный Idle CPU.
Все очень просто. В сутки условно 1 млн тиков. Даже тормоза в 0.01% тиков - 100 тиков в сутки с лагами. Вы скажете, что это ерунда. Я - плохо. Если нарвусь на лаг, когда нужно делать приказ, то это потенциальные денежные потери.
Очень благодарен, что эта ветка не остается незамеченной, и по этой функции, в частности, сделана большая работа по ускорению. Однако, для меня было несколько неожиданным, что ужасный костыль в определенных ситуациях может опережать штатную функцию. И, возможно, если бы Вы разобрались и устранили это отставание, то 100 потенциальных лагов в сутки превратились бы в 10.
Говорю, что стало много лучше, чем в начале ветки. Но факт остается фактом - есть моменты, когда нехорошо. И вижу, что Вы не хотите в этом разбираться. Уважаю Ваш выбор.
Выше приводил снепшотовый вариант получения текущих цен. Он меня бы полностью устроил, если бы не ловил на Idle-CPU машине миллисекундные лаги.
Меня также волнует вопрос не только скорости SymbolInfoTick, но и актуальности отданных ею цен. Вижу, что Вы этот вопрос не поднимаете. Видимо, решили позже посмотреть.
Вы создаете тепличные условия, делая 100К итераций в течение 1.5 секунд на одном и том же тике. Я же специально дожидался тиков, которые не породили OnTick.
Просматривая логи своей торговли, замечаю исполнение SymbolInfoTick в течение нескольких миллисекунд. При этом на 100% знаю, что в этот момент был полный Idle CPU.Все очень просто. В сутки условно 1 млн тиков. Даже тормоза в 0.01% тиков - 100 тиков в сутки с лагами. Вы скажете, что это ерунда. Я - плохо. Если нарвусь на лаг, когда нужно делать приказ, то это потенциальные денежные потери.
Очень благодарен, что эта ветка не остается незамеченной, и по этой функции, в частности, сделана большая работа по ускорению. Однако, для меня было несколько неожиданным, что ужасный костыль в определенных ситуациях может опережать штатную функцию. И, возможно, если бы Вы разобрались и устранили это отставание, то 100 потенциальных лагов в сутки превратились бы в 10.
Говорю, что стало много лучше, чем в начале ветки. Но факт остается фактом - есть моменты, когда нехорошо. И вижу, что Вы не хотите в этом разбираться. Уважаю Ваш выбор.
Выше приводил снепшотовый вариант получения текущих цен. Он меня бы полностью устроил, если бы не ловил на Idle-CPU машине миллисекундные лаги.
Меня также волнует вопрос не только скорости SymbolInfoTick, но и актуальности отданных ею цен. Вижу, что Вы этот вопрос не поднимаете. Видимо, решили позже посмотреть.
Это совершенно не тепличные условия. Цикл на 100000 запросов цены без Sleep() и тому подобного и в 20 потоков одновременно - очевидный стресс тест. Ничего подобного в реальных условиях даже близко быть не должно.
Если вы думаете, что за 1.5 секунды не приходят другие тики - ок, сделайте 10 миллионов запросов, это ничего не поменяет, ваш "костыль" работает хуже:Вот это ваше утверждение на 100% ложное:
Как и вот это ваше предыдущее утверждение:
Доступ к ценам через SymbolInfoTick сейчас очень быстрый и он полностью отвязан от процессинга потока тиков. Вы работаете с готовым кэшем цен, который обновляется очень экономно и быстро.
Все "тормоза в 0.01% тиков" проявляются только в условиях стресс-теста, и это отличный результат. В нормальных условиях доступ гарантированно очень быстрый.
Если вы признаёте, что "сделана большая работа по ускорению" SymbolInfoTick, то вам следуют мне поверить, что "костыль" с получением цен через PositionSelectByTicket не может быть лучшим решением.
По одной простой причине - реализация PositionSelectByTicket полностью идентична первоначальной "медленной" реализации SymbolInfoTick.
Как я писал выше, эта реализация не является медленной в прямом смысле этого слова, но при большой нагрузке на цпу, имеет более высокую вероятность выбросов по времени выполнения (что хорошо видно в моем последнем тесте).
Тут тайминги сильно зависят от работы планировщика задач системы под нагрузкой, т.е. могут быть различия в разных ОС и даже их версиях.
И чем больше нагрузка, тем больше вы тестируете эффективность работы планировщика задач, а не терминала.
На этом тему быстродействия SymbolInfoTick закрываю.
Если ваши эксперты создают нагрузку на уровне синтетических стресс-тестов, то решение одно: "железо должно соответствовать задачам".
У меня вопрос про актуальность тиков, которые отдает SymbolInfoTick.
Ситуация:
1. Делаем TimeCurretn(); получаем время 18:00:00
2. Делаем SymbolInfoTick по нелеквидному символу. Получаем тик со временем 17:58:00.
3. Sleep(1)
4. Делаем SymbolInfoTick по нелеквидному символу. Получаем тик со временем 17:59:00.
Т.е четвертом пункте мы получили новый тик, который на минуту отличается TimeCurretn().
Видите ли вы проблему в данной ситуации ?
Как в такую ситуацию попадать по реже ?
У меня вопрос про актуальность тиков, которые отдает SymbolInfoTick.
Ситуация:
1. Делаем TimeCurretn(); получаем время 18:00:00
2. Делаем SymbolInfoTick по нелеквидному символу. Получаем тик со временем 17:58:00.
3. Sleep(1)
4. Делаем SymbolInfoTick по нелеквидному символу. Получаем тик со временем 17:59:00.
Т.е четвертом пункте мы получили новый тик, который на минуту отличается TimeCurretn().
Видите ли вы проблему в данной ситуации ?
Как в такую ситуацию попадать по реже ?
SymbolInfoTick отдает данные, полученные от сервера брокера. Что сервер прислал, то вы и получаете.
Если есть вопросы по тиковому потоку, который транслирует ваш брокер, то и обращаться надо к вашему брокеру.