Page 1 of 2
Separate play money account killed my discipline story
Posted: Tue Sep 22, 2026 2:26 pm
by LondonScalper
A separate play-money account killed my favourite discipline story.
I told myself the tiny side account was for "experiments." In practice it became a place to break rules with a smile and then wonder why the main account felt the hangover. Discipline is not a costume you wear on the funded login. Leakage trains the same hands.
What I changed
- One discretionary FX book with one rule set
- Experiments go to demo or a strictly capped research log, not live "play"
- If I want a new idea live, it graduates through written criteria — not through a toy account
Play money was permission to be two traders. I trade better as one.
Did a side account ever undermine your main process, or have you found a way to keep research money truly ring-fenced?
If a broker promo tempts a fresh small account for fun, I treat that urge as a red flag tag. New logins are how rule sets fork. One book, one process, fewer stories.
Research stays on demo until it clears a written promotion checklist. Curiosity is allowed; parallel live rule sets are not.
Re: Separate play money account killed my discipline story
Posted: Thu Sep 24, 2026 9:54 am
by PTScalper
LondonScalper wrote: Tue Sep 22, 2026 2:26 pm
A separate play-money account killed my favourite discipline story.
I told myself the tiny side account was for "experiments." In practice it became a place to break rules with a smile and then wonder why the main account felt the hangover. Discipline is not a costume you wear on the funded login. Leakage trains the same hands.
What I changed
- One discretionary FX book with one rule set
- Experiments go to demo or a strictly capped research log, not live "play"
- If I want a new idea live, it graduates through written criteria — not through a toy account
Play money was permission to be two traders. I trade better as one.
Did a side account ever undermine your main process, or have you found a way to keep research money truly ring-fenced?
If a broker promo tempts a fresh small account for fun, I treat that urge as a red flag tag. New logins are how rule sets fork. One book, one process, fewer stories.
Research stays on demo until it clears a written promotion checklist. Curiosity is allowed; parallel live rule sets are not.
Hi LondonScalper,
i personally not use demo accounts + i start to risk more just from profit, not my own capital.
I found out, that demo accounts will not teach you most important discipline and that is how to handle stress from risking you own capital, which is your hard
earned money.
I think that more than half of my trading rules are just for keep my mind cool under pressure and do not make too many mistakes.
Re: Separate play money account killed my discipline story
Posted: Thu Sep 24, 2026 10:02 am
by FTtrader
LondonScalper wrote: Tue Sep 22, 2026 2:26 pm
A separate play-money account killed my favourite discipline story.
I told myself the tiny side account was for "experiments." In practice it became a place to break rules with a smile and then wonder why the main account felt the hangover. Discipline is not a costume you wear on the funded login. Leakage trains the same hands.
What I changed
- One discretionary FX book with one rule set
- Experiments go to demo or a strictly capped research log, not live "play"
- If I want a new idea live, it graduates through written criteria — not through a toy account
Play money was permission to be two traders. I trade better as one.
Did a side account ever undermine your main process, or have you found a way to keep research money truly ring-fenced?
If a broker promo tempts a fresh small account for fun, I treat that urge as a red flag tag. New logins are how rule sets fork. One book, one process, fewer stories.
Research stays on demo until it clears a written promotion checklist. Curiosity is allowed; parallel live rule sets are not.
Hello LondonScalper,
Your realization that “leakage trains the same hands” is one of the most profound truths in trading psychology.
What you experienced is a classic trap rooted in mental accounting bias. We trick ourselves into believing that because the capital is segregated into a "play account," our psychological habits will be segregated, too. But the brain doesn't compartmentalize dopamine, frustration, or rule-breaking. When you allow yourself to punt a trade on a micro account just for the thrill, you are actively burning new neural pathways that normalize sloppy execution. The subconscious doesn't read the account balance; it only remembers the behavior.
In institutional environments, this is exactly why prop desks don't let traders run discretionary side books. The "one book, one rule set" philosophy is mandatory because parallel live rule sets dilute focus and breed hesitation. Your solution—forcing all new ideas to graduate through a written promotion checklist on a demo environment—is the exact framework used to ring-fence research from live capital.
To reinforce your "One Book, One Process" rule, I built an MQL4 script designed to act as a technical failsafe.
Re: Separate play money account killed my discipline story
Posted: Thu Sep 24, 2026 10:02 am
by FTtrader
The "One Book" Discipline Enforcer (MQL4)
This script translates your philosophy into code. You can bind this to a hotkey or run it before initiating any manual trades. It checks the current environment and flat-out refuses to let you proceed if you happen to be logged into an unauthorized live "promo" or "play" account.
Code: Select all
//+------------------------------------------------------------------+
//| DisciplineEnforcer.mq4 |
//| Enforces the "One Book, One Process" trading rule |
//+------------------------------------------------------------------+
#property copyright "Gemini"
#property version "1.00"
#property strict
#property show_inputs
//--- Input Parameters
input int AuthorizedLiveAccount = 12345678; // Your SINGLE Authorized Live Account
input bool AllowDemoTrading = true; // Allow execution on Demo for research
input double FixedRiskPercent = 1.0; // Strict Risk % for the main rule set
void OnStart()
{
// Gather current account information
int currentAccount = (int)AccountInfoInteger(ACCOUNT_LOGIN);
long tradeMode = AccountInfoInteger(ACCOUNT_TRADE_MODE);
bool isDemo = (tradeMode == ACCOUNT_TRADE_MODE_DEMO);
// Rule 1: Research stays on demo.
if(isDemo)
{
if(!AllowDemoTrading)
{
Alert("Demo trading is currently disabled. Use your written research log.");
return;
}
Print("Authorized Demo Environment. Research mode active.");
}
else // Live Account Environment
{
// Rule 2: No side accounts. No play money. One book.
if(currentAccount != AuthorizedLiveAccount)
{
string errorMsg = "RED FLAG: Unauthorized live account (" + IntegerToString(currentAccount) + ").\n" +
"Leakage trains the same hands. Execution blocked.";
Alert(errorMsg);
PlaySound("timeout.wav"); // Audio deterrent
return;
}
Print("Main Book Confirmed. One Process, One Rule Set.");
}
// Rule 3: Enforce the single rule set's risk parameters
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double riskAmount = balance * (FixedRiskPercent / 100.0);
Alert("Discipline Check Passed.\nAccount: ", currentAccount,
"\nMode: ", (isDemo ? "RESEARCH/DEMO" : "LIVE MAIN BOOK"),
"\nMax Risk Allowed: $", DoubleToStr(riskAmount, 2));
// -> You can append your standard order execution logic below this line.
// By placing trades through this script, you guarantee it only fires
// when you are logged into the correct, disciplined environment.
}
Re: Separate play money account killed my discipline story
Posted: Thu Sep 24, 2026 10:03 am
by FTtrader
How it reinforces your new rules:
The Red Flag Tag: If you succumb to a broker promo and open a small side account, dropping this script onto the chart will trigger a hard Alert() and audio warning, immediately calling out the behavior before a trade is placed.
Forced Graduation: It acknowledges demo accounts as legitimate research sandboxes (if enabled in inputs), aligning with your rule that new ideas must be tested outside of live capital.
Standardized Risk: It calculates your strict maximum risk exposure based on your one rule set, keeping your position sizing anchored to logic rather than emotion.
Re: Separate play money account killed my discipline story
Posted: Thu Sep 24, 2026 10:03 am
by FTtrader
To convert this into an Expert Advisor (EA) that actively monitors your environment, we need to shift from a "run-once" script to a continuous background process.
Because MQL4 runs in a sandbox, an EA cannot natively click the terminal's global "AutoTrading" button without importing Windows DLLs. However, we can achieve a more effective psychological deterrent using pure MQL4: The Chart Lockdown.
This EA runs continuously on a timer. If it detects a login to an unauthorized account, it immediately disables its own automated trading logic, spams an alert, and completely covers your chart with a massive red warning label, making it visually impossible to comfortably trade manually.
Re: Separate play money account killed my discipline story
Posted: Thu Sep 24, 2026 10:03 am
by FTtrader
The "One Book" Guardian EA (MQL4)
Save this file in your MQL4\Experts folder as OneBookGuardian.mq4.
Code: Select all
//+------------------------------------------------------------------+
//| OneBookGuardian.mq4 |
//| Continuous EA monitor to enforce trading discipline |
//+------------------------------------------------------------------+
#property copyright "Gemini"
#property version "1.10"
#property strict
//--- Input Parameters
input int AuthorizedLiveAccount = 12345678; // Your SINGLE Authorized Live Account
input bool AllowDemoTrading = true; // Allow execution on Demo for research
//--- Global Variables
bool disciplineBreached = false;
string warningObjName = "DISCIPLINE_LOCKDOWN_LABEL";
string bgObjName = "DISCIPLINE_LOCKDOWN_BG";
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Set a 1-second timer to constantly check the account status
EventSetTimer(1);
// Run an immediate check on startup
VerifyEnvironment();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
EventKillTimer();
UnlockChart(); // Clean up graphics when removed
}
//+------------------------------------------------------------------+
//| Expert tick function (Automated Trading Logic goes here) |
//+------------------------------------------------------------------+
void OnTick()
{
// RULE 1: If discipline is breached, kill all automated trading
if(disciplineBreached)
{
// The EA exits immediately without executing any trade logic
return;
}
// --- YOUR AUTOMATED TRADING LOGIC GOES BELOW THIS LINE ---
// If the EA gets to this point, you are safely in your main book.
}
//+------------------------------------------------------------------+
//| Timer function (Constant Environment Monitoring) |
//+------------------------------------------------------------------+
void OnTimer()
{
VerifyEnvironment();
if(disciplineBreached)
{
// Continuous psychological friction if the warning is ignored
Alert("RED FLAG: Unauthorized Account! Leakage trains the same hands.");
PlaySound("timeout.wav");
}
}
//+------------------------------------------------------------------+
//| Core Logic: Verifies the current account |
//+------------------------------------------------------------------+
void VerifyEnvironment()
{
int currentAccount = (int)AccountInfoInteger(ACCOUNT_LOGIN);
long tradeMode = AccountInfoInteger(ACCOUNT_TRADE_MODE);
bool isDemo = (tradeMode == ACCOUNT_TRADE_MODE_DEMO);
bool isAuthorized = false;
if(isDemo)
{
if(AllowDemoTrading) isAuthorized = true;
}
else // Live Environment
{
if(currentAccount == AuthorizedLiveAccount) isAuthorized = true;
}
// Handle state changes
if(!isAuthorized && !disciplineBreached)
{
disciplineBreached = true;
LockdownChart();
Print("Discipline breach detected. Automated trading disabled.");
}
else if(isAuthorized && disciplineBreached)
{
disciplineBreached = false;
UnlockChart();
Print("Authorized environment confirmed. Systems restored.");
}
}
//+------------------------------------------------------------------+
//| UI functions: Psychological deterrents |
//+------------------------------------------------------------------+
void LockdownChart()
{
// Create a massive red background blocking the chart
if(ObjectFind(0, bgObjName) < 0)
{
ObjectCreate(0, bgObjName, OBJ_RECTANGLE_LABEL, 0, 0, 0);
ObjectSetInteger(0, bgObjName, OBJPROP_XDISTANCE, 0);
ObjectSetInteger(0, bgObjName, OBJPROP_YDISTANCE, 0);
ObjectSetInteger(0, bgObjName, OBJPROP_XSIZE, 3000); // Cover entire screen
ObjectSetInteger(0, bgObjName, OBJPROP_YSIZE, 3000);
ObjectSetInteger(0, bgObjName, OBJPROP_BGCOLOR, clrRed);
ObjectSetInteger(0, bgObjName, OBJPROP_BACK, false);
}
// Add giant warning text
if(ObjectFind(0, warningObjName) < 0)
{
ObjectCreate(0, warningObjName, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, warningObjName, OBJPROP_XDISTANCE, 50);
ObjectSetInteger(0, warningObjName, OBJPROP_YDISTANCE, 100);
ObjectSetString(0, warningObjName, OBJPROP_TEXT, "UNAUTHORIZED PLAY ACCOUNT");
ObjectSetString(0, warningObjName, OBJPROP_FONT, "Arial Black");
ObjectSetInteger(0, warningObjName, OBJPROP_FONTSIZE, 36);
ObjectSetInteger(0, warningObjName, OBJPROP_COLOR, clrWhite);
}
ChartRedraw();
}
void UnlockChart()
{
ObjectDelete(0, bgObjName);
ObjectDelete(0, warningObjName);
ChartRedraw();
}
//+------------------------------------------------------------------+
Re: Separate play money account killed my discipline story
Posted: Thu Sep 24, 2026 10:04 am
by FTtrader
How the Guardian Works in Practice
The Trapdoor (OnTick): Any automated entry, exit, or trailing stop logic you write into this EA is protected by the if(disciplineBreached) return; block. If you are on the wrong account, the EA completely paralyzes itself.
The Constant Monitor (OnTimer): Because checking only on startup (OnInit) isn't enough (you could change accounts while the platform is running), the OnTimer function checks the account login every single second.
Visual Hostility: If a breach is detected, it doesn't just quietly disable itself. It draws a 3000x3000 pixel solid red square over your chart with massive white text declaring it an unauthorized account, while pinging your system with alert dialogues and sounds.
By running this in your default chart template, you ensure that logging into a "play money" broker promo immediately confronts you with a blaring red screen—giving your logical brain the exact friction it needs to override the impulse.
Re: Separate play money account killed my discipline story
Posted: Thu Sep 24, 2026 10:06 am
by FTtrader
Here is the Expert Advisor converted for MetaTrader 5.
MQL5 handles account identifiers and chart objects slightly differently than MQL4. The most critical change here is upgrading the account login variable to a ulong (unsigned long) to accommodate MT5's larger account numbers, and calculating the exact chart dimensions dynamically to ensure the visual lockdown covers the screen perfectly.
Save this file in your MQL5\Experts folder as OneBookGuardian.mq5.
Code: Select all
//+------------------------------------------------------------------+
//| OneBookGuardian.mq5 |
//| Continuous EA monitor to enforce trading discipline |
//+------------------------------------------------------------------+
#property copyright "Gemini"
#property version "1.00"
//--- Input Parameters
input ulong AuthorizedLiveAccount = 12345678; // Your SINGLE Authorized Live Account
input bool AllowDemoTrading = true; // Allow execution on Demo for research
//--- Global Variables
bool disciplineBreached = false;
string warningObjName = "DISCIPLINE_LOCKDOWN_LABEL";
string bgObjName = "DISCIPLINE_LOCKDOWN_BG";
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Set a 1-second timer to constantly check the account status
EventSetTimer(1);
// Run an immediate check on startup
VerifyEnvironment();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
EventKillTimer();
UnlockChart(); // Clean up graphics when removed
}
//+------------------------------------------------------------------+
//| Expert tick function (Automated Trading Logic goes here) |
//+------------------------------------------------------------------+
void OnTick()
{
// RULE 1: If discipline is breached, kill all automated trading
if(disciplineBreached)
{
// The EA exits immediately without executing any trade logic
return;
}
// --- YOUR AUTOMATED TRADING LOGIC GOES BELOW THIS LINE ---
// If the EA gets to this point, you are safely in your main book.
}
//+------------------------------------------------------------------+
//| Timer function (Constant Environment Monitoring) |
//+------------------------------------------------------------------+
void OnTimer()
{
VerifyEnvironment();
if(disciplineBreached)
{
// Continuous psychological friction if the warning is ignored
Alert("RED FLAG: Unauthorized Account! Leakage trains the same hands.");
PlaySound("timeout.wav");
}
}
//+------------------------------------------------------------------+
//| Core Logic: Verifies the current account |
//+------------------------------------------------------------------+
void VerifyEnvironment()
{
// In MQL5, logins are long/ulong variables
ulong currentAccount = (ulong)AccountInfoInteger(ACCOUNT_LOGIN);
long tradeMode = AccountInfoInteger(ACCOUNT_TRADE_MODE);
bool isDemo = (tradeMode == ACCOUNT_TRADE_MODE_DEMO);
bool isAuthorized = false;
if(isDemo)
{
if(AllowDemoTrading)
isAuthorized = true;
}
else // Live Environment
{
if(currentAccount == AuthorizedLiveAccount)
isAuthorized = true;
}
// Handle state changes
if(!isAuthorized && !disciplineBreached)
{
disciplineBreached = true;
LockdownChart();
Print("Discipline breach detected. Automated trading disabled.");
}
else if(isAuthorized && disciplineBreached)
{
disciplineBreached = false;
UnlockChart();
Print("Authorized environment confirmed. Systems restored.");
}
}
//+------------------------------------------------------------------+
//| UI functions: Psychological deterrents |
//+------------------------------------------------------------------+
void LockdownChart()
{
// Create a massive red background blocking the chart
if(ObjectFind(0, bgObjName) < 0)
{
ObjectCreate(0, bgObjName, OBJ_RECTANGLE_LABEL, 0, 0, 0);
ObjectSetInteger(0, bgObjName, OBJPROP_XDISTANCE, 0);
ObjectSetInteger(0, bgObjName, OBJPROP_YDISTANCE, 0);
// Attempt to cover the entire screen dynamically using MQL5 chart properties
int width = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
int height = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
ObjectSetInteger(0, bgObjName, OBJPROP_XSIZE, (width > 0) ? width : 4000);
ObjectSetInteger(0, bgObjName, OBJPROP_YSIZE, (height > 0) ? height : 4000);
ObjectSetInteger(0, bgObjName, OBJPROP_BGCOLOR, clrRed);
ObjectSetInteger(0, bgObjName, OBJPROP_BACK, false);
ObjectSetInteger(0, bgObjName, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, bgObjName, OBJPROP_HIDDEN, true); // Keep out of object list
}
// Add giant warning text
if(ObjectFind(0, warningObjName) < 0)
{
ObjectCreate(0, warningObjName, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, warningObjName, OBJPROP_XDISTANCE, 50);
ObjectSetInteger(0, warningObjName, OBJPROP_YDISTANCE, 100);
ObjectSetString(0, warningObjName, OBJPROP_TEXT, "UNAUTHORIZED PLAY ACCOUNT");
ObjectSetString(0, warningObjName, OBJPROP_FONT, "Arial Black");
ObjectSetInteger(0, warningObjName, OBJPROP_FONTSIZE, 36);
ObjectSetInteger(0, warningObjName, OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, warningObjName, OBJPROP_BACK, false);
ObjectSetInteger(0, warningObjName, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, warningObjName, OBJPROP_HIDDEN, true);
}
ChartRedraw(0);
}
void UnlockChart()
{
ObjectDelete(0, bgObjName);
ObjectDelete(0, warningObjName);
ChartRedraw(0);
}
//+------------------------------------------------------------------+
Re: Separate play money account killed my discipline story
Posted: Thu Sep 24, 2026 10:07 am
by FTtrader
Here is the "One Book" Guardian converted for cTrader.
Because cTrader Automate uses modern C# and has a robust built-in UI framework, the chart lockdown feature is even cleaner to implement here than in MetaTrader. Instead of calculating screen pixels, we can use a UI Border control that automatically stretches to cover 100% of the chart, dynamically resizing itself if you change the window size.
The "One Book" Guardian cBot (C#)
To use this, open cTrader, go to the Automate tab, create a new cBot, and paste this code over the default template.
Code: Select all
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class OneBookGuardian : Robot
{
//--- Input Parameters
[Parameter("Authorized Live Account", DefaultValue = 12345678, Group = "Discipline Settings")]
public int AuthorizedLiveAccount { get; set; }
[Parameter("Allow Demo Trading", DefaultValue = true, Group = "Discipline Settings")]
public bool AllowDemoTrading { get; set; }
//--- Global Variables
private bool disciplineBreached = false;
private Border lockdownScreen;
protected override void OnStart()
{
// Initialize the UI elements immediately
InitializeLockdownUI();
// Run an immediate check on startup
VerifyEnvironment();
// Set a 1-second timer to constantly check the account status
Timer.Start(TimeSpan.FromSeconds(1));
}
protected override void OnTick()
{
// RULE 1: If discipline is breached, kill all automated trading
if (disciplineBreached)
{
// The cBot exits immediately without executing any trade logic
return;
}
// --- YOUR AUTOMATED TRADING LOGIC GOES BELOW THIS LINE ---
// If the cBot gets to this point, you are safely in your main book.
}
protected override void OnTimer()
{
VerifyEnvironment();
if (disciplineBreached)
{
// Continuous psychological friction if the warning is ignored
Print("RED FLAG: Unauthorized Account! Leakage trains the same hands.");
Notifications.PlaySound(SoundType.Warning); // Native cTrader warning sound
}
}
private void VerifyEnvironment()
{
// Gather current account information in cTrader
int currentAccount = Account.Number;
bool isLive = Account.IsLive;
bool isAuthorized = false;
// Rule 1: Research stays on demo.
if (!isLive)
{
if (AllowDemoTrading)
isAuthorized = true;
}
else // Live Environment
{
// Rule 2: No side accounts. One book.
if (currentAccount == AuthorizedLiveAccount)
isAuthorized = true;
}
// Handle state changes
if (!isAuthorized && !disciplineBreached)
{
disciplineBreached = true;
LockdownChart();
Print("Discipline breach detected. Automated trading disabled.");
}
else if (isAuthorized && disciplineBreached)
{
disciplineBreached = false;
UnlockChart();
Print("Authorized environment confirmed. Systems restored.");
}
}
//+------------------------------------------------------------------+
//| UI functions: Psychological deterrents |
//+------------------------------------------------------------------+
private void InitializeLockdownUI()
{
// Create a full-screen red border that automatically stretches
lockdownScreen = new Border
{
BackgroundColor = Color.Red,
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
IsVisible = false // Hidden by default
};
// Add massive warning text inside the border
var textBlock = new TextBlock
{
Text = "UNAUTHORIZED PLAY ACCOUNT\nLeakage trains the same hands.",
ForegroundColor = Color.White,
FontSize = 32,
FontWeight = FontWeight.ExtraBold,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
TextAlignment = TextAlignment.Center
};
lockdownScreen.Child = textBlock;
// Add to the chart so it sits on top of all price action
Chart.AddControl(lockdownScreen);
}
private void LockdownChart()
{
if (lockdownScreen != null)
lockdownScreen.IsVisible = true;
}
private void UnlockChart()
{
if (lockdownScreen != null)
lockdownScreen.IsVisible = false;
}
}
}