Slow backtesting when using Donchian channel

Created at 07 May 2021, 18:48
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!
AM

amml

Joined 27.04.2021

Slow backtesting when using Donchian channel
07 May 2021, 18:48


After introducing Donchian channel indicator (DonchianChannel) to my cBot, I've noticed backtesting to be extremely slow. Please find a minimum reproducible example below where I also show elapsed time for each line in OnTick:

using cAlgo.API;
using cAlgo.API.Indicators;

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

        private DonchianChannel channel;

        private MovingAverage T; // moving average of the top line in the Donchian channel
        private MovingAverage M; // moving average of the mid line in the Donchian channel
        private MovingAverage B; // moving average of the bottom line in the Donchian channel
        
        protected override void OnStart()
        {
            channel = Indicators.DonchianChannel(500);

            T = Indicators.SimpleMovingAverage(channel.Top, 1000);
            M = Indicators.SimpleMovingAverage(channel.Middle, 1000);
            B = Indicators.SimpleMovingAverage(channel.Bottom, 1000);
        }

        protected override void OnTick()
        {
            channel.Top.Last(0); // 10'214ms elapsed 
            channel.Middle.Last(0); // 1ms elapsed 
            channel.Bottom.Last(0); // 2ms elapsed

            T.Result.Last(0); // 10'547ms elapsed 
            M.Result.Last(0); // 10'549ms elapsed 
            B.Result.Last(0); // 10'410ms elapsed

            Functions.HasCrossedAbove(Source, T.Result, 0); // 10'395ms elapsed 
            Functions.HasCrossedAbove(Source, M.Result, 0); // 10'335ms elapsed 
            Functions.HasCrossedAbove(Source, B.Result, 0); // 10'120ms elapsed 
        }
    }
}

Questions:

1. How is the Donchian channel implemented? I could not find the source code for this indicator. Using Source.Minimum(Periods) and Source.Maximum(Periods) for bottom and top lines respectively is not the most efficient implementation.

2. Is there anything I can do to speed this up ATM? It looks like the Donchian channel computation is not shared in the moving averages, and thus a recomputation is performed. 

 


@amml
Replies

PanagiotisCharalampous
10 May 2021, 08:19

Hi amml,

You are using a lot of periods in your indicators. Averaging 1000 periods on every tick would take some time. If you really need to use so many periods and the performance is critical to you, you could consider implementing your own custom indicators, which would be optimized for performance.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

amml
10 May 2021, 11:27

Dear Panagiotis,

Many thanks for this. Yes, in the meantime I implemented my own Donchian channel indicator and the performance issue reported here was resolved. 

The average calculation is not a problem because the new average in a new tick should be quickly updated using the average from the last tick. Assuming, however, that this is what cTrader does (which most likely is, given that there is no performance issue on the MovingAverage calculations). It would be helpful if the standard indicators in cTrader were open-source, as this would welcome contribution from some users.

Best regards,
A.


@amml