How do I stop the cBot after all the positions are closed?

Created at 24 Feb 2021, 16:42
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
CH

ChannelTrader

Joined 31.03.2020

How do I stop the cBot after all the positions are closed?
24 Feb 2021, 16:42


I'm trying to stop my cBot when all the positions are closed, but sometimes it stop before close all the positions

 

I'm trying with this code:

 

 public void ClosingPositions()
        {
            var positions = this.Positions.FindAll(botlabel, Symbol.Name);
            double netProfit = positions.Sum(x => x.NetProfit);

            if (Positions.Count >= 2 && netProfit >= 0.3 * (Account.Balance - _minEquity))
            {
                foreach (var position in positions)
                {
                    ClosePosition(position);

                    telegram.SendTelegram(ChatID, BotToken, Message);
                }
                Stop();


            }


            //            if (Positions.Count <= 1 && netProfit >= 1.5 * (Account.Balance - _minEquity))

            if (Positions.Count <= 1 && positions.Last().Pips >= TargetPips)
            {
                foreach (var position in positions)
                {
                    ClosePosition(position);

                    telegram.SendTelegram(ChatID, BotToken, Message);
                }
                Stop();


            }
        }

 

Is that wrong?


@ChannelTrader
Replies

PanagiotisCharalampous
24 Feb 2021, 16:50

Hi ChannelTrader,

It seems correct to me. Can you help us reproduce this behavior?

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

ChannelTrader
24 Feb 2021, 17:30 ( Updated at: 24 Feb 2021, 17:31 )

RE:

ChannelTrader said:

I'm trying to stop my cBot when all the positions are closed, but sometimes it stop before close all the positions

 

I'm trying with this code:

 

 public void ClosingPositions()
        {
            var positions = this.Positions.FindAll(botlabel, Symbol.Name);
            double netProfit = positions.Sum(x => x.NetProfit);

            if (Positions.Count >= 2 && netProfit >= 0.3 * (Account.Balance - _minEquity))
            {
                foreach (var position in positions)
                {
                    ClosePosition(position);

                    telegram.SendTelegram(ChatID, BotToken, Message);
                }
                Stop();


            }


            //            if (Positions.Count <= 1 && netProfit >= 1.5 * (Account.Balance - _minEquity))

            if (Positions.Count <= 1 && positions.Last().Pips >= TargetPips)
            {
                foreach (var position in positions)
                {
                    ClosePosition(position);

                    telegram.SendTelegram(ChatID, BotToken, Message);
                }
                Stop();


            }
        }

 

Is that wrong?

Dear Panagiotis, thx for your quickly repply. 

It is happening when I have 2 or more positions openend. It closes only the first position and the others keep opened.

Can you help me to solve it?


@ChannelTrader

PanagiotisCharalampous
25 Feb 2021, 08:23

Hi ChannelTrader,

To help you solve it, you need to help me reproduce it. So I need the following

1) The complete cBot code

2) cBot parameters

3) Backtesting dates and the date that this happens.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

ChannelTrader
25 Feb 2021, 14:39 ( Updated at: 25 Feb 2021, 15:14 )

RE:

PanagiotisCharalampous said:

Hi ChannelTrader,

To help you solve it, you need to help me reproduce it. So I need the following

1) The complete cBot code

2) cBot parameters

3) Backtesting dates and the date that this happens.

Best Regards,

Panagiotis 

Join us on Telegram

 

Hi Panagiotis, how are you?

 

The parameters I'm using is set by default an I'm trying to use it on a demo account at live market , but it also happens at any day backtesting, but you can try on 20/03/2019, GBPUSD with parameter IfOpenBuy as true to get the error.

I'm also using a copy of these one for buying with the parameter IfOpenBuy set as true.

I tryed to remove the Stop() method from CloseningPositions() and add        if (Positions.Count < 1)
            {
                Stop();
            }

but I'm having the same error.

 

Here follows the code:

 

 

