Баг с созданием скриншота в индикаторе МТ5 - страница 8

 
Vitaly Muzichenko #:

Позже проверю тот код

Именно

NewBar в режим тестера перенести не предлагали?)))

это же зло адское в реалтайме

 
Сходу написал и сразу заработало.
#property indicator_chart_window
#property indicator_plots 0

int OnCalculate( const int rates_total, const int, const int, const double &[] )
{
  return(rates_total);
}

bool Screen( const long Chart = 0, const int Width = 750, const int Height = 400 )
{
  const ulong StartTime = GetMicrosecondCount();

  string FileName = (string)TimeLocal() + "_" + (string)StartTime;
  StringReplace(FileName, ".", "-");
  StringReplace(FileName, ":", "-");
  
  FileName += "_" + (string)((Chart > 0) ? Chart : ChartID()) + ".png";
  
  return(ChartScreenShot(Chart, FileName, Width, Height) && EventChartCustom(0, 0, StartTime, 1, FileName));
}

void OnChartEvent( const int32_t id, const long& lparam, const double& dparam, const string& sparam )
{
  if (id == CHARTEVENT_KEYDOWN)
    Screen();
  else if (id == CHARTEVENT_CUSTOM)
  {
    uchar Bytes[];

    const ulong Interval = GetMicrosecondCount() - lparam;
    
    if (FileLoad(sparam, Bytes) > 0)
    {
      Alert(sparam + " - " + (string)(Interval) + " mcs, EventChartCustom = " + (string)dparam);
      
      FileDelete(sparam);
    }
    else if (Interval > 3e6)
      Alert(sparam + " - timeout, EventChartCustom = " + (string)dparam);
    else
      EventChartCustom(0, 0, lparam, dparam + 1, sparam);
  }
}


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

2025.08.26 16:57:18.818 Alert: 2025-08-26 16-57-18_6994209_132503570123939382.png - 10577 mcs, EventChartCustom = 1.0
2025.08.26 16:57:19.078 Alert: 2025-08-26 16-57-19_7242352_132503570123939382.png - 22882 mcs, EventChartCustom = 1.0
2025.08.26 16:57:19.078 Alert: 2025-08-26 16-57-19_7254828_132503570123939382.png - 10604 mcs, EventChartCustom = 1.0
2025.08.26 16:57:19.440 Alert: 2025-08-26 16-57-19_7614415_132503570123939382.png - 12474 mcs, EventChartCustom = 1.0
2025.08.26 16:57:19.656 Alert: 2025-08-26 16-57-19_7832112_132503570123939382.png - 11264 mcs, EventChartCustom = 1.0
2025.08.26 16:57:19.884 Alert: 2025-08-26 16-57-19_8048382_132503570123939382.png - 22919 mcs, EventChartCustom = 1.0


Почему-то с первого раза всегда создается скрин. Возможно, EventChartCustom помещает пользовательское событие в очередь ПОСЛЕ ChartScreenShot. Тогда проблема решается совсем элементарно.

 
fxsaber #:

Почему-то с первого раза всегда создается скрин. Возможно, EventChartCustom помещает пользовательское событие в очередь ПОСЛЕ ChartScreenShot. Тогда проблема решается совсем элементарно.

Конечно, если делать скрин чужого чарта, то такого эффекта не будет.

Screen(ChartFirst()); // Чужой чарт.
2025.08.26 17:23:13.226 Alert: 2025-08-26 17-23-12_1408534_132503570123939382.png - 392673 mcs, EventChartCustom = 1900.0
2025.08.26 17:23:14.163 Alert: 2025-08-26 17-23-14_2614670_132503570123939382.png - 123379 mcs, EventChartCustom = 582.0
2025.08.26 17:23:16.062 Alert: 2025-08-26 17-23-15_4372859_132503570123939382.png - 264906 mcs, EventChartCustom = 1400.0
2025.08.26 17:23:18.075 Alert: 2025-08-26 17-23-17_6494615_132503570123939382.png - 155653 mcs, EventChartCustom = 347.0
2025.08.26 17:23:18.075 Alert: 2025-08-26 17-23-17_5609963_132503570123939382.png - 1040805 mcs, EventChartCustom = 5353.0


