How to Get the Last ReadFile position before file update, in order to feed position FileSeek position after file update

 

i want to OPEN position after reading a file. the file isupdate on event by program not mql.
how to detec file change and get last position before update to continue for the next reading the file.

input int InpEncodingType=FILE_UNICODE; // ANSI=32 or UNICODE=64

int OnInit()
  {
   //---
   file_handle= FileOpen(InpDirectoryName+"//"+InpFileName1,FILE_READ|FILE_TXT|InpEncodingType);
   file_sizeA = FileSize(file_handle);
   file_seekA = FileSeek(file_handle,0,SEEK_END);
   file_tellA = FileTell(file_handle);
   FileClose(file_handle);
   Print(" file_size before update: ", file_sizeA);
}

the file is append 4 lines  in newseconds but the size is the same.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
   if(isNewSeconds(30)){
      file_handle=FileOpen(InpDirectoryName+"//"+InpFileName1,FILE_READ|FILE_TXT|InpEncodingType);
      file_sizeB=FileSize(file_handle);
      FileSeek(file_handle,file_seekB,SEEK_END);
      file_tellB = FileTell(file_handle);
      ulong deltaFileTell = 0;
      if(file_tellA != file_tellB && file_tellB!=0) {
         
         deltaFileTell = file_tellB-file_tellA; 
         Print(" file_tell updated: ", file_tellB, " deltaFileTell: ", deltaFileTell);
         //if(FileSeek(file_handle,startPosToRead_Byte,SEEK_SET)==true)
         if(FileSeek(file_handle,file_tellA,SEEK_SET)==true)
           {
         //--- read and print the string with ind number
            PrintFormat("String text with %d number: \"%s\"",file_tellA,FileReadString(file_handle));
           }
         //save posittion for next Reading;
         file_tellA = file_tellB;
         
      }
      
      
      if(file_sizeA != file_sizeB && file_sizeB!=0) {
         
         deltaFileSize = file_sizeB-file_sizeA; 
         startPosToRead_Byte = file_sizeB-deltaFileSize; // startReadingPOs
         Print(" file_size Updated: ", file_sizeB, " deltaFileSize: ", deltaFileSize);
         //if(FileSeek(file_handle,startPosToRead_Byte,SEEK_SET)==true)
         if(FileSeek(file_handle,file_sizeA,SEEK_SET)==true)
           {
         //--- read and print the string with ind number
            PrintFormat("String text with %d number: \"%s\"",startPosToRead_Byte,FileReadString(file_handle));
           }
         //save posittion for next Reading;
         file_sizeA= file_sizeB;
         
      }
      Print(" file_sizeB: ", file_sizeB);
      FileClose(file_handle);
   }
  }
//-----------------------------------------------------------------------------------------------------------------------------

so nothing inside the PrintFormat is executed, how to fix this?

 
the files is UTF-8  so maybe the right choose maybe FILE_UNICODE
input int InpEncodingType=FILE_UNICODE; // ANSI=32 or UNICODE=64
 
Ikan_Terbang #:
the files is UTF-8  so maybe the right choose maybe FILE_UNICODE
input int InpEncodingType=FILE_UNICODE; // ANSI=32 or UNICODE=64
UTF-8 needs to be open with ANSI and codepage=CP_UTF8.
 
Thanks it works now, but now it come the new problem. my EA is do reading and opening position more than once, sometimes it twice, in other day it open 3 times, and sometimes it just once. Not understand what the caused.

Event if i just Print(TimeCurrent()); // it print more than once, i've tried make changes to read every 10 seconds it still remain the same.
When i try to check the current time, it showing the same Time for 3 times.

