Вопрос по переносу данных файлом

Il'ya Matviyenko  

Товарищи подскажите пожалуйста. Балуюсь переносом данных из одного терминала в другой. В примере с приходом новой Н4 надо перенести из терминала 1 в терминал 2 баланс и эквити терминала 1 предидущей Н4 и текущей Н4 для последующего анализа изменения.

Максимум что получилось это перенос двумя файлами, каждый пишет свою свечу.

void OnTick() { 
   static datetime time_bar = 0;
   if(iTime(NULL,0,0) > time_bar) {
      
      time_bar = iTime(NULL,0,1);
      int file_handle2 = FileOpen("BALANCE2.csv",FILE_WRITE|FILE_SHARE_WRITE|FILE_READ|FILE_SHARE_READ|FILE_CSV|FILE_ANSI,";");
      if(file_handle2!=INVALID_HANDLE) {
        FileSeek(file_handle2,0,SEEK_SET);
        FileWrite(file_handle2,
          TimeToString(time_bar),
          DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE),2),
          DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY),2));
        FileFlush(file_handle2);
        FileClose(file_handle2); }
    
      time_bar = iTime(NULL,0,0); 
      int file_handle1 = FileOpen("BALANCE1.csv",FILE_WRITE|FILE_SHARE_WRITE|FILE_READ|FILE_SHARE_READ|FILE_CSV|FILE_ANSI,";");
      if(file_handle1!=INVALID_HANDLE) {
        FileSeek(file_handle1,0,SEEK_SET);
        FileWrite(file_handle1,
          TimeToString(time_bar),
          DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE),2),
          DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY),2));
      FileFlush(file_handle1);
      FileClose(file_handle1); } } }
_________________________________________________________________________
void OnTimer() { 

  static datetime time_bar = 0;
  if(iTime(NULL,0,0) > time_bar) {
    time_bar = iTime(NULL,0,0);
      
    int file_handle2 = FileOpen("BALANCE2.csv",FILE_WRITE|FILE_SHARE_WRITE|FILE_READ|FILE_SHARE_READ|FILE_CSV|FILE_ANSI,";");
    if(file_handle2!=INVALID_HANDLE) {
       FileSeek(file_handle2,0,SEEK_SET);
       while(true) {
         if(FileIsEnding(file_handle2)) break;
         datetime read_date2      = StringToTime(FileReadString(file_handle2));
                  read_balance2   = StringToDouble(FileReadString(file_handle2));
         double   read_equity2    = StringToDouble(FileReadString(file_handle2)); }
       PrevBal2=read_balance2;  Print("Баланс 2..",read_date1,read_balance1,read_equity1);
       FileClose(file_handle2); }

    int file_handle1 = FileOpen("BALANCE1.csv",FILE_WRITE|FILE_SHARE_WRITE|FILE_READ|FILE_SHARE_READ|FILE_CSV|FILE_ANSI,";");
    if(file_handle1!=INVALID_HANDLE) {
      FileSeek(file_handle1,0,SEEK_SET);
      while(true) {
        if(FileIsEnding(file_handle1)) break;
        datetime read_date1      = StringToTime(FileReadString(file_handle1));
                 read_balance1   = StringToDouble(FileReadString(file_handle1));
        double   read_equity1    = StringToDouble(FileReadString(file_handle1)); }
      PrevBal1=read_balance1;  Print("Баланс 1..",read_date1,read_balance1,read_equity1);
      FileClose(file_handle1); }

  if(PrevBal1>=PrevBal2) Reverse=false;
  if(PrevBal1<PrevBal2)  Reverse=true;

  Work(); }

Пробовал через массив но получается на первой строке все виснет т.к. непонятно как выявить общее количество заполненных строк. Есть индикатор работающий с массивом подобных данных но там все сделано на OnCalculate, в советнике не применишь.
Может есть у кого подобное решение чтобы через один файл по человечески. Спасибо

Renat Akhtyamov  

а если так?

 FileOpen("BALANCE2.csv",FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_CSV,";");
Il'ya Matviyenko  
Это пишет в один файл
   static datetime time_bar = 0;
   if(iTime(NULL,0,0) > time_bar) {
      
      time_bar = iTime(NULL,0,0);
      int file_handle = FileOpen("BALANCE.csv",FILE_WRITE|FILE_SHARE_WRITE|FILE_READ|FILE_SHARE_READ|FILE_CSV|FILE_ANSI,";");
      if(file_handle!=INVALID_HANDLE) {
        FileSeek(file_handle,0,SEEK_SET);
        FileWrite(file_handle,
          TimeToString(time_bar),
          DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE),0),
          DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY),0));
        FileFlush(file_handle);
        FileClose(file_handle); 


