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

 
Aleksei Kuznetsov #:

Обновил сегодня код в кодобазе. Основная версия английская. 
Видимо сотрудники сайта сделали переводы на другие языки, с дубликатами кода. После обновления в англ. версии там остались старые версии кода.

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

Там и кнопки на редактирование нет... надеюсь сами обновят.
 

Тут странная ситуация. В коде BuyStop выставляется в двух местах, все внутри OnTick, и только если is_trade_time_1 || is_trade_time_2

 is_trade_time_1 и 2  определяются в начале Ontick. В конце OnTick is_trade_time_1 и is_trade_time_2 выводятся в коммент. В тестере видно что значения false но происходит выставление BuyStop.

и

это в версии_25. В версии _26 сделал только вывод в печать значений is_trade_time_1 и is_trade_time_2, и очудо, если оба времени false, то не выставляет. 


 


Моя пользовательская функция Recv(), на входе сразу делает проверку на доступность данных для чтения SocketIsReadable
если данных нет, выходим из Recv().
То есть реализуется логика неблокирующего чтения.

string Recv()
{
   if(SocketIsReadable(socket) < 2)
      return "";

...

Но оказалось, что SocketIsReadable содержит скрытое, нигде не описанное в документации ожидание, на размер системного таймера, примерно 15 ms.

Например, если мы точно знаем, что в системный сокет приходит ровно одно сообщение (не пачка),
то функция SocketIsReadable мгновенно возвращает управление. На первый взгляд проблем нет.

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

while((msg = Recv()) != "" && !_StopFlag)
{

...

Мы знаем, что в сокет приходит одно сообщение. Но строим логику вычитки на цикле для перестраховки.
На первой while итерации сообщение есть в сокете, SocketIsReadable мгновенно вернёт управление, проблем нет.

На второй while итерации, проверяем пустую строку из Recv(), чтоб завершить цикл.
Вот тут и возникает нигде неописанный таймаут SocketIsReadable
Когда в сокете уже нечего читать, SocketIsReadable блокируется на размер системного таймера.
Что приводит к блокировке выполнения всего остального кода на 15 мс.

Функция

SocketTimeouts(socket, 1, 1);

не применима к SocketIsReadable.


Убедительно прошу, вывести в параметр функции SocketIsReadable(socket, 0) управление значением select

Так как текущее поведение блокирует выполнение функции на размер системного таймера, когда в сокете нечего читать.
Или вообще выставить select на постоянный ноль. Так как по сути, в mql5 вся логика строиться на неблокирующих вызовах.

 
А я всё думаю, почему в другой реализации время выполнения функции SocketTlsReadAvailable никак не может снизиться меньше 10 мс.
Скорее всего и в SocketTlsReadAvailable есть ожидание данных из сокета, на размер системного таймера.
Прошу не предлагать снизить системный таймер принудительно, проблема в блокировке а не в системном таймере.
 

@Renat Fatkhullin
Чтобы более была понятна проблема, покажу наглядно.

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

dom1


вычитку инкрементных обновлений, но по одному сообщению за проход, выполняет ProcessReadDOM

//упрощено чтоб показать суть
void ProcessReadDOM()
{
   msg = Recv();

...

и в среднем время обработки ProcessReadDOM занимает всего 130 микросекунд.


А вот вычитка из другого источника, только лучших уровней bid/ask.
То есть присылается всего два лучших уровня.
Но источник может слать сообщения пачками от 1 до 15 за раз

dom2

соответственно вычитка происходит в цикле за проход

//упрощено чтоб показать суть
void ProcessReadDOM()
{
   while((msg = Recv()) != "" && !_StopFlag)
   {
      ...

   }

...

и что мы наблюдаем?
как среднее время вычитки резко стала похожа на системный таймер.

И это из за того, что SocketIsReadable тупо блокирует на ожидании данных из сокета, когда их уже нет.

 

Проверил свой системный таймер, он оказывается итак установлен на 1 мс, вроде не понижал с момента установки ОС
может Win11 изначально ставит такой системный таймер х.з. не в этом суть.

Таймер системных часов (100-нс единицы):
        Текущий интервал: 10000 (1.0 мс, 1000.0 Гц)
        Минимальный интервал: 5000 (0.5 мс)
        Максимальный интервал: 156250 (15.625 мс)


Суть в том, что в функции SocketIsReadable жестко выставлен select() с не нулевым таймаутом, и скорее всего выставлен на 15 мс.
Прошу выставить select() в ноль.

 
По каким командам в логах понять что терминал отключился от сервера/ соединение прервалось/был дисконнект?
 
Вопрос по терминалу мт4 - есть ли возможность зафиксировать сервер, к которому подключается терминал? некоторые серверы недоступны(скорее всего их блочит ркн), терминал их перебирает видимо сам  и в рандомный момент перестает принимать котировки..
Файлы:
 
Max N #:
Вопрос по терминалу мт4 - есть ли возможность зафиксировать сервер, к которому подключается терминал? некоторые серверы недоступны(скорее всего их блочит ркн), терминал их перебирает видимо сам  и в рандомный момент перестает принимать котировки..
Можно сторонними средствами - заблокировать исходящие на "плохие" серверы на локальном файрволе или на роутере.
 
Большое спасибо (без всякой иронии), что в мобильном приложении снова сделали появление линии нового ордера всегда в видимой части!
 Ну а четыре ненужных лишних опции при выставлении ордера, увы, так и остались. У меня на старом телефоне старая версия, до улучшайзинга. Так там и не 4 лишних кнопки, как сейчас, и даже не 2, оказывается - только одна кнопка! Гениально сделано было! Ставишь ордер, куда надо - и кнопка, если ордер сейчас Sell - кнопка отображается как Buy, а если ордер Buy - кнопка Sell. Ну а Limit и Stop подставляет автоматически, так как это однозначный выбор в зависимости от того, выше или ниже текущей цены. И линия ордера в момент переключения этой кнопкой Buy/Sell ни на пиксель не сбивается! Ну гениально было! Верните, пожалуйста! Не нужны 4 кнопки, над которыми нужно сидеть-соображать, после чего сбивается линия ордера! Хватало одной кнопки, заменяющей все четыре, от которой ничего не сбивалось, с ордера даже мухи не взлетали! А сейчас соседи все взлетают от воплей трейдеров, так неудобно стало!