Чтение бинарных файлов из индикатора

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Andrei Kossarev
399
Andrei Kossarev  
if (!ChartScreenShot(0, name, screenWidth, screenHeight, ALIGN_RIGHT))
      return (false);

   ResetLastError();
   if(!FileIsExist(name,false))
      return (false);

   //---
   int flags=FILE_READ|FILE_BIN;

   //---
   int file=FileOpen(name,flags);
   if(file==INVALID_HANDLE)
      return(false);

   uchar photo[];
   FileReadArray(file,photo);
   FileClose(file);

Вот фрагмент кода, делается скрин экрана и читается картинка из файла. В советнике работает на ура, в индикаторе возвращается пустой массив. Есть какие то ограничения по работе с файлами в индикаторах?? В докумениации никаких ограничений не нашел

Dmitry Fedoseev
56609
Dmitry Fedoseev  
Самое интересное здесь - как вы пришли к такому выводу? А код - не весь, и сделать какой-то вывод исходя из него - нельзя.
Andrei Kossarev
399
Andrei Kossarev  
Dmitry Fedoseev:
Самое интересное здесь - как вы пришли к такому выводу? А код - не весь, и сделать какой-то вывод исходя из него - нельзя.
//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots   1
#property indicator_buffers 1

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
TestPhoto();
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

void TestPhoto() {
   string name;
   MqlDateTime  dtLocal;
   TimeToStruct(TimeLocal(), dtLocal);
   string date = IntegerToString(dtLocal.year) + IntegerToString(dtLocal.mon, 2, '0') + IntegerToString(dtLocal.day, 2, '0');
   string time = IntegerToString(dtLocal.hour, 2, '0') + "." + IntegerToString(dtLocal.min, 2, '0') + "." + IntegerToString(dtLocal.sec, 2, '0');
   name = "ScreenShots/" + date + "/" + _Symbol + "_" +date + "_" + time + ".png";
   
if (!ChartScreenShot(0, name, 800, 600, ALIGN_RIGHT))
      return;

   ResetLastError();
   if(!FileIsExist(name,false))
      return;
  
   //---
   int flags=FILE_READ|FILE_BIN|FILE_SHARE_READ;

   //---
   int file=FileOpen(name,flags);
   if(file<0) {
      Print("Операция FileOpen неудачна, ошибка ",GetLastError());
      return;
}
   uchar photo[];
   FileReadArray(file,photo);
   FileClose(file);
   
   Print(ArraySize(photo));
}
Dmitry Fedoseev
56609
Dmitry Fedoseev  

Оказывается, дело не в чтении файла, а в сохранении скриншота функцией ChartScreenShot(). Получается, что функция асинхронно работает. Сразу после вызова скриншот еще не успел сохраниться, файл есть, но он пустой. И это, скорее всего, не баг, а фича - чтобы индикаторы не тормозили. 

Если надо во что бы то ни стало, то после вызова ChartScreenShot() можно добавить какой-нибудь цикл, что бы паузу обеспечить, или в цикле проверять, пока в файле что-то не появится. 

Andrei Kossarev
399
Andrei Kossarev  
for (int i=0; i < 100000; i++){
      if (FileIsExist(name,false) && FileSize(name) > 0)
         break;
   }

Добавил такой код, ничего не изменилось, файл создается, но не читается

Пробовал также Sleep в цикле, ничего не меняется

Dmitry Fedoseev
56609
Dmitry Fedoseev  

А я вот так делал: 

   for(int i=0;i<10;i++) 
   ChartRedraw();

Гарантии нет.

Можно так: в TestPhoto() делать только сохранение скриншота и сохранять его имя в строковый массив. Где-то в другом месте, может, в OnTimer() или в OnCalculate() проверять, появилось ли что-то в файле и сдвигать массив, что-то делать с файлом.

Andrei Kossarev
399
Andrei Kossarev  

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

Vladimir Simakov
5986
Vladimir Simakov  

Вам доки для чего?

...

Отданная команда поступает в очередь сообщений графика и выполняется только после обработки всех предыдущих команд.

...

А вот к разрабам опять вопрос. Эта инфа есть в справке к mql4, а в mql5 уже не упоминается.
Igor Makanu
9500
Igor Makanu  
Vladimir Simakov:

Вам доки для чего?


...

Отданная команда поступает в очередь сообщений графика и выполняется только после обработки всех предыдущих команд.

...

по моему там еще что то мешает

вот набросал код индикатора - пишем каждые 10 секунд:

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   EventSetTimer(10);

//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   EventKillTimer();

}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
//---

//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
{
   ResetLastError();
   if(!SaveScreenShot()) Print("Ошибка сохранения скриншота № ",GetLastError());
   else Print("Сохранил скриншот");

}
//+------------------------------------------------------------------+
bool SaveScreenShot()
{
   MqlDateTime  dtLocal;
   TimeLocal(dtLocal);
   string date = IntegerToString(dtLocal.year) + IntegerToString(dtLocal.mon, 2, '0') + IntegerToString(dtLocal.day, 2, '0');
   string time = IntegerToString(dtLocal.hour, 2, '0') + "." + IntegerToString(dtLocal.min, 2, '0') + "." + IntegerToString(dtLocal.sec, 2, '0');
   string fname = "ScreenShots/" + date + "/" + _Symbol + "_" + date + "_" + time + ".png";
   if (!ChartScreenShot(0, fname, 800, 600, ALIGN_RIGHT)) return(false);
   return(true);
}
//+------------------------------------------------------------------+

в теории все работает - вижу папку MQL5\Files\ScreenShots\20191207 в ней появляются файлы

но пока индикатор работает, не могу в Вин10 открыть скриншоты для просмотра, т.е. файлы заблокированы, даже если удалить индикатор, превью в проводнике Вин10 заработает секунд через 5-10 , т.е. лишь тогда файлы скриншотов станут доступны для чтения

Dmitry Fedoseev
56609
Dmitry Fedoseev  
Vladimir Simakov:

Вам доки для чего?

...

Отданная команда поступает в очередь сообщений графика и выполняется только после обработки всех предыдущих команд.

...

А вот к разрабам опять вопрос. Эта инфа есть в справке к mql4, а в mql5 уже не упоминается.

А какая польза от столь ценной информации? И так понятно, что не сразу все происходит.

Vladimir Simakov
5986
Vladimir Simakov  
Igor Makanu:

по моему там еще что то мешает

вот набросал код индикатора - пишем каждые 10 секунд:

в теории все работает - вижу папку MQL5\Files\ScreenShots\20191207 в ней появляются файлы

но пока индикатор работает, не могу в Вин10 открыть скриншоты для просмотра, т.е. файлы заблокированы, даже если удалить индикатор, превью в проводнике Вин10 заработает секунд через 5-10 , т.е. лишь тогда файлы скриншотов станут доступны для чтения

Неуж-то разрабы забыли handle закрыть? Так, мысли вслух.

123
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий