Untitled

 avatar
unknown
csharp
10 days ago
8.5 kB
2
Indexable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None, TimeZone = TimeZones.EasternStandardTime)]
    public class Troller2Sides : Robot
    {
        [Parameter("RR", DefaultValue = 4)]
        public double RR { get; set; }

        [Parameter("Stoploss", DefaultValue = 150)]
        public double StopLoss { get; set; }

        [Parameter("Lots", DefaultValue = 10)]
        public double Lots { get; set; }

        [Parameter("Min FVG", DefaultValue = 60)]
        public double MinFVG { get; set; }

        [Parameter("x Pending ? bars", DefaultValue = 10)]
        public double xPendingBars { get; set; }

        [Parameter("Max Holdings", DefaultValue = 4)]
        public double MaxHoldings { get; set; }



        private Dictionary<string, int> barsSinceOrderCreation = new Dictionary<string, int>();
        private double _FvgHigh = Double.MinValue, _FvgLow = Double.MaxValue;
        private bool _isBorn1stFVG = false;

        protected override void OnStart()
        {

        }

        protected override void OnBar()
        {
            // Nếu 1:00 ... --> bot bị break close trước thì bias là buy
            // Đợi nến break close top thì entry
            taskCancelPendingOrders();
            Chart.DrawStaticText(
                "dashboard_minix",
                "FVG pips " + convertToPips(_FvgHigh - _FvgLow) + "\n" +
                "Time " + Bars.OpenTimes.Last(1).Hour + ":" + Bars.OpenTimes.Last(1).Minute + "\n" +
                "_isBorn1stFVG " + _isBorn1stFVG + "\n"
                ,
                VerticalAlignment.Bottom,
                HorizontalAlignment.Left,
                API.Color.GreenYellow
            );

            update1stFVG();

            if (!_isBorn1stFVG)
            {
                return;
            }

            if (Bars.OpenTimes.Last(1).Hour == 11 && Bars.OpenTimes.Last(1).Minute == 31)
            {
                // reset
                _isBorn1stFVG = false;
                return;
            }

            if (Bars.OpenTimes.Last(1).Hour < 10 || Bars.OpenTimes.Last(1).Hour > 11)
            {
                return;
            }

            if (countExecutingPositions() + countPendingOrders() >= 1)
            {
                return;
            }

            if (isBullish(1) && Bars.ClosePrices.Last(1) > _FvgHigh && Bars.LowPrices.Last(1) < _FvgHigh)
            {
                // Buy Limit 
                PlaceLimitOrder(
                    TradeType.Buy,
                    SymbolName,
                    Symbol.QuantityToVolumeInUnits(Lots),
                    _FvgHigh,
                    "order-buy-1-" + Bars.Count,
                    StopLoss,
                    StopLoss * this.RR
                );

                PlaceLimitOrder(
                    TradeType.Buy,
                    SymbolName,
                    Symbol.QuantityToVolumeInUnits(Lots),
                    _FvgHigh,
                    "order-buy-2-" + Bars.Count,
                    StopLoss,
                    StopLoss
                );
                barsSinceOrderCreation["order-buy-1-" + Bars.Count] = 0;
                barsSinceOrderCreation["order-buy-2-" + Bars.Count] = 0;
            }

            if (isBearish(1) && Bars.ClosePrices.Last(1) < _FvgLow && Bars.HighPrices.Last(1) > _FvgLow)
            {
                // Buy Limit 
                PlaceLimitOrder(
                    TradeType.Sell,
                    SymbolName,
                    Symbol.QuantityToVolumeInUnits(Lots),
                    _FvgLow,
                    "order-sell-1-" + Bars.Count,
                    StopLoss,
                    StopLoss * this.RR
                );

                PlaceLimitOrder(
                    TradeType.Sell,
                    SymbolName,
                    Symbol.QuantityToVolumeInUnits(Lots),
                    _FvgLow,
                    "order-sell-2-" + Bars.Count,
                    StopLoss,
                    StopLoss
                );
                
                barsSinceOrderCreation["order-sell-1-" + Bars.Count] = 0;
                barsSinceOrderCreation["order-sell-2-" + Bars.Count] = 0;
            }
        }

        private void update1stFVG()
        {
            // On bot --- before 9.30
            if (!_isBorn1stFVG && Bars.OpenTimes.Last(1).Hour == 9 && Bars.OpenTimes.Last(1).Minute < 59 && Bars.OpenTimes.Last(1).Minute > 30)
            {
                // FVG Buy
                if (Bars.LowPrices.Last(1) > Bars.HighPrices.Last(3))
                {
                    _FvgHigh = Bars.LowPrices.Last(1);
                    _FvgLow = Bars.HighPrices.Last(3);

                    if (isBullish(1) && isBullish(2) && (Bars.OpenPrices.Last(1) > Bars.ClosePrices.Last(2)))
                    {
                        _FvgHigh = Bars.OpenPrices.Last(1);
                    }

                    if (isBullish(2) && isBullish(3) && (Bars.ClosePrices.Last(3) < Bars.OpenPrices.Last(2)))
                    {
                        _FvgLow = Bars.ClosePrices.Last(3);
                    }
                }

                // FVG Sell

                if (Bars.HighPrices.Last(1) < Bars.LowPrices.Last(3))
                {
                    _FvgHigh = Bars.LowPrices.Last(3);
                    _FvgLow = Bars.HighPrices.Last(1);

                    if (isBearish(1) && isBearish(2) && (Bars.OpenPrices.Last(1) < Bars.ClosePrices.Last(2)))
                    {
                        _FvgLow = Bars.OpenPrices.Last(1);
                    }

                    if (isBearish(2) && isBearish(3) && (Bars.ClosePrices.Last(3) > Bars.OpenPrices.Last(2)))
                    {
                        _FvgHigh = Bars.ClosePrices.Last(3);
                    }
                }

                Chart.DrawHorizontalLine("FVG-top", _FvgHigh, Color.DarkRed);
                Chart.DrawHorizontalLine("FVG-bottom", _FvgLow, Color.DarkRed);
                _isBorn1stFVG = true;

                if (convertToPips(_FvgHigh - _FvgLow) < MinFVG)
                {
                    _isBorn1stFVG = false;
                }
            }

        }


        private bool isBullish(int index)
        {
            return Bars.OpenPrices.Last(index) < Bars.ClosePrices.Last(index);
        }

        private bool isBearish(int index)
        {
            return Bars.OpenPrices.Last(index) > Bars.ClosePrices.Last(index);
        }

        private void closeAllPositions()
        {
            Print("** closeAllPositions");
            foreach (var pos in Positions.Where(pos => pos.SymbolName == Symbol.Name))
            {
                ClosePositionAsync(pos);
            }
        }

        private int countExecutingPositions()
        {
            return Positions.Count(position =>
            (position.TradeType == TradeType.Buy || position.TradeType == TradeType.Sell)
            && Symbol.Name == position.SymbolName);
        }

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

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

        private int countPendingOrders()
        {
            return PendingOrders.Count(pod => Symbol.Name == pod.SymbolName);
        }

        private void taskCancelPendingOrders()
        {
            foreach (var label in barsSinceOrderCreation.Keys.ToList())
            {

                if (!barsSinceOrderCreation.ContainsKey(label)) continue;

                barsSinceOrderCreation[label]++;

                if (barsSinceOrderCreation[label] >= this.xPendingBars)
                {
                    PendingOrder pod = PendingOrders.FirstOrDefault(order => order.Label == label && order.SymbolName == Symbol.Name, null);
                    if (pod != null)
                    {
                        pod.Cancel();
                    }
                }
            }
        }
    }
}
Leave a Comment