How to fixed this error, so it just read the file for only once, after detecting the file changes. I have tried filter if with an ID to differ(to make sure EA read if the ID is different from last), but the problem still remain.
//+------------------------------------------------------------------+
//|                                               baca files txt.mq4 |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link      "https://wa.me/6285257250050"
#property version   "1.00"
#property strict
//--- display the window of input parameters when launching the script 
#property script_show_inputs 
//--- parameters for data reading 
extern string InpFileName="fileSignal.txt";    // file name
extern string InpFileName1="names.txt"; // file name
extern int checkEveryXsecond = 1;
extern int magicNumber = 1235114691;
string textGet[], signalName[];
int isSignalText=0,file_handle, size, dsize;
string _kodeId,_msgId, _optype, _symbol, _lastMsgId, mesg;
double _entry1,_entry2,_entry3,_SL,_TP1,_TP2,_TP3=0;
ulong pos[], file_sizeA = 0, file_sizeB = 0, deltaFileSize =0, startPosToRead_Byte =0, file_seekA=0, file_seekB=0, file_tellA=0,file_tellB=0, deltaFileTell=0; 
long file_getIntA=0, file_getIntB=0;
double TradeVolume=0.01;
input int InpEncodingType=FILE_ANSI; // ANSI=32 or UNICODE=64
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   //---
   //EventSetTimer(1);  // this is for 1 Seconds
   file_handle= FileOpen(InpFileName,FILE_COMMON|FILE_SHARE_READ|FILE_READ|FILE_TXT|InpEncodingType);
   if(file_handle!=INVALID_HANDLE) { 
      file_sizeA = FileSize(file_handle); 
      file_seekA = FileSeek(file_handle,0,SEEK_END);
      file_tellA = FileTell(file_handle);
      file_getIntA = FileGetInteger(file_handle, FILE_MODIFY_DATE); 
      FileClose(file_handle);
   }else Print("Operation FileOpen failed, error ",GetLastError());
   TradeVolume= getLotSize(TradeVolume);
   Print(" file_tell before Update: ", file_tellA);
      
 //---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }


