Tagging slippage separately from spread in the trade journal
-
LondonScalper
- Posts: 701
- Joined: Sat Sep 05, 2026 7:54 am
Tagging slippage separately from spread in the trade journal
Journal hygiene that changed how I read my own results.
For years I dumped everything into “costs.” That hid the difference between a wide but honest spread and a fill that printed away from the quote I clicked.
Two tags, always
1. Spread at click — what the platform showed when I sent the order.
2. Slippage — fill price minus that mid/ask (side-aware), in points or ticks.
A ticket can have a normal spread and ugly slippage. Another can be expensive on spread but fill exactly. Mixing them made me blame the “broker” generally instead of fixing either my timing or my order type.
Review habit
Once a week I filter for slippage worse than X on my usual pairs. Patterns I look for: first minutes after data, XAU around round numbers, market orders into a stalling book. If the same window keeps showing up, that window gets a process rule — stand aside, limit only, or half size — not a motivational speech.
I also note reject / requote separately so a no-fill doesn’t get mis-tagged as slippage.
This is boring bookkeeping. It’s also how you stop arguing with anecdotes. If you already split these fields, what threshold makes a ticket “execution review” rather than normal noise?
For years I dumped everything into “costs.” That hid the difference between a wide but honest spread and a fill that printed away from the quote I clicked.
Two tags, always
1. Spread at click — what the platform showed when I sent the order.
2. Slippage — fill price minus that mid/ask (side-aware), in points or ticks.
A ticket can have a normal spread and ugly slippage. Another can be expensive on spread but fill exactly. Mixing them made me blame the “broker” generally instead of fixing either my timing or my order type.
Review habit
Once a week I filter for slippage worse than X on my usual pairs. Patterns I look for: first minutes after data, XAU around round numbers, market orders into a stalling book. If the same window keeps showing up, that window gets a process rule — stand aside, limit only, or half size — not a motivational speech.
I also note reject / requote separately so a no-fill doesn’t get mis-tagged as slippage.
This is boring bookkeeping. It’s also how you stop arguing with anecdotes. If you already split these fields, what threshold makes a ticket “execution review” rather than normal noise?
Re: Tagging slippage separately from spread in the trade journal
Hi LondonScalper,LondonScalper wrote: Sat Sep 12, 2026 8:48 pm Journal hygiene that changed how I read my own results.
For years I dumped everything into “costs.” That hid the difference between a wide but honest spread and a fill that printed away from the quote I clicked.
Two tags, always
1. Spread at click — what the platform showed when I sent the order.
2. Slippage — fill price minus that mid/ask (side-aware), in points or ticks.
A ticket can have a normal spread and ugly slippage. Another can be expensive on spread but fill exactly. Mixing them made me blame the “broker” generally instead of fixing either my timing or my order type.
Review habit
Once a week I filter for slippage worse than X on my usual pairs. Patterns I look for: first minutes after data, XAU around round numbers, market orders into a stalling book. If the same window keeps showing up, that window gets a process rule — stand aside, limit only, or half size — not a motivational speech.
I also note reject / requote separately so a no-fill doesn’t get mis-tagged as slippage.
This is boring bookkeeping. It’s also how you stop arguing with anecdotes. If you already split these fields, what threshold makes a ticket “execution review” rather than normal noise?
This is the kind of “boring” bookkeeping that separates the survivors from the statistics. Blaming the broker is a rite of passage, but realizing that market orders into a thin book during a volatility spike is actually a trader-error is a massive milestone.
To answer your question directly: Static thresholds fail because noise is contextual. A 3-tick slippage on the ES (S&P 500) during the Asian session is an execution anomaly; a 3-tick slippage during the first 5 minutes of the NY open is just the cost of doing business.
Here is how I split my thresholds to separate "normal noise" from an "execution review" ticket:
1. The Dynamic Threshold (The ATR Rule)
Instead of a fixed tick-value, I tie my slippage threshold to the 1-minute Average True Range (ATR) at the time of execution.
Normal Noise: Slippage ≤ 10-15% of the 1-minute ATR. The market is just breathing.
Execution Review: Slippage > 15% of the 1-minute ATR. If I get slipped 20% of a 1-minute candle's entire range, my timing was wrong, my liquidity read was wrong, or I traded directly into a news sweep.
2. The Spread Multiplier
For forex and metals (like XAU), spreads expand wildly. My rule for "Execution Review":
If the Spread at click was > 2.5x the historical average for that session, the ticket gets flagged. The review isn't about the broker; it's asking myself, "Why was I rushing to cross the spread when liquidity was pulled?"
3. Order-Type Flags
If a limit order receives negative slippage (filled worse than the limit price, which implies a platform/routing glitch) or gets rejected on a touch, that goes into a strict Broker Issue bucket. If that bucket fills up, the broker gets cut.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Tagging slippage separately from spread in the trade journal
Pine Script: Dynamic Execution Risk Threshold
Since you are already tracking this, I wrote a Pine Script that visualizes this dynamic threshold. You can load this into a lower pane. It calculates what your "Acceptable Slippage" threshold should be based on real-time volatility, outputting the exact number of ticks/pips.
If your journaled slippage exceeds the red line on this indicator at the time of your trade, it's an execution review ticket. It also highlights background zones where market orders are statistically dangerous.
Since you are already tracking this, I wrote a Pine Script that visualizes this dynamic threshold. You can load this into a lower pane. It calculates what your "Acceptable Slippage" threshold should be based on real-time volatility, outputting the exact number of ticks/pips.
If your journaled slippage exceeds the red line on this indicator at the time of your trade, it's an execution review ticket. It also highlights background zones where market orders are statistically dangerous.
Code: Select all
//@version=5
indicator("Dynamic Execution Threshold [Journal Hygiene]", overlay=false)
// =========================================================================
// INPUTS
// =========================================================================
fixedSpread = input.float(2.0, title="Typical Spread (Ticks/Pips)", tooltip="Your broker's baseline spread for this asset")
atrLength = input.int(14, title="ATR Length", tooltip="Length for volatility calculation")
atrMultiplier = input.float(0.15, title="Slippage Anomaly Threshold (% of ATR)", step=0.05, tooltip="How much of the ATR constitutes 'normal' slippage? (0.15 = 15%)")
riskSpikeMult = input.float(3.0, title="Danger Zone Multiplier", tooltip="Highlight chart when dynamic threshold exceeds this multiple of the baseline spread")
// =========================================================================
// CALCULATIONS
// =========================================================================
// Fetch minimum tick size for the current symbol
tickSize = syminfo.mintick
// Calculate current volatility
currentAtr = ta.atr(atrLength)
// Convert fixed spread input into absolute price value
baselineSpreadValue = fixedSpread * tickSize
// Calculate the Dynamic Slippage Threshold (Baseline Spread + Expected Volatility Slippage)
dynamicThresholdValue = baselineSpreadValue + (currentAtr * atrMultiplier)
// Convert back to Ticks/Pips for easy reading in the Data Window
thresholdInTicks = dynamicThresholdValue / tickSize
// =========================================================================
// PLOTTING
// =========================================================================
// Plot the Baseline as a calm, steady reference
plot(fixedSpread, title="Baseline Spread (Ticks)", color=color.new(color.gray, 30), style=plot.style_circles)
// Plot the Dynamic Threshold - This is your Journaling Benchmark
plot(thresholdInTicks, title="Review Threshold (Ticks)", color=color.new(color.red, 0), linewidth=2)
// Highlight periods of extreme illiquidity/volatility (The "Stand Aside" or "Limit Only" zones)
isDangerZone = thresholdInTicks > (fixedSpread * riskSpikeMult)
bgcolor(isDangerZone ? color.new(color.red, 90) : na, title="High Slippage Risk Zone")Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Tagging slippage separately from spread in the trade journal
When you do your weekly review, you can cross-reference your timestamp with this script's value. If you paid 4 ticks of slippage and the script says the threshold was 2.5 ticks, you know you forced a market order into a stalling or thin book.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Tagging slippage separately from spread in the trade journal
What you are describing is the retail equivalent of institutional Transaction Cost Analysis (TCA). Amateurs bleed capital through unmeasured execution drag and blame the broker; professionals isolate their strategy’s alpha decay from their infrastructure’s inefficiency.
Separating the quoted spread (liquidity cost) from the slippage (latency/market impact cost) is precisely how you optimize execution.
To answer your question regarding thresholds: Static tick thresholds are fundamentally flawed because they ignore liquidity regimes. A 3-tick slip in a thick ES order book is an execution failure; the same slip during the first 60 seconds of the NY open is standard crossing cost.
Here is the quantitative framework I use to isolate standard microstructure noise from a flagged "execution review":
1. Volatility-Normalized Benchmarking
Never measure slippage in absolute ticks; measure it as a function of real-time volatility. I benchmark slippage against the 1-minute Average True Range (ATR) at the exact time of the fill.
Microstructure Noise: Slippage ≤ 10-15% of the 1m ATR.
Execution Review: Slippage > 15% of the 1m ATR. If your fill slips by 20% of a 1-minute candle's entire rotational range, you traded directly into a liquidity void, your timing was off-cycle, or your latency is unacceptable.
2. Spread-to-Historical Mean Ratio
For assets with elastic books (XAU, FX), market makers pull liquidity predictably around data and structural shifts.
The Flag: If the quoted spread at the time of your click exceeds 2.5x the rolling session mean, the ticket is flagged.
The Review: This is an audit of your decision-making, not the broker. The question becomes: "Why did my process dictate crossing the spread with a market order when liquidity providers were explicitly stepping back?"
3. Deterministic Routing Failures
Any limit order that fills at a worse price (negative slippage) or is rejected on a confirmed touch is strictly tagged as an Infrastructure Anomaly. This has nothing to do with your strategy. If this specific tag's frequency breaches a standard deviation, you change your broker, routing, or feed provider.
Separating the quoted spread (liquidity cost) from the slippage (latency/market impact cost) is precisely how you optimize execution.
To answer your question regarding thresholds: Static tick thresholds are fundamentally flawed because they ignore liquidity regimes. A 3-tick slip in a thick ES order book is an execution failure; the same slip during the first 60 seconds of the NY open is standard crossing cost.
Here is the quantitative framework I use to isolate standard microstructure noise from a flagged "execution review":
1. Volatility-Normalized Benchmarking
Never measure slippage in absolute ticks; measure it as a function of real-time volatility. I benchmark slippage against the 1-minute Average True Range (ATR) at the exact time of the fill.
Microstructure Noise: Slippage ≤ 10-15% of the 1m ATR.
Execution Review: Slippage > 15% of the 1m ATR. If your fill slips by 20% of a 1-minute candle's entire rotational range, you traded directly into a liquidity void, your timing was off-cycle, or your latency is unacceptable.
2. Spread-to-Historical Mean Ratio
For assets with elastic books (XAU, FX), market makers pull liquidity predictably around data and structural shifts.
The Flag: If the quoted spread at the time of your click exceeds 2.5x the rolling session mean, the ticket is flagged.
The Review: This is an audit of your decision-making, not the broker. The question becomes: "Why did my process dictate crossing the spread with a market order when liquidity providers were explicitly stepping back?"
3. Deterministic Routing Failures
Any limit order that fills at a worse price (negative slippage) or is rejected on a confirmed touch is strictly tagged as an Infrastructure Anomaly. This has nothing to do with your strategy. If this specific tag's frequency breaches a standard deviation, you change your broker, routing, or feed provider.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Tagging slippage separately from spread in the trade journal
Pine Script: Dynamic TCA & Execution Risk Model
To systemize this, I built a Pine Script that calculates your acceptable execution drag threshold dynamically. It outputs the exact tick/pip limit for "acceptable slippage" based on real-time volatility.
During your weekly review, cross-reference your journaled timestamps with this indicator. If you paid 4 ticks of slippage and the script dictates the threshold was 2.5 ticks, you objectively forced a market order into a thin book.
To systemize this, I built a Pine Script that calculates your acceptable execution drag threshold dynamically. It outputs the exact tick/pip limit for "acceptable slippage" based on real-time volatility.
During your weekly review, cross-reference your journaled timestamps with this indicator. If you paid 4 ticks of slippage and the script dictates the threshold was 2.5 ticks, you objectively forced a market order into a thin book.
Code: Select all
//@version=5
indicator("Dynamic TCA & Execution Risk [Journal]", overlay=false)
// =========================================================================
// QUANTITATIVE INPUTS
// =========================================================================
baseLiqCost = input.float(2.0, title="Base Liquidity Cost (Ticks/Pips)", tooltip="Your broker's baseline spread for this specific asset")
volLength = input.int(14, title="Volatility Lookback (1m ATR)", tooltip="Lookback period for microstructure volatility calculation")
slipTolerance = input.float(0.15, title="Slippage Tolerance (% of ATR)", step=0.05, tooltip="Threshold for execution review. 0.15 = 15% of 1m ATR")
regimeMult = input.float(3.0, title="Illiquidity Regime Multiplier", tooltip="Highlights chart when dynamic slippage threshold exceeds this multiple of base cost")
// =========================================================================
// CORE CALCULATIONS
// =========================================================================
// Fetch symbol granularity
minTick = syminfo.mintick
// Calculate real-time microstructure volatility
currentVol = ta.atr(volLength)
// Convert base spread into absolute price value
baseSpreadValue = baseLiqCost * minTick
// Calculate Dynamic Execution Threshold (Base Cost + Volatility Impact)
dynamicThresholdPrice = baseSpreadValue + (currentVol * slipTolerance)
// Convert to output standard (Ticks/Pips)
thresholdTicks = dynamicThresholdPrice / minTick
// =========================================================================
// VISUALIZATION & LOGIC
// =========================================================================
// Plot Base Liquidity Cost (Static Reference)
plot(baseLiqCost, title="Base Cost (Ticks)", color=color.new(color.gray, 50), style=plot.style_circles)
// Plot Dynamic TCA Threshold (Execution Review Benchmark)
plot(thresholdTicks, title="Review Threshold (Ticks)", color=color.new(#ff0000, 0), linewidth=2)
// Identify and highlight structural illiquidity regimes (Stand-aside / Limit-only zones)
illiquidityRegime = thresholdTicks > (baseLiqCost * regimeMult)
bgcolor(illiquidityRegime ? color.new(#ff0000, 90) : na, title="High Market-Impact Zone")Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Tagging slippage separately from spread in the trade journal
Institutional execution desks do not track “costs”; they model implementation shortfall. Conflating the quoted liquidity premium (spread) with execution degradation (slippage) makes it impossible to isolate true alpha from routing inefficiencies or poor microstructure timing.
By bifurcating these metrics, you are transitioning from anecdotal frustration to Quantitative Transaction Cost Analysis (TCA).
To answer your specific question on thresholds: an execution anomaly cannot be defined by a static integer. A 3-tick variance is negligible during a CPI print but catastrophic during the Asian session doldrums. Standardized execution review thresholds must be dynamically anchored to real-time market variance.
Here is the institutional framework for flagging execution anomalies, followed by the quantitative modeling script.
By bifurcating these metrics, you are transitioning from anecdotal frustration to Quantitative Transaction Cost Analysis (TCA).
To answer your specific question on thresholds: an execution anomaly cannot be defined by a static integer. A 3-tick variance is negligible during a CPI print but catastrophic during the Asian session doldrums. Standardized execution review thresholds must be dynamically anchored to real-time market variance.
Here is the institutional framework for flagging execution anomalies, followed by the quantitative modeling script.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Tagging slippage separately from spread in the trade journal
I. Quantitative TCA Thresholds
Tickets are flagged for manual execution review only when they breach statistically significant boundaries. This prevents auditing normal market microstructure noise.
1. Volatility-Normalized Fill Degradation
Absolute ticks are irrelevant. Slippage must be measured as a function of the asset's realized variance at the millisecond of routing.
The Benchmark: We benchmark fill price against the 1-minute Average True Range (ATR) or the localized standard deviation of price.
The Threshold: A ticket is flagged for review if the execution degradation exceeds 15% of the 1-minute ATR.
The Diagnosis: If you are consistently slipping >15% of a candle’s entire rotational range, your execution logic is fundamentally flawed. You are either initiating market orders into adverse momentum sweeps, or your latency is allowing high-frequency market makers to pull liquidity before your order arrives.
Tickets are flagged for manual execution review only when they breach statistically significant boundaries. This prevents auditing normal market microstructure noise.
1. Volatility-Normalized Fill Degradation
Absolute ticks are irrelevant. Slippage must be measured as a function of the asset's realized variance at the millisecond of routing.
The Benchmark: We benchmark fill price against the 1-minute Average True Range (ATR) or the localized standard deviation of price.
The Threshold: A ticket is flagged for review if the execution degradation exceeds 15% of the 1-minute ATR.
The Diagnosis: If you are consistently slipping >15% of a candle’s entire rotational range, your execution logic is fundamentally flawed. You are either initiating market orders into adverse momentum sweeps, or your latency is allowing high-frequency market makers to pull liquidity before your order arrives.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Tagging slippage separately from spread in the trade journal
2. Spread Z-Score Outliers
Quoted spreads expand elastically based on inventory risk. Auditing a wide spread is useless unless it is a statistical outlier for that specific time of day.
The Benchmark: Calculate a rolling Z-score of the quoted spread.
The Threshold: Flag the ticket if the spread at the time of click exceeds a +2.0 Z-score (roughly the 95th percentile of normal session spread).
The Diagnosis: This is a process audit. Why does your model generate signals exactly when liquidity providers are withdrawing from the book? If the signal requires crossing a +2.0 $\sigma$ spread, the expected value (EV) of the trade must be exponentially higher to justify the entry.
3. Asymmetric Routing Failures
This isolates infrastructure decay from trader error.
The Benchmark: Limit order fills and touch-rejections.
The Threshold: Zero tolerance. Any limit order executing at a negative variance (worse than the limit price), or any hard rejection on adequate tier liquidity, is flagged.
The Diagnosis: If this specific bucket exceeds an acceptable weekly threshold, the routing venue, broker, or feed provider is deprecated.
Quoted spreads expand elastically based on inventory risk. Auditing a wide spread is useless unless it is a statistical outlier for that specific time of day.
The Benchmark: Calculate a rolling Z-score of the quoted spread.
The Threshold: Flag the ticket if the spread at the time of click exceeds a +2.0 Z-score (roughly the 95th percentile of normal session spread).
The Diagnosis: This is a process audit. Why does your model generate signals exactly when liquidity providers are withdrawing from the book? If the signal requires crossing a +2.0 $\sigma$ spread, the expected value (EV) of the trade must be exponentially higher to justify the entry.
3. Asymmetric Routing Failures
This isolates infrastructure decay from trader error.
The Benchmark: Limit order fills and touch-rejections.
The Threshold: Zero tolerance. Any limit order executing at a negative variance (worse than the limit price), or any hard rejection on adequate tier liquidity, is flagged.
The Diagnosis: If this specific bucket exceeds an acceptable weekly threshold, the routing venue, broker, or feed provider is deprecated.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Tagging slippage separately from spread in the trade journal
III. Quantitative TCA Pine Script
To systemize this review process, the following logic models an institutional slippage threshold using Z-scores and volatility benchmarking.
Instead of arbitrarily guessing if the market was "fast," this script calculates a rolling statistical baseline for expected liquidity costs. It flags exactly when the market enters an "Illiquidity Regime"—meaning any market order executed in the highlighted zones that incurs heavy slippage is a trader-timing error, not a broker issue.
To systemize this review process, the following logic models an institutional slippage threshold using Z-scores and volatility benchmarking.
Instead of arbitrarily guessing if the market was "fast," this script calculates a rolling statistical baseline for expected liquidity costs. It flags exactly when the market enters an "Illiquidity Regime"—meaning any market order executed in the highlighted zones that incurs heavy slippage is a trader-timing error, not a broker issue.
Code: Select all
//@version=5
indicator("Quantitative TCA & Execution Shortfall", overlay=false)
// =========================================================================
// ALGORITHMIC PARAMETERS
// =========================================================================
baseSpread = input.float(2.0, title="Expected Baseline Cost (Ticks)", tooltip="Mean spread during high-liquidity hours")
volPeriod = input.int(20, title="Variance Lookback", tooltip="Rolling window for volatility and standard deviation calculations")
slipTolerance = input.float(0.15, title="Shortfall Tolerance coefficient", step=0.01, tooltip="Acceptable slippage as a percentage of real-time ATR (e.g., 0.15 = 15%)")
zScoreLimit = input.float(2.0, title="Illiquidity Z-Score Threshold", step=0.25, tooltip="Highlights regimes where volatility/spreads exceed this standard deviation")
// =========================================================================
// CORE QUANTITATIVE LOGIC
// =========================================================================
minTick = syminfo.mintick
// 1. Real-time Microstructure Variance (ATR)
currentVol = ta.atr(volPeriod)
volInTicks = currentVol / minTick
// 2. Rolling Statistical Baseline (Mean & StdDev of Volatility)
volMean = ta.sma(volInTicks, volPeriod)
volStdDev = ta.stdev(volInTicks, volPeriod)
// 3. Dynamic Z-Score Calculation
// Z = (Current Value - Mean) / Standard Deviation
volZScore = volStdDev == 0 ? 0 : (volInTicks - volMean) / volStdDev
// 4. Dynamic Execution Threshold (Acceptable implementation shortfall in ticks)
// Formula: Baseline Spread + (Real-time Volatility * Tolerance Coefficient)
dynamicShortfallLimit = baseSpread + (volInTicks * slipTolerance)
// =========================================================================
// VISUALIZATION & OUTPUT
// =========================================================================
// Plot 1: Baseline Liquidity Cost (The theoretical perfect fill)
plot(baseSpread, title="Theoretical Base Cost", color=color.new(#787b86, 50), style=plot.style_circles)
// Plot 2: Quantitative TCA Threshold (Your max acceptable slippage benchmark)
plot(dynamicShortfallLimit, title="TCA Shortfall Limit (Ticks)", color=color.new(#ff1100, 0), linewidth=2)
// Regime Filter: Mathematically isolate periods of extreme adverse liquidity
isIlliquidRegime = volZScore >= zScoreLimit
// Paint background to indicate "Execution Danger Zones" (No market orders allowed)
bgcolor(isIlliquidRegime ? color.new(#ff1100, 92) : na, title="Illiquidity / High-Impact Regime")Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.