using System; using System.Collections.Generic; using System.Text.Json; using System.Linq; using cAlgo.API; using cAlgo.API.Internals; // ****************************************** // *** ASSUMING SERVER TIME IS ALWAYS GMT *** // ****************************************** namespace cAlgo { [Indicator(AccessRights = AccessRights.None, IsOverlay = true)] public class HoLo_Indi : Indicator { Bars H1Bars, D1Bars; DateTime CurrentTradingSessionDateTime = DateTime.MinValue; double YesterdayHigh, YesterdayLow, TodayHigh, TodayLow, TodayHighestHTFOpen, TodayLowestHTFOpen; bool FirtsRun = true; int CurrentD1BarIndex = 0, CurrentH1BarIndex = 0; AreaOfInterest UpperAreaOfInterest = new AreaOfInterest(), LowerAreaOfInterest = new AreaOfInterest(); protected override void Initialize() { //System.Diagnostics.Debugger.Launch(); Chart.RemoveAllObjects(); if (Chart.TimeFrame != TimeFrame.Minute5) { Chart.TryChangeTimeFrame(TimeFrame.Minute5); } Chart.ColorSettings.BullFillColor = Color.Lime; Chart.ColorSettings.BullOutlineColor = Color.Lime; Chart.ColorSettings.BearFillColor = Color.DarkOrchid; Chart.ColorSettings.BearOutlineColor = Color.DarkOrchid; Chart.DisplaySettings.Grid = false; Chart.DisplaySettings.PeriodSeparators = false; Chart.DisplaySettings.QuickTradeButtons = false; Chart.DisplaySettings.Targets = false; Chart.DisplaySettings.TickVolume = false; Chart.DisplaySettings.AskPriceLine = false; H1Bars = MarketData.GetBars(TimeFrame.Hour, SymbolName); D1Bars = MarketData.GetBars(TimeFrame.Daily, SymbolName); CurrentTradingSessionDateTime = D1Bars.OpenTimes[1]; Chart.ZoomLevel = 20; Chart.ScrollXTo(Bars.LastBar.OpenTime); Chart.SetYRange(D1Bars.Last(1).Low < D1Bars.Last(0).Low ? D1Bars.Last(1).Low - 5 * Symbol.PipSize : D1Bars.Last(0).Low - 5 * Symbol.PipSize, D1Bars.Last(1).High > D1Bars.Last(0).High ? D1Bars.Last(1).High + 5 * Symbol.PipSize : D1Bars.Last(0).High + 5 * Symbol.PipSize); } public override void Calculate(int index) { if (FirtsRun) { while (D1Bars.OpenTimes.GetIndexByTime(Bars[0].OpenTime) == -1) D1Bars.LoadMoreHistory(); while (H1Bars.OpenTimes.GetIndexByTime(Bars[0].OpenTime) == -1) H1Bars.LoadMoreHistory(); while (D1Bars[D1Bars.OpenTimes.GetIndexByTime(Bars[0].OpenTime)].OpenTime == D1Bars[D1Bars.OpenTimes.GetIndexByTime(Bars[index].OpenTime)].OpenTime) return; while (H1Bars[H1Bars.OpenTimes.GetIndexByTime(Bars[index].OpenTime)].OpenTime.Hour != D1Bars[D1Bars.OpenTimes.GetIndexByTime(Bars[index].OpenTime)].OpenTime.Hour + 1) return; SetupNewSession(index); FirtsRun = false; } CurrentD1BarIndex = D1Bars.OpenTimes.GetIndexByTime(Bars[index].OpenTime); CurrentH1BarIndex = H1Bars.OpenTimes.GetIndexByTime(Bars[index].OpenTime); if (CurrentTradingSessionDateTime != D1Bars[CurrentD1BarIndex].OpenTime) { while (H1Bars[CurrentH1BarIndex].OpenTime.Hour != D1Bars[CurrentD1BarIndex].OpenTime.Hour + 1) return; SetupNewSession(index); } if (Bars[index].OpenTime.Minute == 0) { //New H1 if (H1Bars.Where(b => b.OpenTime >= CurrentTradingSessionDateTime && b.OpenTime <= Bars[index].OpenTime).Max(p => p.Open) > TodayHighestHTFOpen) { TodayHighestHTFOpen = H1Bars.Where(b => b.OpenTime >= CurrentTradingSessionDateTime && b.OpenTime <= Bars[index].OpenTime).Max(p => p.Open); Chart.DrawIcon("TodayHighestHTFOpen" + Guid.NewGuid().ToString(), ChartIconType.DownArrow, Bars[index].OpenTime, TodayHighestHTFOpen, Color.Yellow); UpperAreaOfInterest.Name = Guid.NewGuid().ToString(); UpperAreaOfInterest.StartingFrom = H1Bars[CurrentH1BarIndex].OpenTime; UpperAreaOfInterest.LowerLevel = TodayHighestHTFOpen; UpperAreaOfInterest.UpperLevel = TodayHigh; UpperAreaOfInterest.Enabled = true; } if (H1Bars.Where(b => b.OpenTime >= CurrentTradingSessionDateTime && b.OpenTime <= Bars[index].OpenTime).Min(p => p.Open) < TodayLowestHTFOpen) { TodayLowestHTFOpen = H1Bars.Where(b => b.OpenTime >= CurrentTradingSessionDateTime && b.OpenTime <= Bars[index].OpenTime).Min(p => p.Open); Chart.DrawIcon("TodayHighestHTFOpen" + Guid.NewGuid().ToString(), ChartIconType.UpArrow, Bars[index].OpenTime, TodayLowestHTFOpen, Color.Yellow); LowerAreaOfInterest.Name = Guid.NewGuid().ToString(); LowerAreaOfInterest.StartingFrom = H1Bars[CurrentH1BarIndex].OpenTime; LowerAreaOfInterest.LowerLevel = TodayLow; LowerAreaOfInterest.UpperLevel = TodayLowestHTFOpen; LowerAreaOfInterest.Enabled = true; } } if (Bars[index].High > TodayHigh || Bars[index].Close > YesterdayHigh) UpperAreaOfInterest.Enabled = false; if (Bars[index].Low < TodayLow || Bars[index].Close < YesterdayLow) LowerAreaOfInterest.Enabled = false; TodayHigh = Bars.Where(b => b.OpenTime >= CurrentTradingSessionDateTime && b.OpenTime <= Bars[index].OpenTime).Max(p => p.High); TodayLow = Bars.Where(b => b.OpenTime >= CurrentTradingSessionDateTime && b.OpenTime <= Bars[index].OpenTime).Min(p => p.Low); Chart.DrawRectangle("H1Bar" + H1Bars[CurrentH1BarIndex].Open.ToString(), H1Bars[CurrentH1BarIndex].OpenTime, H1Bars[CurrentH1BarIndex].Open, Bars[index].OpenTime, H1Bars[CurrentH1BarIndex].Close, H1Bars[CurrentH1BarIndex].Open < H1Bars[CurrentH1BarIndex].Close ? Color.Lime : Color.Red, 2, LineStyle.Dots); Chart.DrawRectangle("H1Bar" + H1Bars[CurrentH1BarIndex].Open.ToString(), H1Bars[CurrentH1BarIndex].OpenTime, H1Bars[CurrentH1BarIndex].Open, Bars[index].OpenTime, H1Bars[CurrentH1BarIndex].Close, H1Bars[CurrentH1BarIndex].Open < H1Bars[CurrentH1BarIndex].Close ? Color.Lime : Color.Red, 2, LineStyle.Dots); Chart.DrawTrendLine("YesterdayHigh", D1Bars.LastBar.OpenTime, YesterdayHigh, Server.Time, YesterdayHigh, Color.Gray, 1, LineStyle.LinesDots); Chart.DrawText("YesterdayHighTXT", "YesterdayHigh", new DateTime((Bars[index].OpenTime.Ticks + D1Bars.LastBar.OpenTime.Ticks) / 2), YesterdayHigh, Color.Gray).VerticalAlignment = VerticalAlignment.Bottom; Chart.DrawTrendLine("YesterdayLow", D1Bars.LastBar.OpenTime, YesterdayLow, Server.Time, YesterdayLow, Color.Gray, 1, LineStyle.LinesDots); Chart.DrawText("YesterdayLowTXT", "YesterdayLow", new DateTime((Bars[index].OpenTime.Ticks + D1Bars.LastBar.OpenTime.Ticks) / 2), YesterdayLow, Color.Gray).VerticalAlignment = VerticalAlignment.Top; Chart.DrawTrendLine("TodayHigh", D1Bars.LastBar.OpenTime, D1Bars.LastBar.High, Server.Time, D1Bars.LastBar.High, Color.Lime, 1, LineStyle.LinesDots); Chart.DrawText("TodayHighTXT", "TodayHigh", new DateTime((Bars[index].OpenTime.Ticks + D1Bars.LastBar.OpenTime.Ticks) / 2), D1Bars.LastBar.High, Color.Lime).VerticalAlignment = VerticalAlignment.Bottom; Chart.DrawTrendLine("TodayLow", D1Bars.LastBar.OpenTime, D1Bars.LastBar.Low, Server.Time, D1Bars.LastBar.Low, Color.DarkOrchid, 1, LineStyle.LinesDots); Chart.DrawText("TodayLowTXT", "TodayLow", new DateTime((Bars[index].OpenTime.Ticks + D1Bars.LastBar.OpenTime.Ticks) / 2), D1Bars.LastBar.Low, Color.DarkOrchid).VerticalAlignment = VerticalAlignment.Top; if (UpperAreaOfInterest.Enabled == true) Chart.DrawRectangle("UpperAreaOfInterest" + UpperAreaOfInterest.Name, UpperAreaOfInterest.StartingFrom, UpperAreaOfInterest.UpperLevel, Bars[index].OpenTime, UpperAreaOfInterest.LowerLevel, Color.FromArgb(50, Color.Yellow)).IsFilled = true; if (LowerAreaOfInterest.Enabled == true) Chart.DrawRectangle("LowerAreaOfInterest" + LowerAreaOfInterest.Name, LowerAreaOfInterest.StartingFrom, LowerAreaOfInterest.UpperLevel, Bars[index].OpenTime, LowerAreaOfInterest.LowerLevel, Color.FromArgb(50, Color.Yellow)).IsFilled = true; if (Bars[index].OpenTime.Hour == 7 && Bars[index].OpenTime.Minute == 0) { Chart.DrawVerticalLine("LON" + CurrentTradingSessionDateTime.ToString(), Bars[index].OpenTime, Color.Aqua, 1, LineStyle.DotsRare); } if (Bars[index].OpenTime.Hour == 13 && Bars[index].OpenTime.Minute == 0) { Chart.DrawVerticalLine("NYC" + CurrentTradingSessionDateTime.ToString(), Bars[index].OpenTime, Color.Aqua, 1, LineStyle.DotsRare); } } private void SetupNewSession(int index) { CurrentD1BarIndex = D1Bars.OpenTimes.GetIndexByTime(Bars[index].OpenTime); CurrentH1BarIndex = H1Bars.OpenTimes.GetIndexByTime(Bars[index].OpenTime); CurrentTradingSessionDateTime = D1Bars[D1Bars.OpenTimes.GetIndexByTime(Bars[index].OpenTime)].OpenTime; UpperAreaOfInterest.Enabled = false; LowerAreaOfInterest.Enabled = false; Chart.DrawRectangle("H1Bar" + H1Bars[CurrentH1BarIndex - 1].Open.ToString(), H1Bars[CurrentH1BarIndex - 1].OpenTime, H1Bars[CurrentH1BarIndex].Open, Bars[index - 1].OpenTime, H1Bars[CurrentH1BarIndex - 1].Close, H1Bars[CurrentH1BarIndex - 1].Open < H1Bars[CurrentH1BarIndex - 1].Close ? Color.Lime : Color.Red, 2, LineStyle.Dots); Chart.DrawRectangle("H1Bar" + H1Bars[CurrentH1BarIndex - 1].Open.ToString(), H1Bars[CurrentH1BarIndex - 1].OpenTime, H1Bars[CurrentH1BarIndex].Open, Bars[index - 1].OpenTime, H1Bars[CurrentH1BarIndex - 1].Close, H1Bars[CurrentH1BarIndex - 1].Open < H1Bars[CurrentH1BarIndex - 1].Close ? Color.Lime : Color.Red, 2, LineStyle.Dots); Chart.DrawVerticalLine(CurrentTradingSessionDateTime.ToString(), CurrentTradingSessionDateTime, Color.Gray, 2, LineStyle.Solid); YesterdayHigh = D1Bars[CurrentD1BarIndex - 1].High; YesterdayLow = D1Bars[CurrentD1BarIndex - 1].Low; TodayHigh = Bars.Where(b => b.OpenTime >= CurrentTradingSessionDateTime && b.OpenTime <= Bars[index].OpenTime).Max(p => p.High); TodayLow = Bars.Where(b => b.OpenTime >= CurrentTradingSessionDateTime && b.OpenTime <= Bars[index].OpenTime).Min(p => p.Low); TodayHighestHTFOpen = H1Bars.Where(b => b.OpenTime >= CurrentTradingSessionDateTime && b.OpenTime <= Bars[index].OpenTime).Max(p => p.Open); TodayLowestHTFOpen = H1Bars.Where(b => b.OpenTime >= CurrentTradingSessionDateTime && b.OpenTime <= Bars[index].OpenTime).Min(p => p.Open); } protected override void OnDestroy() { Chart.RemoveAllObjects(); base.OnDestroy(); } } public class AreaOfInterest { public AreaOfInterest() { Enabled = false; StartingFrom = DateTime.MinValue; EndingTo = DateTime.MinValue; Name = "UNK"; UpperLevel = 0; LowerLevel = 0; } public bool Enabled { get; set; } public DateTime StartingFrom { get; set; } public DateTime EndingTo { get; set; } public string Name { get; set; } public double UpperLevel { get; set; } public double LowerLevel { get; set; } } }