Deleting a line from txt file

 

Hi,


So I'm working on this simple script, that reads through a txt file, where each line is in the form of "AUDCAD. 0.9076 a", so the pair, price and a letter meaning (a)bove or (b)elow.

I want to use it as a price alert script.

I manage to read the file, get the pair, compare it with MarketInfo, and send an alert if price is above / beyond what is written.

Up till now all is good.

But my issue is that I would like to delete the line, if the alert is reached. So that when the next occurrence happens, it doesn't alert again.

So what's the simplest way to erase a complete line?

Here is the code that generates the alert:

while(!FileIsEnding(file_handle))
        {
         
         int pos1;
         str1="";str2="";str3="";

         str=FileReadString(file_handle);
         int currentString = 1;
         for(pos1=0;pos1<StringLen(str);pos1++)
            {            
            if(currentString==1)
               {
               if(StringGetChar(str,pos1)!=32)str1+=StringSubstr(str,pos1,1);
               else currentString=2;
               continue;
               }
            if(currentString==2)
               {
               if(StringGetChar(str,pos1)!=32)str2+=StringSubstr(str,pos1,1); //StringGetChar(str,pos1)!=32
               else currentString=3;
               continue;
               }
            else
               {
               if(StringGetChar(str,pos1)!=32)str3+=StringSubstr(str,pos1,1);
               }
                           
            }
        if(MarketInfo(str1,MODE_BID) > StringToDouble(str2) && str3 == "a")Alert("the price of: "+ str1 + " is above: " + str2);
        else if(MarketInfo(str1,MODE_BID) < StringToDouble(str2) && str3 == "b")Alert("the price of: " +str1 + " is below: " + str2);
        }
 

Well, just came across:

https://www.mql5.com/en/forum/151576

and William Roeder hints to a solution, by putting all strings (lines) into an array first, then manipulating the array, and then dumping the array into the file.

Seems nice.

MQL4 Replace line in CSV file
MQL4 Replace line in CSV file
  • 2014.05.16
  • www.mql5.com
So that can I save the important info to me from each trade, I made code to search for the ticket number (first column) while inside a for loop loo...
 

Ok, so I got my code to send an alert / email when the price is reached. 

It re-writes the file with the price levels that are still active (price not yet reached). So like I wanted, good.

Now, the only nuisance I have, is when I want to open the txt file while the EA is running, I can't open it because Windows says it's used by another process.

What I don't understand, is that I close the file after each loop (it loops once per candle).

Here's the code:

void OnTick()
  {
  if(thisTime!=Time[0])
      {
      ResetLastError();
      int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ,';');
      if(file_handle!=INVALID_HANDLE)
         {
         string str; //string per line read from file
         string str1, str2, str3; //serperate each element of line into 3
         while(!FileIsEnding(file_handle))
           {           
            int pos1;
            str1="";str2="";str3="";
   
            str=FileReadString(file_handle);
            int currentString = 1;
            for(pos1=0;pos1<StringLen(str);pos1++)
               {            
               if(currentString==1)
                  {
                  if(StringGetChar(str,pos1)!=32)str1+=StringSubstr(str,pos1,1);
                  else currentString=2;
                  continue;
                  }
               if(currentString==2)
                  {
                  if(StringGetChar(str,pos1)!=32)str2+=StringSubstr(str,pos1,1); //StringGetChar(str,pos1)!=32
                  else currentString=3;
                  continue;
                  }
               else
                  {
                  if(StringGetChar(str,pos1)!=32)str3+=StringSubstr(str,pos1,1);
                  }
                              
               }
           if(MarketInfo(str1,MODE_BID) > StringToDouble(str2) && str3 == "a")mail(str2,str1,str3);
           else if(MarketInfo(str1,MODE_BID) < StringToDouble(str2) && str3 == "b")mail(str2,str1,str3);
           else //if no alerts, add to array the price level
               {
               int oldsize=ArraySize(myArray);
               ArrayResize(myArray,ArraySize(myArray)+StringLen(str));               
               myArray[oldsize]=str;
               }
           }         
         FileClose(file_handle);
         file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_WRITE,';'); //opens & empties the file
         for(int i=0;i<ArraySize(myArray);i++)
            {//from the array of price levels not met, re-write the file
            FileSeek(file_handle, 0, SEEK_END);
            FileWrite(file_handle,myArray[i]);
            }
         FileClose(file_handle); //well this should close the file enabling me to open it until next candle??
         }
      else PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
         
      thisTime=Time[0];
      }
  
   
  }

Am I missing something, because the "FileClose" at the end should enable me to open it, even if the EA is running, until the next candle comes.

 
  1. Barraka:Am I missing something, because the "FileClose" at the end should enable me to open it, even if the EA is running, until the next candle comes.

    You are missing something somewhere because the file is not closed. Try restarting the terminal.

  2.                int oldsize=ArraySize(myArray);
                   ArrayResize(myArray,ArraySize(myArray)+StringLen(str));               
                   myArray[oldsize]=str;
    MyArray is an array of strings; first in [0], next in [1], etc. To store a new string you increase its size by one and store it. Why are you increasing it by the string length?
 
William Roeder:
  1. You are missing something somewhere because the file is not closed. Try restarting the terminal.

  2. MyArray is an array of strings; first in [0], next in [1], etc. To store a new string you increase its size by one and store it. Why are you increasing it by the string length?

You were right, I can now access the file. Actually I've changed the code from an EA to an indicator, it makes more sense like that.

And now I understand why I'm getting all those empty lines, after running it a few times the text file had like 50 empty lines between each pair, and I was just working out why it was. 

I thought if the string was say "AUDJPY", I had to increase it by 6, but now I get it.

Thanks,

 
Barraka:

Ok, so I got my code to send an alert / email when the price is reached. 

It re-writes the file with the price levels that are still active (price not yet reached). So like I wanted, good.

Now, the only nuisance I have, is when I want to open the txt file while the EA is running, I can't open it because Windows says it's used by another process.

What I don't understand, is that I close the file after each loop (it loops once per candle).

Here's the code:

Am I missing something, because the "FileClose" at the end should enable me to open it, even if the EA is running, until the next candle comes.

Oh and one last thing, I also added the re-initialisation of myArray, because it was piling up on the existing alerts, by adding ArrayResize(myArray,0). So overall the working code looks like this:

if(thisTime!=Time[0])
      {
      Comment("Price Alerts running...");
      ResetLastError();
      int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ,';');
      if(file_handle!=INVALID_HANDLE)
         {
         string str; //string per line read from file
         string str1, str2, str3; //serperate each element of line into 3
         while(!FileIsEnding(file_handle))
           {           
            int pos1;
            str1="";str2="";str3="";
   
            str=FileReadString(file_handle);
            int currentString = 1;
            for(pos1=0;pos1<StringLen(str);pos1++)
               {            
               if(currentString==1)
                  {
                  if(StringGetChar(str,pos1)!=32)str1+=StringSubstr(str,pos1,1);
                  else currentString=2;
                  continue;
                  }
               if(currentString==2)
                  {
                  if(StringGetChar(str,pos1)!=32)str2+=StringSubstr(str,pos1,1);
                  else currentString=3;
                  continue;
                  }
               else
                  {
                  if(StringGetChar(str,pos1)!=32)str3+=StringSubstr(str,pos1,1);
                  }
                              
               }
           if(MarketInfo(str1,MODE_BID) > StringToDouble(str2) && str3 == "a")mail(str2,str1,str3);
           else if(MarketInfo(str1,MODE_BID) < StringToDouble(str2) && str3 == "b")mail(str2,str1,str3);
           else //if no alerts, add to array the price level
               {
               int oldsize=ArraySize(myArray);
               ArrayResize(myArray,oldsize+1);                 
               myArray[oldsize]=str;
               }
           }         
         FileClose(file_handle);
         file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_WRITE,';'); //opens & empties the file
         for(int i=0;i<ArraySize(myArray);i++)
            {//from the array of price levels not met, re-write the file            
            FileSeek(file_handle, 0, SEEK_END);
            FileWrite(file_handle,myArray[i]);
            }
         FileClose(file_handle);
         ArrayResize(myArray,0);
         }
      else PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
         
      thisTime=Time[0];
      }

Thanks,