Im looking for a indicator that adds 18:00, 00:00, 09:30, 10:00 NY. Also PDH/PDL (taken/not taken). Im trying to build my own script, but that does not seem traightforward. Any help would be appreciated.
Cheers
Im looking for a indicator that adds 18:00, 00:00, 09:30, 10:00 NY. Also PDH/PDL (taken/not taken). Im trying to build my own script, but that does not seem traightforward. Any help would be appreciated.
Cheers
would it be something like this ?
#region Using declarations
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Xml.Serialization;
using System.Windows.Media;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Tools;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion
namespace NinjaTrader.NinjaScript.Indicators
{
public class WTNYTimesPDHPDL : Indicator
{
private TimeZoneInfo nyZone;
private DateTime currentNySessionDate;
private int currentSessionStartBar;
private double currentSessionHigh;
private double currentSessionLow;
private double pdh;
private double pdl;
private bool hasPreviousDay;
private bool pdhTaken;
private bool pdlTaken;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "WTNYTimesPDHPDL";
Description = "Marks NY 18:00, 00:00, 09:30, 10:00 and tracks PDH/PDL taken or not taken.";
Calculate = Calculate.OnEachTick;
IsOverlay = true;
DrawOnPricePanel = true;
DisplayInDataBox = false;
PaintPriceMarkers = false;
ShowTimeMarkers = true;
ShowPDHPDL = true;
TimeLineBrush = Brushes.DodgerBlue;
Open930Brush = Brushes.LimeGreen;
Open1000Brush = Brushes.Orange;
PDHBrush = Brushes.LimeGreen;
PDLBrush = Brushes.Red;
LineWidth = 2;
TextOffsetTicks = 10;
}
else if (State == State.DataLoaded)
{
try
{
nyZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
}
catch
{
nyZone = TimeZoneInfo.Local;
}
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < 2)
return;
DateTime nyTime = ToNewYorkTime(Time[0]);
DateTime nySessionDate = GetNySessionDate(nyTime);
if (currentNySessionDate == DateTime.MinValue)
{
currentNySessionDate = nySessionDate;
currentSessionStartBar = CurrentBar;
currentSessionHigh = High[0];
currentSessionLow = Low[0];
return;
}
if (nySessionDate != currentNySessionDate)
{
pdh = currentSessionHigh;
pdl = currentSessionLow;
hasPreviousDay = true;
pdhTaken = false;
pdlTaken = false;
currentNySessionDate = nySessionDate;
currentSessionStartBar = CurrentBar;
currentSessionHigh = High[0];
currentSessionLow = Low[0];
}
else
{
currentSessionHigh = Math.Max(currentSessionHigh, High[0]);
currentSessionLow = Math.Min(currentSessionLow, Low[0]);
}
if (ShowTimeMarkers && IsFirstTickOfBar)
DrawNyTimeMarkers();
if (ShowPDHPDL && hasPreviousDay)
DrawPdhPdl();
}
private void DrawNyTimeMarkers()
{
DateTime prevNy = ToNewYorkTime(Time[1]);
DateTime currNy = ToNewYorkTime(Time[0]);
CheckAndDrawTime(prevNy, currNy, 18, 0, "18:00 NY", TimeLineBrush);
CheckAndDrawTime(prevNy, currNy, 0, 0, "00:00 NY", TimeLineBrush);
CheckAndDrawTime(prevNy, currNy, 9, 30, "09:30 NY", Open930Brush);
CheckAndDrawTime(prevNy, currNy, 10, 0, "10:00 NY", Open1000Brush);
}
private void CheckAndDrawTime(DateTime prevNy, DateTime currNy, int hour, int minute, string label, Brush brush)
{
DateTime target = new DateTime(currNy.Year, currNy.Month, currNy.Day, hour, minute, 0);
if (prevNy < target && currNy >= target)
{
string cleanLabel = label.Replace(":", "").Replace(" ", "");
string tag = "WT_TIME_" + cleanLabel + "_" + Time[0].ToString("yyyyMMddHHmmss");
Draw.VerticalLine(
this,
tag,
0,
brush,
NinjaTrader.Gui.DashStyleHelper.Dash,
LineWidth
);
Draw.Text(
this,
tag + "_TEXT",
label,
0,
High[0] + TickSize * TextOffsetTicks,
brush
);
}
}
private void DrawPdhPdl()
{
if (High[0] >= pdh)
pdhTaken = true;
if (Low[0] <= pdl)
pdlTaken = true;
int barsAgoStart = CurrentBar - currentSessionStartBar;
Draw.Line(
this,
"WT_PDH_LINE",
false,
barsAgoStart,
pdh,
0,
pdh,
PDHBrush,
NinjaTrader.Gui.DashStyleHelper.Solid,
LineWidth
);
Draw.Line(
this,
"WT_PDL_LINE",
false,
barsAgoStart,
pdl,
0,
pdl,
PDLBrush,
NinjaTrader.Gui.DashStyleHelper.Solid,
LineWidth
);
string pdhText = pdhTaken ? "PDH TAKEN" : "PDH NOT TAKEN";
string pdlText = pdlTaken ? "PDL TAKEN" : "PDL NOT TAKEN";
Draw.Text(
this,
"WT_PDH_TEXT",
pdhText,
0,
pdh + TickSize * TextOffsetTicks,
PDHBrush
);
Draw.Text(
this,
"WT_PDL_TEXT",
pdlText,
0,
pdl - TickSize * TextOffsetTicks,
PDLBrush
);
}
private DateTime ToNewYorkTime(DateTime chartTime)
{
if (nyZone == null)
return chartTime;
return TimeZoneInfo.ConvertTime(chartTime, Core.Globals.GeneralOptions.TimeZoneInfo, nyZone);
}
private DateTime GetNySessionDate(DateTime nyTime)
{
if (nyTime.TimeOfDay >= new TimeSpan(18, 0, 0))
return nyTime.Date.AddDays(1);
return nyTime.Date;
}
#region Inputs
[NinjaScriptProperty]
[Display(Name = "Show Time Markers", Order = 1, GroupName = "Settings")]
public bool ShowTimeMarkers { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show PDH / PDL", Order = 2, GroupName = "Settings")]
public bool ShowPDHPDL { get; set; }
[NinjaScriptProperty]
[Range(1, 10)]
[Display(Name = "Line Width", Order = 3, GroupName = "Settings")]
public int LineWidth { get; set; }
[NinjaScriptProperty]
[Range(1, 100)]
[Display(Name = "Text Offset Ticks", Order = 4, GroupName = "Settings")]
public int TextOffsetTicks { get; set; }
[XmlIgnore]
[Display(Name = "18:00 / 00:00 Line Color", Order = 1, GroupName = "Colors")]
public Brush TimeLineBrush { get; set; }
[Browsable(false)]
public string TimeLineBrushSerializable
{
get { return Serialize.BrushToString(TimeLineBrush); }
set { TimeLineBrush = Serialize.StringToBrush(value); }
}
[XmlIgnore]
[Display(Name = "09:30 Line Color", Order = 2, GroupName = "Colors")]
public Brush Open930Brush { get; set; }
[Browsable(false)]
public string Open930BrushSerializable
{
get { return Serialize.BrushToString(Open930Brush); }
set { Open930Brush = Serialize.StringToBrush(value); }
}
[XmlIgnore]
[Display(Name = "10:00 Line Color", Order = 3, GroupName = "Colors")]
public Brush Open1000Brush { get; set; }
[Browsable(false)]
public string Open1000BrushSerializable
{
get { return Serialize.BrushToString(Open1000Brush); }
set { Open1000Brush = Serialize.StringToBrush(value); }
}
[XmlIgnore]
[Display(Name = "PDH Color", Order = 4, GroupName = "Colors")]
public Brush PDHBrush { get; set; }
[Browsable(false)]
public string PDHBrushSerializable
{
get { return Serialize.BrushToString(PDHBrush); }
set { PDHBrush = Serialize.StringToBrush(value); }
}
[XmlIgnore]
[Display(Name = "PDL Color", Order = 5, GroupName = "Colors")]
public Brush PDLBrush { get; set; }
[Browsable(false)]
public string PDLBrushSerializable
{
get { return Serialize.BrushToString(PDLBrush); }
set { PDLBrush = Serialize.StringToBrush(value); }
}
#endregion
}
}
#region NinjaScript generated code. Neither change nor remove.
namespace NinjaTrader.NinjaScript.Indicators
{
public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
{
private WTNYTimesPDHPDL cacheWTNYTimesPDHPDL;
public WTNYTimesPDHPDL WTNYTimesPDHPDL(bool showTimeMarkers, bool showPDHPDL, int lineWidth, int textOffsetTicks)
{
return WTNYTimesPDHPDL(Input, showTimeMarkers, showPDHPDL, lineWidth, textOffsetTicks);
}
public WTNYTimesPDHPDL WTNYTimesPDHPDL(ISeries<double> input, bool showTimeMarkers, bool showPDHPDL, int lineWidth, int textOffsetTicks)
{
if (cacheWTNYTimesPDHPDL != null)
for (int idx = 0; idx < cacheWTNYTimesPDHPDL.Length; idx++)
if (cacheWTNYTimesPDHPDL[idx] != null && cacheWTNYTimesPDHPDL[idx].ShowTimeMarkers == showTimeMarkers && cacheWTNYTimesPDHPDL[idx].ShowPDHPDL == showPDHPDL && cacheWTNYTimesPDHPDL[idx].LineWidth == lineWidth && cacheWTNYTimesPDHPDL[idx].TextOffsetTicks == textOffsetTicks && cacheWTNYTimesPDHPDL[idx].EqualsInput(input))
return cacheWTNYTimesPDHPDL[idx];
return CacheIndicator<WTNYTimesPDHPDL>(new WTNYTimesPDHPDL(){ ShowTimeMarkers = showTimeMarkers, ShowPDHPDL = showPDHPDL, LineWidth = lineWidth, TextOffsetTicks = textOffsetTicks }, input, ref cacheWTNYTimesPDHPDL);
}
}
}
namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
{
public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
{
public Indicators.WTNYTimesPDHPDL WTNYTimesPDHPDL(bool showTimeMarkers, bool showPDHPDL, int lineWidth, int textOffsetTicks)
{
return indicator.WTNYTimesPDHPDL(Input, showTimeMarkers, showPDHPDL, lineWidth, textOffsetTicks);
}
public Indicators.WTNYTimesPDHPDL WTNYTimesPDHPDL(ISeries<double> input , bool showTimeMarkers, bool showPDHPDL, int lineWidth, int textOffsetTicks)
{
return indicator.WTNYTimesPDHPDL(input, showTimeMarkers, showPDHPDL, lineWidth, textOffsetTicks);
}
}
}
namespace NinjaTrader.NinjaScript.Strategies
{
public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
{
public Indicators.WTNYTimesPDHPDL WTNYTimesPDHPDL(bool showTimeMarkers, bool showPDHPDL, int lineWidth, int textOffsetTicks)
{
return indicator.WTNYTimesPDHPDL(Input, showTimeMarkers, showPDHPDL, lineWidth, textOffsetTicks);
}
public Indicators.WTNYTimesPDHPDL WTNYTimesPDHPDL(ISeries<double> input , bool showTimeMarkers, bool showPDHPDL, int lineWidth, int textOffsetTicks)
{
return indicator.WTNYTimesPDHPDL(input, showTimeMarkers, showPDHPDL, lineWidth, textOffsetTicks);
}
}
}
#endregion
now if u would like to add a panel , try this
#region Using declarations
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Text;
using System.Xml.Serialization;
using System.Windows.Media;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Tools;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion
namespace NinjaTrader.NinjaScript.Indicators
{
public class WTNYTimesPDHPDL : Indicator
{
private TimeZoneInfo nyZone;
private DateTime currentSessionDate = DateTime.MinValue;
private DateTime currentWeekStart = DateTime.MinValue;
private DateTime currentMonthStart = DateTime.MinValue;
private int sessionStartBar;
private double sessionHigh, sessionLow;
private double weekHigh, weekLow;
private double monthHigh, monthLow;
private double pdh, pdl, pwh, pwl, pmh, pml;
private bool hasPD, hasPW, hasPM;
private bool pdhTaken, pdlTaken, pwhTaken, pwlTaken, pmhTaken, pmlTaken;
private bool inOpeningRange, openingRangeDone;
private double orHigh, orLow;
private bool orhTaken, orlTaken;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "WTNYTimesPDHPDL";
Description = "NY session levels, PDH/PDL, PWH/PWL, PMH/PML, Opening Range, and Liquidity Radar.";
Calculate = Calculate.OnEachTick;
IsOverlay = true;
DrawOnPricePanel = true;
DisplayInDataBox = false;
PaintPriceMarkers = false;
ShowTimeMarkers = true;
ShowDailyLevels = true;
ShowWeeklyLevels = true;
ShowMonthlyLevels = true;
ShowOpeningRange = true;
ShowDashboard = true;
LineWidth = 2;
TextOffsetTicks = 10;
TimeLineBrush = Brushes.DodgerBlue;
Open930Brush = Brushes.LimeGreen;
Open1000Brush = Brushes.Orange;
PDHBrush = Brushes.LimeGreen;
PDLBrush = Brushes.Red;
WeeklyBrush = Brushes.DeepSkyBlue;
MonthlyBrush = Brushes.Gold;
ORBrush = Brushes.MediumPurple;
DashboardTextBrush = Brushes.White;
}
else if (State == State.DataLoaded)
{
try { nyZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); }
catch { nyZone = TimeZoneInfo.Local; }
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < 2)
return;
DateTime nyTime = ToNewYorkTime(Time[0]);
DateTime nySessionDate = GetNySessionDate(nyTime);
DateTime nyWeekStart = GetWeekStart(nySessionDate);
DateTime nyMonthStart = new DateTime(nySessionDate.Year, nySessionDate.Month, 1);
if (currentSessionDate == DateTime.MinValue)
{
StartNewSession(nySessionDate);
StartNewWeek(nyWeekStart);
StartNewMonth(nyMonthStart);
return;
}
if (nySessionDate != currentSessionDate)
{
pdh = sessionHigh;
pdl = sessionLow;
hasPD = true;
pdhTaken = false;
pdlTaken = false;
StartNewSession(nySessionDate);
}
else
{
sessionHigh = Math.Max(sessionHigh, High[0]);
sessionLow = Math.Min(sessionLow, Low[0]);
}
if (nyWeekStart != currentWeekStart)
{
pwh = weekHigh;
pwl = weekLow;
hasPW = true;
pwhTaken = false;
pwlTaken = false;
StartNewWeek(nyWeekStart);
}
else
{
weekHigh = Math.Max(weekHigh, High[0]);
weekLow = Math.Min(weekLow, Low[0]);
}
if (nyMonthStart != currentMonthStart)
{
pmh = monthHigh;
pml = monthLow;
hasPM = true;
pmhTaken = false;
pmlTaken = false;
StartNewMonth(nyMonthStart);
}
else
{
monthHigh = Math.Max(monthHigh, High[0]);
monthLow = Math.Min(monthLow, Low[0]);
}
UpdateOpeningRange(nyTime);
if (ShowTimeMarkers && IsFirstTickOfBar)
DrawNyTimeMarkers();
if (ShowDailyLevels && hasPD)
DrawPreviousDayLevels();
if (ShowWeeklyLevels && hasPW)
DrawPreviousWeekLevels();
if (ShowMonthlyLevels && hasPM)
DrawPreviousMonthLevels();
if (ShowOpeningRange)
DrawOpeningRange();
if (ShowDashboard)
DrawDashboard(nyTime);
}
private void StartNewSession(DateTime date)
{
currentSessionDate = date;
sessionStartBar = CurrentBar;
sessionHigh = High[0];
sessionLow = Low[0];
openingRangeDone = false;
inOpeningRange = false;
orHigh = double.MinValue;
orLow = double.MaxValue;
orhTaken = false;
orlTaken = false;
}
private void StartNewWeek(DateTime date)
{
currentWeekStart = date;
weekHigh = High[0];
weekLow = Low[0];
}
private void StartNewMonth(DateTime date)
{
currentMonthStart = date;
monthHigh = High[0];
monthLow = Low[0];
}
private void DrawNyTimeMarkers()
{
DateTime prevNy = ToNewYorkTime(Time[1]);
DateTime currNy = ToNewYorkTime(Time[0]);
CheckAndDrawTime(prevNy, currNy, 18, 0, "18:00 NY", TimeLineBrush);
CheckAndDrawTime(prevNy, currNy, 0, 0, "00:00 NY", TimeLineBrush);
CheckAndDrawTime(prevNy, currNy, 9, 30, "09:30 NY", Open930Brush);
CheckAndDrawTime(prevNy, currNy, 10, 0, "10:00 NY", Open1000Brush);
}
private void CheckAndDrawTime(DateTime prevNy, DateTime currNy, int hour, int minute, string label, Brush brush)
{
DateTime target = new DateTime(currNy.Year, currNy.Month, currNy.Day, hour, minute, 0);
if (prevNy < target && currNy >= target)
{
string tag = "WT_TIME_" + label.Replace(":", "").Replace(" ", "") + "_" + Time[0].ToString("yyyyMMddHHmmss");
Draw.VerticalLine(this, tag, 0, brush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
Draw.Text(this, tag + "_TXT", label, 0, High[0] + TickSize * TextOffsetTicks, brush);
}
}
private void DrawPreviousDayLevels()
{
if (High[0] >= pdh) pdhTaken = true;
if (Low[0] <= pdl) pdlTaken = true;
int barsAgo = CurrentBar - sessionStartBar;
Draw.Line(this, "WT_PDH_LINE", false, barsAgo, pdh, 0, pdh, PDHBrush, NinjaTrader.Gui.DashStyleHelper.Solid, LineWidth);
Draw.Line(this, "WT_PDL_LINE", false, barsAgo, pdl, 0, pdl, PDLBrush, NinjaTrader.Gui.DashStyleHelper.Solid, LineWidth);
Draw.Text(this, "WT_PDH_LABEL", "PDH " + pdh.ToString("0.00") + " " + (pdhTaken ? "TAKEN" : "OPEN"), 0, pdh + TickSize * TextOffsetTicks, PDHBrush);
Draw.Text(this, "WT_PDL_LABEL", "PDL " + pdl.ToString("0.00") + " " + (pdlTaken ? "TAKEN" : "OPEN"), 0, pdl - TickSize * TextOffsetTicks, PDLBrush);
}
private void DrawPreviousWeekLevels()
{
if (High[0] >= pwh) pwhTaken = true;
if (Low[0] <= pwl) pwlTaken = true;
int barsAgo = CurrentBar - sessionStartBar;
Draw.Line(this, "WT_PWH_LINE", false, barsAgo, pwh, 0, pwh, WeeklyBrush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
Draw.Line(this, "WT_PWL_LINE", false, barsAgo, pwl, 0, pwl, WeeklyBrush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
}
private void DrawPreviousMonthLevels()
{
if (High[0] >= pmh) pmhTaken = true;
if (Low[0] <= pml) pmlTaken = true;
int barsAgo = CurrentBar - sessionStartBar;
Draw.Line(this, "WT_PMH_LINE", false, barsAgo, pmh, 0, pmh, MonthlyBrush, NinjaTrader.Gui.DashStyleHelper.Dot, LineWidth);
Draw.Line(this, "WT_PML_LINE", false, barsAgo, pml, 0, pml, MonthlyBrush, NinjaTrader.Gui.DashStyleHelper.Dot, LineWidth);
}
private void UpdateOpeningRange(DateTime nyTime)
{
TimeSpan t = nyTime.TimeOfDay;
if (t >= new TimeSpan(9, 30, 0) && t < new TimeSpan(10, 0, 0))
{
inOpeningRange = true;
orHigh = Math.Max(orHigh, High[0]);
orLow = Math.Min(orLow, Low[0]);
}
if (t >= new TimeSpan(10, 0, 0) && inOpeningRange)
{
openingRangeDone = true;
inOpeningRange = false;
}
if (openingRangeDone)
{
if (High[0] >= orHigh) orhTaken = true;
if (Low[0] <= orLow) orlTaken = true;
}
}
private void DrawOpeningRange()
{
if (orHigh == double.MinValue || orLow == double.MaxValue)
return;
int barsAgo = CurrentBar - sessionStartBar;
Draw.Line(this, "WT_ORH_LINE", false, barsAgo, orHigh, 0, orHigh, ORBrush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
Draw.Line(this, "WT_ORL_LINE", false, barsAgo, orLow, 0, orLow, ORBrush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
}
private void DrawDashboard(DateTime nyTime)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("WT SESSION PANEL");
sb.AppendLine("----------------------------");
sb.AppendLine("NY Time: " + nyTime.ToString("HH:mm:ss"));
sb.AppendLine("");
sb.AppendLine("LEVEL STATUS DIST");
if (hasPD)
{
sb.AppendLine("PDH " + StatusText(pdhTaken) + " " + DirectionText(pdh));
sb.AppendLine("PDL " + StatusText(pdlTaken) + " " + DirectionText(pdl));
}
if (hasPW)
{
sb.AppendLine("PWH " + StatusText(pwhTaken) + " " + DirectionText(pwh));
sb.AppendLine("PWL " + StatusText(pwlTaken) + " " + DirectionText(pwl));
}
if (hasPM)
{
sb.AppendLine("PMH " + StatusText(pmhTaken) + " " + DirectionText(pmh));
sb.AppendLine("PML " + StatusText(pmlTaken) + " " + DirectionText(pml));
}
sb.AppendLine("");
if (orHigh != double.MinValue && orLow != double.MaxValue)
{
sb.AppendLine("ORH " + StatusText(orhTaken) + " " + DirectionText(orHigh));
sb.AppendLine("ORL " + StatusText(orlTaken) + " " + DirectionText(orLow));
}
sb.AppendLine("");
sb.AppendLine("----------------------------");
sb.AppendLine("LIQUIDITY RADAR");
sb.AppendLine("----------------------------");
sb.AppendLine("");
sb.AppendLine("ABOVE PRICE");
AddAbove(sb, "PDH", pdh, hasPD && !pdhTaken);
AddAbove(sb, "PWH", pwh, hasPW && !pwhTaken);
AddAbove(sb, "PMH", pmh, hasPM && !pmhTaken);
sb.AppendLine("");
sb.AppendLine("BELOW PRICE");
AddBelow(sb, "PDL", pdl, hasPD && !pdlTaken);
AddBelow(sb, "PWL", pwl, hasPW && !pwlTaken);
AddBelow(sb, "PML", pml, hasPM && !pmlTaken);
Draw.TextFixed(
this,
"WT_DASHBOARD",
sb.ToString(),
TextPosition.TopRight,
DashboardTextBrush,
new SimpleFont("Arial", 13),
Brushes.Black,
Brushes.DimGray,
85
);
}
private string StatusText(bool taken)
{
return taken ? "TAKEN" : "OPEN ";
}
private string DirectionText(double level)
{
double ticks = (level - Close[0]) / TickSize;
if (ticks > 0)
return "β " + Math.Abs(ticks).ToString("0") + " ticks";
if (ticks < 0)
return "β " + Math.Abs(ticks).ToString("0") + " ticks";
return "AT PRICE";
}
private void AddAbove(StringBuilder sb, string name, double level, bool active)
{
if (!active)
return;
double ticks = (level - Close[0]) / TickSize;
if (ticks > 0)
sb.AppendLine(name + " β " + ticks.ToString("0") + " ticks");
}
private void AddBelow(StringBuilder sb, string name, double level, bool active)
{
if (!active)
return;
double ticks = (level - Close[0]) / TickSize;
if (ticks < 0)
sb.AppendLine(name + " β " + Math.Abs(ticks).ToString("0") + " ticks");
}
private DateTime ToNewYorkTime(DateTime chartTime)
{
if (nyZone == null)
return chartTime;
return TimeZoneInfo.ConvertTime(chartTime, Core.Globals.GeneralOptions.TimeZoneInfo, nyZone);
}
private DateTime GetNySessionDate(DateTime nyTime)
{
if (nyTime.TimeOfDay >= new TimeSpan(18, 0, 0))
return nyTime.Date.AddDays(1);
return nyTime.Date;
}
private DateTime GetWeekStart(DateTime date)
{
int diff = (7 + (date.DayOfWeek - DayOfWeek.Monday)) % 7;
return date.AddDays(-diff).Date;
}
#region Inputs
[NinjaScriptProperty]
[Display(Name = "Show Time Markers", Order = 1, GroupName = "Settings")]
public bool ShowTimeMarkers { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Daily PDH/PDL", Order = 2, GroupName = "Settings")]
public bool ShowDailyLevels { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Weekly PWH/PWL", Order = 3, GroupName = "Settings")]
public bool ShowWeeklyLevels { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Monthly PMH/PML", Order = 4, GroupName = "Settings")]
public bool ShowMonthlyLevels { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Opening Range", Order = 5, GroupName = "Settings")]
public bool ShowOpeningRange { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Dashboard", Order = 6, GroupName = "Settings")]
public bool ShowDashboard { get; set; }
[NinjaScriptProperty]
[Range(1, 10)]
[Display(Name = "Line Width", Order = 7, GroupName = "Settings")]
public int LineWidth { get; set; }
[NinjaScriptProperty]
[Range(1, 100)]
[Display(Name = "Text Offset Ticks", Order = 8, GroupName = "Settings")]
public int TextOffsetTicks { get; set; }
[XmlIgnore]
[Display(Name = "18:00 / 00:00 Color", Order = 1, GroupName = "Colors")]
public Brush TimeLineBrush { get; set; }
[Browsable(false)]
public string TimeLineBrushSerializable { get { return Serialize.BrushToString(TimeLineBrush); } set { TimeLineBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "09:30 Color", Order = 2, GroupName = "Colors")]
public Brush Open930Brush { get; set; }
[Browsable(false)]
public string Open930BrushSerializable { get { return Serialize.BrushToString(Open930Brush); } set { Open930Brush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "10:00 Color", Order = 3, GroupName = "Colors")]
public Brush Open1000Brush { get; set; }
[Browsable(false)]
public string Open1000BrushSerializable { get { return Serialize.BrushToString(Open1000Brush); } set { Open1000Brush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "PDH Color", Order = 4, GroupName = "Colors")]
public Brush PDHBrush { get; set; }
[Browsable(false)]
public string PDHBrushSerializable { get { return Serialize.BrushToString(PDHBrush); } set { PDHBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "PDL Color", Order = 5, GroupName = "Colors")]
public Brush PDLBrush { get; set; }
[Browsable(false)]
public string PDLBrushSerializable { get { return Serialize.BrushToString(PDLBrush); } set { PDLBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Weekly Color", Order = 6, GroupName = "Colors")]
public Brush WeeklyBrush { get; set; }
[Browsable(false)]
public string WeeklyBrushSerializable { get { return Serialize.BrushToString(WeeklyBrush); } set { WeeklyBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Monthly Color", Order = 7, GroupName = "Colors")]
public Brush MonthlyBrush { get; set; }
[Browsable(false)]
public string MonthlyBrushSerializable { get { return Serialize.BrushToString(MonthlyBrush); } set { MonthlyBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Opening Range Color", Order = 8, GroupName = "Colors")]
public Brush ORBrush { get; set; }
[Browsable(false)]
public string ORBrushSerializable { get { return Serialize.BrushToString(ORBrush); } set { ORBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Dashboard Text Color", Order = 9, GroupName = "Colors")]
public Brush DashboardTextBrush { get; set; }
[Browsable(false)]
public string DashboardTextBrushSerializable { get { return Serialize.BrushToString(DashboardTextBrush); } set { DashboardTextBrush = Serialize.StringToBrush(value); } }
#endregion
}
}
#region NinjaScript generated code. Neither change nor remove.
namespace NinjaTrader.NinjaScript.Indicators
{
public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
{
private WTNYTimesPDHPDL cacheWTNYTimesPDHPDL;
public WTNYTimesPDHPDL WTNYTimesPDHPDL(bool showTimeMarkers, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks)
{
return WTNYTimesPDHPDL(Input, showTimeMarkers, showDailyLevels, showWeeklyLevels, showMonthlyLevels, showOpeningRange, showDashboard, lineWidth, textOffsetTicks);
}
public WTNYTimesPDHPDL WTNYTimesPDHPDL(ISeries<double> input, bool showTimeMarkers, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks)
{
if (cacheWTNYTimesPDHPDL != null)
for (int idx = 0; idx < cacheWTNYTimesPDHPDL.Length; idx++)
if (cacheWTNYTimesPDHPDL[idx] != null && cacheWTNYTimesPDHPDL[idx].ShowTimeMarkers == showTimeMarkers && cacheWTNYTimesPDHPDL[idx].ShowDailyLevels == showDailyLevels && cacheWTNYTimesPDHPDL[idx].ShowWeeklyLevels == showWeeklyLevels && cacheWTNYTimesPDHPDL[idx].ShowMonthlyLevels == showMonthlyLevels && cacheWTNYTimesPDHPDL[idx].ShowOpeningRange == showOpeningRange && cacheWTNYTimesPDHPDL[idx].ShowDashboard == showDashboard && cacheWTNYTimesPDHPDL[idx].LineWidth == lineWidth && cacheWTNYTimesPDHPDL[idx].TextOffsetTicks == textOffsetTicks && cacheWTNYTimesPDHPDL[idx].EqualsInput(input))
return cacheWTNYTimesPDHPDL[idx];
return CacheIndicator<WTNYTimesPDHPDL>(new WTNYTimesPDHPDL(){ ShowTimeMarkers = showTimeMarkers, ShowDailyLevels = showDailyLevels, ShowWeeklyLevels = showWeeklyLevels, ShowMonthlyLevels = showMonthlyLevels, ShowOpeningRange = showOpeningRange, ShowDashboard = showDashboard, LineWidth = lineWidth, TextOffsetTicks = textOffsetTicks }, input, ref cacheWTNYTimesPDHPDL);
}
}
}
namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
{
public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
{
public Indicators.WTNYTimesPDHPDL WTNYTimesPDHPDL(bool showTimeMarkers, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks)
{
return indicator.WTNYTimesPDHPDL(Input, showTimeMarkers, showDailyLevels, showWeeklyLevels, showMonthlyLevels, showOpeningRange, showDashboard, lineWidth, textOffsetTicks);
}
public Indicators.WTNYTimesPDHPDL WTNYTimesPDHPDL(ISeries<double> input , bool showTimeMarkers, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks)
{
return indicator.WTNYTimesPDHPDL(input, showTimeMarkers, showDailyLevels, showWeeklyLevels, showMonthlyLevels, showOpeningRange, showDashboard, lineWidth, textOffsetTicks);
}
}
}
namespace NinjaTrader.NinjaScript.Strategies
{
public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
{
public Indicators.WTNYTimesPDHPDL WTNYTimesPDHPDL(bool showTimeMarkers, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks)
{
return indicator.WTNYTimesPDHPDL(Input, showTimeMarkers, showDailyLevels, showWeeklyLevels, showMonthlyLevels, showOpeningRange, showDashboard, lineWidth, textOffsetTicks);
}
public Indicators.WTNYTimesPDHPDL WTNYTimesPDHPDL(ISeries<double> input , bool showTimeMarkers, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks)
{
return indicator.WTNYTimesPDHPDL(input, showTimeMarkers, showDailyLevels, showWeeklyLevels, showMonthlyLevels, showOpeningRange, showDashboard, lineWidth, textOffsetTicks);
}
}
}
#endregion
I hope you donβt mind - I tweaked it so it works with non time based charts:
#region Using declarations
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Xml.Serialization;
using System.Windows.Media;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Tools;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion
namespace NinjaTrader.NinjaScript.Indicators
{
public class WTNYTimesPDHPDL : Indicator
{
private TimeZoneInfo nyZone;
private DateTime currentNySessionDate;
private int currentSessionStartBar;
private double currentSessionHigh;
private double currentSessionLow;
private double pdh;
private double pdl;
private bool hasPreviousDay;
private bool pdhTaken;
private bool pdlTaken;
// Persistent state trackers to handle multiple bars sharing identical execution times
private bool marker18Drawn = false;
private bool marker00Drawn = false;
private bool marker0930Drawn = false;
private bool marker1000Drawn = false;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "WTNYTimesPDHPDL";
Description = "Marks NY times and tracks PDH/PDL with an optional overnight session filter.";
Calculate = Calculate.OnEachTick;
IsOverlay = true;
DrawOnPricePanel = true;
DisplayInDataBox = false;
PaintPriceMarkers = false;
ShowTimeMarkers = true;
ShowPDHPDL = true;
FilterOvernight = false; // Default: show all data
TimeLineBrush = Brushes.DodgerBlue;
Open930Brush = Brushes.LimeGreen;
Open1000Brush = Brushes.Orange;
PDHBrush = Brushes.LimeGreen;
PDLBrush = Brushes.Red;
LineWidth = 2;
TextOffsetTicks = 10;
}
else if (State == State.DataLoaded)
{
try
{
nyZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
}
catch
{
nyZone = TimeZoneInfo.Local;
}
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < 2) return;
DateTime nyTime = ToNewYorkTime(Time[0]);
// Apply the overnight filter condition
if (FilterOvernight && !IsRth(nyTime))
{
// Clear active lines during the overnight session so they don't stretch artificially
if (ShowPDHPDL)
{
RemoveDrawObject("WT_PDH_LINE");
RemoveDrawObject("WT_PDH_TEXT");
RemoveDrawObject("WT_PDL_LINE");
RemoveDrawObject("WT_PDL_TEXT");
}
return;
}
DateTime nySessionDate = GetNySessionDate(nyTime);
// Handle session transitions safely on non-time bars
if (currentNySessionDate == DateTime.MinValue)
{
currentNySessionDate = nySessionDate;
currentSessionStartBar = CurrentBar;
currentSessionHigh = High[0];
currentSessionLow = Low[0];
return;
}
if (nySessionDate != currentNySessionDate)
{
pdh = currentSessionHigh;
pdl = currentSessionLow;
hasPreviousDay = true;
pdhTaken = false;
pdlTaken = false;
currentNySessionDate = nySessionDate;
currentSessionStartBar = CurrentBar;
currentSessionHigh = High[0];
currentSessionLow = Low[0];
// Reset drawing flags for the brand new session
marker18Drawn = false;
marker00Drawn = false;
marker0930Drawn = false;
marker1000Drawn = false;
}
else
{
currentSessionHigh = Math.Max(currentSessionHigh, High[0]);
currentSessionLow = Math.Min(currentSessionLow, Low[0]);
}
// Evaluation logic triggers on every tick/bar process
if (ShowTimeMarkers)
DrawNyTimeMarkers(nyTime);
if (ShowPDHPDL && hasPreviousDay)
DrawPdhPdl();
}
private bool IsRth(DateTime nyTime)
{
TimeSpan rthStart = new TimeSpan(9, 30, 0);
TimeSpan rthEnd = new TimeSpan(16, 0, 0);
TimeSpan currentBarTime = nyTime.TimeOfDay;
return (currentBarTime >= rthStart && currentBarTime <= rthEnd);
}
private void DrawNyTimeMarkers(DateTime currNy)
{
// 18:00 and 00:00 will only evaluate if the overnight filter is turned off
if (!FilterOvernight)
{
if (!marker18Drawn && currNy.TimeOfDay >= new TimeSpan(18, 0, 0))
{
ExecuteTimeMarkerDraw("1800NY", "18:00 NY", TimeLineBrush);
marker18Drawn = true;
}
if (!marker00Drawn && currNy.TimeOfDay >= new TimeSpan(0, 0, 0) && currNy.TimeOfDay < new TimeSpan(18, 0, 0))
{
ExecuteTimeMarkerDraw("0000NY", "00:00 NY", TimeLineBrush);
marker00Drawn = true;
}
}
if (!marker0930Drawn && currNy.TimeOfDay >= new TimeSpan(9, 30, 0) && currNy.TimeOfDay < new TimeSpan(18, 0, 0))
{
ExecuteTimeMarkerDraw("0930NY", "09:30 NY", Open930Brush);
marker0930Drawn = true;
}
if (!marker1000Drawn && currNy.TimeOfDay >= new TimeSpan(10, 0, 0) && currNy.TimeOfDay < new TimeSpan(18, 0, 0))
{
ExecuteTimeMarkerDraw("1000NY", "10:00 NY", Open1000Brush);
marker1000Drawn = true;
}
}
private void ExecuteTimeMarkerDraw(string tagKey, string label, Brush brush)
{
string tag = "WT_TIME_" + tagKey + "_" + currentNySessionDate.ToString("yyyyMMdd");
Draw.VerticalLine(this, tag, 0, brush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
Draw.Text(this, tag + "_TEXT", label, 0, High[0] + TickSize * TextOffsetTicks, brush);
}
private void DrawPdhPdl()
{
if (High[0] >= pdh) pdhTaken = true;
if (Low[0] <= pdl) pdlTaken = true;
int barsAgoStart = CurrentBar - currentSessionStartBar;
Draw.Line(this, "WT_PDH_LINE", false, barsAgoStart, pdh, 0, pdh, PDHBrush, NinjaTrader.Gui.DashStyleHelper.Solid, LineWidth);
Draw.Line(this, "WT_PDL_LINE", false, barsAgoStart, pdl, 0, pdl, PDLBrush, NinjaTrader.Gui.DashStyleHelper.Solid, LineWidth);
string pdhText = pdhTaken ? "PDH TAKEN" : "PDH NOT TAKEN";
string pdlText = pdlTaken ? "PDL TAKEN" : "PDL NOT TAKEN";
Draw.Text(this, "WT_PDH_TEXT", pdhText, 0, pdh + TickSize * TextOffsetTicks, PDHBrush);
Draw.Text(this, "WT_PDL_TEXT", pdlText, 0, pdl - TickSize * TextOffsetTicks, PDLBrush);
}
private DateTime ToNewYorkTime(DateTime chartTime)
{
if (nyZone == null) return chartTime;
return TimeZoneInfo.ConvertTime(chartTime, Core.Globals.GeneralOptions.TimeZoneInfo, nyZone);
}
private DateTime GetNySessionDate(DateTime nyTime)
{
if (nyTime.TimeOfDay >= new TimeSpan(18, 0, 0)) return nyTime.Date.AddDays(1);
return nyTime.Date;
}
#region Inputs
[NinjaScriptProperty]
[Display(Name = "Show Time Markers", Order = 1, GroupName = "Settings")]
public bool ShowTimeMarkers { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show PDH / PDL", Order = 2, GroupName = "Settings")]
public bool ShowPDHPDL { get; set; }
[NinjaScriptProperty]
[Display(Name = "Filter Overnight Session", Order = 3, GroupName = "Settings", Description = "Hide lines and suspend tracking between 16:00 and 09:30 NY time.")]
public bool FilterOvernight { get; set; }
[NinjaScriptProperty]
[Range(1, 10)]
[Display(Name = "Line Width", Order = 4, GroupName = "Settings")]
public int LineWidth { get; set; }
[NinjaScriptProperty]
[Range(1, 100)]
[Display(Name = "Text Offset Ticks", Order = 5, GroupName = "Settings")]
public int TextOffsetTicks { get; set; }
[XmlIgnore]
[Display(Name = "18:00 / 00:00 Line Color", Order = 1, GroupName = "Colors")]
public Brush TimeLineBrush { get; set; }
[Browsable(false)]
public string TimeLineBrushSerializable
{
get { return Serialize.BrushToString(TimeLineBrush); }
set { TimeLineBrush = Serialize.StringToBrush(value); }
}
[XmlIgnore]
[Display(Name = "09:30 Line Color", Order = 2, GroupName = "Colors")]
public Brush Open930Brush { get; set; }
[Browsable(false)]
public string Open930BrushSerializable
{
get { return Serialize.BrushToString(Open930Brush); }
set { Open930Brush = Serialize.StringToBrush(value); }
}
[XmlIgnore]
[Display(Name = "10:00 Line Color", Order = 3, GroupName = "Colors")]
public Brush Open1000Brush { get; set; }
[Browsable(false)]
public string Open1000BrushSerializable
{
get { return Serialize.BrushToString(Open1000Brush); }
set { Open1000Brush = Serialize.StringToBrush(value); }
}
[XmlIgnore]
[Display(Name = "PDH Color", Order = 4, GroupName = "Colors")]
public Brush PDHBrush { get; set; }
[Browsable(false)]
public string PDHBrushSerializable
{
get { return Serialize.BrushToString(PDHBrush); }
set { PDHBrush = Serialize.StringToBrush(value); }
}
[XmlIgnore]
[Display(Name = "PDL Color", Order = 5, GroupName = "Colors")]
public Brush PDLBrush { get; set; }
[Browsable(false)]
public string PDLBrushSerializable
{
get { return Serialize.BrushToString(PDLBrush); }
set { PDLBrush = Serialize.StringToBrush(value); }
}
#endregion
}
}
thatβs great awesome
#region Using declarations
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Text;
using System.Xml.Serialization;
using System.Windows.Media;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Tools;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion
namespace NinjaTrader.NinjaScript.Indicators
{
public class WTNYTimesPDHPDLPro : Indicator
{
private TimeZoneInfo nyZone;
private DateTime currentSessionDate = DateTime.MinValue;
private DateTime currentWeekStart = DateTime.MinValue;
private DateTime currentMonthStart = DateTime.MinValue;
private int sessionStartBar;
private double sessionHigh, sessionLow;
private double weekHigh, weekLow;
private double monthHigh, monthLow;
private double pdh, pdl, pwh, pwl, pmh, pml;
private bool hasPD, hasPW, hasPM;
private bool pdhTaken, pdlTaken, pwhTaken, pwlTaken, pmhTaken, pmlTaken;
private bool inOpeningRange, openingRangeDone;
private double orHigh, orLow;
private bool orhTaken, orlTaken;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "WTNYTimesPDHPDLPro";
Description = "Modern NY session dashboard with kill zones, PDH/PDL, PWH/PWL, PMH/PML, opening range, and liquidity radar.";
Calculate = Calculate.OnEachTick;
IsOverlay = true;
DrawOnPricePanel = true;
DisplayInDataBox = false;
PaintPriceMarkers = false;
ShowTimeMarkers = true;
ShowKillZones = true;
ShowDailyLevels = true;
ShowWeeklyLevels = true;
ShowMonthlyLevels = true;
ShowOpeningRange = true;
ShowDashboard = true;
LineWidth = 2;
TextOffsetTicks = 10;
TimeLineBrush = Brushes.DodgerBlue;
Open930Brush = Brushes.LimeGreen;
Open1000Brush = Brushes.Orange;
PDHBrush = Brushes.LimeGreen;
PDLBrush = Brushes.Red;
WeeklyBrush = Brushes.DeepSkyBlue;
MonthlyBrush = Brushes.Gold;
ORBrush = Brushes.MediumPurple;
DashboardTextBrush = Brushes.White;
AsiaZoneBrush = Brushes.DarkSlateBlue;
LondonZoneBrush = Brushes.DarkGoldenrod;
NewYorkZoneBrush = Brushes.DarkGreen;
LunchZoneBrush = Brushes.DimGray;
PowerHourBrush = Brushes.DarkRed;
KillZoneOpacity = 12;
}
else if (State == State.DataLoaded)
{
try { nyZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); }
catch { nyZone = TimeZoneInfo.Local; }
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < 2)
return;
DateTime nyTime = ToNewYorkTime(Time[0]);
DateTime nySessionDate = GetNySessionDate(nyTime);
DateTime nyWeekStart = GetWeekStart(nySessionDate);
DateTime nyMonthStart = new DateTime(nySessionDate.Year, nySessionDate.Month, 1);
if (currentSessionDate == DateTime.MinValue)
{
StartNewSession(nySessionDate);
StartNewWeek(nyWeekStart);
StartNewMonth(nyMonthStart);
return;
}
if (nySessionDate != currentSessionDate)
{
pdh = sessionHigh;
pdl = sessionLow;
hasPD = true;
pdhTaken = false;
pdlTaken = false;
StartNewSession(nySessionDate);
}
else
{
sessionHigh = Math.Max(sessionHigh, High[0]);
sessionLow = Math.Min(sessionLow, Low[0]);
}
if (nyWeekStart != currentWeekStart)
{
pwh = weekHigh;
pwl = weekLow;
hasPW = true;
pwhTaken = false;
pwlTaken = false;
StartNewWeek(nyWeekStart);
}
else
{
weekHigh = Math.Max(weekHigh, High[0]);
weekLow = Math.Min(weekLow, Low[0]);
}
if (nyMonthStart != currentMonthStart)
{
pmh = monthHigh;
pml = monthLow;
hasPM = true;
pmhTaken = false;
pmlTaken = false;
StartNewMonth(nyMonthStart);
}
else
{
monthHigh = Math.Max(monthHigh, High[0]);
monthLow = Math.Min(monthLow, Low[0]);
}
UpdateOpeningRange(nyTime);
if (ShowKillZones)
DrawKillZones(nyTime);
if (ShowTimeMarkers && IsFirstTickOfBar)
DrawNyTimeMarkers();
if (ShowDailyLevels && hasPD)
DrawPreviousDayLevels();
if (ShowWeeklyLevels && hasPW)
DrawPreviousWeekLevels();
if (ShowMonthlyLevels && hasPM)
DrawPreviousMonthLevels();
if (ShowOpeningRange)
DrawOpeningRange();
if (ShowDashboard)
DrawDashboard(nyTime);
}
private void StartNewSession(DateTime date)
{
currentSessionDate = date;
sessionStartBar = CurrentBar;
sessionHigh = High[0];
sessionLow = Low[0];
openingRangeDone = false;
inOpeningRange = false;
orHigh = double.MinValue;
orLow = double.MaxValue;
orhTaken = false;
orlTaken = false;
}
private void StartNewWeek(DateTime date)
{
currentWeekStart = date;
weekHigh = High[0];
weekLow = Low[0];
}
private void StartNewMonth(DateTime date)
{
currentMonthStart = date;
monthHigh = High[0];
monthLow = Low[0];
}
private void DrawKillZones(DateTime nyTime)
{
TimeSpan t = nyTime.TimeOfDay;
if (t >= new TimeSpan(0, 0, 0) && t < new TimeSpan(8, 0, 0))
BackBrush = AsiaZoneBrush;
else if (t >= new TimeSpan(3, 0, 0) && t < new TimeSpan(11, 0, 0))
BackBrush = LondonZoneBrush;
else if (t >= new TimeSpan(9, 30, 0) && t < new TimeSpan(12, 0, 0))
BackBrush = NewYorkZoneBrush;
else if (t >= new TimeSpan(12, 0, 0) && t < new TimeSpan(13, 30, 0))
BackBrush = LunchZoneBrush;
else if (t >= new TimeSpan(15, 0, 0) && t < new TimeSpan(16, 0, 0))
BackBrush = PowerHourBrush;
else
BackBrush = null;
}
private void DrawNyTimeMarkers()
{
DateTime prevNy = ToNewYorkTime(Time[1]);
DateTime currNy = ToNewYorkTime(Time[0]);
CheckAndDrawTime(prevNy, currNy, 18, 0, "18:00 NY", TimeLineBrush);
CheckAndDrawTime(prevNy, currNy, 0, 0, "00:00 NY", TimeLineBrush);
CheckAndDrawTime(prevNy, currNy, 9, 30, "09:30 NY", Open930Brush);
CheckAndDrawTime(prevNy, currNy, 10, 0, "10:00 NY", Open1000Brush);
}
private void CheckAndDrawTime(DateTime prevNy, DateTime currNy, int hour, int minute, string label, Brush brush)
{
DateTime target = new DateTime(currNy.Year, currNy.Month, currNy.Day, hour, minute, 0);
if (prevNy < target && currNy >= target)
{
string tag = "WT_TIME_" + label.Replace(":", "").Replace(" ", "") + "_" + Time[0].ToString("yyyyMMddHHmmss");
Draw.VerticalLine(this, tag, 0, brush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
Draw.Text(this, tag + "_TXT", label, 0, High[0] + TickSize * TextOffsetTicks, brush);
}
}
private void DrawPreviousDayLevels()
{
if (High[0] >= pdh) pdhTaken = true;
if (Low[0] <= pdl) pdlTaken = true;
int barsAgo = CurrentBar - sessionStartBar;
Draw.Line(this, "WT_PDH_LINE", false, barsAgo, pdh, 0, pdh, PDHBrush, NinjaTrader.Gui.DashStyleHelper.Solid, LineWidth);
Draw.Line(this, "WT_PDL_LINE", false, barsAgo, pdl, 0, pdl, PDLBrush, NinjaTrader.Gui.DashStyleHelper.Solid, LineWidth);
Draw.Text(this, "WT_PDH_LABEL", "PDH " + pdh.ToString("0.00") + " " + (pdhTaken ? "TAKEN" : "OPEN"), 0, pdh + TickSize * TextOffsetTicks, PDHBrush);
Draw.Text(this, "WT_PDL_LABEL", "PDL " + pdl.ToString("0.00") + " " + (pdlTaken ? "TAKEN" : "OPEN"), 0, pdl - TickSize * TextOffsetTicks, PDLBrush);
}
private void DrawPreviousWeekLevels()
{
if (High[0] >= pwh) pwhTaken = true;
if (Low[0] <= pwl) pwlTaken = true;
int barsAgo = CurrentBar - sessionStartBar;
Draw.Line(this, "WT_PWH_LINE", false, barsAgo, pwh, 0, pwh, WeeklyBrush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
Draw.Line(this, "WT_PWL_LINE", false, barsAgo, pwl, 0, pwl, WeeklyBrush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
Draw.Text(this, "WT_PWH_LABEL", "PWH " + (pwhTaken ? "TAKEN" : "OPEN"), 0, pwh + TickSize * (TextOffsetTicks + 6), WeeklyBrush);
Draw.Text(this, "WT_PWL_LABEL", "PWL " + (pwlTaken ? "TAKEN" : "OPEN"), 0, pwl - TickSize * (TextOffsetTicks + 6), WeeklyBrush);
}
private void DrawPreviousMonthLevels()
{
if (High[0] >= pmh) pmhTaken = true;
if (Low[0] <= pml) pmlTaken = true;
int barsAgo = CurrentBar - sessionStartBar;
Draw.Line(this, "WT_PMH_LINE", false, barsAgo, pmh, 0, pmh, MonthlyBrush, NinjaTrader.Gui.DashStyleHelper.Dot, LineWidth);
Draw.Line(this, "WT_PML_LINE", false, barsAgo, pml, 0, pml, MonthlyBrush, NinjaTrader.Gui.DashStyleHelper.Dot, LineWidth);
Draw.Text(this, "WT_PMH_LABEL", "PMH " + (pmhTaken ? "TAKEN" : "OPEN"), 0, pmh + TickSize * (TextOffsetTicks + 12), MonthlyBrush);
Draw.Text(this, "WT_PML_LABEL", "PML " + (pmlTaken ? "TAKEN" : "OPEN"), 0, pml - TickSize * (TextOffsetTicks + 12), MonthlyBrush);
}
private void UpdateOpeningRange(DateTime nyTime)
{
TimeSpan t = nyTime.TimeOfDay;
if (t >= new TimeSpan(9, 30, 0) && t < new TimeSpan(10, 0, 0))
{
inOpeningRange = true;
orHigh = Math.Max(orHigh, High[0]);
orLow = Math.Min(orLow, Low[0]);
}
if (t >= new TimeSpan(10, 0, 0) && inOpeningRange)
{
openingRangeDone = true;
inOpeningRange = false;
}
if (openingRangeDone)
{
if (High[0] >= orHigh) orhTaken = true;
if (Low[0] <= orLow) orlTaken = true;
}
}
private void DrawOpeningRange()
{
if (orHigh == double.MinValue || orLow == double.MaxValue)
return;
int barsAgo = CurrentBar - sessionStartBar;
Draw.Line(this, "WT_ORH_LINE", false, barsAgo, orHigh, 0, orHigh, ORBrush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
Draw.Line(this, "WT_ORL_LINE", false, barsAgo, orLow, 0, orLow, ORBrush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
Draw.Text(this, "WT_ORH_LABEL", "ORH " + (orhTaken ? "BROKEN" : "OPEN"), 0, orHigh + TickSize * 4, ORBrush);
Draw.Text(this, "WT_ORL_LABEL", "ORL " + (orlTaken ? "BROKEN" : "OPEN"), 0, orLow - TickSize * 4, ORBrush);
}
private void DrawDashboard(DateTime nyTime)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("WT SESSION DASHBOARD");
sb.AppendLine("ββββββββββββββββββββββββ");
sb.AppendLine("NY TIME: " + nyTime.ToString("HH:mm:ss"));
sb.AppendLine("");
sb.AppendLine("LEVEL STATUS DIST");
sb.AppendLine("----------------------------");
if (hasPD)
{
sb.AppendLine("PDH " + StatusText(pdhTaken) + " " + DirectionText(pdh));
sb.AppendLine("PDL " + StatusText(pdlTaken) + " " + DirectionText(pdl));
}
if (hasPW)
{
sb.AppendLine("PWH " + StatusText(pwhTaken) + " " + DirectionText(pwh));
sb.AppendLine("PWL " + StatusText(pwlTaken) + " " + DirectionText(pwl));
}
if (hasPM)
{
sb.AppendLine("PMH " + StatusText(pmhTaken) + " " + DirectionText(pmh));
sb.AppendLine("PML " + StatusText(pmlTaken) + " " + DirectionText(pml));
}
if (orHigh != double.MinValue && orLow != double.MaxValue)
{
sb.AppendLine("");
sb.AppendLine("ORH " + StatusText(orhTaken) + " " + DirectionText(orHigh));
sb.AppendLine("ORL " + StatusText(orlTaken) + " " + DirectionText(orLow));
}
sb.AppendLine("");
sb.AppendLine("LIQUIDITY RADAR");
sb.AppendLine("----------------------------");
sb.AppendLine("ABOVE PRICE");
AddAbove(sb, "PDH", pdh, hasPD && !pdhTaken);
AddAbove(sb, "PWH", pwh, hasPW && !pwhTaken);
AddAbove(sb, "PMH", pmh, hasPM && !pmhTaken);
sb.AppendLine("");
sb.AppendLine("BELOW PRICE");
AddBelow(sb, "PDL", pdl, hasPD && !pdlTaken);
AddBelow(sb, "PWL", pwl, hasPW && !pwlTaken);
AddBelow(sb, "PML", pml, hasPM && !pmlTaken);
sb.AppendLine("");
sb.AppendLine("SESSION STATS");
sb.AppendLine("----------------------------");
sb.AppendLine("Range: " + ((sessionHigh - sessionLow) / TickSize).ToString("0") + " ticks");
sb.AppendLine("PDH Taken: " + YesNo(pdhTaken));
sb.AppendLine("PDL Taken: " + YesNo(pdlTaken));
sb.AppendLine("Bias: " + GetBias());
Draw.TextFixed(
this,
"WT_DASHBOARD",
sb.ToString(),
TextPosition.TopRight,
DashboardTextBrush,
new SimpleFont("Consolas", 13),
Brushes.Black,
Brushes.DimGray,
90
);
}
private string StatusText(bool taken)
{
return taken ? "TAKEN" : "OPEN ";
}
private string YesNo(bool value)
{
return value ? "YES" : "NO";
}
private string DirectionText(double level)
{
double ticks = (level - Close[0]) / TickSize;
if (ticks > 0)
return "β " + Math.Abs(ticks).ToString("0") + " ticks";
if (ticks < 0)
return "β " + Math.Abs(ticks).ToString("0") + " ticks";
return "AT PRICE";
}
private void AddAbove(StringBuilder sb, string name, double level, bool active)
{
if (!active)
return;
double ticks = (level - Close[0]) / TickSize;
if (ticks > 0)
sb.AppendLine(name + " β " + ticks.ToString("0") + " ticks");
}
private void AddBelow(StringBuilder sb, string name, double level, bool active)
{
if (!active)
return;
double ticks = (level - Close[0]) / TickSize;
if (ticks < 0)
sb.AppendLine(name + " β " + Math.Abs(ticks).ToString("0") + " ticks");
}
private string GetBias()
{
if (!hasPD)
return "WAITING";
if (Close[0] > pdh)
return "BULLISH";
if (Close[0] < pdl)
return "BEARISH";
if (Close[0] > ((pdh + pdl) / 2.0))
return "BULLISH INSIDE RANGE";
return "BEARISH INSIDE RANGE";
}
private DateTime ToNewYorkTime(DateTime chartTime)
{
if (nyZone == null)
return chartTime;
return TimeZoneInfo.ConvertTime(chartTime, Core.Globals.GeneralOptions.TimeZoneInfo, nyZone);
}
private DateTime GetNySessionDate(DateTime nyTime)
{
if (nyTime.TimeOfDay >= new TimeSpan(18, 0, 0))
return nyTime.Date.AddDays(1);
return nyTime.Date;
}
private DateTime GetWeekStart(DateTime date)
{
int diff = (7 + (date.DayOfWeek - DayOfWeek.Monday)) % 7;
return date.AddDays(-diff).Date;
}
#region Inputs
[NinjaScriptProperty]
[Display(Name = "Show Time Markers", Order = 1, GroupName = "Settings")]
public bool ShowTimeMarkers { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Kill Zones", Order = 2, GroupName = "Settings")]
public bool ShowKillZones { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Daily PDH/PDL", Order = 3, GroupName = "Settings")]
public bool ShowDailyLevels { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Weekly PWH/PWL", Order = 4, GroupName = "Settings")]
public bool ShowWeeklyLevels { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Monthly PMH/PML", Order = 5, GroupName = "Settings")]
public bool ShowMonthlyLevels { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Opening Range", Order = 6, GroupName = "Settings")]
public bool ShowOpeningRange { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Dashboard", Order = 7, GroupName = "Settings")]
public bool ShowDashboard { get; set; }
[NinjaScriptProperty]
[Range(1, 10)]
[Display(Name = "Line Width", Order = 8, GroupName = "Settings")]
public int LineWidth { get; set; }
[NinjaScriptProperty]
[Range(1, 100)]
[Display(Name = "Text Offset Ticks", Order = 9, GroupName = "Settings")]
public int TextOffsetTicks { get; set; }
[NinjaScriptProperty]
[Range(1, 100)]
[Display(Name = "Kill Zone Opacity", Order = 10, GroupName = "Settings")]
public int KillZoneOpacity { get; set; }
[XmlIgnore]
[Display(Name = "18:00 / 00:00 Color", Order = 1, GroupName = "Colors")]
public Brush TimeLineBrush { get; set; }
[Browsable(false)]
public string TimeLineBrushSerializable { get { return Serialize.BrushToString(TimeLineBrush); } set { TimeLineBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "09:30 Color", Order = 2, GroupName = "Colors")]
public Brush Open930Brush { get; set; }
[Browsable(false)]
public string Open930BrushSerializable { get { return Serialize.BrushToString(Open930Brush); } set { Open930Brush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "10:00 Color", Order = 3, GroupName = "Colors")]
public Brush Open1000Brush { get; set; }
[Browsable(false)]
public string Open1000BrushSerializable { get { return Serialize.BrushToString(Open1000Brush); } set { Open1000Brush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "PDH Color", Order = 4, GroupName = "Colors")]
public Brush PDHBrush { get; set; }
[Browsable(false)]
public string PDHBrushSerializable { get { return Serialize.BrushToString(PDHBrush); } set { PDHBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "PDL Color", Order = 5, GroupName = "Colors")]
public Brush PDLBrush { get; set; }
[Browsable(false)]
public string PDLBrushSerializable { get { return Serialize.BrushToString(PDLBrush); } set { PDLBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Weekly Color", Order = 6, GroupName = "Colors")]
public Brush WeeklyBrush { get; set; }
[Browsable(false)]
public string WeeklyBrushSerializable { get { return Serialize.BrushToString(WeeklyBrush); } set { WeeklyBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Monthly Color", Order = 7, GroupName = "Colors")]
public Brush MonthlyBrush { get; set; }
[Browsable(false)]
public string MonthlyBrushSerializable { get { return Serialize.BrushToString(MonthlyBrush); } set { MonthlyBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Opening Range Color", Order = 8, GroupName = "Colors")]
public Brush ORBrush { get; set; }
[Browsable(false)]
public string ORBrushSerializable { get { return Serialize.BrushToString(ORBrush); } set { ORBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Dashboard Text Color", Order = 9, GroupName = "Colors")]
public Brush DashboardTextBrush { get; set; }
[Browsable(false)]
public string DashboardTextBrushSerializable { get { return Serialize.BrushToString(DashboardTextBrush); } set { DashboardTextBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Asia Zone Color", Order = 10, GroupName = "Colors")]
public Brush AsiaZoneBrush { get; set; }
[Browsable(false)]
public string AsiaZoneBrushSerializable { get { return Serialize.BrushToString(AsiaZoneBrush); } set { AsiaZoneBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "London Zone Color", Order = 11, GroupName = "Colors")]
public Brush LondonZoneBrush { get; set; }
[Browsable(false)]
public string LondonZoneBrushSerializable { get { return Serialize.BrushToString(LondonZoneBrush); } set { LondonZoneBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "New York Zone Color", Order = 12, GroupName = "Colors")]
public Brush NewYorkZoneBrush { get; set; }
[Browsable(false)]
public string NewYorkZoneBrushSerializable { get { return Serialize.BrushToString(NewYorkZoneBrush); } set { NewYorkZoneBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Lunch Zone Color", Order = 13, GroupName = "Colors")]
public Brush LunchZoneBrush { get; set; }
[Browsable(false)]
public string LunchZoneBrushSerializable { get { return Serialize.BrushToString(LunchZoneBrush); } set { LunchZoneBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Power Hour Zone Color", Order = 14, GroupName = "Colors")]
public Brush PowerHourBrush { get; set; }
[Browsable(false)]
public string PowerHourBrushSerializable { get { return Serialize.BrushToString(PowerHourBrush); } set { PowerHourBrush = Serialize.StringToBrush(value); } }
#endregion
}
}
#region NinjaScript generated code. Neither change nor remove.
namespace NinjaTrader.NinjaScript.Indicators
{
public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
{
private WTNYTimesPDHPDLPro cacheWTNYTimesPDHPDLPro;
public WTNYTimesPDHPDLPro WTNYTimesPDHPDLPro(bool showTimeMarkers, bool showKillZones, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks, int killZoneOpacity)
{
return WTNYTimesPDHPDLPro(Input, showTimeMarkers, showKillZones, showDailyLevels, showWeeklyLevels, showMonthlyLevels, showOpeningRange, showDashboard, lineWidth, textOffsetTicks, killZoneOpacity);
}
public WTNYTimesPDHPDLPro WTNYTimesPDHPDLPro(ISeries<double> input, bool showTimeMarkers, bool showKillZones, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks, int killZoneOpacity)
{
if (cacheWTNYTimesPDHPDLPro != null)
for (int idx = 0; idx < cacheWTNYTimesPDHPDLPro.Length; idx++)
if (cacheWTNYTimesPDHPDLPro[idx] != null && cacheWTNYTimesPDHPDLPro[idx].ShowTimeMarkers == showTimeMarkers && cacheWTNYTimesPDHPDLPro[idx].ShowKillZones == showKillZones && cacheWTNYTimesPDHPDLPro[idx].ShowDailyLevels == showDailyLevels && cacheWTNYTimesPDHPDLPro[idx].ShowWeeklyLevels == showWeeklyLevels && cacheWTNYTimesPDHPDLPro[idx].ShowMonthlyLevels == showMonthlyLevels && cacheWTNYTimesPDHPDLPro[idx].ShowOpeningRange == showOpeningRange && cacheWTNYTimesPDHPDLPro[idx].ShowDashboard == showDashboard && cacheWTNYTimesPDHPDLPro[idx].LineWidth == lineWidth && cacheWTNYTimesPDHPDLPro[idx].TextOffsetTicks == textOffsetTicks && cacheWTNYTimesPDHPDLPro[idx].KillZoneOpacity == killZoneOpacity && cacheWTNYTimesPDHPDLPro[idx].EqualsInput(input))
return cacheWTNYTimesPDHPDLPro[idx];
return CacheIndicator<WTNYTimesPDHPDLPro>(new WTNYTimesPDHPDLPro(){ ShowTimeMarkers = showTimeMarkers, ShowKillZones = showKillZones, ShowDailyLevels = showDailyLevels, ShowWeeklyLevels = showWeeklyLevels, ShowMonthlyLevels = showMonthlyLevels, ShowOpeningRange = showOpeningRange, ShowDashboard = showDashboard, LineWidth = lineWidth, TextOffsetTicks = textOffsetTicks, KillZoneOpacity = killZoneOpacity }, input, ref cacheWTNYTimesPDHPDLPro);
}
}
}
namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
{
public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
{
public Indicators.WTNYTimesPDHPDLPro WTNYTimesPDHPDLPro(bool showTimeMarkers, bool showKillZones, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks, int killZoneOpacity)
{
return indicator.WTNYTimesPDHPDLPro(Input, showTimeMarkers, showKillZones, showDailyLevels, showWeeklyLevels, showMonthlyLevels, showOpeningRange, showDashboard, lineWidth, textOffsetTicks, killZoneOpacity);
}
public Indicators.WTNYTimesPDHPDLPro WTNYTimesPDHPDLPro(ISeries<double> input , bool showTimeMarkers, bool showKillZones, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks, int killZoneOpacity)
{
return indicator.WTNYTimesPDHPDLPro(input, showTimeMarkers, showKillZones, showDailyLevels, showWeeklyLevels, showMonthlyLevels, showOpeningRange, showDashboard, lineWidth, textOffsetTicks, killZoneOpacity);
}
}
}
namespace NinjaTrader.NinjaScript.Strategies
{
public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
{
public Indicators.WTNYTimesPDHPDLPro WTNYTimesPDHPDLPro(bool showTimeMarkers, bool showKillZones, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks, int killZoneOpacity)
{
return indicator.WTNYTimesPDHPDLPro(Input, showTimeMarkers, showKillZones, showDailyLevels, showWeeklyLevels, showMonthlyLevels, showOpeningRange, showDashboard, lineWidth, textOffsetTicks, killZoneOpacity);
}
public Indicators.WTNYTimesPDHPDLPro WTNYTimesPDHPDLPro(ISeries<double> input , bool showTimeMarkers, bool showKillZones, bool showDailyLevels, bool showWeeklyLevels, bool showMonthlyLevels, bool showOpeningRange, bool showDashboard, int lineWidth, int textOffsetTicks, int killZoneOpacity)
{
return indicator.WTNYTimesPDHPDLPro(input, showTimeMarkers, showKillZones, showDailyLevels, showWeeklyLevels, showMonthlyLevels, showOpeningRange, showDashboard, lineWidth, textOffsetTicks, killZoneOpacity);
}
}
}
#endregion
Yes absolutely. Since im coding my own version and im making progress ill just keep doing that. I got frustrated today, because its not as nice as tradingview. The feel/coding takes time to get it ok. Do you use claude for coding?
i donβt use Claude but Iβve heard good things about it from Maverick
I replaced text labels and lines with SharpDX version. Each label is visible when corresponding line is visible.
// Based on WTNYTimesPDHPDLPro
// replaced text labels with SharpDX labels
#region Using declarations
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Text;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Windows.Media;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Tools;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.DrawingTools;
using SharpDX;
//using SharpDX.Direct2D1; commented out to avoid ambiguity
using SharpDX.DirectWrite;
using NinjaTrader.Gui.Chart;
#endregion
namespace NinjaTrader.NinjaScript.Indicators
{
public class NYTimesPDHPDLProV2 : Indicator
{
private SharpDX.Direct2D1.Brush dxPdhBrush;
private SharpDX.Direct2D1.Brush dxPdlBrush;
private SharpDX.Direct2D1.Brush dxWeeklyBrush;
private SharpDX.Direct2D1.Brush dxMonthlyBrush;
private SharpDX.Direct2D1.Brush dxOrBrush;
private Dictionary<string, CachedLabel> labelCache = new Dictionary<string, CachedLabel>();
private TimeZoneInfo nyZone;
private DateTime currentSessionDate = DateTime.MinValue;
private DateTime currentWeekStart = DateTime.MinValue;
private DateTime currentMonthStart = DateTime.MinValue;
private int sessionStartBar;
private double sessionHigh, sessionLow;
private double weekHigh, weekLow;
private double monthHigh, monthLow;
private double pdh, pdl, pwh, pwl, pmh, pml;
private bool hasPD, hasPW, hasPM;
private bool pdhTaken, pdlTaken, pwhTaken, pwlTaken, pmhTaken, pmlTaken;
private bool inOpeningRange, openingRangeDone;
private double orHigh, orLow;
private bool orhTaken, orlTaken;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "NYTimesPDHPDLProV2";
Description = "Modern NY session dashboard with kill zones, PDH/PDL, PWH/PWL, PMH/PML, opening range, and liquidity radar.";
Calculate = Calculate.OnEachTick;
IsOverlay = true;
DrawOnPricePanel = true;
DisplayInDataBox = false;
PaintPriceMarkers = false;
ShowTimeMarkers = true;
ShowKillZones = true;
ShowDailyLevels = true;
ShowWeeklyLevels = true;
ShowMonthlyLevels = true;
ShowOpeningRange = true;
ShowDashboard = true;
LineWidth = 2;
TextOffsetTicks = 10;
TimeLineBrush = Brushes.DodgerBlue;
Open930Brush = Brushes.LimeGreen;
Open1000Brush = Brushes.Orange;
PDHBrush = Brushes.LimeGreen;
PDLBrush = Brushes.Red;
WeeklyBrush = Brushes.DeepSkyBlue;
MonthlyBrush = Brushes.Gold;
ORBrush = Brushes.MediumPurple;
DashboardTextBrush = Brushes.White;
AsiaZoneBrush = Brushes.DarkSlateBlue;
LondonZoneBrush = Brushes.DarkGoldenrod;
NewYorkZoneBrush = Brushes.DarkGreen;
LunchZoneBrush = Brushes.DimGray;
PowerHourBrush = Brushes.DarkRed;
KillZoneOpacity = 12;
}
else if (State == State.DataLoaded)
{
try { nyZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); }
catch { nyZone = TimeZoneInfo.Local; }
}
else if (State == State.Terminated)
{
if (labelCache != null)
{
foreach (var item in labelCache.Values)
{
item.Dispose();
}
labelCache.Clear();
}
}
}
public override void OnRenderTargetChanged()
{
// 1. Properly dispose of old device dependent resources to prevent memory leaks
if (dxPdhBrush != null) dxPdhBrush.Dispose();
if (dxPdlBrush != null) dxPdlBrush.Dispose();
if (dxWeeklyBrush != null) dxWeeklyBrush.Dispose();
if (dxMonthlyBrush != null) dxMonthlyBrush.Dispose();
if (dxOrBrush != null) dxOrBrush.Dispose();
// 2. Re-cache the WPF brushes into SharpDX hardware assets using the new RenderTarget
if (RenderTarget != null)
{
dxPdhBrush = PDHBrush.ToDxBrush(RenderTarget);
dxPdlBrush = PDLBrush.ToDxBrush(RenderTarget);
dxWeeklyBrush = WeeklyBrush.ToDxBrush(RenderTarget);
dxMonthlyBrush = MonthlyBrush.ToDxBrush(RenderTarget);
dxOrBrush = ORBrush.ToDxBrush(RenderTarget);
}
}
protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
base.OnRender(chartControl, chartScale);
// Safeguard rendering: Ensure your cached hardware assets are populated
if (CurrentBar < 1 || ChartPanel == null || RenderTarget == null || dxPdhBrush == null)
return;
int firstVisibleBar = ChartBars.FromIndex;
int lastVisibleBar = ChartBars.ToIndex;
float panelEndX = ChartPanel.X + ChartPanel.W;
using (var textFormat = new TextFormat(Core.Globals.DirectWriteFactory, "Segoe UI", FontWeight.SemiBold, FontStyle.Normal, 12))
{
if (ShowDailyLevels && hasPD)
{
RenderLevel(chartControl, chartScale, "PDH", pdh, pdhTaken, dxPdhBrush, sessionStartBar, firstVisibleBar, lastVisibleBar, panelEndX, textFormat);
RenderLevel(chartControl, chartScale, "PDL", pdl, pdlTaken, dxPdlBrush, sessionStartBar, firstVisibleBar, lastVisibleBar, panelEndX, textFormat);
}
if (ShowWeeklyLevels && hasPW)
{
RenderLevel(chartControl, chartScale, "PWH", pwh, pwhTaken, dxWeeklyBrush, sessionStartBar, firstVisibleBar, lastVisibleBar, panelEndX, textFormat);
RenderLevel(chartControl, chartScale, "PWL", pwl, pwlTaken, dxWeeklyBrush, sessionStartBar, firstVisibleBar, lastVisibleBar, panelEndX, textFormat);
}
if (ShowMonthlyLevels && hasPM)
{
RenderLevel(chartControl, chartScale, "PMH", pmh, pmhTaken, dxMonthlyBrush, sessionStartBar, firstVisibleBar, lastVisibleBar, panelEndX, textFormat);
RenderLevel(chartControl, chartScale, "PML", pml, pmlTaken, dxMonthlyBrush, sessionStartBar, firstVisibleBar, lastVisibleBar, panelEndX, textFormat);
}
if (ShowOpeningRange)
{
RenderLevel(chartControl, chartScale, "ORH", orHigh, orhTaken, dxOrBrush, sessionStartBar, firstVisibleBar, lastVisibleBar, panelEndX, textFormat);
RenderLevel(chartControl, chartScale, "ORL", orLow, orlTaken, dxOrBrush, sessionStartBar, firstVisibleBar, lastVisibleBar, panelEndX, textFormat);
}
}
}
private void RenderLevel(
ChartControl chartControl,
ChartScale chartScale,
string name,
double level,
bool taken,
SharpDX.Direct2D1.Brush dxBrush,
int startBar,
int firstVisibleBar,
int lastVisibleBar,
float panelEndX,
TextFormat textFormat)
{
// Horizontal visibility boundary check
if (startBar > lastVisibleBar) return;
// Calculate Y coordinate
float y = chartScale.GetYByValue(level);
// =================================================================
// VERTICAL VISIBILITY SKIP
// Immediately exits before touching strings, dictionaries, or memory
// =================================================================
if (y < ChartPanel.Y || y > ChartPanel.Y + ChartPanel.H) return;
// Calculate X coordinate
float xStart = chartControl.GetXByBarIndex(ChartBars, Math.Max(startBar, firstVisibleBar));
bool anchorVisible = startBar >= firstVisibleBar && startBar <= lastVisibleBar;
float labelX = anchorVisible ? xStart : ChartPanel.X + 5f;
// --- TEXT LAYOUT CACHING LOGIC ---
if (!labelCache.TryGetValue(name, out CachedLabel cachedItem))
{
cachedItem = new CachedLabel();
labelCache[name] = cachedItem;
}
// Only rebuild if data actually changed
if (cachedItem.Layout == null || cachedItem.LastLevel != level || cachedItem.LastTaken != taken)
{
cachedItem.Layout?.Dispose(); // Free the old DirectX text resources
cachedItem.LastLevel = level;
cachedItem.LastTaken = taken;
string status = taken ? "TAKEN" : "OPEN";
cachedItem.LastText = $"{name} {level:0.00} [{status}]";
// Generate the new hardware layout object
cachedItem.Layout = new TextLayout(
Core.Globals.DirectWriteFactory,
cachedItem.LastText,
textFormat,
300f,
20f
);
}
// ======================
// DRAW ASSETS (ZERO ALLOCATIONS)
// ======================
RenderTarget.DrawLine(new Vector2(xStart, y), new Vector2(panelEndX, y), dxBrush, LineWidth);
// Draw utilizing the completely cached hardware object
RenderTarget.DrawTextLayout(new Vector2(labelX, y - 14f), cachedItem.Layout, dxBrush);
}
private class CachedLabel : IDisposable
{
public string LastText { get; set; } = string.Empty;
public double LastLevel { get; set; } = double.MinValue;
public bool LastTaken { get; set; }
public TextLayout Layout { get; set; }
public void Dispose()
{
Layout?.Dispose();
Layout = null;
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < 2)
return;
DateTime nyTime = ToNewYorkTime(Time[0]);
DateTime nySessionDate = GetNySessionDate(nyTime);
DateTime nyWeekStart = GetWeekStart(nySessionDate);
DateTime nyMonthStart = new DateTime(nySessionDate.Year, nySessionDate.Month, 1);
if (currentSessionDate == DateTime.MinValue)
{
StartNewSession(nySessionDate);
StartNewWeek(nyWeekStart);
StartNewMonth(nyMonthStart);
return;
}
if (nySessionDate != currentSessionDate)
{
pdh = sessionHigh;
pdl = sessionLow;
hasPD = true;
pdhTaken = false;
pdlTaken = false;
StartNewSession(nySessionDate);
}
else
{
sessionHigh = Math.Max(sessionHigh, High[0]);
sessionLow = Math.Min(sessionLow, Low[0]);
}
if (nyWeekStart != currentWeekStart)
{
pwh = weekHigh;
pwl = weekLow;
hasPW = true;
pwhTaken = false;
pwlTaken = false;
StartNewWeek(nyWeekStart);
}
else
{
weekHigh = Math.Max(weekHigh, High[0]);
weekLow = Math.Min(weekLow, Low[0]);
}
if (nyMonthStart != currentMonthStart)
{
pmh = monthHigh;
pml = monthLow;
hasPM = true;
pmhTaken = false;
pmlTaken = false;
StartNewMonth(nyMonthStart);
}
else
{
monthHigh = Math.Max(monthHigh, High[0]);
monthLow = Math.Min(monthLow, Low[0]);
}
UpdateOpeningRange(nyTime);
if (ShowKillZones)
DrawKillZones(nyTime);
if (ShowTimeMarkers && IsFirstTickOfBar)
DrawNyTimeMarkers();
if (ShowDashboard)
DrawDashboard(nyTime);
}
private void StartNewSession(DateTime date)
{
currentSessionDate = date;
sessionStartBar = CurrentBar;
sessionHigh = High[0];
sessionLow = Low[0];
openingRangeDone = false;
inOpeningRange = false;
orHigh = double.MinValue;
orLow = double.MaxValue;
orhTaken = false;
orlTaken = false;
}
private void StartNewWeek(DateTime date)
{
currentWeekStart = date;
weekHigh = High[0];
weekLow = Low[0];
}
private void StartNewMonth(DateTime date)
{
currentMonthStart = date;
monthHigh = High[0];
monthLow = Low[0];
}
private void DrawKillZones(DateTime nyTime)
{
TimeSpan t = nyTime.TimeOfDay;
if (t >= new TimeSpan(0, 0, 0) && t < new TimeSpan(8, 0, 0))
BackBrush = AsiaZoneBrush;
else if (t >= new TimeSpan(3, 0, 0) && t < new TimeSpan(11, 0, 0))
BackBrush = LondonZoneBrush;
else if (t >= new TimeSpan(9, 30, 0) && t < new TimeSpan(12, 0, 0))
BackBrush = NewYorkZoneBrush;
else if (t >= new TimeSpan(12, 0, 0) && t < new TimeSpan(13, 30, 0))
BackBrush = LunchZoneBrush;
else if (t >= new TimeSpan(15, 0, 0) && t < new TimeSpan(16, 0, 0))
BackBrush = PowerHourBrush;
else
BackBrush = null;
}
private void DrawNyTimeMarkers()
{
DateTime prevNy = ToNewYorkTime(Time[1]);
DateTime currNy = ToNewYorkTime(Time[0]);
CheckAndDrawTime(prevNy, currNy, 18, 0, "18:00 NY", TimeLineBrush);
CheckAndDrawTime(prevNy, currNy, 0, 0, "00:00 NY", TimeLineBrush);
CheckAndDrawTime(prevNy, currNy, 9, 30, "09:30 NY", Open930Brush);
CheckAndDrawTime(prevNy, currNy, 10, 0, "10:00 NY", Open1000Brush);
}
private void CheckAndDrawTime(DateTime prevNy, DateTime currNy, int hour, int minute, string label, Brush brush)
{
DateTime target = new DateTime(currNy.Year, currNy.Month, currNy.Day, hour, minute, 0);
if (prevNy < target && currNy >= target)
{
string tag = "WT_TIME_" + label.Replace(":", "").Replace(" ", "") + "_" + Time[0].ToString("yyyyMMddHHmmss");
Draw.VerticalLine(this, tag, 0, brush, NinjaTrader.Gui.DashStyleHelper.Dash, LineWidth);
Draw.Text(this, tag + "_TXT", label, 0, High[0] + TickSize * TextOffsetTicks, brush);
}
}
private void UpdateOpeningRange(DateTime nyTime)
{
TimeSpan t = nyTime.TimeOfDay;
if (t >= new TimeSpan(9, 30, 0) && t < new TimeSpan(10, 0, 0))
{
inOpeningRange = true;
orHigh = Math.Max(orHigh, High[0]);
orLow = Math.Min(orLow, Low[0]);
}
if (t >= new TimeSpan(10, 0, 0) && inOpeningRange)
{
openingRangeDone = true;
inOpeningRange = false;
}
if (openingRangeDone)
{
if (High[0] >= orHigh) orhTaken = true;
if (Low[0] <= orLow) orlTaken = true;
}
}
private void DrawDashboard(DateTime nyTime)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("WT SESSION DASHBOARD");
sb.AppendLine("ββββββββββββββββββββββββ");
sb.AppendLine("NY TIME: " + nyTime.ToString("HH:mm:ss"));
sb.AppendLine("");
sb.AppendLine("LEVEL STATUS DIST");
sb.AppendLine("----------------------------");
if (hasPD)
{
sb.AppendLine("PDH " + StatusText(pdhTaken) + " " + DirectionText(pdh));
sb.AppendLine("PDL " + StatusText(pdlTaken) + " " + DirectionText(pdl));
}
if (hasPW)
{
sb.AppendLine("PWH " + StatusText(pwhTaken) + " " + DirectionText(pwh));
sb.AppendLine("PWL " + StatusText(pwlTaken) + " " + DirectionText(pwl));
}
if (hasPM)
{
sb.AppendLine("PMH " + StatusText(pmhTaken) + " " + DirectionText(pmh));
sb.AppendLine("PML " + StatusText(pmlTaken) + " " + DirectionText(pml));
}
if (orHigh != double.MinValue && orLow != double.MaxValue)
{
sb.AppendLine("");
sb.AppendLine("ORH " + StatusText(orhTaken) + " " + DirectionText(orHigh));
sb.AppendLine("ORL " + StatusText(orlTaken) + " " + DirectionText(orLow));
}
sb.AppendLine("");
sb.AppendLine("LIQUIDITY RADAR");
sb.AppendLine("----------------------------");
sb.AppendLine("ABOVE PRICE");
AddAbove(sb, "PDH", pdh, hasPD && !pdhTaken);
AddAbove(sb, "PWH", pwh, hasPW && !pwhTaken);
AddAbove(sb, "PMH", pmh, hasPM && !pmhTaken);
sb.AppendLine("");
sb.AppendLine("BELOW PRICE");
AddBelow(sb, "PDL", pdl, hasPD && !pdlTaken);
AddBelow(sb, "PWL", pwl, hasPW && !pwlTaken);
AddBelow(sb, "PML", pml, hasPM && !pmlTaken);
sb.AppendLine("");
sb.AppendLine("SESSION STATS");
sb.AppendLine("----------------------------");
sb.AppendLine("Range: " + ((sessionHigh - sessionLow) / TickSize).ToString("0") + " ticks");
sb.AppendLine("PDH Taken: " + YesNo(pdhTaken));
sb.AppendLine("PDL Taken: " + YesNo(pdlTaken));
sb.AppendLine("Bias: " + GetBias());
Draw.TextFixed(
this,
"WT_DASHBOARD",
sb.ToString(),
TextPosition.TopRight,
DashboardTextBrush,
new SimpleFont("Consolas", 13),
Brushes.Black,
Brushes.DimGray,
90
);
}
private string StatusText(bool taken)
{
return taken ? "TAKEN" : "OPEN ";
}
private string YesNo(bool value)
{
return value ? "YES" : "NO";
}
private string DirectionText(double level)
{
double ticks = (level - Close[0]) / TickSize;
if (ticks > 0)
return "β " + Math.Abs(ticks).ToString("0") + " ticks";
if (ticks < 0)
return "β " + Math.Abs(ticks).ToString("0") + " ticks";
return "AT PRICE";
}
private void AddAbove(StringBuilder sb, string name, double level, bool active)
{
if (!active)
return;
double ticks = (level - Close[0]) / TickSize;
if (ticks > 0)
sb.AppendLine(name + " β " + ticks.ToString("0") + " ticks");
}
private void AddBelow(StringBuilder sb, string name, double level, bool active)
{
if (!active)
return;
double ticks = (level - Close[0]) / TickSize;
if (ticks < 0)
sb.AppendLine(name + " β " + Math.Abs(ticks).ToString("0") + " ticks");
}
private string GetBias()
{
if (!hasPD)
return "WAITING";
if (Close[0] > pdh)
return "BULLISH";
if (Close[0] < pdl)
return "BEARISH";
if (Close[0] > ((pdh + pdl) / 2.0))
return "BULLISH INSIDE RANGE";
return "BEARISH INSIDE RANGE";
}
private DateTime ToNewYorkTime(DateTime chartTime)
{
if (nyZone == null)
return chartTime;
return TimeZoneInfo.ConvertTime(chartTime, Core.Globals.GeneralOptions.TimeZoneInfo, nyZone);
}
private DateTime GetNySessionDate(DateTime nyTime)
{
if (nyTime.TimeOfDay >= new TimeSpan(18, 0, 0))
return nyTime.Date.AddDays(1);
return nyTime.Date;
}
private DateTime GetWeekStart(DateTime date)
{
int diff = (7 + (date.DayOfWeek - DayOfWeek.Monday)) % 7;
return date.AddDays(-diff).Date;
}
#region Inputs
[NinjaScriptProperty]
[Display(Name = "Show Time Markers", Order = 1, GroupName = "Settings")]
public bool ShowTimeMarkers { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Kill Zones", Order = 2, GroupName = "Settings")]
public bool ShowKillZones { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Daily PDH/PDL", Order = 3, GroupName = "Settings")]
public bool ShowDailyLevels { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Weekly PWH/PWL", Order = 4, GroupName = "Settings")]
public bool ShowWeeklyLevels { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Monthly PMH/PML", Order = 5, GroupName = "Settings")]
public bool ShowMonthlyLevels { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Opening Range", Order = 6, GroupName = "Settings")]
public bool ShowOpeningRange { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Dashboard", Order = 7, GroupName = "Settings")]
public bool ShowDashboard { get; set; }
[NinjaScriptProperty]
[Range(1, 10)]
[Display(Name = "Line Width", Order = 8, GroupName = "Settings")]
public int LineWidth { get; set; }
[NinjaScriptProperty]
[Range(1, 100)]
[Display(Name = "Text Offset Ticks", Order = 9, GroupName = "Settings")]
public int TextOffsetTicks { get; set; }
[NinjaScriptProperty]
[Range(1, 100)]
[Display(Name = "Kill Zone Opacity", Order = 10, GroupName = "Settings")]
public int KillZoneOpacity { get; set; }
[XmlIgnore]
[Display(Name = "18:00 / 00:00 Color", Order = 1, GroupName = "Colors")]
public Brush TimeLineBrush { get; set; }
[Browsable(false)]
public string TimeLineBrushSerializable { get { return Serialize.BrushToString(TimeLineBrush); } set { TimeLineBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "09:30 Color", Order = 2, GroupName = "Colors")]
public Brush Open930Brush { get; set; }
[Browsable(false)]
public string Open930BrushSerializable { get { return Serialize.BrushToString(Open930Brush); } set { Open930Brush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "10:00 Color", Order = 3, GroupName = "Colors")]
public Brush Open1000Brush { get; set; }
[Browsable(false)]
public string Open1000BrushSerializable { get { return Serialize.BrushToString(Open1000Brush); } set { Open1000Brush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "PDH Color", Order = 4, GroupName = "Colors")]
public Brush PDHBrush { get; set; }
[Browsable(false)]
public string PDHBrushSerializable { get { return Serialize.BrushToString(PDHBrush); } set { PDHBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "PDL Color", Order = 5, GroupName = "Colors")]
public Brush PDLBrush { get; set; }
[Browsable(false)]
public string PDLBrushSerializable { get { return Serialize.BrushToString(PDLBrush); } set { PDLBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Weekly Color", Order = 6, GroupName = "Colors")]
public Brush WeeklyBrush { get; set; }
[Browsable(false)]
public string WeeklyBrushSerializable { get { return Serialize.BrushToString(WeeklyBrush); } set { WeeklyBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Monthly Color", Order = 7, GroupName = "Colors")]
public Brush MonthlyBrush { get; set; }
[Browsable(false)]
public string MonthlyBrushSerializable { get { return Serialize.BrushToString(MonthlyBrush); } set { MonthlyBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Opening Range Color", Order = 8, GroupName = "Colors")]
public Brush ORBrush { get; set; }
[Browsable(false)]
public string ORBrushSerializable { get { return Serialize.BrushToString(ORBrush); } set { ORBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Dashboard Text Color", Order = 9, GroupName = "Colors")]
public Brush DashboardTextBrush { get; set; }
[Browsable(false)]
public string DashboardTextBrushSerializable { get { return Serialize.BrushToString(DashboardTextBrush); } set { DashboardTextBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Asia Zone Color", Order = 10, GroupName = "Colors")]
public Brush AsiaZoneBrush { get; set; }
[Browsable(false)]
public string AsiaZoneBrushSerializable { get { return Serialize.BrushToString(AsiaZoneBrush); } set { AsiaZoneBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "London Zone Color", Order = 11, GroupName = "Colors")]
public Brush LondonZoneBrush { get; set; }
[Browsable(false)]
public string LondonZoneBrushSerializable { get { return Serialize.BrushToString(LondonZoneBrush); } set { LondonZoneBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "New York Zone Color", Order = 12, GroupName = "Colors")]
public Brush NewYorkZoneBrush { get; set; }
[Browsable(false)]
public string NewYorkZoneBrushSerializable { get { return Serialize.BrushToString(NewYorkZoneBrush); } set { NewYorkZoneBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Lunch Zone Color", Order = 13, GroupName = "Colors")]
public Brush LunchZoneBrush { get; set; }
[Browsable(false)]
public string LunchZoneBrushSerializable { get { return Serialize.BrushToString(LunchZoneBrush); } set { LunchZoneBrush = Serialize.StringToBrush(value); } }
[XmlIgnore]
[Display(Name = "Power Hour Zone Color", Order = 14, GroupName = "Colors")]
public Brush PowerHourBrush { get; set; }
[Browsable(false)]
public string PowerHourBrushSerializable { get { return Serialize.BrushToString(PowerHourBrush); } set { PowerHourBrush = Serialize.StringToBrush(value); } }
#endregion
}
}
Bill Iβm getting errors on this code
I copy pasted into the editor and compiled just fine. Is it the ambiguity errors?
I think it son my end, never mind, i have the original so itβs getting mixed up.
I should not have used your indicator name to avoid confusion (and conflicts). I updated the code.
Billl I see one issue, The text labels on the lines, such as PDH, PDL, ORH, and ORL, are not staying anchored to their lines. When I drag or move the chart, the labels shift away from the lines instead of moving with them. This needs to be fixed so each label stays attached to its matching line at all times.
Are they shifted horizontally or vertically or you mean that they are visible when lines are not? Labels are rendered at price level the lines are at +fixed offset.