using System.Linq;
using cAlgo.API;
using cAlgo.API.Internals;
using System;
using System.Net;
using Telegram.Bot;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class VENDEDOR : Robot
    {
        [Parameter("Long position?", Group = "Basic Setup", DefaultValue = false)]
        public bool IfOpenBuy { get; set; }

        [Parameter("First order volume", Group = "Basic Setup", DefaultValue = 1000, MinValue = 1, Step = 1)]
        public double InitialVolume { get; set; }

        [Parameter("Distance of trades", Group = "Basic Setup", DefaultValue = 10, MinValue = 1)]
        public int GridSizeInPoints { get; set; }
        [Parameter("Target Pips", DefaultValue = 10)]
        public double TargetPips { get; set; }

        [Parameter("Profit Factor", Group = "Basic Setup", DefaultValue = 0.4, Step = 0.1)]
        public double _profitfactor { get; set; }



        //Sets the minimum distance between a pending order and an open position.

        [Parameter("Minimum Trade Separation", DefaultValue = 10)]
        public double MinPipDistance { get; set; }

        [Parameter("Bot Token", DefaultValue = "", Group = "Telegram Notifications")]
        public string BotToken { get; set; }

        [Parameter("Chat ID", DefaultValue = "", Group = "Telegram Notifications")]
        public string ChatID { get; set; }

        [Parameter("Message", DefaultValue = "", Group = "Telegram Notifications")]
        public string Message { get; set; }

        Telegram telegram;


        public double TotalLoss { get; set; }

        private string botlabel;
        double _minEquity;





        protected override void OnStart()
        {
            telegram = new Telegram();
            // Set position label to cBot name
            botlabel = GetType().Name;
            // Normalize volume in case a wrong volume was entered
            if (InitialVolume != (InitialVolume = Symbol.NormalizeVolumeInUnits(InitialVolume)))
            {
                Print("Initial volume entered incorrectly, volume has been changed to ", InitialVolume);
            }
            _minEquity = Account.Equity;

        }




        protected override void OnTick()
        {



            if (IfOpenBuy)
            {


                if (Positions.Count(x => x.TradeType == TradeType.Buy && x.SymbolName == SymbolName && x.Label == botlabel) == 0)
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, InitialVolume, botlabel, null, null);

                else if (Symbol.Ask <= Positions.FindAll(botlabel, SymbolName, TradeType.Buy).Last().EntryPrice - GridSizeInPoints * Symbol.PipSize)
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, InitialVolume, botlabel, null, null);
            }

            else
            {
                if (Positions.Count(x => x.TradeType == TradeType.Sell && x.SymbolName == SymbolName && x.Label == botlabel) == 0)
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, 1 * InitialVolume, botlabel, null, null);
                else if (Symbol.Bid >= Positions.FindAll(botlabel, SymbolName, TradeType.Sell).Last().EntryPrice + GridSizeInPoints * Symbol.PipSize)
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, InitialVolume, botlabel, null, null);
            }



            if (Account.Equity < _minEquity)
                _minEquity = Account.Equity;


            ClosingPositions();

            if (Positions.Count < 1)
            {
                Stop();
            }





        }

        public void ClosingPositions()
        {
            var positions = this.Positions.FindAll(botlabel, Symbol.Name);
            double netProfit = positions.Sum(x => x.NetProfit);



            if (Positions.Count >= 2 && netProfit >= _profitfactor * (Account.Balance - _minEquity))
            {
                foreach (var position in positions)
                {
                    ClosePosition(position);

                    telegram.SendTelegram(ChatID, BotToken, Message);
                }



            }




            //            if (Positions.Count <= 1 && netProfit >= 1.5 * (Account.Balance - _minEquity))

            if (Positions.Count <= 1 && positions.Last().Pips >= TargetPips)
            {
                foreach (var position in positions)
                {
                    ClosePosition(position);

                    telegram.SendTelegram(ChatID, BotToken, Message);
                }



            }
        }

        protected override void OnBar()
        {


        }




        protected override void OnStop()
        {
            telegram.SendTelegram(ChatID, BotToken, Message);
            ClosingPositions();

        }
    }
}

 

 


@ChannelTrader

PanagiotisCharalampous
25 Feb 2021, 15:06

Hi ChannelTrader,

I tried this on backtesting and seems to close positions just fine before it stops

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

ChannelTrader
25 Feb 2021, 15:31 ( Updated at: 21 Dec 2023, 09:22 )

RE:

PanagiotisCharalampous said:

Hi ChannelTrader,

I tried this on backtesting and seems to close positions just fine before it stops

Best Regards,

Panagiotis 

Join us on Telegram

Mine is throwing an exception Ontick and sometimes OnStop, but I'm using spotware Ctrader 4.0 beta to do the backtest, should I test it on cTrader 3.8 only?


@ChannelTrader

PanagiotisCharalampous
26 Feb 2021, 07:56

Hi ChannelTrader,

Can you provide your symbol and backtesting dates?

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

ChannelTrader
26 Feb 2021, 11:25

RE:

PanagiotisCharalampous said:

Hi ChannelTrader,

Can you provide your symbol and backtesting dates?

Best Regards,

Panagiotis 

Join us on Telegram

Hi Panagiotis, how are you?

Thank you for your reply.

I'm testing on GBPUSD, 20/03/2019, with IfBuyOpen Parameter set as true.

The bot closes all the positions,only on CTrader 3.8, but it still get this warning in log.


@ChannelTrader

PanagiotisCharalampous
26 Feb 2021, 11:44

Hi ChannelTrader,

Your problem is here

 if (Positions.Count <= 1 && positions.Last().Pips >= TargetPips)

You cannot call Last()  method if there are no elements in the collection.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

ChannelTrader
26 Feb 2021, 11:48 ( Updated at: 21 Dec 2023, 09:22 )

RE:

PanagiotisCharalampous said:

Hi ChannelTrader,

Your problem is here

 if (Positions.Count <= 1 && positions.Last().Pips >= TargetPips)

You cannot call Last()  method if there are no elements in the collection.

Best Regards,

Panagiotis 

Join us on Telegram

Dear Panagiotis, I edited this reply.

I modified the parameter to 

if (Positions.Count <= 1 && positioned.Pips >= TargetPips)

var positioned = Positions.Find(botlabel, Symbol.Name);.

Now I'm getting this error.

It says"The reference for the object is not defined to a object instancy" 


@ChannelTrader

PanagiotisCharalampous
26 Feb 2021, 12:14

Hi ChannelTrader,

It's the same problem. You cannot call a position that does not exist.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

ChannelTrader
26 Feb 2021, 12:18

RE:

PanagiotisCharalampous said:

Hi ChannelTrader,

It's the same problem. You cannot call a position that does not exist.

Best Regards,

Panagiotis 

Join us on Telegram

Hi again,

I removed the parameter ClosingPositions() from OnStop() and now I have no error.

Thank you for your help and dedication.

Best regards.


@ChannelTrader