Re: Risk discipline: pair-specific notes for EURUSD
Posted: Thu Sep 24, 2026 11:14 am
Here is the complete C# conversion for cTrader (cAlgo).
Because cTrader uses a modern C# API, it handles volume normalization natively (automatically accounting for your broker's minimum lot sizes and volume steps) and allows for a much cleaner implementation of the screen-locking background colors.
cTrader Version (.cs)
Open cTrader, go to the Automate tab, click New Indicator, name it EURUSDRiskDesk, and paste this code:
Because cTrader uses a modern C# API, it handles volume normalization natively (automatically accounting for your broker's minimum lot sizes and volume steps) and allows for a much cleaner implementation of the screen-locking background colors.
cTrader Version (.cs)
Open cTrader, go to the Automate tab, click New Indicator, name it EURUSDRiskDesk, and paste this code:
Code: Select all
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class EURUSDRiskDesk : Indicator
{
// =========================================================================
// INPUTS & RULES
// =========================================================================
[Parameter("News Start Hour", DefaultValue = 13, Group = "Session & News (Server Time)")]
public int NewsStartHour { get; set; }
[Parameter("News Start Min", DefaultValue = 15, Group = "Session & News (Server Time)")]
public int NewsStartMin { get; set; }
[Parameter("News End Hour", DefaultValue = 13, Group = "Session & News (Server Time)")]
public int NewsEndHour { get; set; }
[Parameter("News End Min", DefaultValue = 45, Group = "Session & News (Server Time)")]
public int NewsEndMin { get; set; }
[Parameter("London Start Hour", DefaultValue = 7, Group = "Session & News (Server Time)")]
public int LondonStartHour { get; set; }
[Parameter("London Start Min", DefaultValue = 0, Group = "Session & News (Server Time)")]
public int LondonStartMin { get; set; }
[Parameter("London End Hour", DefaultValue = 8, Group = "Session & News (Server Time)")]
public int LondonEndHour { get; set; }
[Parameter("London End Min", DefaultValue = 30, Group = "Session & News (Server Time)")]
public int LondonEndMin { get; set; }
[Parameter("2 Process Breaks Hit? (LOCK CHART)", DefaultValue = false, Group = "Discipline Breaker")]
public bool ProcessBreaksHit { get; set; }
[Parameter("Total Risk Budget (%)", DefaultValue = 1.0, Group = "Dynamic Sizing")]
public double TotalRiskPct { get; set; }
[Parameter("Active Correlated EUR Pairs", DefaultValue = 1, Group = "Dynamic Sizing", MinValue = 1)]
public int ActivePairs { get; set; }
[Parameter("ATR Length", DefaultValue = 14, Group = "Dynamic Sizing")]
public int AtrLength { get; set; }
[Parameter("ATR Multiplier", DefaultValue = 1.5, Group = "Dynamic Sizing")]
public double AtrMult { get; set; }
private AverageTrueRange _atr;
private Color _originalBgColor;
protected override void Initialize()
{
// Initialize ATR indicator (Wilder smoothing is standard)
_atr = Indicators.AverageTrueRange(AtrLength, MovingAverageType.Wilder);
// Save the user's original chart color so we can restore it later
_originalBgColor = Chart.ColorSettings.BackgroundColor;
}
public override void Calculate(int index)
{
// Only update the dashboard and background on the live, current bar
if (!IsLastBar) return;
UpdateRiskDesk();
}
private void UpdateRiskDesk()
{
// 1. Time Logic (Using cTrader Server Time)
DateTime currentTime = Server.Time;
int currentMins = currentTime.Hour * 60 + currentTime.Minute;
int newsStart = NewsStartHour * 60 + NewsStartMin;
int newsEnd = NewsEndHour * 60 + NewsEndMin;
bool inNews = (currentMins >= newsStart && currentMins <= newsEnd);
int lonStart = LondonStartHour * 60 + LondonStartMin;
int lonEnd = LondonEndHour * 60 + LondonEndMin;
bool inLondon = (currentMins >= lonStart && currentMins <= lonEnd);
// 2. Dynamic Budgeting
double balance = Account.Balance;
double totalRiskUsd = balance * (TotalRiskPct / 100.0);
double allocatedRiskUsd = totalRiskUsd / ActivePairs;
// 3. ATR & Stop Distance
double atrValue = _atr.Result.LastValue;
double slDistance = atrValue * AtrMult;
double slDistancePips = slDistance / Symbol.PipSize;
// 4. Exact Lot Sizing Math (Native cTrader Volume Calculation)
double lots = 0;
if (slDistancePips > 0 && Symbol.PipValue > 0)
{
// Risk per 1 unit of volume
double riskPerUnit = slDistancePips * Symbol.PipValue;
// Calculate exact units needed, then safely round down to broker's valid step size
double rawUnits = allocatedRiskUsd / riskPerUnit;
double validUnits = Symbol.NormalizeVolumeInUnits(rawUnits, RoundingMode.Down);
// Convert units to Lots for easy readability
lots = validUnits / Symbol.LotSize;
}
// 5. Visual Background Enforcement
if (ProcessBreaksHit)
Chart.ColorSettings.BackgroundColor = Color.Maroon;
else if (inNews)
Chart.ColorSettings.BackgroundColor = Color.DarkRed;
else if (inLondon)
Chart.ColorSettings.BackgroundColor = Color.DarkOrange;
else
Chart.ColorSettings.BackgroundColor = _originalBgColor;
// 6. On-Chart Dashboard
string dash = "=== EURUSD RISK DESK ===\n";
dash += string.Format("Live Balance: {0:C2}\n", balance);
dash += string.Format("Budget ({0} Pairs): {1:C2}\n", ActivePairs, allocatedRiskUsd);
dash += string.Format("Stop Distance: {0:F1} pips\n", slDistancePips);
dash += "---------------------------------\n";
dash += string.Format("MAX POSITION SIZE: {0:F2} LOTS\n", lots);
dash += "---------------------------------\n";
dash += "Tier-1 News: " + (inNews ? "FLAT / ZERO RISK" : "CLEAR") + "\n";
dash += "London Open: " + (inLondon ? "MAX R / SWEEP RISK" : "CLEAR") + "\n";
dash += "Discipline: " + (ProcessBreaksHit ? "DONE FOR MORNING (LOCKED)" : "ACTIVE") + "\n";
// Draw to the top left of the screen
Chart.DrawStaticText("RiskDeskUI", dash, VerticalAlignment.Top, HorizontalAlignment.Left, Color.White);
}
protected override void OnStop()
{
// Crucial: Restores your normal chart background color when you remove the indicator
Chart.ColorSettings.BackgroundColor = _originalBgColor;
}
}
}