Export data - lastbar.CloseTime
Export data - lastbar.CloseTime
25 Jan 2025, 14:19
I got pretty simple code for exporting OHLC values for multiple currencies , but facing issue with Date itself ,
snippet
public void LogData(MultiSymbolOHLCExporter bot)
{
var bars = bot.MarketData.GetBars(TimeFrame.Daily, symbol); //
if (bars.Count < 1)
{
bot.Print($"No bars available for {symbol}. Skipping.");
return;
}
var lastBar = bars.Last(1);
string csvLine = $"{lastBar.OpenTime:dd.MM.yyyy},{lastBar.Open},{lastBar.High},{lastBar.Low},{lastBar.Close}\n";
File.AppendAllText(filePath, csvLine);
bot.Print($"Logged for {symbol}: {csvLine.Trim()}");
This result in output of day earlier Date as TradingView, or Metatrader data export from same broker , what is easiest solution to correct it ?
Replies
Mark86
25 Jan 2025, 21:25
( Updated at: 14 Feb 2025, 18:19 )
HI. I created some code for you that works quite well. There is something to fix. It's about “Overwrite (input)”. This is used to avoid overwriting the file if it already exists. I've seen that the part of the code that adds data to the close of the candle doesn't work if it remains false.
For the rest it should work. tried on btcusd at m1 timeframe.
Try to see if you can fix this error.
Compared to my problem, this was easier to create and I hope someone will help me as soon as they approve the topic.
ps. The data is saved in your_name\Documents\cAlgo\Data\cBots\Export Data To CSV
using System;
using System.IO;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(AccessRights = AccessRights.None, AddIndicators = true, TimeZone = TimeZones.UTC)]
public class ExportDataToCSV : Robot
{
private readonly string[] symbols =
{
"BTCUSD",
"EURUSD",
"USDJPY",
"GBPUSD",
"AUDUSD",
"USDCHF",
"USDCAD",
"EURGBP",
};
[Parameter("Time Frame", DefaultValue = "Daily")]
public TimeFrame TF { get; set; }
[Parameter("Overwrite Existing Files?", DefaultValue = false)]
public bool Overwrite { get; set; }
[Parameter("Date Format (e.g., yyyy/MM/dd HH:mm)", DefaultValue = "yyyy/MM/dd HH:mm")]
public string DateFormat { get; set; }
private readonly Dictionary<string, DateTime> lastExportedTime = new();
protected override void OnStart()
{
foreach (var symbol in symbols)
{
lastExportedTime[symbol] = DateTime.MinValue;
ExportInitialData(symbol);
}
Timer.Start(TimeFrameToMinutes(TF) * 60);
}
protected override void OnBar()
{
foreach (var symbol in symbols)
{
ExportPreviousBarData(symbol);
}
}
private void ExportInitialData(string symbol)
{
var bars = MarketData.GetBars(TF, symbol);
string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), $"{symbol}_{TF}_data.csv");
if (File.Exists(filePath) && !Overwrite)
{
Print($"File {filePath} already exists. Skipping initial export for {symbol}.");
lastExportedTime[symbol] = bars.OpenTimes.LastValue;
return;
}
using (var writer = new StreamWriter(filePath, false))
{
writer.WriteLine("Date,Open,High,Low,Close");
for (int i = 0; i < bars.ClosePrices.Count - 1; i++)
{
try
{
string line = $"{bars.OpenTimes[i].ToString(DateFormat)},{bars.OpenPrices[i]},{bars.HighPrices[i]},{bars.LowPrices[i]},{bars.ClosePrices[i]}";
writer.WriteLine(line);
lastExportedTime[symbol] = bars.OpenTimes[i];
}
catch (FormatException e)
{
Print($"Error formatting date: {e.Message}");
}
}
}
Print($"Initial data for {symbol} exported to {filePath}");
}
private void ExportPreviousBarData(string symbol)
{
var bars = MarketData.GetBars(TF, symbol);
string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), $"{symbol}_{TF}_data.csv");
using (var writer = new StreamWriter(filePath, true))
{
var lastIndex = bars.ClosePrices.Count - 2;
if (lastIndex < 0 || bars.OpenTimes[lastIndex] <= lastExportedTime[symbol])
return;
try
{
string line = $"{bars.OpenTimes[lastIndex].ToString(DateFormat)},{bars.OpenPrices[lastIndex]},{bars.HighPrices[lastIndex]},{bars.LowPrices[lastIndex]},{bars.ClosePrices[lastIndex]}";
writer.WriteLine(line);
lastExportedTime[symbol] = bars.OpenTimes[lastIndex];
}
catch (FormatException e)
{
Print($"Error formatting date: {e.Message}");
}
}
Print($"New data for {symbol} appended to {filePath}");
}
private static int TimeFrameToMinutes(TimeFrame timeFrame)
{
return timeFrame.ToString() switch
{
"Minute" => 1,
"Minute5" => 5,
"Minute15" => 15,
"Minute30" => 30,
"Hour" => 60,
"Hour4" => 240,
"Daily" => 1440,
_ => throw new ArgumentException("Unsupported timeframe: " + timeFrame),
};
}
}
}
@Mark86
algobeginner
25 Jan 2025, 14:27
// Full code
using System;
using System.Collections.Generic;
using System.IO;
using cAlgo.API;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class MultiSymbolOHLCExporter : Robot
{
private string[] symbols =
{
"EURUSD",
"USDJPY",
"GBPUSD",
"AUDUSD",
"USDCHF",
"USDCAD",
"EURGBP",
};
private List<OHLCExporter> exporters = new List<OHLCExporter>();
protected override void OnStart()
{
foreach (var symbol in symbols)
{
var exporter = new OHLCExporter();
exporter.Init(this, symbol);
exporters.Add(exporter);
}
Timer.Start(86400); // Daily in seconds
Print("Exporter Started");
}
protected override void OnTimer()
{
foreach (var exporter in exporters)
{
exporter.LogData(this);
}
}
}
public class OHLCExporter
{
private string symbol;
private string filePath;
public void Init(MultiSymbolOHLCExporter bot, string symbol)
{
this.symbol = symbol;
string formattedTime = bot.Server.Time.ToString("dd-MM-yyyy");
filePath = $"{symbol}_{TimeFrame.Daily}_{formattedTime}.csv"; //
if (!File.Exists(filePath))
{
File.WriteAllText(filePath, "Date,Open,High,Low,Close\n");
bot.Print($"Created new file: {filePath}");
}
}
public void LogData(MultiSymbolOHLCExporter bot)
{
var bars = bot.MarketData.GetBars(TimeFrame.Daily, symbol); //
if (bars.Count < 1)
{
bot.Print($"No bars available for {symbol}. Skipping.");
return;
}
var lastBar = bars.Last(1);
string csvLine = $"{lastBar.OpenTime:dd.MM.yyyy},{lastBar.Open},{lastBar.High},{lastBar.Low},{lastBar.Close}\n";
File.AppendAllText(filePath, csvLine);
bot.Print($"Logged for {symbol}: {csvLine.Trim()}");
}
}
}
@algobeginner