Enter Only During a Specific Time Period

Created at 05 Apr 2021, 19:07
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!
TH

thecaffeinatedtrader

Joined 22.07.2020

Enter Only During a Specific Time Period
05 Apr 2021, 19:07


Hi,

I am not sure how to go about trying to add a parameter that tells my bot to only enter trades between these time periods. (eastern time zone)

1.    7 pm - 9 pm

2.    2 am - 4 am

3.    8 am - 10 am

If someone could please help with this that would be greatly appreciated! 

Thank you! 

 

This is the code I currently have that is using the slow moving average as a position bias, the fast crossing medium as the entry reason, and then the bar crossing medium as the exit reason. 

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 EmaBiaCross : Robot
    {
        [Parameter("Source")]
        public DataSeries SourceSeries { get; set; }

        [Parameter("Label", DefaultValue = "EMA")]
        public string Label { get; set; }

        [Parameter("Slow Periods", DefaultValue = 233)]
        public int SlowPeriods { get; set; }

        [Parameter("Medium Periods", DefaultValue = 55)]
        public int MediumPeriods { get; set; }

        [Parameter("Fast Periods", DefaultValue = 21)]
        public int FastPeriods { get; set; }

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

        private ExponentialMovingAverage slowMa;
        private double _volumeInUnits;
        private ExponentialMovingAverage mediumMa;
        private ExponentialMovingAverage fastMa;

        protected override void OnStart()
        {
            fastMa = Indicators.ExponentialMovingAverage(SourceSeries, FastPeriods);
            mediumMa = Indicators.ExponentialMovingAverage(SourceSeries, MediumPeriods);
            slowMa = Indicators.ExponentialMovingAverage(SourceSeries, SlowPeriods);

            _volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);
        }

        protected override void OnBar()
        {
            int index = Bars.Count - 2;

            Entry(index);

            Exit(index);
        }

        private void Exit(int index)
        {
            var positions = Positions.FindAll(Label);

            foreach (var position in positions)
            {
                if ((position.TradeType == TradeType.Buy && Bars.ClosePrices[index] < mediumMa.Result[index]) || (position.TradeType == TradeType.Sell && Bars.ClosePrices[index] > mediumMa.Result[index]))
                {
                    ClosePosition(position);
                }
            }
        }

        private void Entry(int index)
        {
            // Buy Only
            if (Bars.ClosePrices[index] > slowMa.Result[index])
            {
                // if fast crosses medium upward
                if (fastMa.Result[index] > mediumMa.Result[index] && fastMa.Result[index - 1] < mediumMa.Result[index - 1])
                {
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label);
                }
            }
            // Sell only
            else if (Bars.ClosePrices[index] < slowMa.Result[index])
            {
                // if fast crosses medium downward
                if (fastMa.Result[index] < mediumMa.Result[index] && fastMa.Result[index - 1] > mediumMa.Result[index - 1])
                {
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label);
                }
            }
        }
    }
}


 


@thecaffeinatedtrader
Replies

amusleh
06 Apr 2021, 10:47

Hi,

This sample cBot might help you:

using cAlgo.API;
using System;
using System.Globalization;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class TradeTime : Robot
    {
        private TimeSpan _startTime, _endTime;

        [Parameter("Start Time", DefaultValue = "07:00:00", Group = "Time Filter")]
        public string StartTime { get; set; }

        [Parameter("End Time", DefaultValue = "16:00:00", Group = "Time Filter")]
        public string EndTime { get; set; }

        private DateTime CurrentTime
        {
            get { return Server.TimeInUtc.Add(-Application.UserTimeOffset); }
        }

        private bool IsTimeCorrect
        {
            get { return (_startTime > _endTime && (CurrentTime.TimeOfDay >= _startTime || CurrentTime.TimeOfDay <= _endTime)) || (_startTime < _endTime && (CurrentTime.TimeOfDay >= _startTime && CurrentTime.TimeOfDay <= _endTime)); }
        }

        protected override void OnStart()
        {
            if (!TimeSpan.TryParse(StartTime, CultureInfo.InvariantCulture, out _startTime))
            {
                Print("Invalid start time input");

                Stop();
            }

            if (!TimeSpan.TryParse(EndTime, CultureInfo.InvariantCulture, out _endTime))
            {
                Print("Invalid end time input");

                Stop();
            }
        }

        protected override void OnBar()
        {
            // Return if current time is not in start/end time range
            if (!IsTimeCorrect) return;
        }
    }
}

Please take a look on Server.Time, Server.TimeInUtc, Application.UserTimeOffset, .NET TimeSpan, and DateTime.

If you know the C# basics and cTrader automate API references then you can easily do it.


@amusleh

JerryTrader
06 Apr 2021, 10:54

Hi, 

You can use DateTime.Now to know the current time.

Then you can easily check if your datetime.Hour is in the range you want.

Something like this (not tested though):

protected override void OnBar()
{
    int index = Bars.Count - 2;

    var now = DateTime.Now;
    if ((now.Hour > 19 && now.Hour < 21) ||
        (now.Hour > 2 && now.Hour < 4) ||
        (now.Hour > 8 && now.Hour < 10))
    {
        Entry(index);
    }

    Exit(index);
}

 


@JerryTrader

thecaffeinatedtrader
06 Apr 2021, 16:39

RE:

amusleh said:

Hi,

This sample cBot might help you:

