Advertisement IC Markets

Friday flat-by rule: my cut-off clock and why I keep it rigid

Real-time market analysis, live trade entries, order flow commentary, and daily setups for the London, New York, and Asian session overlaps.
PTScalper
Site Admin
Posts: 1782
Joined: Mon Jul 20, 2026 1:28 pm

Re: Friday flat-by rule: my cut-off clock and why I keep it rigid

Post by PTScalper »

Moving this protocol to cTrader is where the system truly reaches its enterprise potential. cTrader uses C# (.NET) and has a built-in UI framework that allows us to build native, WPF-style control panels directly onto the chart.

Instead of relying on clunky text labels like MT4/MT5, we can build a proper docked visual HUD that looks like a native part of the trading platform. Like the MetaTrader versions, this relies on a precise 1-second timer rather than price ticks, ensuring your protocol enforces exactly on time even if Friday volume has completely dried up.

Here is the complete C# code for the cTrader Automate environment.

cTrader: Enterprise Friday Risk Protocol

How to Install:

1.) Open cTrader and go to the Automate tab on the left menu.

2.) Click the + New button next to Indicators.

3.) Name it FridayRiskManager.

4.) Delete all the default code, paste the C# code below, and click Build (the hammer icon at the top).
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Recommended broker for automated trading & scalping IC Markets
PTScalper
Site Admin
Posts: 1782
Joined: Mon Jul 20, 2026 1:28 pm

Re: Friday flat-by rule: my cut-off clock and why I keep it rigid

Post by PTScalper »

Ctrader version:

Code: Select all

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;