//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//---
   ResetLastError();
   if(isNewSeconds(checkEveryXsecond)){
      file_handle=FileOpen(InpFileName,FILE_COMMON|FILE_SHARE_READ|FILE_READ|FILE_TXT|InpEncodingType);
      if(file_handle!=INVALID_HANDLE) {
         file_sizeB = FileSize(file_handle);
         file_getIntB = FileGetInteger(file_handle, FILE_MODIFY_DATE); 
         
         // Print(" file_tellA: ", file_tellA," file_tellB: ", file_tellB); 
         if(file_getIntA != file_getIntB && file_sizeA!=file_sizeB) {  // if file modified time is changed 
            deltaFileTell = file_getIntB-file_getIntA; 
            FileSeek(file_handle,0,SEEK_END);
            file_tellB = FileTell(file_handle);
            Print(" file_tellA: ", file_tellA," file_getIntA: ", (string)file_getIntA);
            Print(" file_tellB: ", file_tellB," file_getIntB: ", (string)file_getIntB);
            //Print(" file_tellA: ", file_tellA," file_tell updated: ", file_tellB," file_sizeB: ", file_sizeB, " deltaFileSeek: ", deltaFileTell);
            //if(FileSeek(file_handle,startPosToRead_Byte,SEEK_SET)==true)
            if(FileSeek(file_handle,file_tellA,SEEK_SET)==true) {

                 ////--- read and print the string with number
                 //string deStr = FileReadString(file_handle);
                 //PrintFormat("String text with %d number: \"%s\"",file_tellA,deStr);
                 //PrintFormat("new saved text, file_tellA %d : ",file_tellA);
                                 
                 // baca semua teks pesan signal
                 // str = FileReadString(file_handle);   // store line data to str
                 text_reader(file_handle,textGet);
                                                             
            }
         }
      }
      file_sizeA=file_sizeB;
      //--- close the file 
      FileClose(file_handle); 
      //PrintFormat("%s file is closed",InpFileName);
   }
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Get and Execute the signal                                       |
//+------------------------------------------------------------------+
//void text_reader(string str, string& output[])
void text_reader(int handle, string& output[])
{
    //int fileHandle = FileOpen(path,FILE_READ|FILE_TXT); // this line is ommited because already get from parent scope
    int optype=-1, i =0, arrSize = 1;
    ArrayResize(output,1);
    string str;
    string msgId, symbol, chName="", TP, entry, strSignalDate;
    datetime SignalDate;
    // signal related message
    // string str_msgId  = "ID: ";
    // string str_symbol = " - Symbol: ";
    // string str_type   = " - Type: ";
    // string str_entry  = " - Entry: ";
    // string str_SL     = " - Stoploss: ";
    // string str_TP     = " - Takeprofit: ";
    double entry1=0, entry2=0, entry3=0, SL=0, TP1=0, TP2=0, TP3=0;
    while( FileIsEnding(handle) == False)
    {
        // read all text signal
        str = FileReadString(handle);   // store line data to str
        ArrayResize(output,arrSize++);
        output[i] = str; // store data to output Array parameter
        int position=-1; // reset
        datetime currSigDate;

        // if from authorized sender
        if( StringFind(str,"Signal from")>=0 || StringFind(str,"Signal edited from ")>=0 ){
           strSignalDate = (StringSubstr(str,0,StringFind(str,"Signal from")-1));
           SignalDate = stringToTime(strSignalDate);
           Print("TimeCurrent: ",  TimeCurrent(), " jadi==> ", SignalDate);
           // === isSignalText==0  if found date reset counter to 0, // it reset at the end of signal message
           if( isSignalText==0){
              for(int j=ArraySize(signalName)-1;  j>=0; j--){
                 int posChannelName =  StringFind(str,signalName[j]);
                 if(posChannelName>=0){
                    chName = signalName[j];
                    isSignalText++; // if there is signal go to second if
                    //Print("isSignalText: ",isSignalText,"::", str);
                    if(isSignalText==1 && posChannelName>=0){
                       //Print("SignalDate2: ", SignalDate);
                       currSigDate = SignalDate;
                       //Print("currSigDate: ", currSigDate);
                       position = StringFind(str,"ID: ");  
                       msgId = StringSubstr(str,position+4,StringLen(str)-2); //-1 for ommit the last char which is space
                       //if(currSigDate!=""&& msgId!="") Print(" currSigDate: ", currSigDate," msgId: ", msgId);
                 
                       mesg = chName+" "+msgId+" ";
                       if(StringLen(mesg)>12){ 
                          int stringGet= 12-StringLen(" "+msgId+" ");
                          chName = StringSubstr(chName,0,stringGet);
                          mesg = chName+" "+msgId+" ";
                       }
                    }
                 }
              }
           }
        }
        
        if(_lastMsgId!=mesg){ // filter with ID
              if(isSignalText>=1)
              {
              // if found text with date straight into thi scope
              //Print("isSignalText: ",isSignalText,"::", str);
              
              if(isSignalText==2 && StringFind(str,"The signal is edited to")>-1){
                  continue;
               } else if(isSignalText==2 && StringFind(str," - Symbol: ")>-1){position = StringFind(str," - Symbol: "); symbol = StringSubstr(str,position+StringLen(" - Symbol: "),(StringLen(str)-1)-(position+StringLen(" - Symbol: ")));
              //Print("totalstring=", StringLen(str), " pos = ", position+(StringLen(" - Symbol: ")), " length= " ,(StringLen(str)-1)-(position+StringLen(" - Symbol: ")+1));
              } //include spacing
              if(isSignalText==3 ){
                 position = StringFind(str," - Type: ");
                 string strOptype = StringSubstr(str,position+StringLen(" - Type: "),StringLen(str));
                 optype = strOptype=="OP_BUY" ? OP_BUY : strOptype=="OP_SELL" ? OP_SELL : strOptype=="OP_BUYLIMIT" ? OP_BUYLIMIT : strOptype=="OP_SELLLIMIT" ? OP_SELLLIMIT : strOptype=="OP_BUYSTOP" ? OP_BUYSTOP : strOptype=="OP_SELLSTOP" ? OP_SELLSTOP:-1;
                 Print(" strOptype: _", strOptype,"_ optype: ", optype);
              }
              if(isSignalText==4 ){
                 position = StringFind(str," - Entry: "); 
                 StringReplace(str," - Entry: ","");
                 StringReplace(str," ","");
                 //Print(" str: ", str);
                 int pos2 = StringFind(str,"-",0);
                 string entry1str = StringSubstr(str,0,pos2);
                 string entry2str = StringSubstr(str,pos2+1,StringLen(str));
                 //Print(" entry1str: ", entry1str," entry2str: ", entry2str);
                 entry1 = entry1str=="0"?0:(double)DoubleToStr((double)entry1str,Digits);
                 entry2 = entry2str=="0"?0:(double)DoubleToStr((double)entry2str,Digits);
                 Print(" entry1str: ", entry1str," entry1: ", entry1," entry2str: ", entry2str," entry2: ", entry2);
              }
              if(isSignalText==5){position = (int)StringFind(str," - Stoploss: ");   
                 SL = StringSubstr(str,position+StringLen(" - Stoploss: ")-1,StringLen(str)-(position+StringLen(" - Stoploss: ")-1));
                 SL = str=="0"?0:(double)DoubleToStr((double)SL,Digits);
              }
              if(isSignalText==6){
                 string subText[];
                 string strTP1 = StringSubstr(str,StringLen(" - Takeprofit: "),StringLen(str));
                 StringReplace(strTP1," ","");
                 string sep="|";     // A separator as a character 
                 ushort u_sep=StringGetCharacter(sep,0);
                 StringSplit(strTP1,u_sep,subText);
                 Print(" strTP1: ", subText[0]," strTP2: ",subText[1]," strTP3: ",subText[2]," SL: ", SL);
                 TP1 = subText[0]=="0"?0:(double)DoubleToStr((double)subText[0],Digits); 
                 TP2 = subText[0]=="0"?0:(double)DoubleToStr((double)subText[1],Digits); 
                 TP3 = subText[0]=="0"?0:(double)DoubleToStr((double)subText[2],Digits);
                 
              }
              
              if(isSignalText>=6) {  // after all data is gathered
                 isSignalText=0; // reset counter for reread signal
                 string buyOrSell=""; double OP_price;
                 
                 int gap = SecondsDiff(TimeCurrent(),SignalDate);
                 Print(mesg,"#",chName,"#",msgId,"#",optype,"#",symbol," lot: ", TradeVolume," priceAt: ",buyOrSell,"#OP1:",(string)entry1,"#OP2:",(string)entry2,"#OP3:",(string)entry3,"#SL:",(string)SL,"#TP1:",(string)TP1,"#TP2:",(string)TP2,"#TP3:",(string)TP3);
                                  
                 if(gap<120 ){  // if gap time receive signal and current time not more than 120 minutes

                    OP_price = (optype==OP_BUY)?Ask:Bid;
                    // Do Enntry if signal is complete

                    if (optype>-1 && (entry1!=0 && entry2!=0) ){ //, entry3=0, SL=0, TP1=0, TP2=0, TP3=0;
                       // if order without TP2 SL                      
                          if(TP1>0){
                             int buyTicketOrder = OrderSend (Symbol(), optype, TradeVolume, OP_price, 0, 0, 0, mesg+"TP1", magicNumber, 0, CLR_NONE);
                             if(buyTicketOrder>-1 && (SL!=0 || TP!=0)) modifSLTP(buyTicketOrder,SL,TP1);
                          }
                          if(TP2>0){
                             int buyTicketOrder = OrderSend (Symbol(), optype, TradeVolume, OP_price, 0, 0, 0, mesg+"TP2", magicNumber, 0, CLR_NONE);
                             if(buyTicketOrder>-1 && (SL!=0 || TP!=0)) modifSLTP(buyTicketOrder,SL,TP2);
                          }
                          if(TP3>0){
                             int buyTicketOrder = OrderSend (Symbol(), optype, TradeVolume, OP_price, 0, 0, 0, mesg+"TP3", magicNumber, 0, CLR_NONE);
                             if(buyTicketOrder>-1 && (SL!=0 || TP!=0)) modifSLTP(buyTicketOrder,SL,TP3);
                          }
                    }
                 }
                 // reset variable
                 SignalDate=0; chName=""; msgId=""; optype=""; symbol=""; entry=""; entry1=0; entry2=0; entry3=0; SL=0; TP1=0; TP2=0; TP3=0;
                 
              _lastMsgId = mesg; // create ID for differ reading  
              //Print(" _lastMsgId: ", _lastMsgId , " mesg: ", mesg);
              }else{isSignalText++;}
              
           }
        } // end of 1 set signal found
        
        // if(FileIsEnding(fileHandle) == True)FileSeek(fileHandle,0,SEEK_END); // seek not here but by parent scope
        //Print("lines ",i,"=> ",str);
        i++;
    }
    if(FileIsEnding(file_handle) == True) {
      //save position for next Reading;
      file_tellA = file_tellB;
      file_getIntA = file_getIntB;
      //Print("This is the end of file reading with file_tellA: ", file_tellA);
    }
    //  FileClose(fileHandle); // close not here but by parent scope
}
//+------------------------------------------------------------------+
//|  New Seconds Function                                                    |
//+------------------------------------------------------------------+
bool isNewSeconds(int seconds)
  {
   static datetime timeOp = 0;
   datetime now=TimeCurrent();
   bool isNewSeconds = false;
   if(TimeCurrent()-jamOp>=seconds)
     {
      isNewSeconds = true;
      timeOp = now;
     }
   return (isNewSeconds);
  }
 
