FileWrite() flexibilisieren, sodass array in eine Reihe geschrieben wird

Einloggen oder registrieren, um einen Kommentar zu schreiben
Bayne
1010
Bayne  

Ist das möglich?


Habe ein Array "inputrows[]" dieses bekommt inputdaten für ein Neuronales Netz.

Die Anzahl dieser größe soll dabei möglichst flexibel sein und von den Inputs abhängen (ist soweit alles erledigt, jeder zusätzliche input resize't das Array um +1, agefangen bei 0)


Wie lässt sich das unbestimmtgroße Array inputrows[] nun in eine CSV Zeile schreiben? Loops erstellen ja leider automatisch eine neue zeile...

Carl Schreiber
Moderator
9813
Carl Schreiber  
Ist das möglich?

Klar!

Wie lässt sich das unbestimmtgroße Array inputrows[] nun in eine CSV Zeile schreiben? Loops erstellen ja leider automatisch eine neue zeile...


Nimm einen Temp-Zeilen-String, schreib alle Daten getrennt durch ';' hinein, am Ende fügst Du noch ein '\r\n' hinzu und dann schreibst Du das in eine Datei, die zum Schreiben mit der Option FILE_WRITE|FILE_BIN geöffnet wurde.

Bayne
1010
Bayne  
Carl Schreiber:

Klar!

Nimm einen Temp-Zeilen-String, schreib alle Daten getrennt durch ';' hinein, am Ende fügst Du noch ein '\r\n' hinzu und dann schreibst Du das in eine Datei, die zum Schreiben mit der Option FILE_WRITE|FILE_BIN geöffnet wurde.

den letzten teil mit der FileBIN verstehe ich nicht ganz (die Dokumentation über FileWriteArray hellt mich auch nicht ganz auf)

Chris70
543
Chris70  

Ja, ich kann mich noch gut erinnern, dass die Dateioperationen etwas verwirrend sein können. Vielleicht hilft das daher ja auch noch anderen hier.

FILE_BIN meint eine binäre Datei, die den Nachteil hat, dass sie nicht mit einem normalen Texteditor ausgelesen werden kann und nicht z.B. in Excel importiert werden kann. Der große Vorteil ist dafür, dass Du Dir keine Gedanken um die Formatierung oder irgendwelche Trennzeichen machen musst und diese Variante viel flexibler im Umgang mit verschiedenen Variablentypen ist. Da muss dann also nicht hin und zurück in String bzw. aus Strings konvertiert werden.

Man schreibt die Variablen einfach in die Datei und liest sie in gleicher Reihenfolge genauso heraus.

Ein Beispiel sagt mehr als tausend Worte (das hier wäre beispielhaft der Code, mit dem ich für versch. EA-MagicIDs separat vom Gesamtkonto Bilanz führe und auch vom Programm aus andere Größen wie Netto-Balance nach Komissionen+Swap, Profitfaktor und Kelly-Fraction live mitrechnen lasse):

//+------------------------------------------------------------------+
//| save trade result stats                                          |
//+------------------------------------------------------------------+
void CAccount::savestats(string filename)
  {
   int filehandle=FileOpen(filename+".bin",FILE_WRITE|FILE_BIN|FILE_COMMON);
   if (filehandle==INVALID_HANDLE){Print("invalid file handle! unable to save trade statistics!");}
   else
     {
      FileSeek(filehandle,0,SEEK_SET);
      FileWriteDouble(filehandle,maxbalance);
      FileWriteDouble(filehandle,maxequity);
      FileWriteDouble(filehandle,maxdrawdown);
      FileWriteDouble(filehandle,winners);
      FileWriteDouble(filehandle,losers);
      FileWriteDouble(filehandle,loss_total);
      FileWriteDouble(filehandle,profit_total);
      FileWriteDouble(filehandle,total_fees);
      FileWriteDouble(filehandle,total_swap);
      FileWriteInteger(filehandle,total_trades,4);
      FileWriteDouble(filehandle,total_lots_traded);
      FileWriteDouble(filehandle,biggestwinner);
      FileWriteDouble(filehandle,biggestloser);
      FileWriteInteger(filehandle,maxconsecwinners,4);
      FileWriteInteger(filehandle,maxconseclosers,4);
      FileFlush(filehandle);
      FileClose(filehandle);
     }
  }

//+------------------------------------------------------------------+
//| load trade result stats                                          |
//+------------------------------------------------------------------+
void CAccount::loadstats(string filename)
  {
   if (FileIsExist(filename+".bin",FILE_COMMON))
     {
      Print("reading previous trading statistics from file (",filename,".bin)");
      int filehandle=FileOpen(filename+".bin",FILE_READ|FILE_BIN|FILE_COMMON);
      if (filehandle==INVALID_HANDLE){Print("invalid file handle!");TesterStop();ExpertRemove();}
      FileSeek(filehandle,0,SEEK_SET);
      maxbalance=FileReadDouble(filehandle);
      maxequity=FileReadDouble(filehandle);
      maxdrawdown=FileReadDouble(filehandle);
      winners=FileReadDouble(filehandle);
      losers=FileReadDouble(filehandle);
      loss_total=FileReadDouble(filehandle);
      profit_total=FileReadDouble(filehandle);
      total_fees=FileReadDouble(filehandle);
      total_swap=FileReadDouble(filehandle);
      total_trades=FileReadInteger(filehandle,4);
      total_lots_traded=FileReadDouble(filehandle);
      biggestwinner=FileReadDouble(filehandle);
      biggestloser=FileReadDouble(filehandle);
      maxconsecwinners=FileReadInteger(filehandle,4);
      maxconseclosers=FileReadInteger(filehandle,4);
      FileClose(filehandle);
     }
   else
     {
      Print("failed to read trading statistics; file ",filename,".bin not found");
     }
  }

Anmerkung: Mit FileSeek und dem Operator SEEK_SET hat man die Möglichkeit, den Pointer an den Anfang der Datei zu setzen und demzufolge das Lesen/Schreiben dort zu starten. Wenn andere Positionen gewünscht sind, muss man die Bytes bis zu dieser Position zählen. Das FileSeek in diesem Beispiel ist strenggenommen redundant, denn bei einer frisch geöffneten Datei sollte der Pointer eh am Anfang sein. Auch das FileFlush ist etwas redundant, sollte aber in jedem Fall zwischen Schreib- und Lesevorgängen 1x erfolgen. Mit FileClose erübrigt sich das FileFlush strenggenommen und ist hier also nicht obligat.

CSV und TXT sind meist der viel größere Krampf und nur sinnvoll, wenn man die Daten extern weiterverarbeiten will oder mit menschlichem Auge verstehen muss (wie z.B. irgendwelche Error_logs).

amando
2880
amando  

relativ einfach, du darst die Zeile nicht immer übergeben, alles in einer zeile darf nicht mit ";" getrennt sein im code


   string InpFileNameDeals="Order History"+"//"+"Deals"+".csv";

   if(FileGetInteger(InpFileNameDeals,FILE_EXISTS))
      FileDelete(InpFileNameDeals);

   int file_handleDeal=FileOpen(InpFileNameDeals,FILE_WRITE|FILE_CSV);

   FileWrite(file_handleDeal,
             "Deal Ticket",
             "Deal Symbol",
             "Deal Order",

             "Deal Position ID",
             "Deal Deal Time",
             "Deal Type",

             "Deal Entry",
             "Deal Magic",
             "Deal Reason",
             "Deal Volume",
             "Deal Open Price",
             "Deal Commission",
             "Deal Swap",
             "Deal Profit",

             "Order Comment"
             );

   for(int r=0; r<ArraySize(Deal); r++)
      //+------------------------------------------------------------------+
      //|                                                                  |
      //+------------------------------------------------------------------+
     {
      FileWrite(file_handleDeal,
                Deal[r].deal_ticket,
                Deal[r].deal_symbol ,
                Deal[r].deal_order,

                Deal[r].deal_pos_ID,
                Deal[r].deal_time,
                Deal[r].deal_type,
                Replace(Deal[r].deal_entry,Deal[r].Digits_),
                Deal[r].deal_magic,

                Deal[r].deal_reason,
                Replace(Deal[r].deal_volume,2),
                Replace(Deal[r].deal_op_price,Deal[r].Digits_),
                Replace(Deal[r].deal_commission,2),
                Replace(Deal[r].deal_swap,2),

                Replace(Deal[r].deal_profit,2),
                Deal[r].deal_comment


                );

     }

   FileClose(file_handleDeal);
Einloggen oder registrieren, um einen Kommentar zu schreiben