CBot didn't execute It's code properly

Created at 06 Mar 2021, 16:00
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!
AN

anikaurmi420

Joined 18.10.2020

CBot didn't execute It's code properly
06 Mar 2021, 16:00


Hi,

I write a simple CBot. The rules are simple.

Time Frame: H1 Candle. And Trade only 8 hours to 15 hours UTC Time.

Buy Entry Rule: If a candle open bellow VWAP line and close above VWAP line, then It's open a Buy position.

Sell Entry Rule: If a candle open above VWAP line and close bellow VWAP line, then It's open a Sell position.

After writing the code I take small back test. And I find somedays CBot don't follow the rules properly. It's open new position where It shouldn't.

This screenshot take from 15 Feb, 2021 (BackTest). In this photo It's clearly visible that no one candle open bellow the VWAP line but It's still open a Buy position. And this is my problem. Anyone pleas help me. I paste my code bellow,

 

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TestVWAP_Bot : Robot
    {
        [Parameter("Trade Direction : Buy or Sell")]
        public string TradeDir { get; set; }

        [Parameter("Max Buy Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxBuy { get; set; }

        [Parameter("Max Sell Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxSell { get; set; }

        [Parameter("Trade Start Time", DefaultValue = 7, MinValue = 7, MaxValue = 8)]
        public double StartTime { get; set; }

        [Parameter("Trade End Time", DefaultValue = 14, MinValue = 14, MaxValue = 15)]
        public double EndTime { get; set; }


        private TestVWAP vwap;

        protected override void OnStart()
        {
            // Put your initialization logic here

            vwap = Indicators.GetIndicator<TestVWAP>();

        }

        protected override void OnBar()
        {
            // Put your core logic here

            double Time = Server.Time.TimeOfDay.TotalHours;

            if (StartTime <= Time && Time <= EndTime)
            {
                //Trading Time......

                if (TradeDir == "Buy")
                {
                    //Buy Trade.....

                    if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Buy).Length >= MaxBuy)
                    {

                        return;

                    }

                    if (vwap.Open_Result.LastValue < vwap.Result.LastValue && vwap.Close_Result.LastValue > vwap.Result.LastValue)
                    {

                        ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);

                    }

                }
                else if (TradeDir == "Sell")
                {
                    //Sell Trade.....

                    if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Sell).Length >= MaxSell)
                    {

                        return;

                    }

                    if (vwap.Open_Result.LastValue > vwap.Result.LastValue && vwap.Close_Result.LastValue < vwap.Result.LastValue)
                    {

                        ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);

                    }

                }

            }

        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}


@anikaurmi420
Replies

sue.bugg
08 Mar 2021, 08:42

Novice

I'm a novice, so can't give you the actual code and forgive me if I'm completely wrong & of no help to you.

I can't see anything in your code to reflect the open & close prices of the candle. I THINK I can only see you referencing the VWAP

You would have to declare variables. Bars open prices, bars close prices

Then do the math. If open is less than close = Buy. If open is more than close = Sell

Hope this helps in some way & apologies if the info is useless.


@sue.bugg

amusleh
08 Mar 2021, 13:07

Try this:

using cAlgo.API;
using cAlgo.API.Internals;
using System.Linq;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TestVWAP_Bot : Robot
    {
        [Parameter("TradeType")]
        public TradeType TradeDir { get; set; }

        [Parameter("Max Buy Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxBuy { get; set; }

        [Parameter("Max Sell Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxSell { get; set; }

        [Parameter("Trade Start Time", DefaultValue = 7, MinValue = 7, MaxValue = 8)]
        public double StartTime { get; set; }

        [Parameter("Trade End Time", DefaultValue = 14, MinValue = 14, MaxValue = 15)]
        public double EndTime { get; set; }

        private TestVWAP _vwap;

        protected override void OnStart()
        {
            _vwap = Indicators.GetIndicator<TestVWAP>();
        }

        protected override void OnBar()
        {
            double Time = Server.Time.TimeOfDay.TotalHours;

            if (!(StartTime <= Time && Time <= EndTime)) return;

            if (TradeDir == TradeType.Buy)
            {
                if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Buy).Length >= MaxBuy) return;

                if (Bars.OpenPrices.Last(1) < _vwap.Result.Last(1) && Bars.ClosePrices.Last(1) > _vwap.Result.Last(1))
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);
                }
            }
            else if (TradeDir == TradeType.Sell)
            {
                if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Sell).Length >= MaxSell) return;

                if (Bars.OpenPrices.Last(1) > _vwap.Result.Last(1) && Bars.ClosePrices.Last(1) < _vwap.Result.Last(1))
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);
                }
            }
        }
    }
}

Next time please also post the custom indicator code you are using.


@amusleh

anikaurmi420
10 Mar 2021, 13:01

RE: Novice

sue.bugg said:

I'm a novice, so can't give you the actual code and forgive me if I'm completely wrong & of no help to you.

I can't see anything in your code to reflect the open & close prices of the candle. I THINK I can only see you referencing the VWAP

You would have to declare variables. Bars open prices, bars close prices

Then do the math. If open is less than close = Buy. If open is more than close = Sell

Hope this helps in some way & apologies if the info is useless.

Firstly I apologies for not include the custom indicator code in my post. Here my custom indicator code..

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.ArabicStandardTime, AccessRights = AccessRights.None)]
    public class TestVWAP : Indicator
    {
        [Output("Main", LineColor = "White")]
        public IndicatorDataSeries Result { get; set; }

        [Output("Open", LineColor = "Lime")]
        public IndicatorDataSeries Open_Result { get; set; }

        [Output("Close", LineColor = "Red")]
        public IndicatorDataSeries Close_Result { get; set; }


        protected override void Initialize()
        {
            // Initialize and create nested indicators
        }

        public override void Calculate(int index)
        {
            // Calculate value at specified index
            // Result[index] = ...

            int ii = index - 1;
            double CumTypPrice = 0;
            double CumVol = 0;

            while (Bars.OpenTimes[ii] >= Bars.OpenTimes[ii].Date && ii != 0)
            {
                CumTypPrice += Bars.TypicalPrices[ii] * Bars.TickVolumes[ii];
                CumVol += Bars.TickVolumes[ii];
                ii--;

                if (Bars.OpenTimes[ii].Hour == 0 && Bars.OpenTimes[ii].Minute == 0)
                    break;

            }

            Result[index - 1] = CumTypPrice / CumVol;

            Open_Result[index - 1] = Bars.OpenPrices[index - 1];

            Close_Result[index - 1] = Bars.ClosePrices[index - 1];

        }
    }
}

 

I tried every possible way to do that. But unfortunately nothing works. I'm also tried this by using MarketSeries instead Bars.OpenPrices and Bars.ClosePrices. But the problem is still same. First I thought maybe only 15 Feb, 2021 is problem. But I ran a backtest from 1 June, 2020 to 1 march, 2021 and I found 10+ days with the same problem. I put candlestick open and close data into my custom indicator the results are same. I try to use Bars.OpenPrices and Bars.ClosePrices directly into the CBot and all results are same. Even I try different brokers and Spotware default Ctrader. The results are every where is same. all the problems are still remaining same. I didn't understand what's the actual problem. Is this a error? or It's my mistake? Please correct me If I'm wrong. I'm really looking for the solution.

And Thank You, for your interest in this topic.


@anikaurmi420

anikaurmi420
10 Mar 2021, 13:08

RE:

amusleh said:

Try this:

