Hard daily loss stop vs soft throttle: how I apply both in practice
-
LondonScalper
- Posts: 323
- Joined: Sat Sep 05, 2026 7:54 am
Hard daily loss stop vs soft throttle: how I apply both in practice
Risk process that sits above any single setup.
I use two layers so I’m not binary — either “full send” or “account blown.”
Hard daily loss stop
A cash number (or R multiple) where the platform day ends. Flat, no exceptions, no “tiny” tickets to get flat emotionally. This is survival. I want it boring and slightly conservative.
Soft throttle
Earlier checkpoints. Example: after −1R, size steps down. After two process strikes, I switch to observation or A+ only. After a large green morning, I also throttle — protecting a good day is risk management, not superstition.
The soft layer exists because hitting the hard stop every other week means the hard stop is doing too much work. Throttles catch the spiral earlier.
What I write before the open
• Hard stop level
• Throttle points
• Whether today is normal size, half size (post-holiday, post-news week), or observation
I don’t move the hard stop mid-session because I’m “due.” I will tighten the soft throttle if sleep or distraction is obvious.
Curious how others combine a hard floor with earlier brakes without turning the day into constant self-policing. The goal is fewer decisions under stress, not more.
I use two layers so I’m not binary — either “full send” or “account blown.”
Hard daily loss stop
A cash number (or R multiple) where the platform day ends. Flat, no exceptions, no “tiny” tickets to get flat emotionally. This is survival. I want it boring and slightly conservative.
Soft throttle
Earlier checkpoints. Example: after −1R, size steps down. After two process strikes, I switch to observation or A+ only. After a large green morning, I also throttle — protecting a good day is risk management, not superstition.
The soft layer exists because hitting the hard stop every other week means the hard stop is doing too much work. Throttles catch the spiral earlier.
What I write before the open
• Hard stop level
• Throttle points
• Whether today is normal size, half size (post-holiday, post-news week), or observation
I don’t move the hard stop mid-session because I’m “due.” I will tighten the soft throttle if sleep or distraction is obvious.
Curious how others combine a hard floor with earlier brakes without turning the day into constant self-policing. The goal is fewer decisions under stress, not more.
Re: Hard daily loss stop vs soft throttle: how I apply both in practice
Hi LondonScalper,LondonScalper wrote: Sat Sep 12, 2026 9:01 pm Risk process that sits above any single setup.
I use two layers so I’m not binary — either “full send” or “account blown.”
Hard daily loss stop
A cash number (or R multiple) where the platform day ends. Flat, no exceptions, no “tiny” tickets to get flat emotionally. This is survival. I want it boring and slightly conservative.
Soft throttle
Earlier checkpoints. Example: after −1R, size steps down. After two process strikes, I switch to observation or A+ only. After a large green morning, I also throttle — protecting a good day is risk management, not superstition.
The soft layer exists because hitting the hard stop every other week means the hard stop is doing too much work. Throttles catch the spiral earlier.
What I write before the open
• Hard stop level
• Throttle points
• Whether today is normal size, half size (post-holiday, post-news week), or observation
I don’t move the hard stop mid-session because I’m “due.” I will tighten the soft throttle if sleep or distraction is obvious.
Curious how others combine a hard floor with earlier brakes without turning the day into constant self-policing. The goal is fewer decisions under stress, not more.
Great breakdown. Your two-layer system is super useful, especially the concept of using soft throttles so your hard stop isn't doing all the heavy lifting. Writing down those checkpoints before the open to reduce decision fatigue is a great habit.
I use a similar hard floor for my downside, but what works best for me actually goes a bit in the opposite direction when it comes to your point about throttling down after a large green morning.
Time to time, if I have a strong start and I'm sitting on solid profits, I will actually increase my risk later in the session. I only risk the money I’ve already made that day, using that intraday cushion to size up on a prime setup.
My mindset is that in the absolute worst-case scenario, the trade fails and I just end up right back where I started at the morning bell—flat for the day with zero damage to my core account. But on the flip side, if the trade works, it can turn a standard green day into a massive one.
It definitely requires strict discipline so you don't accidentally dip back into your principal, but leveraging those daily profits to push my edge has been a huge boost to my upside. Thanks again for sharing your framework!
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Hard daily loss stop vs soft throttle: how I apply both in practice
Plus i made script for this:
Here is a complete Pine Script v5 strategy template built around your three-tier money management framework.
This script functions as a "risk wrapper." It dynamically calculates your daily PnL, adjusts your position size on the fly, and halts trading if you hit your hard stop. I've included a dummy moving average crossover just so the script compiles and runs, which you can replace with your actual price action triggers.
Here is a complete Pine Script v5 strategy template built around your three-tier money management framework.
This script functions as a "risk wrapper." It dynamically calculates your daily PnL, adjusts your position size on the fly, and halts trading if you hit your hard stop. I've included a dummy moving average crossover just so the script compiles and runs, which you can replace with your actual price action triggers.
Code: Select all
//@version=5
strategy("Intraday Risk Manager [House Money System]", overlay=true, calc_on_every_tick=true, initial_capital=10000)
// =========================================================================
// 1. INPUTS & RISK PARAMETERS
// =========================================================================
grp_risk = "Core Risk Parameters"
baseRiskPct = input.float(1.0, title="Base Risk per Trade (%)", group=grp_risk)
hardStopPct = input.float(3.0, title="Hard Daily Loss Stop (%)", tooltip="Platform shuts down if daily loss hits this %", group=grp_risk)
softStopPct = input.float(1.0, title="Soft Throttle Drawdown (%)", tooltip="Drawdown % where size is cut in half", group=grp_risk)
grp_house = "House Money (Scaling up on profits)"
useHouseMoney = input.bool(true, title="Enable House Money Scaling?", group=grp_house)
profitThreshold = input.float(2.0, title="Profit Threshold to Scale (%)", tooltip="Daily profit % required to start risking house money", group=grp_house)
riskProfitPct = input.float(100.0, title="% of Daily Profit to Risk", tooltip="100% means you risk all intraday profits on the next setup. If you lose, you return to break-even for the day.", group=grp_house)
// =========================================================================
// 2. DAILY PNL TRACKING
// =========================================================================
var float startOfDayEquity = strategy.initial_capital
var float currentRiskPct = baseRiskPct
var bool canTradeToday = true
// Detect new trading day
isNewDay = ta.change(time("D")) != 0
if isNewDay
startOfDayEquity := strategy.equity
canTradeToday := true
// Calculate current daily performance
dailyPnL = strategy.equity - startOfDayEquity
dailyPnLPct = (dailyPnL / startOfDayEquity) * 100
// =========================================================================
// 3. THE RISK ENGINE
// =========================================================================
// Rule A: Hard Stop
if dailyPnLPct <= -hardStopPct
canTradeToday := false
// Rule B & C: Throttles and House Money
if canTradeToday
if dailyPnLPct <= -softStopPct
// Soft throttle: Cut size in half to catch the spiral
currentRiskPct := baseRiskPct * 0.5
else if useHouseMoney and dailyPnLPct >= profitThreshold
// House money: Risk a percentage of the profits you've already made today
// We use math.max to ensure you at least risk your base amount
houseMoneyRisk = dailyPnLPct * (riskProfitPct / 100)
currentRiskPct := math.max(baseRiskPct, houseMoneyRisk)
else
// Standard operating size
currentRiskPct := baseRiskPct
// =========================================================================
// 4. EXECUTION (Replace with your actual setups)
// =========================================================================
// Dummy triggers for demonstration
fastMA = ta.sma(close, 9)
slowMA = ta.sma(close, 21)
longSetup = ta.crossover(fastMA, slowMA)
shortSetup = ta.crossunder(fastMA, slowMA)
// Calculate position size based on current dynamic risk and a fixed 1% Stop Loss
// Formula: Size = (Equity * Risk%) / (Price * SL%)
fixedSlPct = 1.0
posSize = (strategy.equity * (currentRiskPct / 100)) / (close * (fixedSlPct / 100))
if longSetup and canTradeToday and strategy.opentrades == 0
strategy.entry("Long", strategy.long, qty=posSize)
strategy.exit("Exit Long", "Long", loss=close * (fixedSlPct/100) / syminfo.mintick, profit=close * (fixedSlPct*2/100) / syminfo.mintick)
if shortSetup and canTradeToday and strategy.opentrades == 0
strategy.entry("Short", strategy.short, qty=posSize)
strategy.exit("Exit Short", "Short", loss=close * (fixedSlPct/100) / syminfo.mintick, profit=close * (fixedSlPct*2/100) / syminfo.mintick)
// =========================================================================
// 5. ON-CHART DASHBOARD
// =========================================================================
var table dash = table.new(position.top_right, 2, 4, border_width = 1, border_color=color.new(color.gray, 50))
if barstate.islast
// Daily PnL
table.cell(dash, 0, 0, "Daily PnL %", bgcolor=color.new(color.black, 20), text_color=color.white)
table.cell(dash, 1, 0, str.tostring(dailyPnLPct, "#.##") + "%", bgcolor=dailyPnLPct > 0 ? color.new(color.green, 50) : color.new(color.red, 50), text_color=color.white)
// Active Risk
table.cell(dash, 0, 1, "Current Risk %", bgcolor=color.new(color.black, 20), text_color=color.white)
table.cell(dash, 1, 1, str.tostring(currentRiskPct, "#.##") + "%", bgcolor=color.new(color.blue, 50), text_color=color.white)
// System Status
table.cell(dash, 0, 2, "Status", bgcolor=color.new(color.black, 20), text_color=color.white)
table.cell(dash, 1, 2, canTradeToday ? "ACTIVE" : "HALTED", bgcolor=canTradeToday ? color.new(color.green, 50) : color.new(color.red, 50), text_color=color.white)
// Current Mode
table.cell(dash, 0, 3, "State", bgcolor=color.new(color.black, 20), text_color=color.white)
modeText = not canTradeToday ? "Hard Stop Hit" : dailyPnLPct <= -softStopPct ? "Throttled Down" : (useHouseMoney and dailyPnLPct >= profitThreshold) ? "House Money" : "Standard Size"
table.cell(dash, 1, 3, modeText, bgcolor=color.new(color.black, 0), text_color=color.white)Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Hard daily loss stop vs soft throttle: how I apply both in practice
How the Logic Handles Your Rules
The Soft Throttle: If your daily PnL drops below the Soft Throttle Drawdown threshold (default -1%), the risk engine intercepts your position sizing and forces it to baseRiskPct * 0.5.
The Hard Stop: If equity drops to your hard threshold (default -3%), canTradeToday flips to false. The engine will ignore all valid setups for the remainder of the session until isNewDay resets it at the next daily open.
The "House Money" Free Roll: When your daily profits cross the profitThreshold, the engine calculates your risk based strictly on the day's green PnL. If you set % of Daily Profit to Risk to 100%, a full stop-out will simply wipe out your intraday profits, leaving you flat for the day without touching your start-of-day principal.
The Dashboard: Prints a small heads-up display in the top right corner so you can see exactly which state the risk engine is currently in (Standard, Throttled, House Money, or Halted) without having to guess your sizing.
The Soft Throttle: If your daily PnL drops below the Soft Throttle Drawdown threshold (default -1%), the risk engine intercepts your position sizing and forces it to baseRiskPct * 0.5.
The Hard Stop: If equity drops to your hard threshold (default -3%), canTradeToday flips to false. The engine will ignore all valid setups for the remainder of the session until isNewDay resets it at the next daily open.
The "House Money" Free Roll: When your daily profits cross the profitThreshold, the engine calculates your risk based strictly on the day's green PnL. If you set % of Daily Profit to Risk to 100%, a full stop-out will simply wipe out your intraday profits, leaving you flat for the day without touching your start-of-day principal.
The Dashboard: Prints a small heads-up display in the top right corner so you can see exactly which state the risk engine is currently in (Standard, Throttled, House Money, or Halted) without having to guess your sizing.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Hard daily loss stop vs soft throttle: how I apply both in practice
Unlike Pine Script, which manages the whole equity curve natively over time, MQL4 and MQL5 operate tick-by-tick within an Expert Advisor. To implement this dynamic framework, you need a standalone function that calculates your intraday closed and open profit, reconstructs your start-of-day equity, and outputs the exact risk percentage to use for your next order.
MQL4 Implementation
Insert this function into your EA. Call GetDynamicRiskPct() right before calculating your lot size. If it returns 0.0, halt execution.
MQL4 Implementation
Insert this function into your EA. Call GetDynamicRiskPct() right before calculating your lot size. If it returns 0.0, halt execution.
Code: Select all
// --- Input Variables ---
input double InpBaseRiskPct = 1.0;
input double InpHardStopPct = 3.0;
input double InpSoftStopPct = 1.0;
input bool InpUseHouseMoney = true;
input double InpProfitThresholdPct = 2.0;
input double InpRiskProfitPct = 100.0;
// --- Calculate Intraday Risk ---
double GetDynamicRiskPct() {
datetime startOfDay = iTime(Symbol(), PERIOD_D1, 0);
double closedProfitToday = 0.0;
// Sum closed trades for today
for (int i = 0; i < OrdersHistoryTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
if (OrderCloseTime() >= startOfDay) {
closedProfitToday += OrderProfit() + OrderSwap() + OrderCommission();
}
}
}
// Sum open floating profit
double openProfit = 0.0;
for (int i = 0; i < OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
openProfit += OrderProfit() + OrderSwap() + OrderCommission();
}
}
double dailyPnL = closedProfitToday + openProfit;
// Reconstruct start-of-day equity (assumes no intraday deposits/withdrawals)
double startOfDayEquity = AccountBalance() - closedProfitToday;
if (startOfDayEquity <= 0) startOfDayEquity = AccountBalance();
double dailyPnLPct = (dailyPnL / startOfDayEquity) * 100.0;
// Rule A: Hard Stop
if (dailyPnLPct <= -InpHardStopPct) return 0.0;
// Rule B: Soft Throttle
if (dailyPnLPct <= -InpSoftStopPct) return InpBaseRiskPct * 0.5;
// Rule C: House Money Scaling
if (InpUseHouseMoney && dailyPnLPct >= InpProfitThresholdPct) {
double houseMoneyRisk = dailyPnLPct * (InpRiskProfitPct / 100.0);
return MathMax(InpBaseRiskPct, houseMoneyRisk);
}
return InpBaseRiskPct;
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Hard daily loss stop vs soft throttle: how I apply both in practice
MQL5 Implementation (MT5)
MQL5 isolates positions, orders, and deals. We must pull today's closed deals from history to find realized profit, then calculate floating equity.
MQL5 isolates positions, orders, and deals. We must pull today's closed deals from history to find realized profit, then calculate floating equity.
Code: Select all
// --- Input Variables ---
input double InpBaseRiskPct = 1.0;
input double InpHardStopPct = 3.0;
input double InpSoftStopPct = 1.0;
input bool InpUseHouseMoney = true;
input double InpProfitThresholdPct = 2.0;
input double InpRiskProfitPct = 100.0;
// --- Calculate Intraday Risk ---
double GetDynamicRiskPct() {
datetime startOfDay = iTime(_Symbol, PERIOD_D1, 0);
HistorySelect(startOfDay, TimeCurrent());
double closedProfitToday = 0.0;
int deals = HistoryDealsTotal();
// Sum closed deals for today
for (int i = 0; i < deals; i++) {
ulong ticket = HistoryDealGetTicket(i);
if (ticket > 0) {
long entryType = HistoryDealGetInteger(ticket, DEAL_ENTRY);
// Only aggregate exits
if (entryType == DEAL_ENTRY_OUT || entryType == DEAL_ENTRY_OUT_BY) {
closedProfitToday += HistoryDealGetDouble(ticket, DEAL_PROFIT) +
HistoryDealGetDouble(ticket, DEAL_SWAP) +
HistoryDealGetDouble(ticket, DEAL_COMMISSION);
}
}
}
// Floating profit = Current Equity - Current Balance
double openProfit = AccountInfoDouble(ACCOUNT_EQUITY) - AccountInfoDouble(ACCOUNT_BALANCE);
double dailyPnL = closedProfitToday + openProfit;
// Reconstruct start-of-day equity
double startOfDayEquity = AccountInfoDouble(ACCOUNT_BALANCE) - closedProfitToday;
if (startOfDayEquity <= 0) startOfDayEquity = AccountInfoDouble(ACCOUNT_BALANCE);
double dailyPnLPct = (dailyPnL / startOfDayEquity) * 100.0;
// Rule A: Hard Stop
if (dailyPnLPct <= -InpHardStopPct) return 0.0;
// Rule B: Soft Throttle
if (dailyPnLPct <= -InpSoftStopPct) return InpBaseRiskPct * 0.5;
// Rule C: House Money Scaling
if (InpUseHouseMoney && dailyPnLPct >= InpProfitThresholdPct) {
double houseMoneyRisk = dailyPnLPct * (InpRiskProfitPct / 100.0);
return MathMax(InpBaseRiskPct, houseMoneyRisk);
}
return InpBaseRiskPct;
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Hard daily loss stop vs soft throttle: how I apply both in practice
Integration Example
Instead of hardcoding a fixed lot risk per trade, grab the dynamic percentage inside your main OnTick() loop before opening orders:
Instead of hardcoding a fixed lot risk per trade, grab the dynamic percentage inside your main OnTick() loop before opening orders:
Code: Select all
double currentRisk = GetDynamicRiskPct();
if (currentRisk <= 0.0) {
Comment("System Halted: Daily Hard Stop Hit");
return; // Block all new entries today
}
// Proceed with order execution using currentRisk for lot sizingPreserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Hard daily loss stop vs soft throttle: how I apply both in practice
Because cTrader natively supports C# and LINQ, you can bypass the clunky loops required in MQL. The History and Positions collections natively include .NetProfit (which automatically bundles swap and commission), making the intraday PnL calculation extremely clean.
Code: Select all
using System;
using System.Linq;
using cAlgo.API;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class IntradayRiskManager : Robot
{
// --- Input Parameters ---
[Parameter("Base Risk per Trade (%)", Group = "Core Risk", DefaultValue = 1.0)]
public double BaseRiskPct { get; set; }
[Parameter("Hard Daily Loss Stop (%)", Group = "Core Risk", DefaultValue = 3.0)]
public double HardStopPct { get; set; }
[Parameter("Soft Throttle Drawdown (%)", Group = "Core Risk", DefaultValue = 1.0)]
public double SoftStopPct { get; set; }
[Parameter("Enable House Money Scaling?", Group = "House Money", DefaultValue = true)]
public bool UseHouseMoney { get; set; }
[Parameter("Profit Threshold to Scale (%)", Group = "House Money", DefaultValue = 2.0)]
public double ProfitThresholdPct { get; set; }
[Parameter("% of Daily Profit to Risk", Group = "House Money", DefaultValue = 100.0)]
public double RiskProfitPct { get; set; }
// --- Core Risk Engine ---
private double GetDynamicRiskPct()
{
// 1. Define start of the trading day based on broker server time
DateTime startOfDay = Server.Time.Date;
// 2. Sum closed profit for today (NetProfit already includes commissions + swap)
double closedProfitToday = History
.Where(trade => trade.ClosingTime >= startOfDay)
.Sum(trade => trade.NetProfit);
// 3. Sum open floating profit
double openProfit = Positions.Sum(pos => pos.NetProfit);
double dailyPnL = closedProfitToday + openProfit;
// 4. Reconstruct Start-of-Day Equity
double startOfDayEquity = Account.Balance - closedProfitToday;
if (startOfDayEquity <= 0)
startOfDayEquity = Account.Balance; // Fallback
double dailyPnLPct = (dailyPnL / startOfDayEquity) * 100.0;
// Rule A: Hard Stop
if (dailyPnLPct <= -HardStopPct)
return 0.0;
// Rule B: Soft Throttle
if (dailyPnLPct <= -SoftStopPct)
return BaseRiskPct * 0.5;
// Rule C: House Money Scaling
if (UseHouseMoney && dailyPnLPct >= ProfitThresholdPct)
{
double houseMoneyRisk = dailyPnLPct * (RiskProfitPct / 100.0);
return Math.Max(BaseRiskPct, houseMoneyRisk); // Ensures you never scale down below base risk during a green streak
}
// Default: Standard size
return BaseRiskPct;
}
// --- Execution Loop Example ---
protected override void OnTick()
{
double currentRiskPct = GetDynamicRiskPct();
// Intercept and halt if hard stop is hit
if (currentRiskPct <= 0.0)
{
Chart.DrawStaticText("RiskStatus", "SYSTEM HALTED: Hard Stop Hit",
VerticalAlignment.Top, HorizontalAlignment.Right, Color.Red);
// Block all further trade entry logic
return;
}
Chart.DrawStaticText("RiskStatus", $"Active Risk: {currentRiskPct:F2}%",
VerticalAlignment.Top, HorizontalAlignment.Right, Color.DodgerBlue);
// -------------------------------------------------------------
// Place your price action triggers and execution logic below.
// When calculating volume/lot size, use currentRiskPct.
// -------------------------------------------------------------
}
}
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Hard daily loss stop vs soft throttle: how I apply both in practice
Note on Daily Reset Timing
Server.Time.Date effectively grabs 00:00:00 of the broker's current day. If you trade an asset class where your personal session starts at a different specific hour (like the New York open or after the Asian session rollover), you can easily offset the startOfDay variable to isolate the PnL to just your active window.
Server.Time.Date effectively grabs 00:00:00 of the broker's current day. If you trade an asset class where your personal session starts at a different specific hour (like the New York open or after the Asian session rollover), you can easily offset the startOfDay variable to isolate the PnL to just your active window.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
-
LondonScalper
- Posts: 323
- Joined: Sat Sep 05, 2026 7:54 am
Re: Hard daily loss stop vs soft throttle: how I apply both in practice
You’re describing the mirror image of my soft throttle — and I see why it feels clean on paper. Worst case you finish flat; best case you stretch a green morning.PTScalper wrote:if I have a strong start and I'm sitting on solid profits, I will actually increase my risk later in the session. I only risk the money I’ve already made that day.
I don’t size up off the day’s cushion. Too many afternoons the “house money” ticket turned a solid day into a soft-throttle day. After a large green morning I cut risk one notch and keep the hard floor untouched. Soft checkpoints at −0.5R and −1R still apply; the hard stop never moves.
Concrete process: realised P&L is ring-fenced in the blotter as closed. It does not feed the next ticket’s size calculator. That removes the argument at 14:00 London.
Gently: using only profits as cushion works until you mis-tag open risk as “already made.” How do you hard-cap that sized-up ticket so slippage cannot dip back into principal?