I completely don't trust cAlgo back testing

Created at 21 Mar 2018, 17:35
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!
CE

ceakuk

Joined 19.03.2018

I completely don't trust cAlgo back testing
21 Mar 2018, 17:35


After many months of  coding, I can't tell if my Robots could have worked or not. All lost money on back testing but now I can see the problem is the platform. This backtesting business is not right,

 

I'm using Renko of 10 pips. I buy when  renko chart gets red and buy when its green. I expect no position can loose 10pips+  some small  number. unfortunately I loose  even 75 pips which is crazy see image https://imgur.com/a/p02Bl

but when I print logs for Symbol.Bid, Symbol.Ask,  and Renko Position, none shows a loosing position. Infact the pisition  should be +25pips and counting but  calgo closes the position as -75pips.

What exactly is wrong with calgo.

I try both1M bar data and Ticks data


@ceakuk
Replies

ceakuk
21 Mar 2018, 17:39

RE:

ceakuk said:

Open buy position and closs all sell positions  when renko turns green and
Open sell position and close all buy positions  when renko turns red
https://www.tradingacademy.com/lessons/wp-content/uploads/bwendell-20131210-spy-renko.jpg

@ceakuk

PanagiotisCharalampous
21 Mar 2018, 17:45

Hi ceakuk,

We would be able to help you if you share with us the cBot code and steps to reproduce the results. Only by seeing an image, we cannot come to any conclusions.

Best Regards,

Panagiotis


@PanagiotisCharalampous

ceakuk
22 Mar 2018, 02:46 ( Updated at: 21 Dec 2023, 09:20 )

RE:

Panagiotis Charalampous said:

Thank you Panagiotis. Here is the Renko Indicator

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

