Untitled
unknown
plain_text
5 months ago
10 kB
2
Indexable
using System; using cAlgo.API; using cAlgo.API.Collections; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(AccessRights = AccessRights.None, AddIndicators = true, TimeZone = TimeZones.UTC)] public class BreakerToNDOG : Robot { [Parameter("Hour Start", Group = "Box", DefaultValue = 7)] public int HourStart { get; set; } [Parameter("Minute Start", Group = "Box", DefaultValue = 30)] public int MinuteStart { get; set; } [Parameter("Hour Start", Group = "Box", DefaultValue = 7)] public int HourEnd { get; set; } [Parameter("Minute Start", Group = "Box", DefaultValue = 59)] public int MinuteEnd { get; set; } [Parameter("UTC Shift", Group = "Box", DefaultValue = -5)] public int UtcShift { get; set; } [Parameter("First Trade Bars", Group = "Trade Setup", DefaultValue = 15)] public int FirstTradeBars { get; set; } [Parameter("Finding Trade Timing", Group = "Trade Setup", DefaultValue = "8:00,8:30,9:00,9:30,10:00,10:30")] public string FindingTradeTiming { get; set; } [Parameter("SL Pips", Group = "Trade Setup", DefaultValue = 300)] public int stoplossPips { get; set; } [Parameter("Min FVG Pips", Group = "Trade Setup", DefaultValue = 4)] public int minFVGpips { get; set; } [Parameter("Min RR", Group = "Trade Setup", DefaultValue = 2)] public int minRR { get; set; } // PRIVATE private Us30BreakerBox Us30BreakerBox { get; set; } private double boxHigh, boxLow; private double ndog1, ndog2; private string SideOfBox, BreakerDir; private double fvgHigh, fvgLow; private string currentFVGtype; private TradeType tradeType; protected override void OnStart() { bool isOneMinute = TimeFrame == TimeFrame.Minute; if (!isOneMinute) { Print("The current time frame is NOT 1 minute."); Stop(); return; } boxHigh = double.MinValue; boxLow = double.MaxValue; // Us30BreakerBox = Indicators.GetIndicator<Us30BreakerBox>("bias box", HourStart, MinuteStart, HourEnd, MinuteEnd, UtcShift, false, false); } protected override void OnBar() { // Get the time of the last closed bar DateTime lastBarTime = Bars.OpenTimes.Last(1); // Convert last bar time to UTC-5 DateTime lastBarTimeUtc = lastBarTime.AddHours(UtcShift); // Check if the last bar is 8:00 AM in UTC-5 Chart.DrawStaticText( "dashboard_minix", $"Time {lastBarTimeUtc.Hour} : {lastBarTimeUtc.Minute} \n" + $"NDOG (1 2) {ndog1} : {ndog2} \n" + $"box H,L {boxHigh} : {boxLow} \n" + $"Side Of Box {SideOfBox} \n" + $"Breaker Direction {BreakerDir} \n", VerticalAlignment.Bottom, HorizontalAlignment.Left, API.Color.GreenYellow ); if (lastBarTimeUtc.Hour == 8 && lastBarTimeUtc.Minute == 0) { (ndog1, ndog2) = this.FindDailyPrices(); Print($"ndog1 {ndog1}"); Print($"ndog2 {ndog2}"); // Get the High and Low for the range 7:30 AM to 7:59 AM (UTC-5) for (int i = 1; i <= 30; i++) { boxHigh = Math.Max(boxHigh, Bars.HighPrices.Last(i)); boxLow = Math.Min(boxLow, Bars.LowPrices.Last(i)); } // Print the results Chart.DrawHorizontalLine("box-top", boxHigh, Color.DarkRed); Chart.DrawHorizontalLine("box-bottom", boxLow, Color.DarkRed); // Check Side Box with NDOG Line SideOfBox = "none"; currentFVGtype = "none"; if (boxHigh < Math.Min(ndog2, ndog1)) { // Sell Model SideOfBox = "bottom"; } if (boxLow > Math.Max(ndog2, ndog1)) { // Buy Model SideOfBox = "top"; } } // Clear Limit Orders if (lastBarTimeUtc.Minute == 0 || lastBarTimeUtc.Minute == 30) { // taskDeletePendingOrders() } // Check lố giờ trade if (lastBarTimeUtc.Hour > 10 || lastBarTimeUtc.Hour < 8) // 11 7 { SideOfBox = "none"; BreakerDir = "none"; currentFVGtype = "none"; return; } if (SideOfBox == "none") return; // Check Market Break box if (SideOfBox == "top" && (BreakerDir != "breakedBoxHigh")) { if(Bars.HighPrices.Last(1) > boxHigh) { BreakerDir = "breakedBoxHigh"; } } // Check Market Break box if (SideOfBox == "bottom" && (BreakerDir != "breakedBoxLow")) { if(Bars.LowPrices.Last(1) < boxLow) { BreakerDir = "breakedBoxLow"; updateFvg("buy"); } } // finding FVG if(BreakerDir == "breakedBoxHigh") { currentFVGtype = "sell"; updateFvg(currentFVGtype); } if(BreakerDir == "breakedBoxLow") { currentFVGtype = "buy"; updateFvg(currentFVGtype); } bool validTimingEntry = (lastBarTimeUtc.Minute >= 0 && lastBarTimeUtc.Minute < 16) || (lastBarTimeUtc.Minute >= 30 && lastBarTimeUtc.Minute < 46); if(validTimingEntry) { if(currentFVGtype == "buy") { // Place Order Buy Limit Print("-- Place Buy Limit"); if(this.isFVgapBuy()) { PlaceLimitOrder( TradeType.Buy, SymbolName, Symbol.QuantityToVolumeInUnits(1), this.fvgHigh, "order-sell-" + Bars.Count, stoplossPips, this.convertToPips(Math.Abs(this.fvgHigh - Math.Min(ndog1, ndog2))) ); } } if (currentFVGtype == "sell") { // Place Order Sell Limit } } // } protected override void OnStop() { // Handle cBot stop here } public (double highestHigh, double lowestLow) GetHighLowInRange( int startHour, int startMinute, int endHour, int endMinute) { double highestHigh = double.MinValue; double lowestLow = double.MaxValue; // Convert the specified time range to UTC DateTime today = DateTime.UtcNow.Date; DateTime startUtc = today.AddHours(startHour - UtcShift).AddMinutes(startMinute); DateTime endUtc = today.AddHours(endHour - UtcShift).AddMinutes(endMinute); for (int i = 0; i < Bars.Count; i++) { DateTime barTime = Bars.OpenTimes[i]; // Skip bars outside the specified range if (barTime < startUtc || barTime > endUtc) continue; // Update the highest high and lowest low highestHigh = Math.Max(highestHigh, Bars.HighPrices[i]); lowestLow = Math.Min(lowestLow, Bars.LowPrices[i]); Print($"HL {highestHigh} {lowestLow}"); } return (highestHigh, lowestLow); } public (double previousDayClose, double todayOpen) FindDailyPrices() { Bars _bars = MarketData.GetBars(TimeFrame.Daily); if (_bars.Count < 2) throw new InvalidOperationException("Not enough daily bars to calculate daily prices."); double previousDayClose = _bars.ClosePrices[_bars.Count - 2]; double todayOpen = _bars.OpenPrices[_bars.Count - 1]; return (previousDayClose, todayOpen); } private void updateFvg(string fvgType) { if(fvgType == "buy") { isFVgapBuy(); } if(fvgType == "sell") { isFVgapSell(); } } private bool isFVgapSell() { if (Bars.HighPrices.Last(1) < Bars.LowPrices.Last(3)) { if(convertToPips(Math.Abs(Bars.HighPrices.Last(1) - Bars.LowPrices.Last(3))) < this.minFVGpips) { return false; } this.fvgHigh = Bars.LowPrices.Last(3); this.fvgLow = Bars.HighPrices.Last(1); return true; } return false; } private bool isFVgapBuy() { if (Bars.LowPrices.Last(1) > Bars.HighPrices.Last(3)) { if (convertToPips(Math.Abs(Bars.LowPrices.Last(1) - Bars.HighPrices.Last(3))) < this.minFVGpips) { return false; } this.fvgHigh = Bars.LowPrices.Last(1); this.fvgLow = Bars.HighPrices.Last(3); return true; } return false; } private double convertToPips(double priceDif) { return Math.Round(Math.Abs(priceDif / Symbol.PipSize), 1); } } }
Editor is loading...
Leave a Comment