Inconsistent TimeZone Functionality

Created at 09 Sep 2013, 23:24
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!
lec0456's avatar

lec0456

Joined 14.11.2012

Inconsistent TimeZone Functionality
09 Sep 2013, 23:24


Ok, so here is a problem I have been trying to describe for a long time.

Here is a test Robot:

//#reference: C:\Users\lcespedes\Documents\cAlgo\Sources\Indicators\MarketHours.algo
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.EEuropeStandardTime)]
    public class TimeZoneTest : Robot
    {

        private MarketHours markethours;


        protected override void OnStart()
        {
            markethours = Indicators.GetIndicator<MarketHours>();
        }


        protected override void OnBar()
        {
            int t0 = MarketSeries.Close.Count - 1;
            //** t0 results are not final because the bar has not completed
            int t1 = t0 - 1;

            if (t1 < 0)return;

//** Day End Processes Start			
            if (markethours.NewYork[t1] == 1655)
            {
                Print("New Day*****" + Server.Time.ToString("MM/dd/yyyy HH:mm") + "*****");
                Print(Server.Time.Kind);
            }
//** Day End Processes Start
        }
    }
}

It uses an indicator I posted here:

/algos/indicators/show/235

There is some strange behavior here. First, no matter If you change the timezone of the robot the new day occurs at the same time.  Second, if you leave the print statement in the indicator.  You will see that the time.Kind property starts out as unspecified and then changes to UTC no matter if the robot is using another time zone.

This is not the behavior I expect.  I expect that when robot time is set to UTC new day is at 21:00 ; If set to E.Europe new day should be 00:00.

So, please let me know whats going on here.  Thanks!

 


@lec0456
Replies

cAlgo_Development
10 Sep 2013, 14:25

First, no matter If you change the timezone of the robot the new day occurs at the same time....

This is not the behavior I expect.  I expect that when robot time is set to UTC new day is at 21:00 ; If set to E.Europe new day should be 00:00.

Yes, new day starts at 17:00 EST. Time offset that trader chooses on main window status-bar and robot's timezone do not affect trend-bar aggregation rules.

 

You will see that the time.Kind property starts out as unspecified and then changes to UTC no matter if the robot is using another time zone.

This is very strange. Sounds like a bug, we will investigate this.


@cAlgo_Development

lec0456
10 Sep 2013, 17:54

ok, I'm glad you will investigate.  However, for the first behavior I described.  And Time one behavior is a little hard to explain so let me go slowly.

True, a new day starts at 17:00EST or 21;00UTC or 00:00EEST.  However, the robot will print out the new day as 21:00 no matter what time zone you set the robot.  

So, in my opinion what seems to be happpening is that the indicator is reverting to using UTC time no matter what the robot says.  And that would be consistent with the behavior of the Kind property.


@lec0456

lec0456
12 Sep 2013, 14:09

I hope you will have an answer for this soon! Its extremely important to have the time working properly within indicators and robots. and between indicators and robots.


@lec0456

lec0456
13 Sep 2013, 22:00

Any ETA on this issue?


@lec0456

lec0456
15 Sep 2013, 04:12

BTW, the robot is expecting to be run on a 5min time frame.  Thats why it tests the previous bar for 16:55 before indicating a new day


@lec0456

lec0456
15 Sep 2013, 22:51

protected override void OnStart()
        {
            markethours = Indicators.GetIndicator<MarketHours>();
            
            var attribute = (IndicatorAttribute)typeof(MarketHours).GetCustomAttributes(typeof(IndicatorAttribute), false)[0];
            //BrokerTimeZone = TimeZoneInfo.FindSystemTimeZoneById(attribute.TimeZone);
            BrokerTimeZone = TimeZoneInfo.FindSystemTimeZoneById("E. Europe Standard Time");
            Print("RobotTimeZone Setting: {0}", attribute.TimeZone);
            Print("RobotTimeZone Name: {0}", BrokerTimeZone.DisplayName);
            Print("Offset: {0}", BrokerTimeZone.BaseUtcOffset);
            Print("DST: {0}", BrokerTimeZone.SupportsDaylightSavingTime);

        }

I Inserted the above code and it shows that the attribute.TimeZone property is returning UTC no matter what the robot is set to!!!!!


@lec0456

cAlgo_Development
17 Sep 2013, 12:33

