ClickAlgo RM Friday Stop - error in code?

jani's avatar
Jan  since: 05 Apr 2019; 
 08 Nov 2019, 16:39
ClickAlgo RM Friday Stop - error in code?

Thank you  ClickAlgo for great code samples!

I'm starting to build a strategy Template by integrating    ClickAlgo School SMA & ClickAlgo RM Friday Stop together 

I have a question regarding ClickAlgo RM Friday Stop cBot (I'm very much a beginner in programming, so I just try to make sense of the code I see)

in The ClickAlgo RM Friday Stop there is code line:
 

// if the day is friday and the time is equal to the stop trading time, stop trading and close positions
                if (_tradingTime.DayOfWeek == DayOfWeek.Monday && _tradingTime.Hour == StopHour && _tradingTime.Minute >= StopMin)

Shouldn't it be:

 DayOfWeek.Friday

not 

DayOfWeek.Monday

?

also I would use:

_tradingTime.Hour >= StopHour

instead of:

_tradingTime.Hour == StopHour

.. in case there is a disconnect from server, VPS crash etc. anfd the stop hour is skipped somehow

Am I on the right track here...?

============================== ClickAlgo RM Friday Stop ======================================

#region Referenced assemblies

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System.Windows.Forms;
using System.Timers;

#endregion

//  
// Date: 27th February 2017
// Description: This cTrader algo file class shows how to stop a robot and close open positions at a set time on a Friday.  
//
// If you use a repository like Team Foundation Server (TFS) or GIT, you will not head any header comments.
//

namespace cAlgo
{
    // TimeZone attribute
    // All dates and times within the robot or indicator will be converted to this timezone

    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class RMFridayStop : Robot
    {
        #region Private variables

        private DateTime _tradingTime { get; set; }

        #endregion

        #region User defined parameters

        [Parameter("Stop Trading (hour)", DefaultValue = 17)]
        public int StopHour { get; set; }

        [Parameter("Stop Trading (min)", DefaultValue = 15)]
        public int StopMin { get; set; }

        [Parameter("Close all positions?", DefaultValue = false)]
        public bool IsCloseAllPositions { get; set; }

        [Parameter("Timer interval (seconds)", DefaultValue = 5)]
        public int TimerInterval { get; set; }

        #endregion

        #region cTrader events

        /// <summary>
        /// called when the robot first starts
        /// </summary>
        protected override void OnStart()
        {
            ConfigureTimer();

            // get the current time
            _tradingTime = TradingDateTime();

            if (this.IsBacktesting)
            {
                Print("Using server time for trading (UTC+0): " + _tradingTime.ToLongTimeString());
            }
            else
            {
                Print("Using PC time for trading: " + _tradingTime.ToLongTimeString());
            }

            var Account = this.Account;
        }

        /// <summary>
        /// called every incomming tick of data to the symbol, this can be many times per second or nothing for flat
        /// </summary>
        protected override void OnTick()
        {

        }

        /// <summary>
        /// called at the close of each candle (bar)
        /// if the time-frame is 1 hr. then it will be called each hour
        /// </summary>
        protected override void OnBar()
        {
        }

        /// <summary>
        /// called when the robot stops
        /// </summary>
        protected override void OnStop()
        {
        }

        #endregion

        #region Time validation logic

        /// <summary>
        /// returns server time if back-testing and local time if forward testing
        /// </summary>
        /// <returns></returns>
        public DateTime TradingDateTime()
        {
            if (this.IsBacktesting)
            {
                return Server.Time;
            }
            else
            {
                return TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.Local);
            }
        }

        /// <summary>
        /// Configures and starts the timer
        /// </summary>
        private void ConfigureTimer()
        {
            System.Timers.Timer fridayTimer = new System.Timers.Timer();
            fridayTimer.Interval = TimerInterval * 1000;
            // miliseconds
            fridayTimer.AutoReset = true;
            fridayTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

            // start the timer
            fridayTimer.Enabled = true;

            // timer has been declared at class level, it will not go out of scope, ONLY USE THIS FOR LONG RUNNING PROCESSES.
            // Keep the timer alive until the end, to prevent the JIT compiler from allowing 
            // aggressive garbage collection to occur before all the open positions are closed.
            GC.KeepAlive(fridayTimer);
        }

        /// <summary>
        /// this is called every 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnTimedEvent(object sender, ElapsedEventArgs e)
        {
            // get the current time
            _tradingTime = TradingDateTime();

            try
            {
                // if the day is friday and the time is equal to the stop trading time, stop trading and close positions
                if (_tradingTime.DayOfWeek == DayOfWeek.Monday && _tradingTime.Hour == StopHour && _tradingTime.Minute >= StopMin)
                {
                    CloseAllPositions();

                    // stop robot
                    this.Stop();
                }
            } catch (Exception ex)
            {
                // manage your exception here
                Print("Error: " + ex.Message);
            }
        }

        #endregion

        #region Position management

        /// <summary>
        /// In asynchronous operation, when a request is send to the server, the program continues to execute the next statements, without waiting for the response from the server.  
        /// The statements that follow the asynchronous trade operation request cannot assume anything about the result of those requests.  
        /// </summary>
        private void CloseAllPositions()
        {
            // if user has chosen to close all positions
            if (IsCloseAllPositions)
            {
                foreach (var position in Positions)
                {
                    ClosePositionAsync(position);
                }
            }
        }

        #endregion
    }
}
“If you love the sacred and despise the ordinary, you are still bobbing in the sea of delusion.” ― Línjì Yìxuán, 866 CE
ClickAlgo's avatar
Paul Hayes since: 05 Feb 2015; 
 08 Nov 2019, 20:41

Hi, Jan,

After 2-years you have found an obvious bug in the code, congratulations you have won a Willy-Wonka Golden ticket, you are quite right it should be DayOfWeek.Friday, we will update the source code and I would also use the _tradingTime.Hour >= StopHour

ps: I hope you like chocolate.

Paul.

~ Contact us for all your cBot & Indicator development ~
jani's avatar
Jan  since: 05 Apr 2019; 
 09 Nov 2019, 16:58
RE:

ClickAlgo said:

Hi, Jan,

After 2-years you have found an obvious bug in the code, congratulations you have won a Willy-Wonka Golden ticket, you are quite right it should be DayOfWeek.Friday, we will update the source code and I would also use the _tradingTime.Hour >= StopHour

ps: I hope you like chocolate.

Paul.

Cheers!! :)

Ps. Would be great if you could combine "RM Friday Stop"  and  "School SMA" bots. I tried to do this but was not sure how to call the RM Friday Stop functions on the School SMA bot...

I actually programmer Friday Stop and a daily stop timer to School SMA.algo, but in my code both timers are checked OnTick.  I think Friday stop would be fine ti check on a timer, for example, every minute or so, but daily stop/start timer, in my opinion, has to be checked OnTick if there is any entry logic that is checked/executed OnTick, right?

“If you love the sacred and despise the ordinary, you are still bobbing in the sea of delusion.” ― Línjì Yìxuán, 866 CE