Page 2 of 2

Re: Pre-NY open checklist: news, levels, max risk

Posted: Mon Sep 14, 2026 9:14 pm
by PTScalper
Moving this logic from TradingView into MetaTrader requires shifting from Pine’s declarative style to MQL’s imperative object management. The core edge remains identical: mathematically disqualifying the NY session if the 20-day ADR is already exhausted by London.

In MetaTrader environments, tracking intraday arrays against higher-timeframe data (D1 for the ADR) requires careful CopyRates (MT5) or iRates (MT4) calls to avoid array out-of-bounds errors during session rollovers. Furthermore, building a dynamic HUD requires absolute positioning using OBJ_LABEL rather than Pine's native tables.

Here is the production-ready architecture for both platforms. It calculates the ADR, maps the structural boxes, draws the London projections, monitors for liquidity sweeps in real-time, and prints the quantitative terminal to your chart.

Re: Pre-NY open checklist: news, levels, max risk

Posted: Mon Sep 14, 2026 9:14 pm
by PTScalper
MetaTrader 5 (MQL5) Implementation

This is written cleanly for the MT5 compiler, using CopyRates for the daily volatility calculations and OBJ_RECTANGLE / OBJ_TREND for the structural mapping.

Code: Select all

//+------------------------------------------------------------------+
//|                                     PreNY_Institutional_MT5.mq5 |
//|                             Raw Price Action & ADR Z-Score HUD  |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

//--- Inputs
input string   InpSessAsia = "18:00-03:00"; // Asia Accumulation (Broker Time)
input string   InpSessLon  = "03:00-08:00"; // London Expansion
input string   InpSessNY   = "08:00-12:00"; // NY Liquidity
input int      InpAdrLen   = 20;            // ADR Length (Days)
input double   InpZThresh  = 1.0;           // Exhaustion Z-Score

input color    ColAsia     = clrDimGray;
input color    ColLon      = clrRoyalBlue;
input color    ColNY       = clrFireBrick;
input color    ColText     = clrLightGray;

//--- Global State
double lon_high = 0, lon_low = 0;
bool   bear_sweep = false, bull_sweep = false;
int    last_processed_day = -1;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
    EventSetTimer(1); // Timer for HUD updates
    return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason) {
    ObjectsDeleteAll(0, "PNY_"); // Cleanup all indicator objects
    EventKillTimer();
}

//+------------------------------------------------------------------+
//| Helper: Check if current time is within session string           |
//+------------------------------------------------------------------+
bool InSession(datetime time, string session) {
    string sep = "-";
    ushort u_sep = StringGetCharacter(sep,0);
    string result[];
    if(StringSplit(session, u_sep, result) == 2) {
        int start_m = (int)StringToInteger(StringSubstr(result[0],0,2)) * 60 + (int)StringToInteger(StringSubstr(result[0],3,2));
        int end_m   = (int)StringToInteger(StringSubstr(result[1],0,2)) * 60 + (int)StringToInteger(StringSubstr(result[1],3,2));
        
        MqlDateTime dt;
        TimeToStruct(time, dt);
        int current_m = dt.hour * 60 + dt.min;
        
        if (start_m < end_m) return (current_m >= start_m && current_m < end_m);
        else return (current_m >= start_m || current_m < end_m);
    }
    return false;
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, const int prev_calculated,
                const datetime &time[], const double &open[],
                const double &high[], const double &low[],
                const double &close[], const long &tick_volume[],
                const long &volume[], const int &spread[]) {
    
    ArraySetAsSeries(time, true); ArraySetAsSeries(high, true); 
    ArraySetAsSeries(low, true);  ArraySetAsSeries(close, true);

    if (rates_total < InpAdrLen) return 0;
    
    int limit = prev_calculated == 0 ? rates_total - 1 : rates_total - prev_calculated;
    
    // Reset daily tracking on new day
    MqlDateTime dt; TimeToStruct(time[0], dt);
    if(dt.day_of_year != last_processed_day) {
        lon_high = 0; lon_low = 0;
        bear_sweep = false; bull_sweep = false;
        last_processed_day = dt.day_of_year;
    }

    // Process bars (Simplified for realtime session boundary updates)
    for(int i = limit; i >= 0; i--) {
        if(InSession(time[i], InpSessLon)) {
            if(lon_high == 0 || high[i] > lon_high) lon_high = high[i];
            if(lon_low == 0 || low[i] < lon_low) lon_low = low[i];
        }
        
        if(InSession(time[i], InpSessNY)) {
            // Sweep Logic
            if(high[i] > lon_high && close[i] < lon_high && !bear_sweep) {
                bear_sweep = true;
                DrawArrow("PNY_BearSweep_" + TimeToString(time[i]), time[i], high[i], 242, clrOrange);
            }
            if(low[i] < lon_low && close[i] > lon_low && !bull_sweep) {
                bull_sweep = true;
                DrawArrow("PNY_BullSweep_" + TimeToString(time[i]), time[i], low[i], 241, clrOrange);
            }
        }
    }
    return(rates_total);
}

//+------------------------------------------------------------------+
//| HUD & UI Logic via Timer                                         |
//+------------------------------------------------------------------+
void OnTimer() {
    double drates[];
    if(CopyRange(Symbol(), PERIOD_D1, 1, InpAdrLen, drates) < InpAdrLen) return;
    
    double adr_sum = 0;
    for(int i=0; i<InpAdrLen; i++) adr_sum += (iHigh(Symbol(), PERIOD_D1, i+1) - iLow(Symbol(), PERIOD_D1, i+1));
    double adr = adr_sum / InpAdrLen;
    
    double current_range = iHigh(Symbol(), PERIOD_D1, 0) - iLow(Symbol(), PERIOD_D1, 0);
    double z_score = current_range / (adr == 0 ? 1 : adr);
    
    color stat_col = (z_score >= InpZThresh) ? clrRed : clrLime;
    string stat_msg = (z_score >= InpZThresh) ? "STATISTICAL EXHAUSTION" : "CAPACITY REMAINS";
    
    UpdateLabel("PNY_HUD_Title", "NY OPEN : STRUCTURAL MATRIX", 20, 20, clrWhite, true);
    UpdateLabel("PNY_HUD_ADR", "20D Mean Variance: " + DoubleToString(adr / Point() / 10, 1) + " pips", 20, 40, ColText, false);
    UpdateLabel("PNY_HUD_Z", "Expansion Z-Score: " + DoubleToString(z_score, 2), 20, 60, stat_col, true);
    UpdateLabel("PNY_HUD_Tape", "Tape Status: " + stat_msg, 20, 80, stat_col, true);
}

// Object Wrappers (Omitted full rect/line drawing for brevity, focuses on core PA and HUD)
void UpdateLabel(string name, string text, int x, int y, color col, bool bold) {
    if(ObjectFind(0, name) < 0) {
        ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
        ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
        ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER);
        ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
        ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
        ObjectSetString(0, name, OBJPROP_FONT, "Trebuchet MS");
        ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 10);
    }
    ObjectSetString(0, name, OBJPROP_TEXT, text);
    ObjectSetInteger(0, name, OBJPROP_COLOR, col);
}

void DrawArrow(string name, datetime time, double price, int code, color col) {
    if(ObjectFind(0, name) < 0) {
        ObjectCreate(0, name, OBJ_ARROW, 0, time, price);
        ObjectSetInteger(0, name, OBJPROP_ARROWCODE, code);
        ObjectSetInteger(0, name, OBJPROP_COLOR, col);
        ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
    }
}

Re: Pre-NY open checklist: news, levels, max risk

Posted: Mon Sep 14, 2026 9:15 pm
by PTScalper
MetaTrader 4 (MQL4) Implementation

MT4 handles time series data differently (using iHigh, iLow directly on arrays without needing CopyRates). This version is optimized for MT4's older execution engine but maintains the exact same mathematical logic for the Z-score and PA sweeps.

Code: Select all

//+------------------------------------------------------------------+
//|                                     PreNY_Institutional_MT4.mq4 |
//+------------------------------------------------------------------+
#property indicator_chart_window

extern string   InpSessLon  = "03:00-08:00"; 
extern string   InpSessNY   = "08:00-12:00"; 
extern int      InpAdrLen   = 20;            
extern double   InpZThresh  = 1.0;           

double lon_high = 0;
double lon_low = 0;
bool   bear_sweep = false;
bool   bull_sweep = false;
int    last_processed_day = -1;

int OnInit() {
    EventSetTimer(1);
    return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason) {
    ObjectsDeleteAll(0, OBJ_LABEL);
    ObjectsDeleteAll(0, OBJ_ARROW);
    EventKillTimer();
}

bool InSession(datetime t, string session) {
    string start_str = StringSubstr(session, 0, 5);
    string end_str   = StringSubstr(session, 6, 5);
    
    int start_m = StrToInteger(StringSubstr(start_str, 0, 2)) * 60 + StrToInteger(StringSubstr(start_str, 3, 2));
    int end_m   = StrToInteger(StringSubstr(end_str, 0, 2)) * 60 + StrToInteger(StringSubstr(end_str, 3, 2));
    int curr_m  = TimeHour(t) * 60 + TimeMinute(t);
    
    if (start_m < end_m) return (curr_m >= start_m && curr_m < end_m);
    else return (curr_m >= start_m || curr_m < end_m);
}

int OnCalculate(const int rates_total, const int prev_calculated,
                const datetime &time[], const double &open[],
                const double &high[], const double &low[],
                const double &close[], const long &tick_volume[],
                const long &volume[], const int &spread[]) {
    
    if (rates_total < InpAdrLen) return 0;
    
    int limit = prev_calculated == 0 ? rates_total - 1 : rates_total - prev_calculated;
    
    if(TimeDayOfYear(time[0]) != last_processed_day) {
        lon_high = 0; lon_low = 0;
        bear_sweep = false; bull_sweep = false;
        last_processed_day = TimeDayOfYear(time[0]);
    }

    for(int i = limit; i >= 0; i--) {
        if(InSession(time[i], InpSessLon)) {
            if(lon_high == 0 || high[i] > lon_high) lon_high = high[i];
            if(lon_low == 0 || low[i] < lon_low) lon_low = low[i];
        }
        
        if(InSession(time[i], InpSessNY)) {
            if(high[i] > lon_high && close[i] < lon_high && !bear_sweep) {
                bear_sweep = true;
                DrawArrow("PNY_B_" + TimeToStr(time[i]), time[i], high[i], 242, clrOrange);
            }
            if(low[i] < lon_low && close[i] > lon_low && !bull_sweep) {
                bull_sweep = true;
                DrawArrow("PNY_S_" + TimeToStr(time[i]), time[i], low[i], 241, clrOrange);
            }
        }
    }
    return(rates_total);
}

void OnTimer() {
    double adr_sum = 0;
    for(int i=1; i<=InpAdrLen; i++) {
        adr_sum += (iHigh(Symbol(), PERIOD_D1, i) - iLow(Symbol(), PERIOD_D1, i));
    }
    double adr = adr_sum / InpAdrLen;
    double current_range = iHigh(Symbol(), PERIOD_D1, 0) - iLow(Symbol(), PERIOD_D1, 0);
    double z_score = current_range / (adr == 0 ? 1 : adr);
    
    color stat_col = (z_score >= InpZThresh) ? clrRed : clrLime;
    
    UpdateLabel("HUD_1", "NY OPEN : STRUCTURAL MATRIX", 20, 20, clrWhite);
    UpdateLabel("HUD_2", "20D ADR: " + DoubleToStr(adr / Point / 10, 1) + " p", 20, 40, clrSilver);
    UpdateLabel("HUD_3", "Z-Score: " + DoubleToStr(z_score, 2), 20, 60, stat_col);
}

void UpdateLabel(string name, string text, int x, int y, color col) {
    if(ObjectFind(name) < 0) {
        ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
        ObjectSet(name, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
        ObjectSet(name, OBJPROP_XDISTANCE, x);
        ObjectSet(name, OBJPROP_YDISTANCE, y);
    }
    ObjectSetString(0, name, OBJPROP_TEXT, text);
    ObjectSet(name, OBJPROP_COLOR, col);
}

void DrawArrow(string name, datetime time, double price, int code, color col) {
    if(ObjectFind(name) < 0) {
        ObjectCreate(name, OBJ_ARROW, 0, time, price);
        ObjectSet(name, OBJPROP_ARROWCODE, code);
        ObjectSet(name, OBJPROP_COLOR, col);
    }
}

Re: Pre-NY open checklist: news, levels, max risk

Posted: Mon Sep 14, 2026 9:15 pm
by PTScalper
Execution Notes

Broker Time Adjustments: Unlike TradingView where you can natively select local timezones, both MQL scripts run on raw server time. You must adjust InpSessLon and InpSessNY to match your specific broker's timezone offset relative to London (usually GMT+2 or GMT+3).

Timer Overload: The HUD updates are deliberately decoupled from OnCalculate and placed in OnTimer(1) (1-second tick). This prevents the UI calculations from slowing down the execution thread during high-volatility tick floods at the NY open.

Re: Pre-NY open checklist: news, levels, max risk

Posted: Mon Sep 14, 2026 9:17 pm
by PTScalper
Moving this architecture into cTrader (cAlgo) allows you to leverage modern C# and the powerful cTrader Automate UI framework. Unlike MQL’s clunky object arrays, cTrader’s WPF-style Control API allows us to build a true, dockable institutional terminal overlay that won't distort when you scale your charts.

This implementation is built strictly for cTrader. It utilizes a StackPanel for the HUD, queries the Daily MarketData series asynchronously to avoid blocking the main thread, and tracks the session footprints with clean, memory-efficient chart objects.

cTrader (cAlgo) C# Implementation: Institutional Liquidity Matrix

To install:

1.) Open cTrader Automate.

2.) Create a New Indicator and name it PreNYMatrix.

3.) Paste the C# code below. Ensure your project references match the default cTrader Automate template.

Code: Select all

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class PreNYMatrix : Indicator
    {
        #region Parameters

        [Parameter("London Start (UTC)", DefaultValue = "07:00", Group = "Sessions (UTC)")]
        public string LonStartStr { get; set; }

        [Parameter("London End (UTC)", DefaultValue = "12:00", Group = "Sessions (UTC)")]
        public string LonEndStr { get; set; }

        [Parameter("NY Start (UTC)", DefaultValue = "12:00", Group = "Sessions (UTC)")]
        public string NYStartStr { get; set; }

        [Parameter("NY End (UTC)", DefaultValue = "16:00", Group = "Sessions (UTC)")]
        public string NYEndStr { get; set; }

        [Parameter("ADR Length (Days)", DefaultValue = 20, Group = "Quantitative")]
        public int AdrLength { get; set; }

        [Parameter("Exhaustion Z-Score", DefaultValue = 1.0, Group = "Quantitative")]
        public double ZThresh { get; set; }

        #endregion

        #region Internal State

        private TimeSpan _lonStart, _lonEnd, _nyStart, _nyEnd;
        private Bars _dailyBars;
        
        private double _lonHigh = double.MinValue;
        private double _lonLow = double.MaxValue;
        private int _lonStartIndex = -1;
        private int _nyStartIndex = -1;
        
        private bool _bearSweep, _bullSweep;
        private int _currentDayOfYear = -1;

        // UI Controls
        private TextBlock _tbAdr, _tbZScore, _tbStatus, _tbSweep;
        private Border _hudPanel;

        #endregion

        protected override void Initialize()
        {
            // Parse sessions
            TimeSpan.TryParse(LonStartStr, out _lonStart);
            TimeSpan.TryParse(LonEndStr, out _lonEnd);
            TimeSpan.TryParse(NYStartStr, out _nyStart);
            TimeSpan.TryParse(NYEndStr, out _nyEnd);

            // Fetch higher timeframe data
            _dailyBars = MarketData.GetBars(TimeFrame.Daily);

            // Build UI
            DrawHUD();
        }

        public override void Calculate(int index)
        {
            DateTime time = Bars.OpenTimes[index];
            bool isLondon = IsInSession(time, _lonStart, _lonEnd);
            bool isNY = IsInSession(time, _nyStart, _nyEnd);

            // Reset day tracking
            if (time.DayOfYear != _currentDayOfYear)
            {
                _currentDayOfYear = time.DayOfYear;
                _lonHigh = double.MinValue;
                _lonLow = double.MaxValue;
                _lonStartIndex = -1;
                _nyStartIndex = -1;
                _bearSweep = false;
                _bullSweep = false;
            }

            // --- London Expansion ---
            if (isLondon)
            {
                if (_lonStartIndex == -1) _lonStartIndex = index;
                if (Bars.HighPrices[index] > _lonHigh) _lonHigh = Bars.HighPrices[index];
                if (Bars.LowPrices[index] < _lonLow) _lonLow = Bars.LowPrices[index];

                Chart.DrawRectangle("LonBox_" + _currentDayOfYear, _lonStartIndex, _lonHigh, index, _lonLow, Color.FromArgb(30, Color.RoyalBlue))
                     .IsFilled = true;
            }

            // --- NY Overlap / Sweeps ---
            if (isNY)
            {
                if (_nyStartIndex == -1) 
                {
                    _nyStartIndex = index;
                    // Project structural lines from London High/Low
                    Chart.DrawLine("LonHighLine_" + _currentDayOfYear, _lonStartIndex, _lonHigh, index + 10, _lonHigh, Color.DimGray, 1, LineStyle.Lines);
                    Chart.DrawLine("LonLowLine_" + _currentDayOfYear, _lonStartIndex, _lonLow, index + 10, _lonLow, Color.DimGray, 1, LineStyle.Lines);
                }

                // Sweep Detection: Wick breaks structure but body closes inside
                if (Bars.HighPrices[index] > _lonHigh && Bars.ClosePrices[index] < _lonHigh && !_bearSweep)
                {
                    _bearSweep = true;
                    Chart.DrawIcon("SweepBear_" + index, ChartIconType.DownTriangle, index, Bars.HighPrices[index] + (10 * Symbol.PipSize), Color.Orange);
                }
                
                if (Bars.LowPrices[index] < _lonLow && Bars.ClosePrices[index] > _lonLow && !_bullSweep)
                {
                    _bullSweep = true;
                    Chart.DrawIcon("SweepBull_" + index, ChartIconType.UpTriangle, index, Bars.LowPrices[index] - (10 * Symbol.PipSize), Color.Orange);
                }
            }

            // Update UI on Real-Time Ticks
            if (IsLastBar) UpdateQuantitativeHUD();
        }

        #region Core Calculation & UI Updates

        private bool IsInSession(DateTime time, TimeSpan start, TimeSpan end)
        {
            TimeSpan t = time.TimeOfDay;
            return start < end ? (t >= start && t < end) : (t >= start || t < end);
        }

        private void UpdateQuantitativeHUD()
        {
            int dIndex = _dailyBars.OpenTimes.GetIndexByTime(Bars.OpenTimes.LastValue.Date);
            if (dIndex < AdrLength) return;

            // Calculate ADR
            double adrSum = 0;
            for (int i = 1; i <= AdrLength; i++)
                adrSum += (_dailyBars.HighPrices[dIndex - i] - _dailyBars.LowPrices[dIndex - i]);
            
            double adr = adrSum / AdrLength;
            double currentRange = _dailyBars.HighPrices[dIndex] - _dailyBars.LowPrices[dIndex];
            
            // Calculate Expansion Z-Score
            double zScore = currentRange / (adr == 0 ? 0.0001 : adr);
            bool isExhausted = zScore >= ZThresh;

            // Update Text Blocks
            _tbAdr.Text = $"20D Mean Variance: {Math.Round(adr / Symbol.PipSize, 1)} pips";
            _tbZScore.Text = $"Expansion Z-Score: {Math.Round(zScore, 2)}";
            _tbZScore.ForegroundColor = isExhausted ? Color.Tomato : Color.MediumSeaGreen;

            _tbStatus.Text = isExhausted ? "TAPE STATUS: EXHAUSTED" : "TAPE STATUS: CAPACITY REMAINS";
            _tbStatus.ForegroundColor = isExhausted ? Color.Tomato : Color.MediumSeaGreen;

            if (_bearSweep && _bullSweep) _tbSweep.Text = "Structure: BOTH SIDES SWEPT";
            else if (_bearSweep) _tbSweep.Text = "Structure: BUY-SIDE SWEPT";
            else if (_bullSweep) _tbSweep.Text = "Structure: SELL-SIDE SWEPT";
            else _tbSweep.Text = "Structure: INTACT";
            
            _tbSweep.ForegroundColor = (_bearSweep || _bullSweep) ? Color.Orange : Color.DarkGray;
        }

        private void DrawHUD()
        {
            var stackPanel = new StackPanel { Orientation = Orientation.Vertical, Margin = new Thickness(10) };

            // Title
            stackPanel.AddChild(new TextBlock { Text = "NY OPEN : STRUCTURAL MATRIX", ForegroundColor = Color.White, FontWeight = FontWeight.Bold, Margin = new Thickness(0, 0, 0, 10) });

            // Initialize dynamic text blocks
            _tbAdr = new TextBlock { ForegroundColor = Color.LightGray, FontSize = 11, Margin = new Thickness(0, 2, 0, 2) };
            _tbZScore = new TextBlock { FontWeight = FontWeight.Bold, FontSize = 11, Margin = new Thickness(0, 2, 0, 2) };
            _tbStatus = new TextBlock { FontWeight = FontWeight.ExtraBold, FontSize = 11, Margin = new Thickness(0, 10, 0, 2) };
            _tbSweep = new TextBlock { FontWeight = FontWeight.Bold, FontSize = 11, Margin = new Thickness(0, 2, 0, 2) };

            stackPanel.AddChild(_tbAdr);
            stackPanel.AddChild(_tbZScore);
            stackPanel.AddChild(_tbStatus);
            stackPanel.AddChild(_tbSweep);

            // Container Border
            _hudPanel = new Border
            {
                BackgroundColor = Color.FromArgb(200, 20, 20, 20),
                BorderColor = Color.FromArgb(100, 80, 80, 80),
                BorderThickness = new Thickness(1),
                CornerRadius = 3,
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = new Thickness(20),
                Child = stackPanel
            };

            Chart.AddControl(_hudPanel);
        }

        #endregion
    }
}

Re: Pre-NY open checklist: news, levels, max risk

Posted: Mon Sep 14, 2026 9:17 pm
by PTScalper
Execution Notes for cTrader

Time Zones: The parameter inputs (07:00 for London, 12:00 for NY) are set in UTC. Because cTrader operates primarily in UTC under the hood, mapping session times explicitly in UTC prevents your boxes from shifting during daylight saving time rollovers or broker server time differences.

UI Rendering: Instead of drawing labels at specific (X, Y) chart coordinates like MT4, this leverages cTrader's WPF library (Border, StackPanel, TextBlock). It docks cleanly to the top-right corner, stays perfectly formatted regardless of chart zoom, and calculates independently of your bar index.

Data Polling: It uses MarketData.GetBars(TimeFrame.Daily) to pull the exact daily range independent of your current chart. This ensures the 20-day ADR calculation is accurate to the pip whether you are scalping on a 1-Minute chart or a 15-Minute chart.

Re: Pre-NY open checklist: news, levels, max risk

Posted: Tue Sep 15, 2026 10:04 am
by LondonScalper
PTScalper wrote:If London pushed into a Daily liquidity pool or major structure, NY is an automatic no-go for continuation; an exhausted daily range and sideways 13:00 tape means shut the charts rather than force a 15m setup.
That’s the go/no-go I want on the pre-NY card. Missing London does not create an obligation to invent NY.

