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;
}
}
}