Second, if you leave the print statement in the indicator.  You will see that the time.Kind property starts out as unspecified and then changes to UTC no matter if the robot is using another time zone.

We've investigated your case. The problem is that your indicator is used inside a robot so robot's timezone is applied to it. This behavior is described here. When indicator is added directly to a chart UTC timezone is used so DateTime.Kind is UTC.

 

I Inserted the above code and it shows that the attribute.TimeZone property is returning UTC no matter what the robot is set to!!!!!

When you use typeof(MarketHours).GetCustomAttributes() you get timezone that is declared at specified type (MarketHours indicator in this case) but not the timezone that is currently used.

Our solution that we will provide in future is TimeZone property that will be available from both robots and indicators and will contain currently used timezone.


@cAlgo_Development

lec0456
17 Sep 2013, 17:25

I'm getting different behavior depending if I test the robot in real-time or backtested.


@lec0456

lec0456
17 Sep 2013, 19:21 ( Updated at: 21 Dec 2023, 09:20 )

I created a robot to test this and the indicator is not inheriting the timezone from the robot.  In this example, the robot is starting the day at 17:00 and the indicator is starting the new day at 21:00

Here is the code:

//#reference: C:\Users\lcespedes\Documents\cAlgo\Sources\Indicators\MarketHours.algo
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.EasternStandardTime)]
    public class TimeZoneTest : Robot
    {

        private MarketHours markethours;
        private TimeZoneInfo BrokerTimeZone;


        protected override void OnStart()
        {
            markethours = Indicators.GetIndicator<MarketHours>();
            
            var attribute = (RobotAttribute)typeof(TimeZoneTest).GetCustomAttributes(typeof(RobotAttribute), false)[0];
            BrokerTimeZone = TimeZoneInfo.FindSystemTimeZoneById(attribute.TimeZone);
            //BrokerTimeZone = TimeZoneInfo.FindSystemTimeZoneById("E. Europe Standard Time");
            Print("RobotTimeZone Setting: {0}", attribute.TimeZone);
            Print("RobotTimeZone Name: {0}", BrokerTimeZone.DisplayName);
            Print("Offset: {0}", BrokerTimeZone.BaseUtcOffset);
            Print("DST: {0}", BrokerTimeZone.SupportsDaylightSavingTime);
        }
 
 
        protected override void OnBar()
        {
            int t0 = MarketSeries.Close.Count - 1;
            //** t0 results are not final because the bar has not completed
            int t1 = t0 - 1; 
 
            if (t1 < 0)return;

            DateTime BrokerTime = DateTime.SpecifyKind(MarketSeries.OpenTime[t0],DateTimeKind.Unspecified);
            TimeZoneInfo NYTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
            DateTime NYTime = TimeZoneInfo.ConvertTime(BrokerTime, BrokerTimeZone, NYTimeZone);
            double NYValue = (NYTime.Hour * 100) + NYTime.Minute;
            
//** Day End Processes Start
            if (NYValue==1700){
            Print("BrokerTime: {0} , NYTime: {1}", BrokerTime, NYTime);
            Print("Robot New Day****" + Server.Time.ToString("MM/dd/yyyy HH:mm") + "*****");}
            
            if (markethours.NewYork[t1] == 1655)
            {
                Print(NYValue);
                Print("Indicator New Day*****" + Server.Time.ToString("MM/dd/yyyy HH:mm") + "*****");
                Print(Server.Time.Kind);
            }
//** Day End Processes Start
        }
    }
}

Please let me know whats going on...


@lec0456

Spotware
11 Nov 2013, 15:22

We've implemented new property in both Robot and Indicator classes: TimeZone. Instead of getting timezone from attribute you can use it;

        protected override void OnStart()
        {
            Print("RobotTimeZone Setting: {0}", TimeZone);
            Print("RobotTimeZone Name: {0}", TimeZone.DisplayName);
            Print("Offset: {0}", TimeZone.BaseUtcOffset);
            Print("DST: {0}", TimeZone.SupportsDaylightSavingTime);
        }

Moreover, in nested indicators that inherit timezone from robot TimeZone property returns actual inherited timezone.

Please check new release of Spotware cAlgo (1.12).


@Spotware

lec0456
11 Nov 2013, 22:21

Beautiful!


@lec0456