namespace cAlgo
{
    public enum WeekStatus
    {
        Neutral,
        Green_Protect,
        Red_StopDigging
    }

    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class FridayRiskManager : Indicator
    {
        [Parameter("Week Status", DefaultValue = WeekStatus.Neutral, Group = "Risk Desk Parameters")]
        public WeekStatus CurrentWeekStatus { get; set; }

        [Parameter("FX Cut-off Hour", DefaultValue = 17, MinValue = 0, MaxValue = 23, Group = "Cut-offs (BROKER TIME)")]
        public int FxCutoffHour { get; set; }

        [Parameter("FX Cut-off Min", DefaultValue = 30, MinValue = 0, MaxValue = 59, Group = "Cut-offs (BROKER TIME)")]
        public int FxCutoffMin { get; set; }

        [Parameter("XAU Cut-off Hour", DefaultValue = 17, MinValue = 0, MaxValue = 23, Group = "Cut-offs (BROKER TIME)")]
        public int XauCutoffHour { get; set; }

        [Parameter("XAU Cut-off Min", DefaultValue = 0, MinValue = 0, MaxValue = 59, Group = "Cut-offs (BROKER TIME)")]
        public int XauCutoffMin { get; set; }

        [Parameter("Warning Window (Mins)", DefaultValue = 30, MinValue = 5, Group = "Cut-offs (BROKER TIME)")]
        public int WarningMins { get; set; }

        // UI Elements
        private StackPanel _hud;
        private TextBlock _txtAsset, _txtCutoff, _txtStatus;
        private TextBlock _txtL4, _txtR4, _txtL5, _txtR5, _txtL6, _txtR6, _txtL7, _txtR7;
        
        // Colors
        private Color _clrBg = Color.FromArgb(240, 30, 34, 45); // Dark Slate
        private Color _clrBorder = Color.FromArgb(255, 67, 70, 81);
        private Color _clrLabel = Color.FromArgb(255, 138, 145, 165);
        private Color _clrWhite = Color.White;
        private Color _clrGreen = Color.FromHex("#00e676");
        private Color _clrOrange = Color.FromHex("#ffaa00");
        private Color _clrRed = Color.FromHex("#ff5252");

        // Logic variables
        private bool _isMetals;
        private int _baseHour, _baseMin, _protectFactor;
        private int _currentState = -1; // 0=Normal, 1=Warning, 2=Locked
        private ChartRectangle _bgRectangle;

        protected override void Initialize()
        {
            // Auto-detect metals (stricter liquidity profile)
            _isMetals = Symbol.Name.Contains("XAU") || Symbol.Name.Contains("GOLD");
            _baseHour = _isMetals ? XauCutoffHour : FxCutoffHour;
            _baseMin = _isMetals ? XauCutoffMin : FxCutoffMin;
            
            // Context logic
            _protectFactor = (CurrentWeekStatus == WeekStatus.Green_Protect) ? 15 : 0;

            // Build UI HUD
            BuildHUD();
            
            // Start precision timer (runs every 1 second)
            Timer.Start(TimeSpan.FromSeconds(1));
        }

        public override void Calculate(int index)
        {
            // Calculation logic is bypassed; system relies entirely on OnTimer for accuracy.
        }

        protected override void OnTimer()
        {
            DateTime now = Server.Time;

            if (now.DayOfWeek != DayOfWeek.Friday)
            {
                _hud.IsVisible = false;
                if (_bgRectangle != null) _bgRectangle.IsVisible = false;
                return;
            }

            _hud.IsVisible = true;

            // Compute precise cutoff time for today
            DateTime cutoff = new DateTime(now.Year, now.Month, now.Day, _baseHour, _baseMin, 0).AddMinutes(-_protectFactor);
            TimeSpan remaining = cutoff - now;

            int prevState = _currentState;

            if (remaining.TotalSeconds <= 0)
                _currentState = 2; // Locked
            else if (remaining.TotalMinutes <= WarningMins)
                _currentState = 1; // Warning
            else
                _currentState = 0; // Active

            // Trigger sound alerts on transition
            if (_currentState == 1 && prevState == 0) Notifications.PlaySound(SoundType.Timeout);
            if (_currentState == 2 && prevState == 1) Notifications.PlaySound(SoundType.Error);

            // Update visuals
            UpdateHUD(remaining, cutoff);
            UpdateBackground(now, cutoff);
        }

        private void UpdateHUD(TimeSpan remaining, DateTime cutoff)
        {
            _txtAsset.Text = _isMetals ? "METALS (XAU)" : "FX MAJOR";
            _txtCutoff.Text = cutoff.ToString("HH:mm") + " BRK";

            if (_currentState == 2)
            {
                _txtStatus.Text = "LOCKED";
                _txtStatus.ForegroundColor = _clrRed;

                _txtL4.Text = "PROTOCOL";        _txtL4.ForegroundColor = _clrRed;
                _txtR4.Text = "HARD BLACKOUT";   _txtR4.ForegroundColor = _clrRed;

                _txtL5.Text = "✅ ALLOWED";      _txtL5.ForegroundColor = _clrGreen;
                _txtR5.Text = "Manage Open, Log Day"; _txtR5.ForegroundColor = _clrWhite;

                _txtL6.Text = "❌ DENIED";       _txtL6.ForegroundColor = _clrRed;
                _txtR6.Text = "Revenge Size, Ext."; _txtR6.ForegroundColor = _clrWhite;

                _txtL7.Text = "RATIONALE";       _txtL7.ForegroundColor = _clrLabel;
                _txtR7.Text = CurrentWeekStatus == WeekStatus.Green_Protect ? "Protect the Week" : "Stop Digging"; 
                _txtR7.ForegroundColor = _clrWhite;
            }
            else
            {
                _txtStatus.Text = _currentState == 1 ? "WINDING DOWN" : "ACTIVE";
                _txtStatus.ForegroundColor = _currentState == 1 ? _clrOrange : _clrGreen;

                _txtL4.Text = "TIME REMAINING";  _txtL4.ForegroundColor = _clrLabel;
                _txtR4.Text = $"{(int)Math.Max(0, remaining.TotalMinutes)} MIN"; 
                _txtR4.ForegroundColor = _txtStatus.ForegroundColor;

                _txtL5.Text = "WEEK CONTEXT";    _txtL5.ForegroundColor = _clrLabel;
                _txtR5.Text = CurrentWeekStatus.ToString().Replace("_", " "); 
                _txtR5.ForegroundColor = _clrWhite;

                _txtL6.Text = ""; _txtR6.Text = "";
                _txtL7.Text = ""; _txtR7.Text = "";
            }
        }

        private void UpdateBackground(DateTime now, DateTime cutoff)
        {
            if (_currentState == 0)
            {
                if (_bgRectangle != null) _bgRectangle.IsVisible = false;
                return;
            }

            string rectName = "FriRiskBG";
            double topY = Chart.TopY;
            double botY = Chart.BottomY;
            
            // Expand rectangle into the future so it paints the right edge
            DateTime endOfDay = new DateTime(now.Year, now.Month, now.Day, 23, 59, 59);

            if (_bgRectangle == null)
            {
                _bgRectangle = Chart.DrawRectangle(rectName, now.AddHours(-1), botY, endOfDay, topY, Color.Transparent);
                _bgRectangle.IsFilled = true;
            }

            _bgRectangle.IsVisible = true;
            _bgRectangle.Time2 = endOfDay;
            _bgRectangle.Y1 = botY;
            _bgRectangle.Y2 = topY;
            
            // Alpha blended colors overlay the chart smoothly
            _bgRectangle.Color = _currentState == 2 
                ? Color.FromArgb(60, 255, 0, 0)     // Translucent Red
                : Color.FromArgb(60, 255, 140, 0);  // Translucent Orange
        }

        private void BuildHUD()
        {
            _hud = new StackPanel 
            {
                Orientation = Orientation.Vertical,
                BackgroundColor = _clrBg,
                Margin = new Thickness(15),
                Width = 260
            };

            var border = new Border 
            {
                BorderColor = _clrBorder,
                BorderThickness = new Thickness(1),
                Child = _hud,
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top
            };

            // Initialize Rows
            _txtAsset = AddRow(_hud, "ASSET PROFILE");
            _txtCutoff = AddRow(_hud, "DESK CUT-OFF");
            _txtStatus = AddRow(_hud, "STATUS");
            _txtR4 = AddRow(_hud, "", out _txtL4);
            _txtR5 = AddRow(_hud, "", out _txtL5);
            _txtR6 = AddRow(_hud, "", out _txtL6);
            _txtR7 = AddRow(_hud, "", out _txtL7);

            Chart.AddControl(border);
        }

        private TextBlock AddRow(StackPanel parent, string leftText)
        {
            TextBlock dummyLabel;
            return AddRow(parent, leftText, out dummyLabel);
        }

        private TextBlock AddRow(StackPanel parent, string leftText, out TextBlock leftLabelBlock)
        {
            var grid = new Grid { Margin = new Thickness(10, 5, 10, 5) };
            grid.AddColumn(GridLength.Auto);
            grid.AddColumn(GridLength.Star);

            leftLabelBlock = new TextBlock 
            {
                Text = leftText,
                ForegroundColor = _clrLabel,
                FontWeight = FontWeight.Bold,
                FontSize = 11
            };

            var rightValueBlock = new TextBlock 
            {
                Text = "-",
                ForegroundColor = _clrWhite,
                FontWeight = FontWeight.ExtraBold,
                FontSize = 11,
                HorizontalAlignment = HorizontalAlignment.Right
            };

            grid.AddChild(leftLabelBlock, 0, 0);
            grid.AddChild(rightValueBlock, 0, 1);
            
            parent.AddChild(grid);
            return rightValueBlock;
        }
    }
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 1782
Joined: Mon Jul 20, 2026 1:28 pm

Re: Friday flat-by rule: my cut-off clock and why I keep it rigid

Post by PTScalper »

Why this shines in cTrader

Native GUI Integration: Unlike MT4/MT5 where you have to calculate X and Y pixel distances to fake a panel, this script uses cTrader's native .NET StackPanel and Grid classes. The HUD acts like a built-in cTrader menu. It is perfectly aligned, cleanly boxed, and floats smoothly in the top right corner.

Translucent Alpha-Blending: The warning/locked background colors (_bgRectangle) use alpha-channels (Color.FromArgb). This creates a tinted "glass" overlay over your candlesticks (instead of MT4’s solid opaque boxes), allowing you to clearly see price action without the colors blinding you.

Time-Safe Background Extension: In thin conditions, cTrader can sometimes compress the right margin of the chart. The code specifically anchors the visual cut-off block to stretch forward in time to 23:59, guaranteeing the red zone visually locks down the rest of your trading day.

Note: As with MT4/MT5, input the cut-off hours according to your cTrader Broker Time (Server Time) displayed at the bottom right corner of your platform, as the server handles executions.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Post Reply