Problem with File functions

 

Hi,

I'm currently trying to use file functions, with csv files, I create 3 files in the init function and write something, it works, but when I try to write something else later, files aren't modified ..

Here is my code:

int init()
  {
//----
    touched = FileOpen("bollinger_touched.csv", FILE_CSV|FILE_WRITE,';');
    FileWrite(touched, "#", "Open", "Close", "High", "Low", "Date", "Order", "Profit");
    FileClose(touched);  
    
    depassement = FileOpen("bollinger_depassement.csv", FILE_CSV|FILE_WRITE,';');
    FileWrite(depassement, "#", "Open", "Close", "High", "Low", "Date", "Order", "Profit");
    FileClose(depassement); 
    
    reverse = FileOpen("bollinger_reverse.csv", FILE_CSV|FILE_WRITE,';');
    FileWrite(reverse, "#", "Open", "Close", "High", "Low", "Date", "Order", "Profit");
    FileClose(reverse);  

//----
   return(0);
   
  }

It works, but when the function below is called, nothing happen, there is no error in the journal, instructions inside the conditions are executed (verified with print):

void report(){
    if(ticket > 0 && OrderSelect(ticket, SELECT_BY_TICKET)){
        string comment = OrderComment();
        if(comment == "DEPASSEMENT_UPPER" || comment == "DEPASSEMENT_LOWER" || comment == "DEPASSEMENT_MIDDLE_BULLISH" || comment == "DEPASSEMENT_MIDDLE_BEARISH"){
            
            depassement = FileOpen("bollinger_depassement.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
            FileSeek(depassement, 0, SEEK_END);
            FileWrite(depassement, cpt_depassement, iOpen(NULL, 0, 1), iClose(NULL, 0, 1), iHigh(NULL, 0, 1), iLow(NULL, 0, 1), TimeToStr(iTime(NULL, 0, 1), TIME_DATE|TIME_MINUTES), OrderType());
            FileClose(depassement);  
            cpt_depassement++;
        }
        else if(comment == "BEARISH_REVERSE" || comment == "BULLISH_REVERSE"){
            reverse = FileOpen("bollinger_reverse.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
            FileSeek(reverse, 0, SEEK_END);
            FileWrite(reverse, cpt_reverse, iOpen(NULL, 0, 1), iClose(NULL, 0, 1), iHigh(NULL, 0, 1), iLow(NULL, 0, 1), TimeToStr(iTime(NULL, 0, 1), TIME_DATE|TIME_MINUTES), OrderType());
            FileClose(reverse);  
            cpt_reverse++;
        }
        else if(comment == "UPPER_TOUCHED" || comment == "LOWER_TOUCHED"){
            Print("Touched");
            touched = FileOpen("bollinger_touched.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
            FileSeek(touched, 0, SEEK_END);
            FileWrite(touched, cpt_touched, iOpen(NULL, 0, 1), iClose(NULL, 0, 1), iHigh(NULL, 0, 1), iLow(NULL, 0, 1), TimeToStr(iTime(NULL, 0, 1), TIME_DATE|TIME_MINUTES), OrderType());
            FileClose(touched);  
            cpt_touched++;
        }
        
        ticket = 0;
    }
}
 

try this perhaps ...

//FileSeek(touched, 0, SEEK_END);

... on all FileSeek() ...

like in Init() ?

There's no need to use FileSeek(). Look for explanation of FileOpen() function in MetaEditor. It said " ... If there is a need to add data to an existing file, it must be opened using combination of FILE_READ | FILE_WRITE. ...".

If you must using FileSeek(), check if it's return true or false before continue. :)

 
Arkenis:

Hi,

I'm currently trying to use file functions, with csv files, I create 3 files in the init function and write something, it works, but when I try to write something else later, files aren't modified ..

Here is my code:

It works, but when the function below is called, nothing happen, there is no error in the journal, instructions inside the conditions are executed (verified with print):

You should check the file handles are not -1 before using them.
 

Thanks for answers,

@onewithzachy: I don't use FileSeek in init because I just want to initialize all my files, but in report function, I want to add data at the end of each file, so I checked if it FileSeek returned true or false, and it seems to return true :/

@dabbler: Checked in report functions, it's always set to 1

added print:

void report(){
    if(ticket > 0 && OrderSelect(ticket, SELECT_BY_TICKET)){
        string comment = OrderComment();
        Print(depassement + " " + reverse + " " + touched);
        if(comment == "DEPASSEMENT_UPPER" || comment == "DEPASSEMENT_LOWER" || comment == "DEPASSEMENT_MIDDLE_BULLISH" || comment == "DEPASSEMENT_MIDDLE_BEARISH"){
            
            depassement = FileOpen("bollinger_depassement.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
            Print("depassement = " + depassement);
            if(FileSeek(depassement, 0, SEEK_END)){
                Print("OK");
                FileWrite(depassement, cpt_depassement, iOpen(NULL, 0, 1), iClose(NULL, 0, 1), iHigh(NULL, 0, 1), iLow(NULL, 0, 1), TimeToStr(iTime(NULL, 0, 1), TIME_DATE|TIME_MINUTES), OrderType());
                FileClose(depassement);  
                cpt_depassement++;
            }
        }
        else if(comment == "BEARISH_REVERSE" || comment == "BULLISH_REVERSE"){
            Print("reverse = " + reverse);
            reverse = FileOpen("bollinger_reverse.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
            if(FileSeek(reverse, 0, SEEK_END)){
                Print("OK");
                FileWrite(reverse, cpt_reverse, iOpen(NULL, 0, 1), iClose(NULL, 0, 1), iHigh(NULL, 0, 1), iLow(NULL, 0, 1), TimeToStr(iTime(NULL, 0, 1), TIME_DATE|TIME_MINUTES), OrderType());
                FileClose(reverse);  
                cpt_reverse++;
            }
        }
        else if(comment == "UPPER_TOUCHED" || comment == "LOWER_TOUCHED"){
            Print("touched = " + touched);
            touched = FileOpen("bollinger_touched.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
            if(FileSeek(touched, 0, SEEK_END)){
                Print("OK");
                FileWrite(touched, cpt_touched, iOpen(NULL, 0, 1), iClose(NULL, 0, 1), iHigh(NULL, 0, 1), iLow(NULL, 0, 1), TimeToStr(iTime(NULL, 0, 1), TIME_DATE|TIME_MINUTES), OrderType());
                FileClose(touched);  
                cpt_touched++;
            }
        }
        
        ticket = 0;
    }
}

 

No, what I meant was, you don't need to use the file seek. Just write the code like the one in init. But, come to think of it, it is good idea to use file seek since you write a lots of data.

And use doubletostr() conversion function. I should looked at your codes closely but I was busy reading other and answering post as well :). Hope you don't mind

touched = FileOpen("bollinger_touched.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
if (touched > 0)
  {
  if (FileSeek  (touched, 0 , SEEK_END) == True)
     {
     int written = FileWrite(touched, 
                          DoubleToStr (cpt_touched, 0), 
                          DoubleToStr (iOpen (NULL, 0, 1), Digits), 
                          DoubleToStr (iClose(NULL, 0, 1), Digits), 
                          DoubleToStr (iHigh (NULL, 0, 1), Digits),
                          DoubleToStr (iLow  (NULL, 0, 1), Digits),
                          TimeToStr   (iTime (NULL, 0, 1), TIME_DATE|TIME_MINUTES), 
                          DoubleToStr (OrderType(), 0);
     }
  FileClose(touched);
  Print ("Writing touched number "+cpt_touched+". Number of written character is "+written) ; // written will return negative if there's error
  
  cpt_touched++;
  }

BTW you can change :

iOpen(NULL, 0, 1)

... into this ...

iOpen(Symbol(), Period(), 1)

... or simply this ...This one is better especially on weekend ...

Open[1]

all of it will return open price of attached chart.

 
Arkenis:

@dabbler: Checked in report functions, it's always set to 1


What I meant was that as a matter of principle in your code you should always be checking the file handle before using it. It's just a routine thing to do.
 

You are obviously doing something stupid with the stuff other than what you have shown (unless it is that bizarre ticket=0 at the end of the function) I wrote a test harness for it and mine runs fine.

int touched=-1;
int depassement=-1;
int reverse=-1;
int ticket= -1;

int cpt_depassement=0;
int cpt_reverse=0;
int cpt_touched=0;

//------------------------------------------------------------------------------------------------+
int init(){

    touched = FileOpen("bollinger_touched.csv", FILE_CSV|FILE_WRITE,';');
    if( touched > -1 ){
      FileWrite(touched, "#", "Open", "Close", "High", "Low", "Date", "Order", "Profit");
      FileClose(touched);
    }  
    
    depassement = FileOpen("bollinger_depassement.csv", FILE_CSV|FILE_WRITE,';');
    if( depassement>-1){
      FileWrite(depassement, "#", "Open", "Close", "High", "Low", "Date", "Order", "Profit");
      FileClose(depassement);
    } 
    
    reverse = FileOpen("bollinger_reverse.csv", FILE_CSV|FILE_WRITE,';');
    if( reverse>-1 ){
      FileWrite(reverse, "#", "Open", "Close", "High", "Low", "Date", "Order", "Profit");
      FileClose(reverse);  
    }

   return(0);
}
//------------------------------------------------------------------------------------------------+
int start(){
   datetime oldBar=0;
   
   if( oldBar== Time[0] )
      return(0);
   
   oldBar= Time[0];
   
   if( OrdersTotal()==0 )
      ticket= OrderSend( Symbol(),OP_BUY,0.1,Ask,10,0,0,"DEPASSEMENT_UPPER" );
      
   cpt_depassement += 1;
   cpt_reverse += 3;
   cpt_touched += 7;

   report();
}
//------------------------------------------------------------------------------------------------+
void report(){
   if( ticket < 0 ){
      Print("No valid ticket");
      return;
   }
   
   if( !OrderSelect(ticket, SELECT_BY_TICKET) ){
      Print("Failed to select ticket");
      return;
   }
   
   string comment = OrderComment();
   Print(depassement + " " + reverse + " " + touched);
   if(comment == "DEPASSEMENT_UPPER" || comment == "DEPASSEMENT_LOWER" || comment == "DEPASSEMENT_MIDDLE_BULLISH" || comment == "DEPASSEMENT_MIDDLE_BEARISH"){
      Print("depassement = " + depassement);
      depassement = FileOpen("bollinger_depassement.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
      if( depassement>-1 ){
         if(FileSeek(depassement, 0, SEEK_END)){
             Print("OK");
             FileWrite(depassement, cpt_depassement, iOpen(NULL, 0, 1), iClose(NULL, 0, 1), iHigh(NULL, 0, 1), iLow(NULL, 0, 1), TimeToStr(iTime(NULL, 0, 1), TIME_DATE|TIME_MINUTES), OrderType());
             FileClose(depassement);  
             cpt_depassement++;
         }
      }
   }
   else if(comment == "BEARISH_REVERSE" || comment == "BULLISH_REVERSE"){
      Print("reverse = " + reverse);
      reverse = FileOpen("bollinger_reverse.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
      if( reverse > -1 ){
         if(FileSeek(reverse, 0, SEEK_END)){
             Print("OK");
             FileWrite(reverse, cpt_reverse, iOpen(NULL, 0, 1), iClose(NULL, 0, 1), iHigh(NULL, 0, 1), iLow(NULL, 0, 1), TimeToStr(iTime(NULL, 0, 1), TIME_DATE|TIME_MINUTES), OrderType());
             FileClose(reverse);  
             cpt_reverse++;
         }
      }
   }
   else if(comment == "UPPER_TOUCHED" || comment == "LOWER_TOUCHED"){
      Print("touched = " + touched);
      touched = FileOpen("bollinger_touched.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
      if( touched > -1 ){
         if(FileSeek(touched, 0, SEEK_END)){
             Print("OK");
             FileWrite(touched, cpt_touched, iOpen(NULL, 0, 1), iClose(NULL, 0, 1), iHigh(NULL, 0, 1), iLow(NULL, 0, 1), TimeToStr(iTime(NULL, 0, 1), TIME_DATE|TIME_MINUTES), OrderType());
             FileClose(touched);  
             cpt_touched++;
         }
      }
   }

   //WTF?
   //ticket = 0;
}

Note how I return from the report function rather than do complicated tests. It makes the code easier to debug and reduces the indentation level.

 

Thanks for advices :)

I thought it wasn't necessary to use doubletostr because it was converted automatically by FileWrite, but I added it anyway. About Open[1], won't it changes it's value when there is a new tick ? I just need to get new values when there is a new bar..

I also updated my code to get less complicated tests, in addition, is there a way to re-indent automatically a portion of code ?

I wrote ticket = 0; at the end of report function because if i do not, ticket keeps its value while there aren't new order or close order so that it will always pass the test and write too much data (I just want to write data when I send an Order),

also, i get message like this in the journal: Writing touched number 17. Number of written character is 54 - but my files are still empty (there are just data written in init function)

bollinger and mode functions don't call File functions and use ticket declared as global variable to send orders

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
bool newBar;
int start()
  {
    static string Time0;
    newBar = TimeToStr(iTime(NULL, 0,0), TIME_DATE|TIME_SECONDS) != Time0;
    if (newBar){
        Time0 = TimeToStr(iTime("EURUSD",PERIOD_H4,0), TIME_DATE|TIME_SECONDS);
         
        mode();
        bollinger();
        
        report();
    }
    
    

    return(0);
  }
//+------------------------------------------------------------------+

void report(){
    int written;
    if( ticket < 0 ){
       Print("No valid ticket");
       return;
    }
   
    if( !OrderSelect(ticket, SELECT_BY_TICKET) ){
        Print("Failed to select ticket");
        return;
    }
    
        string comment = OrderComment();
        Print(depassement + " " + reverse + " " + touched);
        if(comment == "DEPASSEMENT_UPPER" || comment == "DEPASSEMENT_LOWER" || comment == "DEPASSEMENT_MIDDLE_BULLISH" || comment == "DEPASSEMENT_MIDDLE_BEARISH"){
            
            depassement = FileOpen("bollinger_depassement.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
            if (depassement > 0)
            {
                if (FileSeek(depassement, 0, SEEK_END) == True)
                {
                    written = FileWrite(depassement, 
                          DoubleToStr (cpt_depassement, 0), 
                          DoubleToStr (iOpen (NULL, 0, 1), Digits), 
                          DoubleToStr (iClose(NULL, 0, 1), Digits), 
                          DoubleToStr (iHigh (NULL, 0, 1), Digits),
                          DoubleToStr (iLow  (NULL, 0, 1), Digits),
                          TimeToStr   (iTime (NULL, 0, 1), TIME_DATE|TIME_MINUTES), 
                          DoubleToStr (OrderType(), 0));
                }
                FileClose(depassement);
                Print ("Writing touched number "+cpt_depassement+". Number of written character is "+written) ; // written will return negative if there's error
                
                cpt_depassement++;
            }
        }
        else if(comment == "BEARISH_REVERSE" || comment == "BULLISH_REVERSE"){
            Print("reverse = " + reverse);
            reverse = FileOpen("bollinger_reverse.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
            if (reverse > 0)
            {
                if (FileSeek(reverse, 0, SEEK_END) == True)
                {
                    written = FileWrite(reverse, 
                          DoubleToStr (cpt_reverse, 0), 
                          DoubleToStr (iOpen (NULL, 0, 1), Digits), 
                          DoubleToStr (iClose(NULL, 0, 1), Digits), 
                          DoubleToStr (iHigh (NULL, 0, 1), Digits),
                          DoubleToStr (iLow  (NULL, 0, 1), Digits),
                          TimeToStr   (iTime (NULL, 0, 1), TIME_DATE|TIME_MINUTES), 
                          DoubleToStr (OrderType(), 0));
                }
                FileClose(reverse);
                Print ("Writing touched number "+cpt_reverse+". Number of written character is "+written) ; // written will return negative if there's error
                
                cpt_reverse++;
            }
        }
        else if(comment == "UPPER_TOUCHED" || comment == "LOWER_TOUCHED"){
            touched = FileOpen("bollinger_touched.csv", FILE_CSV|FILE_READ|FILE_WRITE,';');
            if (touched > 0)
            {
                if (FileSeek(touched, 0, SEEK_END) == True)
                {
                        written = FileWrite(touched, 
                          DoubleToStr (cpt_touched, 0), 
                          DoubleToStr (iOpen (NULL, 0, 1), Digits), 
                          DoubleToStr (iClose(NULL, 0, 1), Digits), 
                          DoubleToStr (iHigh (NULL, 0, 1), Digits),
                          DoubleToStr (iLow  (NULL, 0, 1), Digits),
                          TimeToStr   (iTime (NULL, 0, 1), TIME_DATE|TIME_MINUTES), 
                          DoubleToStr (OrderType(), 0));
                }
                FileClose(touched);
                Print ("Writing touched number "+cpt_touched+". Number of written character is "+written) ; // written will return negative if there's error
  
                cpt_touched++;
            }
        }
        
        ticket = 0;
    
}
 
Arkenis:

Thanks for advices :)

About Open[1], won't it changes it's value when there is a new tick ? (reply : NoI

You're welcome :)

No. Open[1] will never change its value when there's a new tick, and also Close [1], High [1], Low [1], Time [1], Volume [1].

The only thing that change it's value when there's a new tick is, Close [0], Open [0], High [0], Low [0], Time [0], Volume [0].

also, i get message like this in the journal: Writing touched number 17. Number of written character is 54 - but my files are still empty (there are just data written in init function)

Really ?. I'm officially lost like you :).

Right bact at ya later. Let me have the weekend.

 

@dabbler: I just tested the code you used to verify if it worked, and I have the same result, the problem could be elsewhere ? It seems that once I've created my files, I can't modify them anymore

If I delete it manually, it is recreated automatically when I execute the EA, but then if I modify the parameters of FileWrite in init function, nothing change, and the last modification of each file doesn't change either..

It's like if I could create file but not modify it later, checked their rights properties, and I should be able to modify it, the file folders is in read-only mode, I don't know if the problem could be here ..

Any idea ?

 
Arkenis:

also, i get message like this in the journal: Writing touched number 17. Number of written character is 54 - but my files are still empty (there are just data written in init function)

Well that sort of message says you have a system file problem. I assume that if you run my known working code on your system it also doesn't work (if you haven't done that test then I suggest you do so).

In this case you are probably running Windows 7 and have installed MT4 in the wrong place. I have seen loads of posts on this (but I run XP so I don't read them :-)

Reason: