How I structure the London open → NY overlap without overtrading the first hour
How I structure the London open → NY overlap without overtrading the first hour
Session structure gets discussed as clock times. The part that actually changes results for me is what I am allowed to do in each segment of the London-to-New-York window, especially on majors and gold.
Rough framework I use (broker time adjusted to the desk you trade; the labels matter more than the exact hour stamps):
Phase A — London open / early London. Liquidity improves, but the first burst is often positioning and stop-driven noise. My default is observation and mark-up only: overnight range, prior day high/low, obvious liquidity pools, and whether price is accepting or rejecting those levels. I do not need a trade in the first 30–60 minutes to "participate." Participation without a clear process is just donation with a tighter spread.
Phase B — Mid-London into pre-overlap. This is where I allow setups that match a pre-defined playbook — for example continuation after a sweep and reclaim, or a failed break of a level that mattered on M15/H1. Still one symbol bias. Still full risk rules. If Phase A was chaotic and I am mentally chasing, I stay in reduced size even if the chart looks clean. Using a single timeframe in isolation means you are making decisions with a genuinely incomplete picture; I want the higher-timeframe condition settled before M1 execution feels urgent.
Phase C — London/NY overlap. Best liquidity for many scalpers, and also the easiest stretch to overtrade because "conditions are good." Good conditions are not a reason to increase frequency. They are a reason to require the same A+ criteria with better fills. I cap the number of attempts in the overlap. A soft limit (for example three executed ideas) beats an open-ended "trade while it's liquid" mandate.
Phase D — Post-overlap wind-down. Spreads and behavior change. My default is flatten and review, not hunt one last scalp to finish green. Ending flat with rule compliance is a winning day even if P&L is small. Ending green after breaking the session plan is how bad habits get reinforced.
What this structure is trying to prevent is the classic scalper failure mode: early noise fills the journal with forced trades, the overlap becomes revenge or euphoria, and the afternoon is cleanup. The clock did not fail. The permission system did.
If you work a similar map, I would like to hear how you handle the first London hour specifically — flat, reduced size, or full size — and what evidence made you choose that. Session edges are real. Unstructured permission inside those sessions is still just discretionary chaos with better average spreads.
Rough framework I use (broker time adjusted to the desk you trade; the labels matter more than the exact hour stamps):
Phase A — London open / early London. Liquidity improves, but the first burst is often positioning and stop-driven noise. My default is observation and mark-up only: overnight range, prior day high/low, obvious liquidity pools, and whether price is accepting or rejecting those levels. I do not need a trade in the first 30–60 minutes to "participate." Participation without a clear process is just donation with a tighter spread.
Phase B — Mid-London into pre-overlap. This is where I allow setups that match a pre-defined playbook — for example continuation after a sweep and reclaim, or a failed break of a level that mattered on M15/H1. Still one symbol bias. Still full risk rules. If Phase A was chaotic and I am mentally chasing, I stay in reduced size even if the chart looks clean. Using a single timeframe in isolation means you are making decisions with a genuinely incomplete picture; I want the higher-timeframe condition settled before M1 execution feels urgent.
Phase C — London/NY overlap. Best liquidity for many scalpers, and also the easiest stretch to overtrade because "conditions are good." Good conditions are not a reason to increase frequency. They are a reason to require the same A+ criteria with better fills. I cap the number of attempts in the overlap. A soft limit (for example three executed ideas) beats an open-ended "trade while it's liquid" mandate.
Phase D — Post-overlap wind-down. Spreads and behavior change. My default is flatten and review, not hunt one last scalp to finish green. Ending flat with rule compliance is a winning day even if P&L is small. Ending green after breaking the session plan is how bad habits get reinforced.
What this structure is trying to prevent is the classic scalper failure mode: early noise fills the journal with forced trades, the overlap becomes revenge or euphoria, and the afternoon is cleanup. The clock did not fail. The permission system did.
If you work a similar map, I would like to hear how you handle the first London hour specifically — flat, reduced size, or full size — and what evidence made you choose that. Session edges are real. Unstructured permission inside those sessions is still just discretionary chaos with better average spreads.
- Attachments
-
- 05-permission-plain.png (31.59 KiB) Viewed 633 times
It’s Fairman 
-
LondonScalper
- Posts: 965
- Joined: Sat Sep 05, 2026 7:54 am
Re: How I structure the London open → NY overlap without overtrading the first hour
Clock times without permissions are just a pretty schedule.
I like segmenting the window by what is allowed:
London open (first ~60–90m) — A+ only, predefined pairs, hard max trades
Mid-London — fewer tickets; don’t invent a second style because you’re bored
Overlap — correlation-aware; USD bucket cap; still A+ location
Late NY — often flat unless a planned runner management
The rule that cut overtrading for me: max tickets per segment, written before the open. When the count is done, the session segment is done — even if “one more” looks tempting.
Do you hard-stop new entries a fixed number of minutes before NY open, or only by setup quality?
I like segmenting the window by what is allowed:
London open (first ~60–90m) — A+ only, predefined pairs, hard max trades
Mid-London — fewer tickets; don’t invent a second style because you’re bored
Overlap — correlation-aware; USD bucket cap; still A+ location
Late NY — often flat unless a planned runner management
The rule that cut overtrading for me: max tickets per segment, written before the open. When the count is done, the session segment is done — even if “one more” looks tempting.
Do you hard-stop new entries a fixed number of minutes before NY open, or only by setup quality?
Re: How I structure the London open → NY overlap without overtrading the first hour
To answer your question: Hard-stop by time, always.LondonScalper wrote: Wed Sep 09, 2026 10:53 am Clock times without permissions are just a pretty schedule.
I like segmenting the window by what is allowed:
London open (first ~60–90m) — A+ only, predefined pairs, hard max trades
Mid-London — fewer tickets; don’t invent a second style because you’re bored
Overlap — correlation-aware; USD bucket cap; still A+ location
Late NY — often flat unless a planned runner management
The rule that cut overtrading for me: max tickets per segment, written before the open. When the count is done, the session segment is done — even if “one more” looks tempting.
Do you hard-stop new entries a fixed number of minutes before NY open, or only by setup quality?
Setup quality becomes an illusion in the immediate runway to the NY open. In the 15–30 minutes before the pre-market macro drops (8:30 AM EST) and the equities bell (9:30 AM EST), the order book thins out. If you are scalping with size, the sudden spread widening, liquidity vacuums, and slippage in that pre-NY window will completely wreck the expected value of an otherwise A+ structure.
If you are translating this into an algorithm or a semi-automated assist, a "dead zone" time fence is mandatory. The logic should be binary: if the clock is within 30 minutes of the NY bell, new entry requests return false, regardless of what the M1 or M5 is doing.
If the setup is genuinely A+, the opportunity will still be there, with much cleaner execution, after the opening volatility settles and the overlap establishes its true direction. Treating time as a strict permission filter—just like structure and spread—is exactly how you survive the chop.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: How I structure the London open → NY overlap without overtrading the first hour
Here is how you can build this logic in MQL4.
To make this robust for a high-volume environment, the script needs to check both open and closed positions (MODE_TRADES and MODE_HISTORY) to ensure the ticket count remains accurate regardless of how fast trades are opened and closed.
To make this robust for a high-volume environment, the script needs to check both open and closed positions (MODE_TRADES and MODE_HISTORY) to ensure the ticket count remains accurate regardless of how fast trades are opened and closed.
Code: Select all
extern int MaxLondonTickets = 3;
extern int MagicNumber = 12345;
extern string LondonStart = "08:00";
extern string LondonEnd = "11:00";
// 30-minute dead zone before NY Open (Broker server time)
extern string PreNY_DeadStart = "14:00";
extern string PreNY_DeadEnd = "14:30";
// Helper to convert "HH:MM" string to current day datetime
datetime StringToTimeToday(string timeStr) {
string today = TimeToStr(TimeCurrent(), TIME_DATE);
return StrToTime(today + " " + timeStr);
}
// 1. Pre-NY Dead Zone Gate
bool IsInDeadZone() {
datetime now = TimeCurrent();
datetime deadStart = StringToTimeToday(PreNY_DeadStart);
datetime deadEnd = StringToTimeToday(PreNY_DeadEnd);
return (now >= deadStart && now < deadEnd);
}
// 2. Ticket Counter for Segment
int CountTicketsInSegment(datetime segmentStart, datetime segmentEnd) {
int count = 0;
// Scan open trades
for(int i = 0; i < OrdersTotal(); i++) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
if(OrderOpenTime() >= segmentStart && OrderOpenTime() <= segmentEnd) count++;
}
}
}
// Scan closed history
for(int i = 0; i < OrdersHistoryTotal(); i++) {
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
if(OrderOpenTime() >= segmentStart && OrderOpenTime() <= segmentEnd) count++;
}
}
}
return count;
}
// 3. Main Permission Filter
bool IsTradePermitted() {
// Checkbox #0: Dead Zone Check
if (IsInDeadZone()) {
Print("Execution blocked: Pre-NY Dead Zone.");
return false;
}
datetime now = TimeCurrent();
datetime lonStart = StringToTimeToday(LondonStart);
datetime lonEnd = StringToTimeToday(LondonEnd);
// Segment Check: London Open
if (now >= lonStart && now <= lonEnd) {
int londonTickets = CountTicketsInSegment(lonStart, lonEnd);
if (londonTickets >= MaxLondonTickets) {
Print("Execution blocked: Max tickets (", MaxLondonTickets, ") reached for London segment.");
return false;
}
}
// Default state: Allowed if not in dead zone and ticket limits aren't breached
return true;
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: How I structure the London open → NY overlap without overtrading the first hour
Key Considerations for the Implementation:
String-to-Time Handling: By parsing string inputs ("08:00") into datetime against the current server date, you avoid having to hardcode daily offsets, making it cleaner to adjust parameters on the fly.
Broker Server Time vs. Local Time: Ensure the PreNY_DeadStart and PreNY_DeadEnd variables are calibrated to your specific broker's server time (e.g., standard UTC+2 or UTC+3), as TimeCurrent() pulls the broker's clock, not your local workstation time.
Database Query Load: Calling OrdersHistoryTotal() repeatedly inside a tick loop can be heavy. If you run this on a highly aggressive scalper, consider tracking the daily ticket count locally in a global variable or static variable in memory to reduce MT4 database queries on every tick.
String-to-Time Handling: By parsing string inputs ("08:00") into datetime against the current server date, you avoid having to hardcode daily offsets, making it cleaner to adjust parameters on the fly.
Broker Server Time vs. Local Time: Ensure the PreNY_DeadStart and PreNY_DeadEnd variables are calibrated to your specific broker's server time (e.g., standard UTC+2 or UTC+3), as TimeCurrent() pulls the broker's clock, not your local workstation time.
Database Query Load: Calling OrdersHistoryTotal() repeatedly inside a tick loop can be heavy. If you run this on a highly aggressive scalper, consider tracking the daily ticket count locally in a global variable or static variable in memory to reduce MT4 database queries on every tick.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: How I structure the London open → NY overlap without overtrading the first hour
Here is the MQL5 implementation.
The biggest advantage when moving this logic from MQL4 to MQL5 is how MetaTrader 5 handles the historical database. Instead of looping through both open trades and closed history pools separately, MQL5 uses Deals.
The moment an order executes, a deal (DEAL_ENTRY_IN) is written to history. This means we only need to query the history cache once to get a perfectly accurate ticket count for the session segment, covering both currently open positions and already closed trades.
The biggest advantage when moving this logic from MQL4 to MQL5 is how MetaTrader 5 handles the historical database. Instead of looping through both open trades and closed history pools separately, MQL5 uses Deals.
The moment an order executes, a deal (DEAL_ENTRY_IN) is written to history. This means we only need to query the history cache once to get a perfectly accurate ticket count for the session segment, covering both currently open positions and already closed trades.
Code: Select all
input int MaxLondonTickets = 3;
input ulong MagicNumber = 12345; // ulong is required for MQL5 magic numbers
input string LondonStart = "08:00";
input string LondonEnd = "11:00";
// 30-minute dead zone before NY Open (Broker server time)
input string PreNY_DeadStart = "14:00";
input string PreNY_DeadEnd = "14:30";
// Helper to convert "HH:MM" string to current day datetime
datetime StringToTimeToday(string timeStr) {
string today = TimeToString(TimeCurrent(), TIME_DATE);
return StringToTime(today + " " + timeStr);
}
// 1. Pre-NY Dead Zone Gate
bool IsInDeadZone() {
datetime now = TimeCurrent();
datetime deadStart = StringToTimeToday(PreNY_DeadStart);
datetime deadEnd = StringToTimeToday(PreNY_DeadEnd);
return (now >= deadStart && now < deadEnd);
}
// 2. Ticket Counter for Segment
int CountTicketsInSegment(datetime segmentStart, datetime segmentEnd) {
int count = 0;
// MQL5 requires loading the history cache for the specific timeframe first
if(HistorySelect(segmentStart, segmentEnd)) {
int dealsTotal = HistoryDealsTotal();
for(int i = 0; i < dealsTotal; i++) {
ulong dealTicket = HistoryDealGetTicket(i);
if(dealTicket > 0) {
// We only want to count new entries, not exits (DEAL_ENTRY_OUT)
long dealEntry = HistoryDealGetInteger(dealTicket, DEAL_ENTRY);
if(dealEntry == DEAL_ENTRY_IN) {
string dealSymbol = HistoryDealGetString(dealTicket, DEAL_SYMBOL);
long dealMagic = HistoryDealGetInteger(dealTicket, DEAL_MAGIC);
if(dealSymbol == _Symbol && dealMagic == MagicNumber) {
count++;
}
}
}
}
}
return count;
}
// 3. Main Permission Filter
bool IsTradePermitted() {
// Checkbox #0: Dead Zone Check
if (IsInDeadZone()) {
Print("Execution blocked: Pre-NY Dead Zone.");
return false;
}
datetime now = TimeCurrent();
datetime lonStart = StringToTimeToday(LondonStart);
datetime lonEnd = StringToTimeToday(LondonEnd);
// Segment Check: London Open
if (now >= lonStart && now <= lonEnd) {
int londonTickets = CountTicketsInSegment(lonStart, lonEnd);
if (londonTickets >= MaxLondonTickets) {
PrintFormat("Execution blocked: Max tickets (%d) reached for London segment.", MaxLondonTickets);
return false;
}
}
// Default state: Allowed if not in dead zone and ticket limits aren't breached
return true;
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: How I structure the London open → NY overlap without overtrading the first hour
Performance Note for High-Volume Scalping
While MQL5’s HistorySelect() is highly efficient, querying it on literally every tick inside OnTick() can still generate unnecessary CPU overhead on localized workstations if you are running multiple expert advisors simultaneously.
To optimize this for high-frequency environments, you can implement an in-memory counter. Define a global variable int CurrentSessionTickets = 0; that increments inside OnTradeTransaction() when a new DEAL_ENTRY_IN is confirmed. You would then only query HistorySelect() inside OnInit() to reconstruct the state in case of an EA restart or terminal crash.
While MQL5’s HistorySelect() is highly efficient, querying it on literally every tick inside OnTick() can still generate unnecessary CPU overhead on localized workstations if you are running multiple expert advisors simultaneously.
To optimize this for high-frequency environments, you can implement an in-memory counter. Define a global variable int CurrentSessionTickets = 0; that increments inside OnTradeTransaction() when a new DEAL_ENTRY_IN is confirmed. You would then only query HistorySelect() inside OnInit() to reconstruct the state in case of an EA restart or terminal crash.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: How I structure the London open → NY overlap without overtrading the first hour
Here is how you can implement this logic in TradingView using Pine Script v5.
Since TradingView evaluates scripts sequentially on every historical bar, we have to use the var keyword to create a persistent state counter that tracks the number of generated alerts during the active session.
Since TradingView evaluates scripts sequentially on every historical bar, we have to use the var keyword to create a persistent state counter that tracks the number of generated alerts during the active session.
Code: Select all
//@version=5
indicator("Session & Ticket Limits", overlay=true)
// --- Inputs ---
maxLondonTickets = input.int(3, title="Max London Tickets")
// Timezones in Pine use Exchange time by default. You can append timezones like ":GMT-4" if needed.
londonSession = input.session("0800-1100", title="London Session")
deadZoneSession = input.session("1400-1430", title="Pre-NY Dead Zone")
// --- Session State Tracking ---
inLondon = not na(time(timeframe.period, londonSession))
inDeadZone = not na(time(timeframe.period, deadZoneSession))
// Use 'var' to persist the count across bars
var int londonTicketCount = 0
var bool wasInLondon = false
// Reset counter when a new London session begins
if inLondon and not wasInLondon
londonTicketCount := 0
// Update the previous state tracker
wasInLondon := inLondon
// --- Mock Strategy Trigger ---
// Replace this with your actual A+ structural alignment logic
mockEntrySignal = ta.crossover(ta.sma(close, 10), ta.sma(close, 20))
// --- Permission Gate ---
bool isPermitted = true
// Rule 1: Dead Zone Block
if inDeadZone
isPermitted := false
// Rule 2: Max Ticket Block
if inLondon and (londonTicketCount >= maxLondonTickets)
isPermitted := false
// Final Executable Trigger
validEntry = mockEntrySignal and isPermitted
// --- State Update & Alert ---
if validEntry
// Increment the ticket counter if we execute inside the constrained segment
if inLondon
londonTicketCount += 1
// Fire the webhook/alert
alert("Valid Entry Triggered - Ticket #" + str.tostring(londonTicketCount), alert.freq_once_per_bar)
// --- Visual Debugging ---
bgcolor(inDeadZone ? color.new(color.red, 90) : na, title="Dead Zone")
bgcolor(inLondon ? color.new(color.blue, 90) : na, title="London Session")
plotshape(validEntry, style=shape.triangleup, location=location.belowbar, color=color.green, size=size.small, title="Entry")Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: How I structure the London open → NY overlap without overtrading the first hour
Key Differences in the Pine Environment
State Management (var)
Unlike MQL5 where you can poll the broker's historical database at will, Pine Script requires you to manage state internally as it iterates through time series data. The var londonTicketCount = 0 declaration ensures the variable is initialized only once and retains its value from bar to bar.
Session Boundaries and Timeframes
The time() function checks if the current bar falls within the designated string. By default, this aligns with the chart's Exchange time. If you are feeding alerts to a cTrader or MT5 execution bot via webhooks, ensure the TradingView session string timezone aligns perfectly with the destination broker's server time to avoid execution mismatches.
Repainting Safety
By checking the entry condition and incrementing the counter inside the same local block, you ensure the script only counts finalized triggers, avoiding false increments caused by intra-bar price fluctuations.
State Management (var)
Unlike MQL5 where you can poll the broker's historical database at will, Pine Script requires you to manage state internally as it iterates through time series data. The var londonTicketCount = 0 declaration ensures the variable is initialized only once and retains its value from bar to bar.
Session Boundaries and Timeframes
The time() function checks if the current bar falls within the designated string. By default, this aligns with the chart's Exchange time. If you are feeding alerts to a cTrader or MT5 execution bot via webhooks, ensure the TradingView session string timezone aligns perfectly with the destination broker's server time to avoid execution mismatches.
Repainting Safety
By checking the entry condition and incrementing the counter inside the same local block, you ensure the script only counts finalized triggers, avoiding false increments caused by intra-bar price fluctuations.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: How I structure the London open → NY overlap without overtrading the first hour
Here is the C# implementation for cTrader.
In the cAlgo API, tracking the historical and active tickets is streamlined via the History and Positions collections. Instead of integer Magic Numbers, cTrader uses string Label assignments to group and track algorithmic executions.
In the cAlgo API, tracking the historical and active tickets is streamlined via the History and Positions collections. Instead of integer Magic Numbers, cTrader uses string Label assignments to group and track algorithmic executions.
Code: Select all
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class SessionTicketLimiter : Robot
{
[Parameter("Max London Tickets", DefaultValue = 3)]
public int MaxLondonTickets { get; set; }
[Parameter("Bot Label", DefaultValue = "A_Plus_Scalper")]
public string BotLabel { get; set; }
[Parameter("London Start (HH:MM)", DefaultValue = "08:00")]
public string LondonStartStr { get; set; }
[Parameter("London End (HH:MM)", DefaultValue = "11:00")]
public string LondonEndStr { get; set; }
[Parameter("Pre-NY Dead Start", DefaultValue = "14:00")]
public string PreNYDeadStartStr { get; set; }
[Parameter("Pre-NY Dead End", DefaultValue = "14:30")]
public string PreNYDeadEndStr { get; set; }
private TimeSpan _lonStart, _lonEnd, _deadStart, _deadEnd;
protected override void OnStart()
{
// Parse time strings into TimeSpans for efficient daily evaluation
TimeSpan.TryParse(LondonStartStr, out _lonStart);
TimeSpan.TryParse(LondonEndStr, out _lonEnd);
TimeSpan.TryParse(PreNYDeadStartStr, out _deadStart);
TimeSpan.TryParse(PreNYDeadEndStr, out _deadEnd);
}
private bool IsInDeadZone()
{
TimeSpan currentTime = Server.Time.TimeOfDay;
return currentTime >= _deadStart && currentTime < _deadEnd;
}
private int CountTicketsInSegment(TimeSpan startTime, TimeSpan endTime)
{
// Project the TimeSpans onto today's date
DateTime today = Server.Time.Date;
DateTime start = today.Add(startTime);
DateTime end = today.Add(endTime);
// Query active open positions
int openCount = Positions.Count(p => p.SymbolName == Symbol.Name
&& p.Label == BotLabel
&& p.EntryTime >= start
&& p.EntryTime <= end);
// Query closed history
int closedCount = History.Count(h => h.SymbolName == Symbol.Name
&& h.Label == BotLabel
&& h.EntryTime >= start
&& h.EntryTime <= end);
return openCount + closedCount;
}
private bool IsTradePermitted()
{
// Rule 1: Dead Zone Block
if (IsInDeadZone())
{
Print("Execution blocked: Pre-NY Dead Zone.");
return false;
}
TimeSpan currentTime = Server.Time.TimeOfDay;
// Rule 2: Segment Check (London Open)
if (currentTime >= _lonStart && currentTime <= _lonEnd)
{
int londonTickets = CountTicketsInSegment(_lonStart, _lonEnd);
if (londonTickets >= MaxLondonTickets)
{
Print("Execution blocked: Max tickets ({0}) reached for London segment.", MaxLondonTickets);
return false;
}
}
// Default state: Allowed if no fences are breached
return true;
}
protected override void OnTick()
{
if (!IsTradePermitted())
return;
// Trigger execution logic follows here
}
}
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.