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