Как получить уникальное число во время тестирования? - страница 3

 
Nikolay Ivanov:

 Компиляция ничего удалить не может. Вы сделали не правильные выводы. Компиляция вызывает перезапуск советника, если он включен в работу. Перезапуск сопровождается запуском функций deinit и init. Если файлы удаляются значит алгоритм их удаления находится в одной из этих функций. 


Напоминаю: не при работе советника, а при его тестировании. Вся описанная в данной теме ситуация происходит при тестировании. При каждом проходе тестирования после компиляции, генерируемые файлы советника удаляются системой.

 
Francuz:

Напоминаю: не при работе советника, а при его тестировании. Вся описанная в данной теме ситуация происходит при тестировании. При каждом проходе тестирования после компиляции, генерируемые файлы советника удаляются системой.


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

 
Francuz:

Неудобочитаемая вещь. Как быстро ориентироваться в файлах из таких последовательностей 6F9619FF-8B86-D011-B42D-00CF4FC964FF?


Зато уникально. Если работать с файлом предстоит только эксперту или индикатору то ему все равно как выглядит его название.

...

Я для своих нужд делал сохранение некоторых данных после завершения работы индикатора в файле с именем Symbol()+Period(). Для моих нужд это было достаточно. Что бы избежать ошибок совместного доступа к файлу двух и более индикаторов установленных на одном и том же TF и на одном и том же символе использовал семафоры.

 
Nikolay Ivanov:

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


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

Алгоритм воспроизведения:

Запускаете эксперта на тестирование. Он не найдёт файла с именем FileName и тогда создаст его.

Запускаете эксперт на тестирование ещё раз. Он найдёт файл и ничего больше делать не будет.

Открываете код эксперта, делаете фиктивную правку, проводите компиляцию.

Запускаете эксперта на тестирование. Система удалит файл. Експерт не найдёт файла с именем FileName и тогда создаст его.

string FileName = "FileName";

//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit()

{

   // Обнулить лог ошибки

   ResetLastError();

   if(!FileIsExist(FileName, 0))

   {

      PrintFormat("Файл %s не найден!", FileName);

      // Обнулить лог ошибки

      ResetLastError();

      int FileHandle = FileOpen(FileName, FILE_READ|FILE_WRITE|FILE_CSV);

      if(FileHandle != INVALID_HANDLE)

      {

         PrintFormat("Создан файл %s", FileName);

      }

      else

      {

         PrintFormat("Не удалось создать файл %s, Код ошибки = %d", FileName, GetLastError());

      }

   }

   else

   {

      PrintFormat("Файл %s найден! Всё отлично!", FileName);

   }

   return(INIT_SUCCEEDED);

}

Файлы:
 
Vitalii Ananev:

Зато уникально. Если работать с файлом предстоит только эксперту или индикатору то ему все равно как выглядит его название.

...

Я для своих нужд делал сохранение некоторых данных после завершения работы индикатора в файле с именем Symbol()+Period(). Для моих нужд это было достаточно. Что бы избежать ошибок совместного доступа к файлу двух и более индикаторов установленных на одном и том же TF и на одном и том же символе использовал семафоры.


Да, такое решение будет работать. Но в моём случае между первым и вторым этапом разработки с этими файлами будут много работать люди. По этому лучше сразу утрудить себя сделать как надо, чем потом мучатся.

 
Maxim Kuznetsov:

не трогайте каку...:-)

FileGetInteger(fileDescription,FILE_CREATE_DATE)


Запилил. Работает но с какими-то непонятными мне глюками.

Насколько я разобрался, функция FileGetInteger по неизвестной причине возвращает значение из кеша, который обновляется раз в минуту.