namespace cAlgo
{
    [Indicator("Renko", IsOverlay = true, AutoRescale = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Renko : Indicator
    {
        [Parameter("Renko (Pips)", DefaultValue = 10, MinValue = 0.1, Step = 1)]
        public double RenkoPips { get; set; }

        [Parameter("Bricks To Show", DefaultValue = 100, MinValue = 1)]
        public int BricksToShow { get; set; }

        [Parameter("Zoom Level", DefaultValue = 3, MinValue = 0, MaxValue = 5, Step = 1)]
        public double ZoomLevel { get; set; }

        [Parameter("Bullish Color", DefaultValue = "SeaGreen")]
        public string ColorBull { get; set; }

        [Parameter("Bearish Color", DefaultValue = "Tomato")]
        public string ColorBear { get; set; }

        [Output("Open", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
        public IndicatorDataSeries Open { get; set; }

        [Output("High", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
        public IndicatorDataSeries High { get; set; }

        [Output("Low", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
        public IndicatorDataSeries Low { get; set; }

        [Output("Close", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
        public IndicatorDataSeries Close { get; set; }

        public class Brick
        {
            public double Open { get; set; }
            public double Close { get; set; }
        }

        private List<Brick> renkos = new List<Brick>();
        private double closeLastValue, thickness, renkoPips, renkoLastValue;
        private Colors colorBull, colorBear;
        private bool colorError;
        private int lastCount;

        protected override void Initialize()
        {
            if (!Enum.TryParse<Colors>(ColorBull, out colorBull) || !Enum.TryParse<Colors>(ColorBear, out colorBear))
                colorError = true;

            renkoPips = RenkoPips * Symbol.PipSize;
            thickness = Math.Pow(2, ZoomLevel) - (ZoomLevel > 0 ? 1 : 0);
            renkoLastValue = 0;
        }

        public override void Calculate(int index)
        {
            if (colorError)
            {
                ChartObjects.DrawText("Error0", "{o,o}\n/)_)\n \" \"\nOops! Incorrect colors.", StaticPosition.TopCenter, Colors.Gray);
                return;
            }

            if (renkoLastValue == 0)
            {
                var open = MarketSeries.Open.LastValue;

                renkoLastValue = open - (open % renkoPips) + renkoPips / 2;
                //renkoLastValue = MarketSeries.Close.LastValue;
            }

            closeLastValue = MarketSeries.Close.LastValue;

            while (closeLastValue >= renkoLastValue + renkoPips)
            {
                renkoLastValue += renkoPips;
                renkos.Insert(0, new Brick 
                {
                    Open = renkoLastValue - renkoPips,
                    Close = renkoLastValue
                });
                if (renkos.Count() > BricksToShow)
                    renkos.RemoveRange(BricksToShow, renkos.Count() - BricksToShow);
                if (IsLastBar)
                    UpdateHistory(index);
            }
            while (closeLastValue <= renkoLastValue - renkoPips)
            {
                renkoLastValue -= renkoPips;
                renkos.Insert(0, new Brick 
                {
                    Open = renkoLastValue + renkoPips,
                    Close = renkoLastValue
                });
                if (renkos.Count() > BricksToShow)
                    renkos.RemoveRange(BricksToShow, renkos.Count() - BricksToShow);
                if (IsLastBar)
                    UpdateHistory(index);
            }

            bool isNewBar = MarketSeries.Close.Count > lastCount;

            if (IsLastBar && isNewBar)
            {
                UpdateHistory(index);

                Open[index - BricksToShow] = double.NaN;
                High[index - BricksToShow] = double.NaN;
                Low[index - BricksToShow] = double.NaN;
                Close[index - BricksToShow] = double.NaN;

                lastCount = MarketSeries.Close.Count;
            }

            if (IsRealTime)
                UpdateLive(index);
        }

        private void UpdateHistory(int index)
        {
            for (int i = 0; i < BricksToShow - 1 && i < renkos.Count() - 1; i++)
            {
                var color = renkos[i].Open < renkos[i].Close ? colorBull : colorBear;

                ChartObjects.DrawLine(string.Format("renko.Last({0})", i + 1), index - i - 1, renkos[i].Open, index - i - 1, renkos[i].Close, color, thickness, LineStyle.Solid);

                Open[index - i - 1] = renkos[i].Open;
                High[index - i - 1] = Math.Max(renkos[i].Open, renkos[i].Close);
                Low[index - i - 1] = Math.Min(renkos[i].Open, renkos[i].Close);
                Close[index - i - 1] = renkos[i].Close;
            }
        }

        private void UpdateLive(int index)
        {
            double y1, y2;
            var top = Math.Max(renkos[0].Open, renkos[0].Close);
            var bottom = Math.Min(renkos[0].Open, renkos[0].Close);

            if (closeLastValue > top)
                y1 = top;
            else if (closeLastValue < bottom)
                y1 = bottom;
            else
                y1 = closeLastValue;

            y2 = closeLastValue;

            var colorLive = y1 < y2 ? colorBull : colorBear;

            ChartObjects.DrawLine("renko.Live", index, y1, index, y2, colorLive, thickness, LineStyle.Solid);

            Open[index] = y1;
            High[index] = y1 > y2 ? y1 : y2;
            Low[index] = y1 < y2 ? y1 : y2;
            Close[index] = y2;
        }
    }
}

Here is the Renko Cbot

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }
        private Renko renko;
        [Parameter("Renko Pips", DefaultValue = 10, MinValue = 0.5, Step = 2)]
        public double RenkoPips { get; set; }


        [Parameter("Number Of Bricks", DefaultValue = 100, MinValue = 10, Step = 100)]
        public int BricksToShow { get; set; }

        [Parameter("Zoom Level", DefaultValue = 3, MinValue = 0, MaxValue = 5, Step = 1)]
        public double ZoomLevel { get; set; }

        [Parameter("Bullish bar color", DefaultValue = "SeaGreen")]
        public string BullishBarColor { get; set; }

        [Parameter("Bearish bar color", DefaultValue = "Tomato")]
        public string BearishBarColor { get; set; }

        [Parameter("Quantity", DefaultValue = 1000, MinValue = 1000, Step = 1000)]
        public int Quantity { get; set; }


        protected override void OnStart()
        {
            object[] parameterValues = 
            {
                RenkoPips,
                // Bar size
                BricksToShow,
                // Show number of bricks
                ZoomLevel,
                //ZoomLevel
                BullishBarColor,
                // Bullish bar color
                BearishBarColor
                // Bearish bar color
            };
            Print("start");
            renko = Indicators.GetIndicator<Renko>(parameterValues);
        }

        protected override void OnTick()
        {

            double renkoPips = RenkoPips * Symbol.PipSize;
            bool isLastBrickBullish = renko.Open.Last(0) < renko.Close.Last(0);

            var buyPosition = Positions.Find("Renko", Symbol, TradeType.Buy);
            var sellPosition = Positions.Find("Renko", Symbol, TradeType.Sell);
            if (buyPosition != null)
            {
                if (buyPosition.Pips < -2 * RenkoPips)
                {
                    Print("start===================================");
                    Print("buyPositionpips=" + buyPosition.Pips);
                    Print("renkoPips=" + renkoPips + "cbot Symbol.Bid=" + Symbol.Bid + "  Symbol.Ask=" + Symbol.Ask);
                    Print("renko.Open.LastValue=" + renko.Open.LastValue + "  renko.Close.LastValue=" + renko.Close.LastValue);
                    Print("difference Symbol.Bid - renko.Open.LastValue= " + (Symbol.Bid - renko.Open.LastValue));
                    Print("difference Symbol.Bid - renko.Close.LastValue=  " + (Symbol.Bid - renko.Close.LastValue));
                    Print("difference Symbol.Bid - renko.Close.LastValue=  " + (Symbol.Ask - renko.Open.LastValue));
                    Print("difference Symbol.Bid - renko.Close.LastValue=  " + (Symbol.Ask - renko.Close.LastValue));
                    Print("end===================================");
                }
            }

            if (sellPosition != null)
            {
                if (sellPosition.Pips < -2 * RenkoPips || sellPosition.Id == 11)
                {
                    Print("start===================================");
                    Print("sellPositionpips=" + sellPosition.Pips);
                    Print("renkoPips=" + renkoPips + "cbot Symbol.Bid=" + Symbol.Bid + "  Symbol.Ask=" + Symbol.Ask);
                    Print("renko.Open.LastValue=" + renko.Open.LastValue + "  renko.Close.LastValue=" + renko.Close.LastValue);
                    Print("difference Symbol.Bid - renko.Open.LastValue= " + (Symbol.Bid - renko.Open.LastValue));
                    Print("difference Symbol.Bid - renko.Close.LastValue=  " + (Symbol.Bid - renko.Close.LastValue));
                    Print("difference Symbol.Bid - renko.Close.LastValue=  " + (Symbol.Ask - renko.Open.LastValue));
                    Print("difference Symbol.Bid - renko.Close.LastValue=  " + (Symbol.Ask - renko.Close.LastValue));
                    Print("end===================================");
                }
            }



            if (isLastBrickBullish && buyPosition == null)
            {
                if (sellPosition != null)
                    ClosePosition(sellPosition);
                //Print("buying");
                ExecuteMarketOrder(TradeType.Buy, Symbol, Quantity, "Renko");
            }

            else if (!isLastBrickBullish && sellPosition == null)
            {
                if (buyPosition != null)
                    ClosePosition(buyPosition);
                //Print("Selling");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Quantity, "Renko");
            }
        }
    }
}

 and here is the Image

 Im 09/03/2017- 23/04/2017 using 1M Ticks data. I guess being ticks it doesnt matter if its 1M. My commision is 70 per million. my time zone is UTC+1 trading 50 pips but I get as  high as -187.6 pips. 2 minutes before closing its just -2.8pips . It happens a lot that clog can record high gain in pips but when the position close a minute later, its large negative pips 4 times (-187.6pips) my stoploss of 1 brick=-5pips.

I used to think the indicator feeds wrong results to cbot but as i print  both the pips and theSymbol.Bis, Symbol.Ask and renko.Open.LastValue, renko.Closelastvalue. its now apparent that something is wrong with the calgo backtesting platform.

Thank you and i'm looking foward.

With kind regards,

Kevin


@ceakuk

PanagiotisCharalampous
22 Mar 2018, 11:03 ( Updated at: 21 Dec 2023, 09:20 )

Hi ceacuk,

This seems to be happening because of a weekend gap between the 21st and 24th of April. See below

Let me know if this addresses your concerns.

Best Regards,

Panagiotis


@PanagiotisCharalampous