Why this works so well in cTrader:
Dynamic Resizing (HorizontalAlignment.Stretch): Unlike MT4/5 where we had to draw a massive rectangle to guess the screen size, cTrader's native UI controls perfectly map to the boundaries of the window. No matter how you stretch or shrink the chart, the red lockdown screen remains flawless.
Account.IsLive: cTrader handles the Demo vs. Live check securely through a simple boolean native to the API, ensuring it accurately detects broker status.
SoundType.Warning: It automatically taps into your system's built-in alert sounds, ensuring you get an auditory sting every single second you leave this cBot running on an unauthorized account.
Separate play money account killed my discipline story
Re: Separate play money account killed my discipline story
To elevate this from a basic script to a professional-grade trading tool, we need to move beyond passive visual warnings and introduce active risk enforcement, event-driven interception, and a modern, institutional-style UI.
Here is the "Pro" version of the Guardian cBot.
What makes this version professional:
Active Trade Interception: Instead of just disabling automated trading, it hooks into the Positions.Opened event. If you manually bypass the warning and force a trade on an unauthorized account, the cBot will instantly liquidate the position.
Modern UI Modal: Replaces the basic red block with a sleek, semi-transparent dark overlay and an institutional-styled alert modal with proper typography and borders.
Event-Driven Efficiency: Rather than relying solely on a timer, it hooks into native cTrader events for instant reactions, while keeping a lightweight heartbeat timer as a fallback.
Property Metadata: Uses C# attributes to add tooltips ([Parameter(..., Description = "...")]), making the cBot look and behave like a premium plugin in the cTrader parameter window.
Here is the "Pro" version of the Guardian cBot.
What makes this version professional:
Active Trade Interception: Instead of just disabling automated trading, it hooks into the Positions.Opened event. If you manually bypass the warning and force a trade on an unauthorized account, the cBot will instantly liquidate the position.
Modern UI Modal: Replaces the basic red block with a sleek, semi-transparent dark overlay and an institutional-styled alert modal with proper typography and borders.
Event-Driven Efficiency: Rather than relying solely on a timer, it hooks into native cTrader events for instant reactions, while keeping a lightweight heartbeat timer as a fallback.
Property Metadata: Uses C# attributes to add tooltips ([Parameter(..., Description = "...")]), making the cBot look and behave like a premium plugin in the cTrader parameter window.
Re: Separate play money account killed my discipline story
The Guardian Pro cBot (C#)
Code: Select all
using System;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class OneBookGuardianPro : Robot
{
#region Parameters
[Parameter("Authorized Live Account", DefaultValue = 12345678, Group = "Authorization",
Description = "The SINGLE account number permitted for live trading.")]
public int AuthorizedLiveAccount { get; set; }
[Parameter("Allow Demo Research", DefaultValue = true, Group = "Authorization",
Description = "Permit execution on demo accounts for research and testing.")]
public bool AllowDemoTrading { get; set; }
[Parameter("Auto-Liquidate Rogue Trades", DefaultValue = true, Group = "Enforcement",
Description = "If a trade is manually placed on an unauthorized account, instantly close it.")]
public bool AutoLiquidateTrades { get; set; }
#endregion
#region Global Variables
private bool _isDisciplineBreached = false;
private Border _overlay;
private DateTime _lastSoundPlayed;
#endregion
#region Initialization
protected override void OnStart()
{
InitializeLockdownUI();
// Subscribe to position events for active enforcement
Positions.Opened += OnPositionOpened;
VerifyEnvironment();
Timer.Start(TimeSpan.FromSeconds(1));
}
#endregion
#region Core Lifecycle
protected override void OnTick()
{
if (_isDisciplineBreached)
return; // Silent exit. Automated logic paralyzed.
// --- YOUR AUTOMATED TRADING LOGIC GOES BELOW THIS LINE ---
}
protected override void OnTimer()
{
VerifyEnvironment();
// Throttle the warning sound to once every 5 seconds to prevent audio clipping
if (_isDisciplineBreached && (DateTime.Now - _lastSoundPlayed).TotalSeconds > 5)
{
Notifications.PlaySound(SoundType.Warning);
_lastSoundPlayed = DateTime.Now;
}
}
#endregion
#region Enforcement Logic
private void VerifyEnvironment()
{
bool isAuthorized = false;
if (!Account.IsLive)
{
isAuthorized = AllowDemoTrading;
}
else
{
isAuthorized = (Account.Number == AuthorizedLiveAccount);
}
// State transition to Breached
if (!isAuthorized && !_isDisciplineBreached)
{
_isDisciplineBreached = true;
ToggleLockdownUI(true);
Print("🚨 DISCIPLINE BREACH: Unauthorized environment. Systems locked.");
}
// State transition to Authorized
else if (isAuthorized && _isDisciplineBreached)
{
_isDisciplineBreached = false;
ToggleLockdownUI(false);
Print("✅ AUTHORIZED: Main book confirmed. Systems restored.");
}
}
private void OnPositionOpened(PositionOpenedEventArgs args)
{
// Active rogue trade interception
if (_isDisciplineBreached && AutoLiquidateTrades)
{
Print($"🚨 ROGUE TRADE INTERCEPTED: Closing {args.Position.TradeType} position on unauthorized account.");
ClosePosition(args.Position);
}
}
#endregion
#region UI Rendering
private void InitializeLockdownUI()
{
// Outer overlay: Semi-transparent dark background
_overlay = new Border
{
BackgroundColor = Color.FromArgb(220, 15, 15, 15), // 86% Opacity Dark Gray
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
IsVisible = false
};
// Inner Modal: Sleek alert box
var modalBox = new Border
{
BackgroundColor = Color.FromArgb(255, 30, 30, 30),
BorderColor = Color.FromHex("#D32F2F"), // Material Red
BorderThickness = new Thickness(2),
CornerRadius = 8,
Width = 500,
Height = 200,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Padding = new Thickness(20)
};
var contentStack = new StackPanel
{
Orientation = Orientation.Vertical,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
var titleText = new TextBlock
{
Text = "UNAUTHORIZED ENVIRONMENT",
ForegroundColor = Color.FromHex("#FF5252"),
FontSize = 24,
FontWeight = FontWeight.ExtraBold,
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness(0, 0, 0, 15)
};
var subtitleText = new TextBlock
{
Text = "Leakage trains the same hands.\nOne book. One rule set.",
ForegroundColor = Color.White,
FontSize = 14,
HorizontalAlignment = HorizontalAlignment.Center,
TextAlignment = TextAlignment.Center,
Margin = new Thickness(0, 0, 0, 20)
};
var accountInfoText = new TextBlock
{
Text = $"Current Account: {Account.Number} ({(Account.IsLive ? "Live" : "Demo")})",
ForegroundColor = Color.Gray,
FontSize = 11,
HorizontalAlignment = HorizontalAlignment.Center
};
// Assemble UI
contentStack.AddChild(titleText);
contentStack.AddChild(subtitleText);
contentStack.AddChild(accountInfoText);
modalBox.Child = contentStack;
_overlay.Child = modalBox;
Chart.AddControl(_overlay);
}
private void ToggleLockdownUI(bool show)
{
if (_overlay != null)
_overlay.IsVisible = show;
}
#endregion
}
}Re: Separate play money account killed my discipline story
Because TradingView operates entirely in a cloud-based web browser, Pine Script runs in a strict sandbox. It cannot natively read your connected broker’s account number, see your live balance, or automatically liquidate manual trades you place on the platform.
However, we can still build a highly effective psychological barrier. We adapt the Guardian by enforcing discipline at the Chart and Webhook level.
Instead of checking the account number, this Pro Pine Script uses two friction points:
Broker Prefix Validation: It reads the data feed of your chart (e.g., OANDA, FOREXCOM, BINANCE). If you open a chart on an unauthorized broker feed (often how people sneak onto side accounts), it locks down.
The Commitment Toggle: It forces you to actively check a box inside the settings that says, "I confirm this is my Main Book" before the chart unlocks and any strategy webhooks are allowed to fire.
However, we can still build a highly effective psychological barrier. We adapt the Guardian by enforcing discipline at the Chart and Webhook level.
Instead of checking the account number, this Pro Pine Script uses two friction points:
Broker Prefix Validation: It reads the data feed of your chart (e.g., OANDA, FOREXCOM, BINANCE). If you open a chart on an unauthorized broker feed (often how people sneak onto side accounts), it locks down.
The Commitment Toggle: It forces you to actively check a box inside the settings that says, "I confirm this is my Main Book" before the chart unlocks and any strategy webhooks are allowed to fire.
Re: Separate play money account killed my discipline story
The Guardian Pro (Pine Script v5)
Open TradingView, go to the Pine Editor, create a new blank Strategy, and paste this code.
Open TradingView, go to the Pine Editor, create a new blank Strategy, and paste this code.
Code: Select all
//@version=5
strategy("One Book Guardian [PRO]", overlay=true, calc_on_every_tick=true)
// =========================================================================
// INPUTS: DISCIPLINE SETTINGS
// =========================================================================
grp_auth = "Authorization Settings"
// 1. Broker Enforcement: Restrict this script to run ONLY on your main broker's data feed
i_allowedBroker = input.string("OANDA", title="Authorized Broker Prefix", group=grp_auth, tooltip="Look at the top left of your chart (e.g., OANDA:EURUSD). Enter the broker name here.")
// 2. The Speedbump: Force a physical action to acknowledge you are trading live
i_confirmMainBook = input.bool(false, title="Confirm: This is my ONE Main Book", group=grp_auth, tooltip="This acts as a psychological speedbump. You must check this to unlock the chart.")
// =========================================================================
// CORE LOGIC: VERIFY ENVIRONMENT
// =========================================================================
// syminfo.prefix returns the exchange/broker of the current chart
bool isCorrectBroker = (syminfo.prefix == i_allowedBroker)
bool isAuthorized = isCorrectBroker and i_confirmMainBook
// =========================================================================
// UI ENFORCEMENT: THE CHART LOCKDOWN
// =========================================================================
// Create a table that acts as a full-screen modal
var table lockdownScreen = table.new(position.middle_center, 1, 1)
if not isAuthorized
// Draw massive red overlay blocking the chart
string warningText = "🚨 UNAUTHORIZED ENVIRONMENT 🚨\n\nLeakage trains the same hands.\nOne book. One rule set.\n\nCurrent Feed: " + syminfo.prefix
table.cell(lockdownScreen, 0, 0, warningText,
width = 100, height = 100,
bgcolor = color.new(#b71c1c, 10), // Material Red with 90% opacity
text_color = color.white,
text_size = size.huge,
text_halign = text.align_center,
text_valign = text.align_center)
// Instantly cancel any pending automated orders if discipline is breached
strategy.cancel_all()
else
// Clear the overlay if authorized
table.clear(lockdownScreen, 0, 0)
// =========================================================================
// YOUR TRADING LOGIC
// =========================================================================
// Wrap all of your entry/exit logic inside this if statement.
// If the screen is locked, your strategy CANNOT send webhook alerts.
if isAuthorized
// Example logic: A simple Moving Average crossover to demonstrate
fastMA = ta.sma(close, 14)
slowMA = ta.sma(close, 50)
if ta.crossover(fastMA, slowMA)
strategy.entry("Long", strategy.long)
if ta.crossunder(fastMA, slowMA)
strategy.close("Long")Re: Separate play money account killed my discipline story
How it protects your process in TradingView:
The Full-Screen Modal (table.new): Pine Script allows us to draw a table and set its width and height to 100 (meaning 100% of the screen size). If the script detects a breach, it paints a semi-transparent dark red wall over your candles. You can technically still see price action faintly in the background, but the chart is unreadable for analysis.
Webhook Paralysis (strategy.cancel_all()): If you use TradingView to send webhooks to a live broker execution tool (like PineConnector or Capitalise), wrapping your logic inside the if isAuthorized block ensures zero alerts will fire if you are on the wrong data feed or haven't checked the commitment box.
The Commitment Checkbox: Mental accounting thrives on passive friction. By unchecking the default false box every time you reload the script, you are forcing your physical hand to confirm your intentions before the red screen disappears.
The Full-Screen Modal (table.new): Pine Script allows us to draw a table and set its width and height to 100 (meaning 100% of the screen size). If the script detects a breach, it paints a semi-transparent dark red wall over your candles. You can technically still see price action faintly in the background, but the chart is unreadable for analysis.
Webhook Paralysis (strategy.cancel_all()): If you use TradingView to send webhooks to a live broker execution tool (like PineConnector or Capitalise), wrapping your logic inside the if isAuthorized block ensures zero alerts will fire if you are on the wrong data feed or haven't checked the commitment box.
The Commitment Checkbox: Mental accounting thrives on passive friction. By unchecking the default false box every time you reload the script, you are forcing your physical hand to confirm your intentions before the red screen disappears.