//+------------------------------------------------------------------+ //| OHLC_Append_Script.mq5 | //| Read existing CSV, copy only NEW bars, append without rewrite | //+------------------------------------------------------------------+ #property strict #property script_show_inputs input string FileName = "XAUUSDm_PERIOD_M30_OHLC.csv"; // existing CSV void OnStart() { string sym = _Symbol; ENUM_TIMEFRAMES tf = _Period; int digits = (int)SymbolInfoInteger(sym, SYMBOL_DIGITS); int totalBars = Bars(sym, tf); if(totalBars <= 0) { Print("No bars for ", sym); return; } // --- 1. Count existing data rows in CSV --- int existingRows = 0; int h = FileOpen(FileName, FILE_READ|FILE_CSV|FILE_ANSI, ','); if(h == INVALID_HANDLE) { // File doesn't exist yet — do full export FileClose(h); FullExport(sym, tf, digits, 0, totalBars); return; } // Count lines (skip header) while(!FileIsEnding(h)) { string line = FileReadString(h); if(line != "Timestamp" && StringLen(line) > 10) existingRows++; } FileClose(h); // --- 2. If no new bars, exit --- int newBars = totalBars - existingRows; if(newBars <= 0) { PrintFormat("CSV is up to date. %d bars total, %d in file. Nothing to append.", totalBars, existingRows); return; } PrintFormat("Existing: %d rows | Total MT5 bars: %d | New: %d bars", existingRows, totalBars, newBars); // --- 3. Copy only new bars --- MqlRates r[]; ArraySetAsSeries(r, true); int copied = CopyRates(sym, tf, 0, newBars, r); if(copied <= 0) { Print("CopyRates failed"); return; } // --- 4. Append to CSV (open for appending) --- int hOut = FileOpen(FileName, FILE_WRITE|FILE_READ|FILE_CSV|FILE_ANSI, ','); if(hOut == INVALID_HANDLE) { Print("Cannot open for append"); return; } // Seek to end of file FileSeek(hOut, 0, SEEK_END); // Write new bars in chronological order (oldest first) for(int i = copied - 1; i >= 0; i--) { FileWrite(hOut, TimeToString(r[i].time, TIME_DATE|TIME_MINUTES|TIME_SECONDS), DoubleToString(r[i].open, digits), DoubleToString(r[i].high, digits), DoubleToString(r[i].low, digits), DoubleToString(r[i].close, digits), (long)r[i].tick_volume, (int)r[i].spread); } FileClose(hOut); PrintFormat("[OK] Appended %d new bars to %s", copied, FileName); } void FullExport(string sym, ENUM_TIMEFRAMES tf, int digits, int start, int count) { MqlRates r[]; ArraySetAsSeries(r, true); int copied = CopyRates(sym, tf, start, count, r); if(copied <= 0) { Print("CopyRates failed"); return; } int h = FileOpen(FileName, FILE_WRITE|FILE_CSV|FILE_ANSI, ','); if(h == INVALID_HANDLE) { Print("Cannot create file"); return; } FileWrite(h, "Timestamp", "Open", "High", "Low", "Close", "TickVolume", "Spread"); for(int i = copied - 1; i >= 0; i--) { FileWrite(h, TimeToString(r[i].time, TIME_DATE|TIME_MINUTES|TIME_SECONDS), DoubleToString(r[i].open,digits), DoubleToString(r[i].high,digits), DoubleToString(r[i].low,digits), DoubleToString(r[i].close,digits), (long)r[i].tick_volume, (int)r[i].spread); } FileClose(h); PrintFormat("[OK] Created %s with %d bars", FileName, copied); } //+------------------------------------------------------------------+