По этому, подряд несколько файлов за одну минуту создать не получается. :(

Как это вылечить?

//+------------------------------------------------------------------+

//| Script program start function                                    |

//+------------------------------------------------------------------+

void OnStart()

{

   CreateFile();

}

//+------------------------------------------------------------------+

//| Функция создания файла с уникальным именем                       |

//+------------------------------------------------------------------+

bool CreateFile()

{

   string WriteText = "Текст для записи в файл";

   string FileNameStart   = "robot_";

   // Обнулить лог ошибки

   ResetLastError();

   // Создать файл

   int OneFileHandle = FileOpen(FileNameStart, FILE_READ|FILE_WRITE|FILE_CSV);

   if(OneFileHandle != INVALID_HANDLE)

   {

      PrintFormat("Файл %s создан", FileNameStart);

      PrintFormat("Путь к файлу: %s\\MQL5\\Files\\", TerminalInfoString(TERMINAL_DATA_PATH));

      // Получить дату создания файла

      long CreateFileDate = FileGetInteger(OneFileHandle, FILE_CREATE_DATE);

      printf("CreateFileDate = " + (string)CreateFileDate);

      printf("CreateFileDate = " + (string)((datetime)CreateFileDate));

      // Закрыть файл

      FileClose(OneFileHandle);

      // Преобразовать дату в строку

      string FileDate = (string)((datetime)CreateFileDate);

      // Удалить лишние символы

      StringReplace(FileDate, " ", "");

      //printf("FileDate1 = " + FileDate);

      StringReplace(FileDate, ".", "");

      //printf("FileDate2 = " + FileDate);

      StringReplace(FileDate, ":", "");

      //printf("FileDate3 = " + FileDate);

      // Собрать уникальное имя файла

      string FileNameFinish = FileNameStart + FileDate + ".txt";

      // Переименовать файл

      if(FileMove(FileNameStart, 0, FileNameFinish, FILE_REWRITE))

      {

         PrintFormat("Файл %s переименован в %s", FileNameStart, FileNameFinish);

      }

      else

      {

         PrintFormat("Файл %s не удалось переименовать в %s", FileNameStart, FileNameFinish);

      }

      // Обнулить лог ошибки

      ResetLastError();

      // Открыть файл для записи

      int TwoFileHandle = FileOpen(FileNameFinish, FILE_READ|FILE_WRITE|FILE_CSV);

      if(TwoFileHandle != INVALID_HANDLE)

      {

         PrintFormat("Файл %s открыт для записи", FileNameFinish);

         // Записать в файл

         FileWrite(TwoFileHandle, WriteText);

         // Закрыть файл

         FileClose(TwoFileHandle);

         PrintFormat("Данные записаны, файл %s закрыт", FileNameFinish);

         return true;

      }

      else

      {

         PrintFormat("Не удалось открыть файл %s, Код ошибки = %d", FileNameFinish, GetLastError());

         return false;

      }

   }

   else

   {

      PrintFormat("Не удалось открыть файл %s, Код ошибки = %d", FileNameStart, GetLastError());

      return false;

   }

   return false;

}

Файлы:
 
Francuz:

Запилил. Работает но с какими-то непонятными мне глюками.

Насколько я разобрался, функция FileGetInteger по неизвестной причине возвращает значение из кеша, который обновляется раз в минуту.

По этому, подряд несколько файлов за одну минуту создать не получается. :(

Как это вылечить?

Вылечил создавая файл с рандомным временным названием.


//+------------------------------------------------------------------+

//| Script program start function                                    |

//+------------------------------------------------------------------+

void OnStart()

{

   CreateFile();

}


//+------------------------------------------------------------------+

//| Функция создания файла с уникальным именем                       |

//+------------------------------------------------------------------+

bool CreateFile()

{

   MathSrand(GetTickCount());

   int NomberA = 99999 - MathRand();

   int NomberB = 99999 - MathRand();

   string WriteText = "Текст для записи в файл";

   string FileName   = "robot_";

   string FileNameStart   = FileName + (string)NomberA + (string)NomberB + "_";


   // Обнулить лог ошибки

   ResetLastError();

   

   // Создать файл

   int OneFileHandle = FileOpen(FileNameStart, FILE_READ|FILE_WRITE|FILE_CSV);

   if(OneFileHandle != INVALID_HANDLE)

   {

      PrintFormat("Файл %s создан", FileNameStart);

      PrintFormat("Путь к файлу: %s\\MQL5\\Files\\", TerminalInfoString(TERMINAL_DATA_PATH));


      // Получить дату создания файла

      long CreateFileDate = FileGetInteger(OneFileHandle, FILE_CREATE_DATE);

      printf("CreateFileDate = " + (string)CreateFileDate);

      printf("CreateFileDate = " + (string)((datetime)CreateFileDate));

      

      // Закрыть файл

      FileClose(OneFileHandle);


      // Преобразовать дату в строку

      string FileDate = (string)((datetime)CreateFileDate);


      // Удалить лишние символы

      StringReplace(FileDate, " ", "");

      //printf("FileDate1 = " + FileDate);

      StringReplace(FileDate, ".", "");

      //printf("FileDate2 = " + FileDate);

      StringReplace(FileDate, ":", "");

      //printf("FileDate3 = " + FileDate);


      // Собрать уникальное имя файла

      string FileNameFinish = FileName + FileDate + ".txt";

      

      // Переименовать файл

      if(FileMove(FileNameStart, 0, FileNameFinish, FILE_REWRITE))

      {

         PrintFormat("Файл %s переименован в %s", FileNameStart, FileNameFinish);

      }

      else

      {

         PrintFormat("Файл %s не удалось переименовать в %s", FileNameStart, FileNameFinish);

      }

      

      // Обнулить лог ошибки

      ResetLastError();


      // Открыть файл для записи

      int TwoFileHandle = FileOpen(FileNameFinish, FILE_READ|FILE_WRITE|FILE_CSV);

      if(TwoFileHandle != INVALID_HANDLE)

      {

         PrintFormat("Файл %s открыт для записи", FileNameFinish);

      

         // Записать в файл

         FileWrite(TwoFileHandle, WriteText);


         // Закрыть файл

         FileClose(TwoFileHandle);

         PrintFormat("Данные записаны, файл %s закрыт", FileNameFinish);

         return true;

      }

      else

      {

         PrintFormat("Не удалось открыть файл %s, Код ошибки = %d", FileNameFinish, GetLastError());

         return false;

      }

   }

   else

   {

      PrintFormat("Не удалось открыть файл %s, Код ошибки = %d", FileNameStart, GetLastError());

      return false;

   }

   

   return false;

}

Файлы:
 
Francuz:

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

Алгоритм воспроизведения:

Запускаете эксперта на тестирование. Он не найдёт файла с именем FileName и тогда создаст его.

Запускаете эксперт на тестирование ещё раз. Он найдёт файл и ничего больше делать не будет.

Открываете код эксперта, делаете фиктивную правку, проводите компиляцию.

Запускаете эксперта на тестирование. Система удалит файл. Експерт не найдёт файла с именем FileName и тогда создаст его.


 Попробуйте свой алгоритм воспроизведения на этом поправленном варианте..

Файлы:
 
Nikolay Ivanov:


 Попробуйте свой алгоритм воспроизведения на этом поправленном варианте..


Спасибо. Я рад что наш небольшой спор привёл к взаимному повышению опыта.

Локальное файловое пространство эксперта после компиляции очищается (предполагаю в целях безопасности). Ваши правки предлагают использовать общее файловое пространство всех экспертов.