Это читает три последние значения

  if(iTime(NULL,0,0) > read_date0) {
    int file_handle = FileOpen("BALANCE.csv",FILE_WRITE|FILE_SHARE_WRITE|FILE_READ|FILE_SHARE_READ|FILE_CSV|FILE_ANSI,";");
    if(file_handle!=INVALID_HANDLE) {
      FileSeek(file_handle,0,SEEK_SET);
      while(true) {
        if(FileIsEnding(file_handle)) break;
        datetime read_date      = StringToTime(FileReadString  (file_handle));
        double   read_balance   = StringToDouble(FileReadString(file_handle));
        double   read_equity    = StringToDouble(FileReadString(file_handle));
        int found_bar = iBarShift(NULL,0,read_date,false);
          if(found_bar==0) { read_date0=read_date; read_balance0=read_balance; read_equity0=read_equity; Print("found_bar==0  /",found_bar,"/",read_date0,"/",read_balance0,"/",read_equity0); }
          if(found_bar==1) { read_date1=read_date; read_balance1=read_balance; read_equity1=read_equity; Print("found_bar==1  /",found_bar,"/",read_date1,"/",read_balance1,"/",read_equity1); }
          if(found_bar==2) { read_date2=read_date; read_balance2=read_balance; read_equity2=read_equity; Print("found_bar==2  /",found_bar,"/",read_date2,"/",read_balance2,"/",read_equity2); } }
        FileClose(file_handle); } }

вымучал

DrSky  
Il'ya Matviyenko #:
Это пишет в один файл


Это читает три последние значения

вымучал

При работе 2 процессов с 1 файлом нельзя использовать SHARED_READ и SHARED_WRITE. При большом количестве повторов регулярно будет возникать ситуация одновременной записи и чтения из файла. В данном случае, так как в mql5 не предусмотрены мьютексы через файл, в читающем процессе, нужно дожидаться закрытия файла на запись, после чего читать его. В записывающем процессе так же.

Maxim Kuznetsov  
Вадим Калашнков #:

При работе 2 процессов с 1 файлом нельзя использовать SHARED_READ и SHARED_WRITE. При большом количестве повторов регулярно будет возникать ситуация одновременной записи и чтения из файла. В данном случае, так как в mql5 не предусмотрены мьютексы через файл, в читающем процессе, нужно дожидаться закрытия файла на запись, после чего читать его. В записывающем процессе так же.

дополнение:

если надо синхронизовать работу двух советников в разных терминалах, то файлы это одно их худших решений.
Последнее время вполне заслуженно упоминается Redis - возьмите его, будет и быстрее и конфликтов меньше и логичнее всё. Он через память и там есть streams и pub/sub. 

у файлов единственный плюс - они всегда под рукой и не требуют DLL. 

Il'ya Matviyenko  
Maxim Kuznetsov #:

дополнение:

если надо синхронизовать работу двух советников в разных терминалах, то файлы это одно их худших решений.
Последнее время вполне заслуженно упоминается Redis - возьмите его, будет и быстрее и конфликтов меньше и логичнее всё. Он через память и там есть streams и pub/sub. 

у файлов единственный плюс - они всегда под рукой и не требуют DLL. 

Спасибо, попробую изучить что это

Denis Vasyutin  

Maxim Kuznetsov #:

то файлы это одно их худших решений.

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

А кто вас заставляет читать и писать из одного и того же файла? Вы ограничены в количестве файлов?

С файлами тоже надо уметь правильно работать.

Не но можно еще и с буфером обмена напрямую работать без редисов, но с длл.

Так что файлы самое простое и универсальное решение.

Причина обращения: