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.
Pre-NY open checklist: news, levels, max risk
Re: Pre-NY open checklist: news, levels, max risk
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Pre-NY open checklist: news, levels, max risk
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.
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);
}
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Pre-NY open checklist: news, levels, max risk
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.
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);
}
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Pre-NY open checklist: news, levels, max risk
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.
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.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Pre-NY open checklist: news, levels, max risk
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.
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
}
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Pre-NY open checklist: news, levels, max risk
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.
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.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
-
LondonScalper
- Posts: 701
- Joined: Sat Sep 05, 2026 7:54 am
Re: Pre-NY open checklist: news, levels, max risk
That’s the go/no-go I want on the pre-NY card. Missing London does not create an obligation to invent NY.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.
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?
-
PropScalpDesk
- Posts: 273
- Joined: Sat Sep 19, 2026 7:50 pm
Re: Pre-NY open checklist: news, levels, max risk
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.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.
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?
-
LondonNewsTrader
- Posts: 79
- Joined: Mon Sep 21, 2026 9:30 am
Re: Pre-NY open checklist: news, levels, max risk
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.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.
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.