Topics
04 Apr 2022, 09:42
 1144
 9
Replies

hejnekem
08 Apr 2022, 11:37

RE:

amusleh said:

OK, thanks for your help!


@hejnekem

hejnekem
07 Apr 2022, 14:17 ( Updated at: 07 Apr 2022, 14:19 )

RE:

amusleh said:

Hi,

I think you have to re-write the Bot based on new cTrader Automate API, specifically those Trade calls.

I rewrote it, but it still doesnt work, I cant run two instances side by side.

        [Parameter(DefaultValue = 10000, MinValue = 1000)]
        public int FirstLot { get; set; }

        [Parameter(DefaultValue = 10000, MinValue = 1000)]
        public int LotStep { get; set; }

        [Parameter("Stop_Loss", DefaultValue = 50, MinValue = 0)]
        public int Stop_Loss { get; set; }

        [Parameter("Take_Profit", DefaultValue = 180, MinValue = 10)]
        public int TakeProfit { get; set; }

        [Parameter("Tral_Start", DefaultValue = 50, MinValue = 10)]
        public int Tral_Start { get; set; }

        [Parameter("Tral_Stop", DefaultValue = 50, MinValue = 10)]
        public int Tral_Stop { get; set; }

        [Parameter(DefaultValue = 5, MinValue = 2)]
        public int MaxOrders { get; set; }

        private Position position;
        private bool RobotStopped;
        private string botLabel;


        protected override void OnStart()
        {
            botLabel = ToString();

            Positions.Opened += OnPositionOpened;
        }

        protected override void OnTick()
        {
            double Bid = Symbol.Bid;
            double Ask = Symbol.Ask;
            double Point = Symbol.TickSize;

            if (Trade.IsExecuting)
                return;

            if (Positions.Count > 0 && RobotStopped)
                return;
            else
                RobotStopped = false;

            if (Positions.Count == 0)
                SendFirstOrder(FirstLot);
            else
                ControlSeries();

            foreach (var position in Positions.FindAll(botLabel, SymbolName))
            {
                if (position.SymbolName == Symbol.Name)
                {

                    if (position.TradeType == TradeType.Buy)
                    {
                        if (Bid - GetAveragePrice(TradeType.Buy) >= Tral_Start * Point)
                            if (Bid - Tral_Stop * Point >= position.StopLoss)
                                ModifyPosition(position, Bid - Tral_Stop * Point, 
                                position.TakeProfit);
                    }

                    if (position.TradeType == TradeType.Sell)
                    {
                        if (GetAveragePrice(TradeType.Sell) - Ask >= Tral_Start * Point)
                            if (Ask + Tral_Stop * Point <= position.StopLoss || position.StopLoss 
                            == 0)
                                ModifyPosition(position, Ask + Tral_Stop * Point, 
                                position.TakeProfit);
                    }
                }
            }
        }

        protected override void OnError(Error CodeOfError)
        {
            if (CodeOfError.Code == ErrorCode.NoMoney)
            {
                RobotStopped = true;
                Print("ERROR!!! No money for order open, robot is stopped!");
            }
            else if (CodeOfError.Code == ErrorCode.BadVolume)
            {
                RobotStopped = true;
                Print("ERROR!!! Bad volume for order open, robot is stopped!");
            }
        }

        private void SendFirstOrder(int OrderVolume)
        {
            int Signal = GetStdIlanSignal();
            if (!(Signal < 0))
                switch (Signal)
                {
                    case 0:
                        ExecuteMarketOrder(TradeType.Buy, SymbolName, OrderVolume, botLabel);
                        break;
                    case 1:
                        ExecuteMarketOrder(TradeType.Sell, SymbolName, OrderVolume, botLabel);
                        break;
                }
        }

        private void OnPositionOpened(PositionOpenedEventArgs args)
        {
            double? StopLossPrice = null;
            double? TakeProfitPrice = null;

            if (Positions.Count == 1)
            {
                position = args.Position;

                if (position.TradeType == TradeType.Buy)
                    TakeProfitPrice = position.EntryPrice + TakeProfit * Symbol.TickSize;
                if (position.TradeType == TradeType.Sell)
                    TakeProfitPrice = position.EntryPrice - TakeProfit * Symbol.TickSize;
            }
            else
                switch (GetPositionsSide())
                {
                    case 0:
                        TakeProfitPrice = GetAveragePrice(TradeType.Buy) + TakeProfit * 
                        Symbol.TickSize;
                        break;
                    case 1:
                        TakeProfitPrice = GetAveragePrice(TradeType.Sell) - TakeProfit * 
                        Symbol.TickSize;
                        break;
                }

            for (int i = 0; i < Positions.Count; i++)
            {
                position = Positions[i];
                if (StopLossPrice != null || TakeProfitPrice != null)
                    ModifyPosition(position, position.StopLoss, TakeProfitPrice);
            }
        }

        private double GetAveragePrice(TradeType TypeOfTrade)
        {
            double Result = Symbol.Bid;
            double AveragePrice = 0;
            long Count = 0;

            for (int i = 0; i < Positions.Count; i++)
            {
                position = Positions[i];
                if (position.TradeType == TypeOfTrade)
                {
                    AveragePrice += position.EntryPrice * position.Volume;
                    Count += position.Volume;
                }
            }
            if (AveragePrice > 0 && Count > 0)
                Result = AveragePrice / Count;
            return Result;
        }

        private int GetPositionsSide()
        {
            int Result = -1;
            int i, BuySide = 0, SellSide = 0;

            for (i = 0; i < Positions.Count; i++)
            {
                if (Positions[i].TradeType == TradeType.Buy)
                    BuySide++;
                if (Positions[i].TradeType == TradeType.Sell)
                    SellSide++;
            }
            if (BuySide == Positions.Count)
                Result = 0;
            if (SellSide == Positions.Count)
                Result = 1;
            return Result;
        }

        private void ControlSeries()
        {
            const int BarCount = 25;
            int gradient = MaxOrders - 1;

            foreach (Position position in Positions.FindAll(botLabel, SymbolName))
            {
                if (-position.Pips > Stop_Loss)
                    ClosePosition(position);

            }

            int _pipstep = GetDynamicPipstep(BarCount, gradient);

            if (Positions.Count < MaxOrders)
            {

                long NewVolume = Symbol.NormalizeVolume(FirstLot + FirstLot * Positions.Count, 
                RoundingMode.ToNearest);
                int positionSide = GetPositionsSide();

                switch (positionSide)
                {
                    case 0:
                        if (Symbol.Ask < FindLastPrice(TradeType.Buy) - _pipstep * 
                        Symbol.TickSize)
                        {

                            if (NewVolume >= LotStep)
                                ExecuteMarketOrder(TradeType.Buy, SymbolName, NewVolume, 
                                botLabel);
                        }
                        break;

                    case 1:
                        if (Symbol.Bid > FindLastPrice(TradeType.Sell) + _pipstep * 
                        Symbol.TickSize)
                        {

                            if (NewVolume >= LotStep)
                                ExecuteMarketOrder(TradeType.Sell, SymbolName, NewVolume, 
                                botLabel);
                        }
                        break;
                }
            }

        }

        private int GetDynamicPipstep(int CountOfBars, int gradient)
        {
            int Result;
            double HighestPrice = 0, LowestPrice = 0;
            int StartBar = Bars.ClosePrices.Count - 2 - CountOfBars;
            int EndBar = Bars.ClosePrices.Count - 2;

            for (int i = StartBar; i < EndBar; i++)
            {
                if (HighestPrice == 0 && LowestPrice == 0)
                {
                    HighestPrice = Bars.HighPrices[i];
                    LowestPrice = Bars.LowPrices[i];
                    continue;
                }
                if (Bars.HighPrices[i] > HighestPrice)
                    HighestPrice = Bars.HighPrices[i];
                if (Bars.LowPrices[i] < LowestPrice)
                    LowestPrice = Bars.LowPrices[i];
            }

            Result = (int)((HighestPrice - LowestPrice) / Symbol.TickSize / gradient);

            return Result;
        }

        private double FindLastPrice(TradeType TypeOfTrade)
        {
            double LastPrice = 0;

            for (int i = 0; i < Positions.Count; i++)
            {
                position = Positions[i];
                if (TypeOfTrade == TradeType.Buy)
                    if (position.TradeType == TypeOfTrade)
                    {
                        if (LastPrice == 0)
                        {
                            LastPrice = position.EntryPrice;
                            continue;
                        }
                        if (position.EntryPrice < LastPrice)
                            LastPrice = position.EntryPrice;
                    }
                if (TypeOfTrade == TradeType.Sell)
                    if (position.TradeType == TypeOfTrade)
                    {
                        if (LastPrice == 0)
                        {
                            LastPrice = position.EntryPrice;
                            continue;
                        }
                        if (position.EntryPrice > LastPrice)
                            LastPrice = position.EntryPrice;
                    }
            }
            return LastPrice;
        }

        private int GetStdIlanSignal()
        {
            int Result = -1;
            int LastBarIndex = Bars.ClosePrices.Count - 2;
            int PrevBarIndex = LastBarIndex - 1;

            if (Bars.ClosePrices[LastBarIndex] > Bars.OpenPrices[LastBarIndex])
                if (Bars.ClosePrices[PrevBarIndex] > Bars.OpenPrices[PrevBarIndex])
                    Result = 0;
            if (Bars.ClosePrices[LastBarIndex] < Bars.OpenPrices[LastBarIndex])
                if (Bars.ClosePrices[PrevBarIndex] < Bars.OpenPrices[PrevBarIndex])
                    Result = 1;
            return Result;
        }

 


