Untitled

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

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.FullAccess, AddIndicators = true, TimeZone= TimeZones.EasternStandardTime)]
    public class ScalpingUtec : Robot
    {

        [Parameter("Hour End", Group = "Box", DefaultValue = 9)]
        public int HourEnd { get; set; }

        [Parameter("Minute End", Group = "Box", DefaultValue = 29)]
        public int MinuteEnd { get; set; }

        [Parameter("Hour End", Group = "Destroy Limit", DefaultValue = 9)]
        public int LimitHourEnd { get; set; }

        [Parameter("Minute End", Group = "Destroy Limit", DefaultValue = 29)]
        public int LimitMinuteEnd { get; set; }
        
        [Parameter("Hour End", Group = "Ending Session", DefaultValue = 9)]
        public int SessionHourEnd { get; set; }

        [Parameter("Minute End", Group = "Ending Session", DefaultValue = 29)]
        public int SessionMinuteEnd { get; set; }


        [Parameter("Look Back Bars", Group = "Box", DefaultValue = 89)]
        public int BoxLookBackBars { get; set; }

        [Parameter("Breaker After Box Bars", Group = "Box", DefaultValue = 2)]
        public int breakerAfterBoxBars { get; set; }


        [Parameter("RR", Group = "Risk", DefaultValue = 2)]
        public double RR { get; set; }

        [Parameter("SL Gap", Group = "Risk", DefaultValue = 50)]
        public double stoplossPipsGap { get; set; }

        [Parameter("Risk percent", Group = "Risk", DefaultValue = 50)]
        public double riskPercent { get; set; }

        [Parameter("Apply Balance", Group = "Risk", DefaultValue = 3000)]
        public double applyBalance { get; set; }

        [Parameter("Max Limit State", Group = "Risk", DefaultValue = 4)]
        public double maxLimitState { get; set; }
        
        [Parameter("Max Position State", Group = "Risk", DefaultValue = 2)]
        public double maxPositionState { get; set; }


        // PRIVATE
        private double boxHigh, boxLow;
        
        private bool isBoxForming = false;
        private bool isRunSearching = false;
        private bool isKillSession = false;
        private string breakerSide = "none";

        private double EntryPrice, StoplossPips;

        private int _breakerAfterBoxBarsCount;

        private int _positionOpenedCount = 0;

        protected override void OnStart()
        {
            boxHigh = double.MinValue; boxLow = double.MaxValue;

            Positions.Opened += OnPositionOpened;
        }

        private void OnPositionOpened(PositionOpenedEventArgs args)
        {
            Print("What Opened");
            _positionOpenedCount++;
        }

        protected override void OnBar()
        {
            // Handle price updates here
            DateTime lastBarTime = Bars.OpenTimes.Last(1);

            Chart.DrawStaticText(
                "dashboard_minix",
                $"-- Now {lastBarTime.Hour}:{lastBarTime.Minute} \n" +
                $"-- Position items {_positionOpenedCount} \n" +
                $"-- Limit items {PendingOrders.Where(pod => pod.SymbolName == Symbol.Name).Count()} \n" +
                ($"-- Box High {boxHigh} | Low {boxLow} \n") +
                $"-- Break Side {breakerSide} \n" + 
                $"-- Goodbye Folk ? {isKillSession} \n"
                ,
                VerticalAlignment.Bottom,
                HorizontalAlignment.Left,
                API.Color.OrangeRed
            );

            // --- Start Game Preprocessing ---
            if(_positionOpenedCount >= maxPositionState)
            {
                // Destroy all pending
                isKillSession = true;
                deleteAllPendingOrders();
            }

            //
            if (PendingOrders.Where(pod => pod.SymbolName == Symbol.Name).Count() >= maxPositionState)
            {
                // Destroy all pending
            }

            // 10:00 AM - No finding new trade
            if ((lastBarTime.Hour > LimitHourEnd) || (lastBarTime.Hour == SessionHourEnd && lastBarTime.Minute >= SessionMinuteEnd))
            {
                // Destroy all pending
                isKillSession = true;
                deleteAllPendingOrders();
            }


            // --- End Game Preprocessing ---



            // Game Start Here  
            // =================== LET GO ===================

            // Wait Box Forming
            if (lastBarTime.Hour == HourEnd && lastBarTime.Minute == MinuteEnd)
            {
                isKillSession = false;
                for (int i = 1; i <= BoxLookBackBars; i++)
                {
                    boxHigh = Math.Max(boxHigh, Bars.HighPrices.Last(i));
                    boxLow = Math.Min(boxLow, Bars.LowPrices.Last(i));
                }
                isBoxForming = true;
            }


            // Wait for Breaker box -- Case Continue
            if (isBoxForming && _breakerAfterBoxBarsCount < breakerAfterBoxBars)
            {
                _breakerAfterBoxBarsCount++;

                if (Bars.HighPrices.Last(1) > boxHigh && breakerSide == "none")
                {
                    breakerSide = "top";
                    isRunSearching = true;
                }

                if (Bars.LowPrices.Last(1) < boxLow && breakerSide == "none")
                {
                    breakerSide = "bottom";
                    isRunSearching = true;
                }
            }

            if (isKillSession)
            {
                return;
            }

            if (!isRunSearching) return;

            if(!this.IsImFvgBuy() && !this.IsImFvgSell() ) { return; }
            
            if(breakerSide == "top" && this.IsImFvgBuy())
            {
                // Bias BUY
                EntryPrice = Math.Min(Bars.OpenPrices.Last(1), Bars.ClosePrices.Last(1));
                StoplossPips = convertToPips(Math.Abs(EntryPrice - Bars.LowPrices.Last(3))) + stoplossPipsGap;

                PlaceLimitOrder(
                    TradeType.Buy,
                    SymbolName,
                    Symbol.QuantityToVolumeInUnits(1),
                    EntryPrice,
                    "order-buy-" + Bars.Count,
                    StoplossPips,
                    StoplossPips * RR
                );

                Print(" --- --- BUY LIMIT --- --- ");
            }
            
            if(breakerSide == "bottom" && this.IsImFvgSell())
            {
                EntryPrice = Math.Max(Bars.OpenPrices.Last(1), Bars.ClosePrices.Last(1));
                StoplossPips = convertToPips(Math.Abs(EntryPrice - Bars.HighPrices.Last(3))) + stoplossPipsGap;

                PlaceLimitOrder(
                    TradeType.Sell,
                    SymbolName,
                    Symbol.QuantityToVolumeInUnits(1),
                    EntryPrice,
                    "order-sell-" + Bars.Count,
                    StoplossPips,
                    StoplossPips * RR
                );
                Print(" --- --- SELL LIMIT --- --- ");
            }

            // 
        }

        protected override void OnTick() {

            
        }

        protected override void OnStop()
        {
            // Handle cBot stop here
        }

        private void deleteAllPendingOrders()
        {

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


        private bool IsImFvgBuy() {

            bool check1 = Bars.LowPrices.Last(1) > Math.Max(Bars.OpenPrices.Last(3), Bars.ClosePrices.Last(3));
            bool check2 = Bars.HighPrices.Last(3) < Math.Min(Bars.OpenPrices.Last(1), Bars.ClosePrices.Last(1));
            return check1 && check2;

        }
        
        private bool IsImFvgSell() {
            bool check1 = Bars.HighPrices.Last(1) < Math.Min(Bars.OpenPrices.Last(3), Bars.ClosePrices.Last(3));
            bool check2 = Bars.HighPrices.Last(3) > Math.Max(Bars.OpenPrices.Last(1), Bars.ClosePrices.Last(1));

            return check1 && check2;

        }

        private bool isFvgSell()
        {
            if (Bars.HighPrices.Last(1) < Bars.LowPrices.Last(3))
            {
                return true;
            }

            return false;

        }

        private bool isFvgBuy()
        {
            if (Bars.LowPrices.Last(1) > Bars.HighPrices.Last(3))
            {
                return true;
            }

            return false;

        }



        private void ResetGame() {
            breakerSide = "none";


        }

        private double convertToPips(double priceDif)
        {
            return Math.Round(Math.Abs(priceDif / Symbol.PipSize), 1);
        }


    }
}
Editor is loading...
Leave a Comment