Ikan_Terbang #:
   if(TimeCurrent()-jamOp>=seconds)

This line looks like it could need investigation - I cannot see where you define or set  jamOp but it seems to be the most important factor in the function 

Debug that first and make sure it is behaving as expected

Also why do you use static in this case?
   static datetime timeOp = 0;
 
Ikan_Terbang #:
Thanks it works now, but now it come the new problem. my EA is do reading and opening position more than once, sometimes it twice, in other day it open 3 times, and sometimes it just once. Not understand what the caused.

Event if i just Print(TimeCurrent()); // it print more than once, i've tried make changes to read every 10 seconds it still remain the same.
When i try to check the current time, it showing the same Time for 3 times.

How to fixed this error, so it just read the file for only once, after detecting the file changes. I have tried filter if with an ID to differ(to make sure EA read if the ID is different from last), but the problem still remain.

mql4 is off-topic on this section of the forum.

And your last post is not related to your topic.

Use mql4 section please.

 
R4tna C #:

This line looks like it could need investigation - I cannot see where you define or set  jamOp but it seems to be the most important factor in the function 

Debug that first and make sure it is behaving as expected

Also why do you use static in this case?
Yes you're right, i forget to translate that jamOP to english, for asking question here. Yes my code in real is already use the same variable name with your code.