В общем, если индикатор делает скрины своего чарта, то никаких проверок даже делать не нужно на создание скрина. Он гарантировано будет готов.

 
fxsaber #:
Сходу написал и сразу заработало.

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

Почему-то с первого раза всегда создается скрин. Возможно, EventChartCustom помещает пользовательское событие в очередь ПОСЛЕ ChartScreenShot. Тогда проблема решается совсем элементарно.

Спасибо, это сработало


 

Из поднятой проблемы можно сделать вывод.
Отсутствие в документации информации о том, что ChartScreenShot выполняется асинхронно.
Поэтому вводит в заблуждение как применять функцию правильно.  

Документация по MQL5: Операции с графиками / ChartScreenShot
Документация по MQL5: Операции с графиками / ChartScreenShot
  • www.mql5.com
Функция обеспечивает скриншот указанного графика в его текущем состоянии в формате GIF, PNG или BMP в зависимости от указанного расширения...
 
Roman #:

Из поднятой проблемы можно сделать вывод.
Отсутствие в документации информации о том, что ChartScreenShot выполняется асинхронно.
Поэтому вводит в заблуждение как применять функцию правильно.  

Но всё-же хотелось-бы, чтоб разработчики обратили на это внимание

fxsaber огромное СПАСИБО, пока работает отменно.
 
Vitaly Muzichenko #:

Но всё-же хотелось-бы, чтоб разработчики обратили на это внимание

Об этом и речь. Разработчикам, добавьте в документацию что функция асинхронная. 

 
Roman #:

Об этом и речь. Разработчикам, добавьте в документацию что функция асинхронная. 

Функция не асинхронная, но для создания скриншота она запрашивает содержимое чарта об актуальном состоянии - это касается объектов и индикаторов, так что вызов её из индикатора фактически приводит к реентерабельности индикатора - как это реализовано внутри - я не в курсе, а до теста индюка руки не дошли. Решение с событием, помещаемым в очередь, - верное.

 
Stanislav Korotky #:

Функция не асинхронная, но для создания скриншота она запрашивает содержимое чарта об актуальном состоянии - это касается объектов и индикаторов, так что вызов её из индикатора фактически приводит к реентерабельности индикатора - как это реализовано внутри - я не в курсе, а до теста индюка руки не дошли. Решение с событием, помещаемым в очередь, - верное.

Если бы она была синхронной, то дожидалась бы готового файла.
Об этой проблеме(фиче) и была ветка, когда выяснили её истинное поведение.
Да, отдать задачу на усмотрение самому терминалу получается лучшее решение, чем обрабатывать самому. 
Исходя из этого, теперь понятен принцип работы и с другими асинхронными функциями.
Огорчает то, что пользовательские события завязаны на чартах, а не реализованы отдельно, поэтому тут тоже можно нарваться на задержку очереди.
Ну конечно это надо сильно нагрузить очередь чартов в таком случае, но сам факт переполнения очереди никуда не делся. 
Например если читать потоковые сокеты через события терминала, мне кажется сомнительная затея.


Вопрос разработчикам.
Подскажите пожалуйста, какой лимит на размер очереди заложен в пользовательских событиях терминала?
 
Stanislav Korotky #:

Функция не асинхронная, но для создания скриншота она запрашивает содержимое чарта об актуальном состоянии - это касается объектов и индикаторов, так что вызов её из индикатора фактически приводит к реентерабельности индикатора - как это реализовано внутри - я не в курсе, а до теста индюка руки не дошли. Решение с событием, помещаемым в очередь, - верное.

Как показали тесты, ChartScreenShot в ЕА и скрипте работает без каких либо изощрений.

В индикаторе МТ5 - нужно извращаться.  В МТ4 индикаторе также работает без проблем.