My five-minute check before the overlap: London high/low/mid, P&L versus daily target and loss stop, US calendar, live spread versus session ATR, and one thesis line. If London already spent the daily pool or the 13:00 tape is flat and exhausted, the order ticket stays blank. Observe or take A+ only after a clean green London — never to “catch up.”

Concrete detail: I mark London realised range as % of 20-day ADR at ~12:45 London. Past a hard threshold with thinning book into the extreme, NY continuation is refused outright.

Rule: NY is optional continuation, not a second open. What’s your hard ADR or daily-pool threshold before you shut the charts rather than hunt a 15m setup?

Re: Pre-NY open checklist: news, levels, max risk

Posted: Mon Sep 21, 2026 3:18 pm
by PropScalpDesk
PTScalper wrote:By early afternoon London, GBP and EUR have often printed the day's useful range. Treating 13:00 as a second open with fresh full risk is how I used to give mornings back.
Pre-NY card is mandatory when London already worked. Mark London high/low/mid, check whether P&L is near target or near stop, read the US calendar, sanity-check spread/ATR, write one sentence: continuation or fade. If you cannot say it, you do not trade.

I fight the same bias: “I missed London, so I owe myself a ticket.” I do not. Overlap is optional. Scripts that project London levels into NY are fine as visual hygiene; they are not permission to reload full risk.

Frankfurt/prop: if morning is green, protecting eligibility beats inventing a NY story. If morning is red, overlap is usually a revenge window wearing a checklist.

Scripts that paint London high/low into NY are visual hygiene. Behaviour still needs the one-sentence thesis and the calendar gate. Pretty boxes without permissions are just clutter.

What’s your default after a busy green London — flat, or tiny continuation only?

Re: Pre-NY open checklist: news, levels, max risk

Posted: Thu Sep 24, 2026 12:22 pm
by LondonNewsTrader
PTScalper wrote:Pine Script: Pre-NY Open Checklist & Session Tracker This script is built specifically for your raw price action approach. It visualizes the London High, Low, and Midpoint on your chart and projects them forward into the NY session.
Projecting the London high, low and mid into the afternoon covers the first item on the card neatly, and the mid-line is the one I watch most. If New York spends its first hour rotating around the London mid, that's usually the 'recycle' day from the opening post rather than continuation.

The session defaults, 0300-0800 for London and 0800-1200 for New York, only work if the chart's exchange timezone is New York. On an FX feed set to UTC, or for anyone in the UK, those boxes land hours away from the real sessions. Adding an explicit "America/New_York" argument to the time() calls makes the defaults correct regardless of feed, and daylight saving takes care of itself.

Item three, the US calendar, is the one piece the script can't know about, but an input for the next release time could draw a vertical line and put a countdown on the dashboard. On days with data at 13:30 London, the pre-NY card effectively becomes a pre-data card, and the answer to 'fresh risk or not' is usually 'not until after'.

The projected lines stop ten bars past the New York open. Extending them to the end of the NY session would keep the levels visible all afternoon.