//+------------------------------------------------------------------+
//| Checking every X New Seconds                                            |
//+------------------------------------------------------------------+
bool isNewSeconds(int seconds)
  {
   static datetime timeOp = 0;
   datetime now=TimeCurrent();
   bool isNewSeconds = false;
   if(TimeCurrent()-timeOp>=seconds)
     {
      isNewSeconds = true;
      timeOp = now;
     }
   return (isNewSeconds);
  }
static is use to make sure that the next time i come into these scope code it will keep update with the last time value for comparing.
 
Alain Verleyen #:

mql4 is off-topic on this section of the forum.

And your last post is not related to your topic.

Use mql4 section please.

Sorry my bad, then i will place my question on the right section.
 
Ikan_Terbang #:
Yes you're right, i forget to translate that jamOP to english, for asking question here. Yes my code in real is already use the same variable name with your code.

static is use to make sure that the next time i come into these scope code it will keep update with the last time value for comparing.

I see what your intention is - I rarely use static variables, especially like this. 

Anyway, if I understand correctly, you need the process to execute once only and then wait for the specified number of secs. Somehow I feel your isNewSeconds() function over complicates this and could the the reason why you have an issue.

I usually do a delay function in a much simpler way - just have a variable called NextExecTime and an if condition (here is the (untested) pseudo code just to give you an idea)

if (TimeCurrent >= NextExecTime)  //This works even if NextExecTime  is 0 (if you have not initialized it)

{

        //perform the task

        NextExecTime = TimeCurrent() + secsDelay;

}



 
R4tna C #:

I see what your intention is - I rarely use static variables, especially like this. 

Anyway, if I understand correctly, you need the process to execute once only and then wait for the specified number of secs. Somehow I feel your isNewSeconds() function over complicates this and could the the reason why you have an issue.

I usually do a delay function in a much simpler way - just have a variable called NextExecTime and an if condition (here is the (untested) pseudo code just to give you an idea)

Thanks before, but your code for NewExecTime with delay not working.



I already make changes and Now its running, by add static variable outside the function
static bool isReading=false; 
and make it true when reading until finished'

if(file_getIntA != file_getIntB && file_sizeA!=file_sizeB && isreading==false) {  
   isReading=true;
}

// at the end of reading process has finished
isReading =false;
And now it running fine.
 
Ikan_Terbang #:
Thanks before, but your code for NewExecTime with delay not working.

I use this a lot so I am sure this method works - it depends how you implemented.

But if you have a working solution, that's good!