using cAlgo.API;
using cAlgo.API.Internals;
using System.Linq;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TestVWAP_Bot : Robot
    {
        [Parameter("TradeType")]
        public TradeType TradeDir { get; set; }

        [Parameter("Max Buy Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxBuy { get; set; }

        [Parameter("Max Sell Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxSell { get; set; }

        [Parameter("Trade Start Time", DefaultValue = 7, MinValue = 7, MaxValue = 8)]
        public double StartTime { get; set; }

        [Parameter("Trade End Time", DefaultValue = 14, MinValue = 14, MaxValue = 15)]
        public double EndTime { get; set; }

        private TestVWAP _vwap;

        protected override void OnStart()
        {
            _vwap = Indicators.GetIndicator<TestVWAP>();
        }

        protected override void OnBar()
        {
            double Time = Server.Time.TimeOfDay.TotalHours;

            if (!(StartTime <= Time && Time <= EndTime)) return;

            if (TradeDir == TradeType.Buy)
            {
                if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Buy).Length >= MaxBuy) return;

                if (Bars.OpenPrices.Last(1) < _vwap.Result.Last(1) && Bars.ClosePrices.Last(1) > _vwap.Result.Last(1))
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);
                }
            }
            else if (TradeDir == TradeType.Sell)
            {
                if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Sell).Length >= MaxSell) return;

                if (Bars.OpenPrices.Last(1) > _vwap.Result.Last(1) && Bars.ClosePrices.Last(1) < _vwap.Result.Last(1))
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);
                }
            }
        }
    }
}

Next time please also post the custom indicator code you are using.

Firstly I apologies for not include the custom indicator code in my post. Here my custom indicator code..

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.ArabicStandardTime, AccessRights = AccessRights.None)]
    public class TestVWAP : Indicator
    {
        [Output("Main", LineColor = "White")]
        public IndicatorDataSeries Result { get; set; }

        [Output("Open", LineColor = "Lime")]
        public IndicatorDataSeries Open_Result { get; set; }

        [Output("Close", LineColor = "Red")]
        public IndicatorDataSeries Close_Result { get; set; }


        protected override void Initialize()
        {
            // Initialize and create nested indicators
        }

        public override void Calculate(int index)
        {
            // Calculate value at specified index
            // Result[index] = ...

            int ii = index - 1;
            double CumTypPrice = 0;
            double CumVol = 0;

            while (Bars.OpenTimes[ii] >= Bars.OpenTimes[ii].Date && ii != 0)
            {
                CumTypPrice += Bars.TypicalPrices[ii] * Bars.TickVolumes[ii];
                CumVol += Bars.TickVolumes[ii];
                ii--;

                if (Bars.OpenTimes[ii].Hour == 0 && Bars.OpenTimes[ii].Minute == 0)
                    break;

            }

            Result[index - 1] = CumTypPrice / CumVol;

            Open_Result[index - 1] = Bars.OpenPrices[index - 1];

            Close_Result[index - 1] = Bars.ClosePrices[index - 1];

        }
    }
}

I tried your code the problem is still same. And I tried every possible way to do that. But unfortunately nothing works. I'm also tried this by using MarketSeries instead Bars.OpenPrices and Bars.ClosePrices. But the problem is still same. First I thought maybe only 15 Feb, 2021 is problem. But I ran a backtest GBPUSD from 1 June, 2020 to 1 march, 2021 and I found 10+ days with the same problem. I put candlestick open and close data into my custom indicator the results are same. I try to use Bars.OpenPrices and Bars.ClosePrices directly into the CBot and all results are same. Even I try different brokers and Spotware default Ctrader. The results are every where is same. all the problems are still remaining same. I didn't understand what's the actual problem. Is this a error? or It's my mistake? Please correct me If I'm wrong. I'm really looking for the solution.

And Thank You, for your interest in this topic.


@anikaurmi420

anikaurmi420
10 Mar 2021, 13:17 ( Updated at: 21 Dec 2023, 09:22 )

RE:

anikaurmi420 said:

Hi,

I write a simple CBot. The rules are simple.

Time Frame: H1 Candle. And Trade only 8 hours to 15 hours UTC Time.

Buy Entry Rule: If a candle open bellow VWAP line and close above VWAP line, then It's open a Buy position.

Sell Entry Rule: If a candle open above VWAP line and close bellow VWAP line, then It's open a Sell position.

After writing the code I take small back test. And I find somedays CBot don't follow the rules properly. It's open new position where It shouldn't.

This screenshot take from 15 Feb, 2021 (BackTest). In this photo It's clearly visible that no one candle open bellow the VWAP line but It's still open a Buy position. And this is my problem. Anyone pleas help me. I paste my code bellow,

 

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TestVWAP_Bot : Robot
    {
        [Parameter("Trade Direction : Buy or Sell")]
        public string TradeDir { get; set; }

        [Parameter("Max Buy Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxBuy { get; set; }

        [Parameter("Max Sell Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxSell { get; set; }

        [Parameter("Trade Start Time", DefaultValue = 7, MinValue = 7, MaxValue = 8)]
        public double StartTime { get; set; }

        [Parameter("Trade End Time", DefaultValue = 14, MinValue = 14, MaxValue = 15)]
        public double EndTime { get; set; }


        private TestVWAP vwap;

        protected override void OnStart()
        {
            // Put your initialization logic here

            vwap = Indicators.GetIndicator<TestVWAP>();

        }

        protected override void OnBar()
        {
            // Put your core logic here

            double Time = Server.Time.TimeOfDay.TotalHours;

            if (StartTime <= Time && Time <= EndTime)
            {
                //Trading Time......

                if (TradeDir == "Buy")
                {
                    //Buy Trade.....

                    if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Buy).Length >= MaxBuy)
                    {

                        return;

                    }

                    if (vwap.Open_Result.LastValue < vwap.Result.LastValue && vwap.Close_Result.LastValue > vwap.Result.LastValue)
                    {

                        ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);

                    }

                }
                else if (TradeDir == "Sell")
                {
                    //Sell Trade.....

                    if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Sell).Length >= MaxSell)
                    {

                        return;

                    }

                    if (vwap.Open_Result.LastValue > vwap.Result.LastValue && vwap.Close_Result.LastValue < vwap.Result.LastValue)
                    {

                        ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);

                    }

                }

            }

        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

Maybe I found the solution man. Thanks. I think this problem occurs for TimeZone differences between the CBot and Custom Indicator. Thanks again.


@anikaurmi420

anikaurmi420
10 Mar 2021, 13:18

RE:

amusleh said:

Try this:

using cAlgo.API;
using cAlgo.API.Internals;
using System.Linq;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TestVWAP_Bot : Robot
    {
        [Parameter("TradeType")]
        public TradeType TradeDir { get; set; }

        [Parameter("Max Buy Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxBuy { get; set; }

        [Parameter("Max Sell Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxSell { get; set; }

        [Parameter("Trade Start Time", DefaultValue = 7, MinValue = 7, MaxValue = 8)]
        public double StartTime { get; set; }

        [Parameter("Trade End Time", DefaultValue = 14, MinValue = 14, MaxValue = 15)]
        public double EndTime { get; set; }

        private TestVWAP _vwap;

        protected override void OnStart()
        {
            _vwap = Indicators.GetIndicator<TestVWAP>();
        }

        protected override void OnBar()
        {
            double Time = Server.Time.TimeOfDay.TotalHours;

            if (!(StartTime <= Time && Time <= EndTime)) return;

            if (TradeDir == TradeType.Buy)
            {
                if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Buy).Length >= MaxBuy) return;

                if (Bars.OpenPrices.Last(1) < _vwap.Result.Last(1) && Bars.ClosePrices.Last(1) > _vwap.Result.Last(1))
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);
                }
            }
            else if (TradeDir == TradeType.Sell)
            {
                if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Sell).Length >= MaxSell) return;

                if (Bars.OpenPrices.Last(1) > _vwap.Result.Last(1) && Bars.ClosePrices.Last(1) < _vwap.Result.Last(1))
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);
                }
            }
        }
    }
}

Next time please also post the custom indicator code you are using.

Maybe I found the solution man. Thanks. I think this problem occurs for TimeZone differences between the CBot and Custom Indicator. Thanks again.


@anikaurmi420