Untitled

 avatar
unknown
plain_text
5 months ago
13 kB
4
Indexable
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    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 = 400)]
        public int stoplossPips { get; set; }

        [Parameter("Min FVG Pips", Group = "Trade Setup", DefaultValue = 100)]
        public int minFVGpips { get; set; }

        [Parameter("Min RR", Group = "Trade Setup", DefaultValue = 4)]
        public int minRR { get; set; }
        
        [Parameter("Max Holding Positions", Group = "Trade Setup", DefaultValue = 4)]
        public int minHoldingPositions { 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;

        private bool hittedNdog;

        protected override void OnStart()
        {
            bool isOneMinute = TimeFrame == TimeFrame.Minute;
            Print("hello");

            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) {
                // deleteAllPendingOrders()
                deleteAllPendingOrders();
            }

            // 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(countExecutingPositions() >= this.minHoldingPositions)
                {
                    return;
                }

                if(currentFVGtype == "buy")
                {

                    if (convertToPips(Math.Abs(Bars.LowPrices.Last(1) - Bars.HighPrices.Last(3))) < this.minFVGpips)
                    {
                        Print("small pips FVG buy ", convertToPips(Math.Abs(Bars.LowPrices.Last(1) - Bars.HighPrices.Last(3))));
                        return;
                    }
                    

                    // 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)))
                         );*/

                        Chart.DrawHorizontalLine("fvgHigh", fvgHigh, Color.Blue);
                        Chart.DrawHorizontalLine("fvgLow", fvgLow, Color.Blue);

                        PlaceLimitOrder(
                            TradeType.Buy,
                            SymbolName,
                            Symbol.QuantityToVolumeInUnits(1),
                            this.fvgHigh,
                            "order-buy-" + Bars.Count,
                            stoplossPips,
                            stoplossPips * minRR
                        );
                    }
                    
                }

                if (currentFVGtype == "sell")
                {
                    // Place Order Sell Limit
                    if (convertToPips(Math.Abs(Bars.HighPrices.Last(1) - Bars.LowPrices.Last(3))) < this.minFVGpips)
                    {
                        Print("small pips FVG sell ", convertToPips(Math.Abs(Bars.HighPrices.Last(1) - Bars.LowPrices.Last(3))));
                        return;
                    }

                    if (this.isFVgapSell()) {
                        Chart.DrawHorizontalLine("fvgHigh", fvgHigh, Color.Blue);
                        Chart.DrawHorizontalLine("fvgLow", fvgLow, Color.Blue);
                        PlaceLimitOrder(
                            TradeType.Sell,
                            SymbolName,
                            Symbol.QuantityToVolumeInUnits(1),
                            this.fvgLow,
                            "order-sell-" + Bars.Count,
                            stoplossPips,
                            stoplossPips * minRR
                        );
                    }

                        
                }
            }



            // 






        }

        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 int countExecutingPositions()
        {
            return Positions.Count(position =>
            (position.TradeType == TradeType.Buy || position.TradeType == TradeType.Sell)
            && Symbol.Name == position.SymbolName);
        }

        private void deleteAllPendingOrders()
        {

            // Loop through each pending order and delete it
            Print("** deleteAllPendingOrders");
            foreach (var pod in PendingOrders.Where(pod => pod.SymbolName == Symbol.Name))
            {
                CancelPendingOrder(pod);
            }
        }


        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