using System; using cAlgo.API; namespace cAlgo.Indicators { [Indicator(IsOverlay = true, AccessRights = AccessRights.None)] public class NYOpen : Indicator { [Parameter("Show NY Open Trendline", DefaultValue = true)] public bool ShowLine { get; set; } [Parameter("Show DEBUG Logs", DefaultValue = false)] public bool EnableLogs { get; set; } [Parameter("Draw Short Line", DefaultValue = true)] public bool DrawShortLine { get; set; } [Parameter("Line Color", DefaultValue = "Gold")] public Color LineColor { get; set; } [Parameter("Line Thickness", DefaultValue = 2, MinValue = 1, MaxValue = 5)] public int LineThickness { get; set; } [Parameter("Show Label", DefaultValue = true)] public bool ShowLabel { get; set; } //private Color _color; private static bool _warnedAboutMissingNYBar = false; protected override void Initialize() { } public override void Calculate(int index) { if (!ShowLine || index != Bars.Count - 1) return; var nyTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); var todayLocal = DateTime.UtcNow.Date; var nyLocalMidnight = new DateTime(todayLocal.Year, todayLocal.Month, todayLocal.Day, 0, 0, 0, DateTimeKind.Unspecified); var nyMidnightUtc = TimeZoneInfo.ConvertTimeToUtc(nyLocalMidnight, nyTimeZone); if (EnableLogs) { Print("NY Midnight UTC Target:", nyMidnightUtc); } // Find the bar on the chart closest to NY Midnight UTC double? nyOpenPrice = null; const double toleranceSeconds = 60; for (int i = 0; i < Bars.Count; i++) { var delta = Math.Abs((Bars[i].OpenTime - nyMidnightUtc).TotalSeconds); if (delta <= toleranceSeconds) { nyOpenPrice = Bars[i].Open; break; } } if (nyOpenPrice == null) { if (EnableLogs && !_warnedAboutMissingNYBar) { Print("NY Open bar not found in current chart data."); _warnedAboutMissingNYBar = true; } return; } // Get start and end of today's chart period (UTC-aligned) var sessionStart = todayLocal; var sessionEnd = todayLocal.AddDays(1); int startIndex = -1, endIndex = -1; for (int i = 0; i < Bars.Count; i++) { if (startIndex == -1 && Bars[i].OpenTime >= sessionStart) startIndex = i; if (endIndex == -1 && Bars[i].OpenTime >= sessionEnd) { endIndex = i; break; } } if (EnableLogs && startIndex == -1) { Print("Start of session not found."); return; } if (endIndex == -1) endIndex = Bars.Count - 1; string id = "NYOpenTrend_" + todayLocal.ToString("yyyyMMdd"); if (DrawShortLine) { // Draw short length line int x1 = Bars.Count - 4; int x2 = Bars.Count -1; Chart.DrawTrendLine(id, x1, nyOpenPrice.Value, x2, nyOpenPrice.Value, LineColor, LineThickness, LineStyle.Solid); if (ShowLabel) Chart.DrawText(id + "_label", "NY Midnight Open", x2 + 1, nyOpenPrice.Value, LineColor); } else { //Default length Chart.DrawTrendLine(id, startIndex, nyOpenPrice.Value, endIndex, nyOpenPrice.Value, LineColor, LineThickness, LineStyle.Solid); if (ShowLabel) Chart.DrawText(id + "_label", "NY Midnight Open", endIndex, nyOpenPrice.Value, LineColor); } if (EnableLogs) { Print($"NY Open price: {nyOpenPrice.Value} drawn from bar {startIndex} to {endIndex}."); } } } }