using cAlgo.API;
using System;
using System.Globalization;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class TradeTime : Robot
    {
        private TimeSpan _startTime, _endTime;

        [Parameter("Start Time", DefaultValue = "07:00:00", Group = "Time Filter")]
        public string StartTime { get; set; }

        [Parameter("End Time", DefaultValue = "16:00:00", Group = "Time Filter")]
        public string EndTime { get; set; }

        private DateTime CurrentTime
        {
            get { return Server.TimeInUtc.Add(-Application.UserTimeOffset); }
        }

        private bool IsTimeCorrect
        {
            get { return (_startTime > _endTime && (CurrentTime.TimeOfDay >= _startTime || CurrentTime.TimeOfDay <= _endTime)) || (_startTime < _endTime && (CurrentTime.TimeOfDay >= _startTime && CurrentTime.TimeOfDay <= _endTime)); }
        }

        protected override void OnStart()
        {
            if (!TimeSpan.TryParse(StartTime, CultureInfo.InvariantCulture, out _startTime))
            {
                Print("Invalid start time input");

                Stop();
            }

            if (!TimeSpan.TryParse(EndTime, CultureInfo.InvariantCulture, out _endTime))
            {
                Print("Invalid end time input");

                Stop();
            }
        }

        protected override void OnBar()
        {
            // Return if current time is not in start/end time range
            if (!IsTimeCorrect) return;
        }
    }
}

Please take a look on Server.Time, Server.TimeInUtc, Application.UserTimeOffset, .NET TimeSpan, and DateTime.

If you know the C# basics and cTrader automate API references then you can easily do it.

 

 

I was able to play around with a few things last night and got the Trading Times to work, but it changed the rest of the code somehow and does not exit trades as it use to... not sure why and can't even determine what the exit reason even is anymore, seems to be exiting at random locations, there's no correlation between exits??


Either way, this is what it looks like now...

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 Tradinghours : Robot
    {

        [Parameter("Start Time", DefaultValue = 12)]
        public double StartTime { get; set; }

        [Parameter("Stop Time", DefaultValue = 14)]
        public double StopTime { get; set; }

        [Parameter("Source")]
        public DataSeries SourceSeries { get; set; }

        [Parameter("Label", DefaultValue = "EMA")]
        public string Label { get; set; }

        [Parameter("Slow Periods", DefaultValue = 233)]
        public int SlowPeriods { get; set; }

        [Parameter("Medium Periods", DefaultValue = 55)]
        public int MediumPeriods { get; set; }

        [Parameter("Fast Periods", DefaultValue = 21)]
        public int FastPeriods { get; set; }

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


        private ExponentialMovingAverage slowMa;
        private double _volumeInUnits;
        private ExponentialMovingAverage mediumMa;
        private ExponentialMovingAverage fastMa;
        private DateTime _startTime;
        private DateTime _stopTime;


        protected override void OnStart()
        {
            fastMa = Indicators.ExponentialMovingAverage(SourceSeries, FastPeriods);
            mediumMa = Indicators.ExponentialMovingAverage(SourceSeries, MediumPeriods);
            slowMa = Indicators.ExponentialMovingAverage(SourceSeries, SlowPeriods);
            _volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);
            _startTime = Server.Time.Date.AddHours(StartTime);
            _stopTime = Server.Time.Date.AddHours(StopTime);
        }


        protected override void OnBar()
        {
            {
                var currentHours = Server.Time.TimeOfDay.TotalHours;
                bool tradeTime = StartTime < StopTime ? currentHours > StartTime && currentHours < StopTime : currentHours < StopTime || currentHours > StartTime;
                if (!tradeTime)
                    return;
            }
            {
                int index = Bars.Count - 2;
                Entry(index);

                Exit(index);
            }
        }


        private void Exit(int index)
        {
            var positions = Positions.FindAll(Label);

            foreach (var position in positions)

                if ((position.TradeType == TradeType.Buy && Bars.ClosePrices[index] < mediumMa.Result[index]) || (position.TradeType == TradeType.Sell && Bars.ClosePrices[index] > mediumMa.Result[index]))

                    ClosePosition(position);
        }


        private void Entry(int index)
        {
            // Buy Only
            if (Bars.ClosePrices[index] > slowMa.Result[index])
            {
                // if fast crosses medium upward
                if (fastMa.Result[index] > mediumMa.Result[index] && fastMa.Result[index - 1] < mediumMa.Result[index - 1])
                {
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label);
                }
            }
            // Sell only
            else if (Bars.ClosePrices[index] < slowMa.Result[index])
            {
                // if fast crosses medium downward
                if (fastMa.Result[index] < mediumMa.Result[index] && fastMa.Result[index - 1] > mediumMa.Result[index - 1])
                {
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label);
                }
            }
        }
    }
}


@thecaffeinatedtrader

amusleh
07 Apr 2021, 11:08

Hi,

Please use my sample code for adding time range on your cBot, your cBot code is not correct and it even doesn't compile.

Next time you post code use the editor code snippet feature.

I recommend you to study C# basic and API references.

I consider this thread closed, we can't develop your cBot for you, all you need is already posted.


@amusleh

thecaffeinatedtrader
07 Apr 2021, 16:00

RE:

amusleh said:

Hi,

Please use my sample code for adding time range on your cBot, your cBot code is not correct and it even doesn't compile.

Next time you post code use the editor code snippet feature.

I recommend you to study C# basic and API references.

I consider this thread closed, we can't develop your cBot for you, all you need is already posted.

 

 

 

Thanks for your help, I was able to figure it out last night... I needed to change a part from    Void Onbar    to    Void Entry   ... it is running perfectly now.. 


I do want to add more to it where I would have 3 separate time parameters..

1.    2 - 4 am EST

2.    8 - 10 am EST

3.    7 - 9 pm EST

This I am not sure yet how to do yet.. I can get the Parameters to show up, but it does not actually pick up those times in the data set compiled after running it. 


@thecaffeinatedtrader