@hejnekem

hejnekem
05 Apr 2022, 15:10 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE: RE:

amusleh said:

hejnekem said:

firemyst said:

> Hi, I would like to run this bot on different instances, but I couldnt do it. I tried label and symbol too.

 

What do you mean?

To run multiple instances of a bot, just add more "instances" under the bot and choose the symbol you want to run it against.

Example:

In teh above, one instance will run on EURUSD H1 timeframe, the other bot will run under the US30 symbol.

It doesnt work, because when I start a second instance it doesnt start, other times the first instance closes the second one.

Hi,

Are you sure it's a cTrader cBot code? It uses some APIs that is not part of cTrader automate API.

 

I am not sure, it's an old cbot. Should I fix the code so that would solve my problem?


@hejnekem

hejnekem
05 Apr 2022, 12:52 ( Updated at: 21 Dec 2023, 09:22 )

RE:

firemyst said:

> Hi, I would like to run this bot on different instances, but I couldnt do it. I tried label and symbol too.

 

What do you mean?

To run multiple instances of a bot, just add more "instances" under the bot and choose the symbol you want to run it against.

Example:

In teh above, one instance will run on EURUSD H1 timeframe, the other bot will run under the US30 symbol.

It doesnt work, because when I start a second instance it doesnt start, other times the first instance closes the second one.


@hejnekem