Page 2 of 2

Re: Avoiding EURJPY during Friday afternoon when spreads exceed my filter

Posted: Sun Sep 20, 2026 9:29 am
by FTtrader
Because cTrader’s native language (cAlgo) is pure C#, you can bypass proprietary workarounds and leverage the standard System.IO namespace for file handling.

The biggest gotcha when porting to cTrader is permissions. You must explicitly declare AccessRights = AccessRights.FileSystem in the [Robot] attribute; otherwise, cTrader’s sandbox will throw a security exception the moment you try to create the CSV.

Here is the complete cBot logic, utilizing standard C# string interpolation and stream writers. It uses the Bars.OpenTimes.LastValue property to ensure it only evaluates the spread and writes to the log once per bar, preventing redundant tick-by-tick spam.

Re: Avoiding EURJPY during Friday afternoon when spreads exceed my filter

Posted: Sun Sep 20, 2026 9:29 am
by FTtrader
Ctrader code:

Code: Select all

using System;
using System.IO;
using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FileSystem)]
    public class FridaySpreadFilterLog : Robot
    {
        [Parameter("Max Spread Cap (Pips)", DefaultValue = 1.8, MinValue = 0.1, Step = 0.1)]
        public double MaxSpreadPips { get; set; }

        [Parameter("Friday Cutoff Hour", DefaultValue = 14, MinValue = 0, MaxValue = 23)]
        public int FridayCutoffHour { get; set; }

        private DateTime _lastBarTime;
        private string _filePath;

        protected override void OnStart()
        {
            // Safely route the CSV to the user's Documents/cAlgo folder
            string docsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            _filePath = Path.Combine(docsPath, "cAlgo", "SkippedTradesLog.csv");
        }

        protected override void OnTick()
        {
            // 1. Evaluate once per bar to prevent CSV log spam
            var currentBarTime = Bars.OpenTimes.LastValue;
            if (_lastBarTime == currentBarTime)
                return;

            // 2. Time Logic: Broker Time
            bool isFriday = Server.Time.DayOfWeek == DayOfWeek.Friday;
            bool isAfterCutoff = Server.Time.Hour >= FridayCutoffHour;
            bool killzoneActive = isFriday && isAfterCutoff;

            // 3. Spread Logic
            // cTrader natively handles pricing digits; Symbol.PipSize safely calculates true pips
            double currentSpreadPips = Symbol.Spread / Symbol.PipSize;
            bool spreadExceeded = currentSpreadPips > MaxSpreadPips;

            // 4. Execution Logging
            if (spreadExceeded && !killzoneActive)
            {
                LogSkippedTrade("Spread Cap Exceeded", currentSpreadPips);
                _lastBarTime = currentBarTime; 
            }
            else if (killzoneActive)
            {
                LogSkippedTrade("Friday Cutoff Time Reached", currentSpreadPips);
                _lastBarTime = currentBarTime; 
            }
        }

        private void LogSkippedTrade(string reason, double spreadPips)
        {
            try
            {
                // Check if file is new to write the header row
                bool writeHeader = !File.Exists(_filePath) || new FileInfo(_filePath).Length == 0;
                
                using (StreamWriter sw = new StreamWriter(_filePath, append: true))
                {
                    if (writeHeader)
                    {
                        sw.WriteLine("Time,Symbol,Action,Reason,SpreadPips,Price");
                    }

                    sw.WriteLine($"{Server.Time:yyyy-MM-dd HH:mm:ss},{SymbolName},SKIP,{reason},{Math.Round(spreadPips, 1)},{Symbol.Ask}");
                }
                
                Print($"Logged Skip: {reason} | Spread: {Math.Round(spreadPips, 1)}");
            }
            catch (Exception ex)
            {
                Print($"Failed to write to CSV. Error: {ex.Message}");
            }
        }
    }
}

Re: Avoiding EURJPY during Friday afternoon when spreads exceed my filter

Posted: Sun Sep 20, 2026 9:29 am
by FTtrader
Accessing the Log Data

When you build and attach this cBot to your chart, it will automatically route the SkippedTradesLog.csv to your Documents\cAlgo folder. Since it leaves the file handle open only during the split-second write operation inside the using block, you can safely open the CSV in Excel or a custom data pipeline in real-time while the cBot continues running.