Visual Mode for BackTesting

22 Mar 2018, 20:08Visual Mode for BackTesting#1
yjouraposts: 1since: 22 Mar 2018

Hi All,
This page https://spotware.com/ctrader/trading/ctrader-automated-trading-platform
Claims that backtesting visual mode is there. But its actually not in the product? Am I missing something?

23 Mar 2018, 09:10#2
Panagiotis Charalampousposts: 1785since: 13 Jan 2017

Hi yjoura,

The current plan is to release visual backtesting in cTrader Desktop v3.01. Stay tuned!

Best Regards,

Panagiotis


Head of Community Management at cTrader
23 Mar 2018, 10:14RE:#3
MaRCHeWposts: 45since: 05 May 2012

Fantastic info. Thanks Panagiotis :)

Panagiotis Charalampous said:

Hi yjoura,

The current plan is to release visual backtesting in cTrader Desktop v3.01. Stay tuned!

Best Regards,

Panagiotis

 

08 Oct 2018, 23:05#4
aboukerkerposts: 14since: 27 Jun 2013

HI,

My cAlgo version 3.03 is freezing in visual testing when i add this code :

        void OnPositionOpened(PositionOpenedEventArgs args)
        {
            if (RunningMode != RunningMode.Optimization)
            {
                Chart.DrawVerticalLine(Guid.NewGuid().ToString(), args.Position.EntryTime, (args.Position.TradeType == TradeType.Buy ? Color.Red : Color.Blue));
                Chart.DrawText(Guid.NewGuid().ToString(), "Opened " + args.Position.TradeType, args.Position.EntryTime, args.Position.EntryPrice, Color.White);
            }
        }

 

09 Oct 2018, 09:59#5
Panagiotis Charalampousposts: 1785since: 13 Jan 2017

Hi aboukerker,

Can you please share the complete cBot code so that we can reproduce the issue?

Best Regards,

Panagiotis


Head of Community Management at cTrader
09 Oct 2018, 20:50#6
aboukerkerposts: 14since: 27 Jun 2013
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MACD_PSAR_STOCH : Robot
    {
        const string Label = "MACD_PSAR_STOCH";

        [Parameter(DefaultValue = 1, Step = 1, MaxValue = 1, MinValue = 1)]
        public int MaxTrades { get; set; }

        [Parameter(DefaultValue = 70, Step = 1, MaxValue = 300, MinValue = 70)]
        public double TakeProfit { get; set; }

        [Parameter(DefaultValue = 300, Step = 1, MaxValue = 350, MinValue = 70)]
        public double StopLoss { get; set; }

        // MACD
        [Parameter(DefaultValue = 26, Step = 1, MaxValue = 50, MinValue = 1)]
        public int LongCycle { get; set; }

        [Parameter(DefaultValue = 14, Step = 1, MaxValue = 30, MinValue = 1)]
        public int ShortCycle { get; set; }

        [Parameter(DefaultValue = 9, Step = 1, MaxValue = 50, MinValue = 1)]
        public int Period { get; set; }

        // Stochastic
        [Parameter(DefaultValue = 14, Step = 1, MaxValue = 50, MinValue = 1)]
        public int Kperiod { get; set; }

        [Parameter(DefaultValue = 3, Step = 1, MaxValue = 50, MinValue = 1)]
        public int KSlowing { get; set; }

        [Parameter(DefaultValue = 9, Step = 1, MaxValue = 50, MinValue = 1)]
        public int Dperiod { get; set; }

        [Parameter(DefaultValue = 2, Step = 1)]
        public int RiskPercent { get; set; }

        [Parameter(DefaultValue = 10, Step = 10)]
        public int Volume { get; set; }

        [Parameter(DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MAType { get; set; }

        MacdCrossOver macd;
        ParabolicSAR sar;
        StochasticOscillator stoch;

        protected override void OnStart()
        {
            Positions.Opened += OnPositionOpened;
            Positions.Closed += OnPositionClosed;
            macd = Indicators.MacdCrossOver(MarketSeries.Close, LongCycle, ShortCycle, Period);
            sar = Indicators.ParabolicSAR(0.02, 0.2);
            stoch = Indicators.StochasticOscillator(Kperiod, KSlowing, Dperiod, MAType);
        }

        protected override void OnTick()
        {
            double Bid = Symbol.Bid;
            double Ask = Symbol.Ask;
            double Point = Symbol.TickSize;
            if (sar.Result.Last(1) > Bid && macd.MACD.IsRising() && macd.MACD.HasCrossedAbove(macd.Signal, 0) && (stoch.PercentK.Last(0) < 35 || (stoch.PercentK.HasCrossedAbove(stoch.PercentD, 0) && stoch.PercentK.IsRising())))
            {
                ClosePositions(TradeType.Sell);
                if (Check())
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol, CalculateVolume(), Label, StopLoss, TakeProfit);
                }
            }
            else if (sar.Result.Last(1) < Ask && macd.MACD.IsFalling() && macd.MACD.HasCrossedBelow(macd.Signal, 0) && (stoch.PercentK.Last(0) > 60 || (stoch.PercentD.HasCrossedAbove(stoch.PercentK, 0) && stoch.PercentD.IsRising())))
            {
                ClosePositions(TradeType.Buy);
                if (Check())
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol, CalculateVolume(), Label, StopLoss, TakeProfit);
                }
            }
        }
          protected override void OnStop()
        {
            if (IsBacktesting)
            {
                foreach (var pos in Positions.FindAll(Label, Symbol))
                {
                    ClosePosition(pos);
                }
            }
        }

        void OnPositionOpened(PositionOpenedEventArgs args)
        {
            if (RunningMode != RunningMode.Optimization)
            {
                Chart.DrawVerticalLine(Guid.NewGuid().ToString(), args.Position.EntryTime, (args.Position.TradeType == TradeType.Buy ? Color.Red : Color.Blue));
                //Chart.DrawText(Guid.NewGuid().ToString(), "Opened " + args.Position.TradeType, args.Position.EntryTime, args.Position.EntryPrice, Color.White);
            }
        }

        void OnPositionClosed(PositionClosedEventArgs args)
        {

        }


        double CalculateVolume()
        {
            double _volume = 0;
            if (Volume == 0)
            {
                // Our total balance is our account balance plus any reserve funds. We do not always keep all our money in the trading account.
                double totalBalance = Account.Balance / MaxTrades;

                // Calculate the total risk allowed per trade.
                double riskPerTrade = (totalBalance * RiskPercent) / 100;
                // Add the stop loss, commission pips and spread to get the total pips used for the volume calculation.
                double totalPips = StopLoss + Symbol.Spread + 0.8;
                // CommissionPips
                // Calculate the exact volume to be traded. Then round the volume to the nearest 100,000 and convert to an int so that it can be returned to the caller.
                _volume = Math.Round(riskPerTrade / (Symbol.PipValue * totalPips), 2);

            }
            else
            {
                _volume = Volume;
            }
            return Symbol.NormalizeVolumeInUnits(_volume);
        }

        int NumberOfOpenOrders()
        {
            return Positions.FindAll(Label, Symbol).Length;
        }

        bool Check()
        {

            bool result = true;
            if (NumberOfOpenOrders() >= MaxTrades)
            {
                result = false;
            }
            else if (Account.MarginLevel != null && Account.MarginLevel < 130)
            {
                string msg = String.Format("{0} Check => Equity {1} MarginLevel {2} ", Server.Time, Account.Equity, Account.MarginLevel);
                Print(msg);
                result = false;
            }
            return result;
        }

        void ClosePositions(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll(Label, Symbol, tradeType))
            {
                ClosePosition(position);
            }
        }

        double NormalizePrice(double d)
        {
            return Math.Round(d, Symbol.Digits);
        }

        protected override void OnError(Error error)
        {
            Print("Error Code : {0} ", error.Code);
            if (error.Code == ErrorCode.NoMoney)
                Stop();
        }
    }
}

parameter !

 

[ChartParameters]
Symbol = MICROSOFT
Timeframe = m1

[cBotParameters]
MaxTrades = 1
TakeProfit = 178
StopLoss = 235
LongCycle = 17
ShortCycle = 5
Period = 15
Kperiod = 11
KSlowing = 38
Dperiod = 20
RiskPercent = 2
Volume = 1
MAType = TimeSeries

10 Oct 2018, 10:11#7
Panagiotis Charalampousposts: 1785since: 13 Jan 2017

Hi aboukerker,

I could not reproduce any issue. Visual backtesting seems to be working fine. Can you make sure that this is not caused because of the speed setting?

Best Regards,

Panagiotis


Head of Community Management at cTrader
10 Oct 2018, 14:25#8
aboukerkerposts: 14since: 27 Jun 2013

Please retry with this method 


        void OnPositionOpened(PositionOpenedEventArgs args)
        {
            if (RunningMode != RunningMode.Optimization)
            {
                Chart.DrawVerticalLine(Guid.NewGuid().ToString(), args.Position.EntryTime, (args.Position.TradeType == TradeType.Buy ? Color.Red : Color.Blue));
                Chart.DrawText(Guid.NewGuid().ToString(), "Opened " + args.Position.TradeType, args.Position.EntryTime, args.Position.EntryPrice, Color.White);
            }
        }

 

11 Oct 2018, 10:58#9
Panagiotis Charalampousposts: 1785since: 13 Jan 2017

Hi aboukerker,

That works fine as well. Is it possible to make a short video with your issue and send it to us?

Best Regards,

Panagiotis


Head of Community Management at cTrader