Build Succeeded but Backtesting not Running

Created at 16 Nov 2020, 07:13
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

CharlieBrown

Joined 14.11.2020

Build Succeeded but Backtesting not Running
16 Nov 2020, 07:13


Hi cBots enthusiasts

This is my first attempt at coding. I modified the trend sample to include exits at loss and profit.

The build is succeeded but I cannot seem to run backtesting.

Any help is most appreciated.

 

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 MyFirstcBot : Robot
    {
        #region User Defined Parameters
        // List all parameters required for this cBots.
        [Parameter("cBots Name", Group = "Trades")]
        public string cBotsName { get; set; }

        [Parameter("Quantity (Lots)", Group = "Trades", DefaultValue = 0.3, MinValue = 0.01, Step = 0.3)]
        public double Quantity { get; set; }

        [Parameter("Set Hours", Group = "Trading Hours", DefaultValue = false)]
        public bool IsTradingSession { get; set; }

        [Parameter("Start Time", Group = "Trading Hours", DefaultValue = 10, Step = 1)]
        public double StartTime { get; set; }

        [Parameter("Stop Time", Group = "Trading Hours", DefaultValue = 23, Step = 1)]
        public double StopTime { get; set; }

        [Parameter("Avoid Trading News", Group = "Trading Hours", DefaultValue = false)]
        public bool IsNewsTradingSession { get; set; }

        [Parameter("Alert New Trade", Group = "Notifications", DefaultValue = false)]
        public bool IsSendEmail { get; set; }

        [Parameter("Email Address", Group = "Notifications", DefaultValue = "your@email.com")]
        public string EmailAddress { get; set; }

        [Parameter("Set Time Frame", Group = "Time Frame", DefaultValue = false)]
        public bool IsTimeFrame { get; set; }

        [Parameter("Time Frame 1", Group = "Time Frame")]
        public TimeFrame EntryTimeFrame { get; set; }

        [Parameter("Time Frame 2", Group = "Time Frame")]
        public TimeFrame ExitTimeFrame { get; set; }

        [Parameter("MA Type", Group = "Moving Average")]
        public MovingAverageType MAType { get; set; }

        [Parameter("MA Source", Group = "Moving Average")]
        public DataSeries MASourceSeries { get; set; }

        [Parameter("Fast", Group = "Moving Average", DefaultValue = 5)]
        public int FastPeriods { get; set; }

        [Parameter("Med", Group = "Moving Average", DefaultValue = 26)]
        public int MedPeriods { get; set; }

        [Parameter("Slow", Group = "Moving Average", DefaultValue = 60)]
        public int SlowPeriods { get; set; }

        [Parameter("RSI Source", Group = "RSI")]
        public DataSeries RSISourceSeries { get; set; }

        [Parameter("RSI Periods", Group = "RSI", DefaultValue = 14)]
        public int RSIPeriods { get; set; }
        #endregion User Defined Parameters

        #region User Defined Indicators
        // List all indicators required for this cBots.
        private MovingAverage fastMa;
        private MovingAverage medMa;
        private MovingAverage slowMa;
        private RelativeStrengthIndex rsi;

        public TimeFrame entryTf;
        public TimeFrame exitTf;

        public DateTime startHr;
        public DateTime endHr;
        #endregion User Defined Indicators

        #region OnStart
        // This method is called when the robot first starts, it is only called once.
        // Put your initialization logic here - construct all the indicators.
        protected override void OnStart()
        {
            {
                // Only trade between UTC+11, 09:00 current day and 05:00 the following day
                startHr = Server.Time.Date.AddHours(StartTime);
                endHr = Server.Time.Date.AddHours(StopTime);

                // TO COMPLETE - NO ENTRY 10 minutes before and after major news

                // Indicators used for entry and exit positions
                fastMa = Indicators.MovingAverage(MASourceSeries, FastPeriods, MAType);
                medMa = Indicators.MovingAverage(MASourceSeries, MedPeriods, MAType);
                slowMa = Indicators.MovingAverage(MASourceSeries, SlowPeriods, MAType);
                rsi = Indicators.RelativeStrengthIndex(RSISourceSeries, RSIPeriods);

                // Time Frame used for entry and exit positions
                entryTf = TimeFrame.Hour;
                exitTf = TimeFrame.Minute;
            }
        }
        #endregion OnStart

        #region OnTick
        // This method is called every time the price changes for the symbol.
        // Put your core logic here.
        protected override void OnTick()
        {
            var longPosition = Positions.Find(cBotsName, SymbolName, TradeType.Buy);
            var shortPosition = Positions.Find(cBotsName, SymbolName, TradeType.Sell);
            var currentSlowMa = slowMa.Result.Last(0);
            var currentMedMa = medMa.Result.Last(0);
            var currentFastMa = fastMa.Result.Last(0);
            var previousSlowMa = slowMa.Result.Last(1);
            var previousMedMa = medMa.Result.Last(1);
            var previousFastMa = fastMa.Result.Last(1);
            var _rsi = rsi.Result.Last(0);
            var currentPrice = Bars.ClosePrices.Last(0);
            var entryPrice = LastResult.Position.EntryPrice;

            if (longPosition == null && previousFastMa < currentSlowMa && currentFastMa > currentSlowMa && currentPrice > currentFastMa && currentFastMa > currentMedMa && currentMedMa > currentSlowMa && _rsi > 52)
            {
                // Close long at profit
                if (previousFastMa > currentMedMa && currentFastMa < currentMedMa && ((1.5 * currentPrice) > entryPrice) && _rsi < 50)
                {
                    ClosePosition(longPosition);
                }

                // Close long at Loss
                else if (previousFastMa > currentMedMa && currentFastMa < currentMedMa && ((1.5 * currentPrice) < entryPrice) && _rsi < 50)
                {
                    ClosePosition(longPosition);
                }

                ExecuteMarketOrder(TradeType.Buy, SymbolName, VolumeInUnits, cBotsName);
            }

            else if (shortPosition == null && previousFastMa > currentSlowMa && currentFastMa < currentSlowMa && currentPrice < currentFastMa && currentFastMa < currentMedMa && currentMedMa < currentSlowMa && _rsi < 48)
            {
                // Close short at profit
                if (previousFastMa > currentMedMa && currentFastMa < currentMedMa && ((1.5 * currentPrice) > entryPrice) && _rsi < 50)
                {
                    ClosePosition(shortPosition);
                }

                // Close short at Loss
                else if (previousFastMa > currentMedMa && currentFastMa < currentMedMa && ((1.5 * currentPrice) < entryPrice) && _rsi < 50)
                {
                    ClosePosition(shortPosition);
                }

                ExecuteMarketOrder(TradeType.Sell, SymbolName, VolumeInUnits, cBotsName);
            }
        }
        #endregion OnTick

        private double VolumeInUnits
        {
            get { return Symbol.QuantityToVolumeInUnits(Quantity); }
        }
    }
}

 


@CharlieBrown
Replies

PanagiotisCharalampous
16 Nov 2020, 11:30 ( Updated at: 21 Dec 2023, 09:22 )

Hi CharlieBrown,

Did you debug your cBot? I get an exception as soon as I run it

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous