Time between interval for trading sessions - c#

I'm having trouble figuring out which tradings session any particular time is in.
There are four possible sessions, show in this picture taken from ForexFactory.com
I have this method that I need to check is currentTime is during the specified trading session.
public bool IsTradingSession(TradingSession tradingSession, DateTime currentTime)
{
//Regular session is 5PM - next day 5PM, this is the session in the picture.
//Irregular sessions also occur for example late open (3AM - same day 5PM) or early close (5PM - next day 11AM)
DateTime sessionStart = Exchange.CurrentSessionOpen;
DateTime sessionEnd = Exchange.CurrentSessionClose;
if(tradingSession == TradingSession.Sydney)
return ....... ? true : false;
if(tradingSession == TradingSession.Tokyo)
return ....... ? true : false;
if(tradingSession == TradingSession.London)
return ....... ? true : false;
if (tradingSession == TradingSession.NewYork)
return ....... ? true : false;
return false;
}
Use:
bool isSydneySession = IsTradingSession(TradingSession.Sydney, CurrentTime);
bool isTokyoSession = IsTradingSession(TradingSession.Tokyo, CurrentTime);
bool isLondonSession = IsTradingSession(TradingSession.London, CurrentTime);
bool isNewYorkSession = IsTradingSession(TradingSession.NewYork, CurrentTime);
Thanks for any help

First you need the datasource of the DateTimes (start and end) for each market. Then,
based on the argument currentTime you can check if it lies within by doing a simple check like:
if (currentTime.Ticks >= marketOpen.Ticks && currentTime.Ticks <= marketClose.Ticks)
{
//Market is open!
}
The above is the assumption that currentTime is in the same timezone as the market. If it's not, then I'd suggest converting all times in question to UTC so there is no question of whether you have the right timezone.

Related

How to compare and validate 2 times with 2 dates in MVC C#?

How to compare and validate two times?
My scenario is I need to add various schedules. Assume that person 1 has schedules on today 18/08/2017 as Sch1: 0800-1600 and sch2:2200-0600 that is sch1 starts and ends on same daywhereassch2 starts on 18/08/2017 and ends on 19/08/2017 6am.
Now when I try to edit Schedule end time, I want to add 2 validations that schedule end time must be greater than start time and also must be greater than current system time. How to validate these two ? When I add validation then end time after 24 hrs, it takes 19/08/2017's 1am,2am,3am as less than value of 18/08/2017's 2000,2100(8pm,9pm).
My coding for validation below
if ( D.ScheduleEndTime != T.EndTime && D.ScheduleEndTime < Time)
{
return Json(new { success = "fail", message = "End Time must be greater than current time!!!" }, JsonRequestBehavior.AllowGet);
}
else if (D.ScheduleEndTime != T.EndTime && D.ScheduleEndTime < T.StartTime)
{
return Json(new { success = "fail", message = "End Time must be greater than start time!!!" }, JsonRequestBehavior.AllowGet);
}
In the above code D&T. D means values that entered while editing and T means values from Table in database
You didn't give any information on the data types you are using but sounds like you are using a custom date-time object rather than the datetime data type?
So each of your custom date-time objects have something similar to the following structure:
custom_datetime:
- string Date (ie: 18/08/2017)
- int startTime (ie: 2200)
- int endTime (ie: 0600)
In that case, it would be something like this maybe...
// Temp variable to manipulate, instantiated to passed in custom_datetime D.
custom_datetime temp = D;
// First check if the passed in date time is different than date time stored
if ((temp.Date != T.Date) || ((temp.Date == T.Date) && (temp.endTime != T.endTime))) {
// Then check if the endTime is less than the startTime
// If it is, then the end time is the next day so increment the date in temp variable. Now use temp variable to do rest of the checks.
if (temp.endTime < temp.startTime) {
temp.Date++; // Increment to next day, so 18/08/2017 becomes 19/08/2017
}
//Check if passed in date < stored date, if it is, then it will also be less than startTime so return error.
if (temp.Date < T.Date) {
return Json(new { success = "fail", message = "End Time must be greater than current time!!!" }, JsonRequestBehavior.AllowGet);
}
//Check if the passed in date is the same as the stored date. If it is, make sure the endTime is greater than the stored startTime
else if ((temp.Date == T.Date) && (temp.endTime <= T.startTime)) {
return Json(new { success = "fail", message = "End Time must be greater than current time!!!" }, JsonRequestBehavior.AllowGet);
}
//Check if the passed in date < current system date or if the passed in date == current system date but the endTime <= the current time.
else if ((temp.Date < Time.Date) || ((temp.Date == Time.Date) && (temp.endTime <= Time.Time)) {
return Json(new { success = "fail", message = "End Time must be greater than current time!!!" }, JsonRequestBehavior.AllowGet);
}
}
The code doesn't actually work, but hopefully it gives you an idea of something you can do. Need more information to give an exact answer.

What is the most efficient way to check that a given DateTime is on the hour?

I have System.DateTime object which I need to confirm is on the hour.
So what would be the most efficient way of checking this?
The current solution that I have thought of involves converting the object ToString() and obtaining the minutes/seconds section to see if they equal zero. If there are easier ways to do this I would appreciate suggestions!
DateTime has minute and seconds properties, you could directly check that, no need to convert. You could do the same for milliseconds, if that is relevant to you.
You could go this way with highest accuracy.
if(date.Ticks % TimeSpan.TicksPerHour == 0)
My personal solution would be to create a new DateTime which is on the hour and compare it with the one I wish to check, something like:
public bool IsOnHour(DateTime dateTime)
{
var onHour = dateTime.Date + TimeSpan.FromHours(dateTime.Hour);
return onHour == dateTime;
}
Then I don't need to check the Minutes, Seconds, Milliseconds etc.
Try following .
var dt = new DateTime();
if (dt.Minute == 0 && dt.Second == 0 && dt.Millisecond == 0)
Here's a programatic way:
DateTime min = new DateTime(value.Year, value.Month, value.Day, value.Hour, 0, 0);
DateTime max = min.AddMinutes(1);
if (min <= value && value < max)
This intentionally looses precision so that 12:59:00.000 is the same as 12:59:27.198.
You can use this: if(DateTime.Now.Minute == 0 && DateTime.Now.Second == 0 && DateTime.Now.Millisecond == 0)
Edit: comments

Difficulty comparing differences in DateTimes

I have a DateTime variable called "lastActivated", that is set to DateTime.Now when the Form_Activated event fires. The goal is to make sure something doesn't happen within the first 1 second of a user clicking the screen from another screen.
DateTime? lastActivate = null; //used to determine the last time the screen was focused.
private void Form1_Activated(object sender, EventArgs e)
{
lastActivate = DateTime.Now;
}
The code for determining whether it has been longer than 1 second looks like
TimeSpan oneSec = new TimeSpan(0,0,1);
if (lastActivate == null || (TimeSpan)(lastActivate - DateTime.Now) > oneSec)
{
//stuff
}
The above if statement always, ALWAYS fails. Even when the values are:
lastActivate {11/30/2013 10:23:21 AM} System.DateTime?
now {11/30/2013 10:32:48 AM} System.DateTime
(I made a temp value DateTime now = DateTime.Now so I could paste the value here, since I couldn't directly access DateTime.Now's value)
Does anyone have any suggestions on what I'm doing wrong, and what I should change to get it to accomplish the goal I am after?
Thanks!
You can test the time between two dates by doing this:
var lastActivated = DateTime.Now;
if (DateTime.Now.Subtract(lastActivated).TotalSeconds > 1)
{
// Do whatever you need.
}
DateTime.Subtract(DateTime) returns a TimeSpan of the time difference between the two given dates.
Last active date is less than current time, you should subtract it from current time:
if (!lastActivate.HasValue || (DateTime.Now - lastActivate.Value).TotalSeconds > 1)
{
//stuff
}
Problem : You are subtracting in reverse order, you should subtract the lastActivate Time from the current Time(DateTime.Now).
otherwise you will always get -ve value when you subtract DateTime.Now from lastActivate as lastActivate time is always less than the Current Time (DateTime.Now).
Solution :
This:
(TimeSpan)(lastActivate - DateTime.Now)
Should be :
(TimeSpan)(DateTime.Now - lastActivate)
Complete Code:
TimeSpan oneSec = new TimeSpan(0,0,1);
if (lastActivate == null || (TimeSpan)(DateTime.Now - lastActivate) > oneSec)
{
//stuff
}

Determine if current time between multiple time spans

I'm having trouble figuring out which tradings session any particular time is in.
There are four possible sessions, show in this picture taken from ForexFactory.com
I have this method that I need to check is currentTime is during the specified trading session.
public bool IsTradingSession(TradingSession tradingSession, DateTime currentTime)
{
//currentTime is in local time.
//Regular session is 5PM - next day 5PM, this is the session in the picture.
//Irregular sessions also occur for example late open (3AM - same day 5PM) or early close (5PM - next day 11AM)
DateTime sessionStart = Exchange.ToLocalTime(Exchange.CurrentSessionOpen);
DateTime sessionEnd = Exchange.ToLocalTime(Exchange.CurrentSessionClose);
if(tradingSession == TradingSession.Sydney)
return ....... ? true : false;
if(tradingSession == TradingSession.Tokyo)
return ....... ? true : false;
if(tradingSession == TradingSession.London)
return ....... ? true : false;
if (tradingSession == TradingSession.NewYork)
return ....... ? true : false;
return false;
}
Use:
bool isSydneySession = IsTradingSession(TradingSession.Sydney, CurrentTime);
bool isTokyoSession = IsTradingSession(TradingSession.Tokyo, CurrentTime);
bool isLondonSession = IsTradingSession(TradingSession.London, CurrentTime);
bool isNewYorkSession = IsTradingSession(TradingSession.NewYork, CurrentTime);
Thank you
I'd suggest writing a simple function for each trading session, which takes a DateTime and returns a bool indicating if it's open at that time.
var sydneyOpen = new TimeSpan(17, 0, 0);
var sydneyClose = new TimeSpan(2, 0, 0);
Func<DateTime, bool> isOpenInSydney = d =>
(d.TimeOfDay > sydneyOpen || d.TimeOfDay < sydneyClose);
// same for other markets, write a function to check against two times
Then place these into a Dictionary<TradingSession, Func> like this for generic retrieval...
var marketHours = new Dictionary<TradingSession, Func<DateTime, bool>>();
marketHours.Add(TradingSession.Sydney, isOpenInSydney);
// add other markets...
And then your existing method simply selects the appropriate function for the given TradingSession and applies it
public bool IsTradingSession(TradingSession tradingSession, DateTime currentTime)
{
var functionForSession = marketHours[tradingSession];
return functionForSession(currentTime);
}
I don't believe you need UTC time here as long as your application only runs in a single timezone, but daylight savings might cause problems.
A nice way to account for the problem of trading sessions which cover two days, as opposed to just one day, is to write a helper that precisely considers whether it's a 'cross-day' trading session and applies a different rule for you:
private bool IsBetween(DateTime now, TimeSpan open, TimeSpan close)
{
var nowTime = now.TimeOfDay;
return (open < close
// if open is before close, then now must be between them
? (nowTime > open && nowTime < close)
// otherwise now must be *either* after open or before close
: (nowTime > open || nowTime < close));
}
and then
var sydneyOpen = new TimeSpan(17, 0, 0);
var sydneyClose = new TimeSpan(2, 0, 0);
Func<DateTime, bool> isOpenInSydney = d => IsBetween(d, sydneyOpen, sydneyClose);
You can compare with > & < or compare ticks.
See related questions: Check if datetime instance falls in between other two datetime objects
To avoid the multiple if statements, you could also create a TradingSession object with start and end time and define a property/function to check if in session. When I have big switch or if blocks, it usually indicates a missed OO opportunity :)
TradingSession sydneySession = new TradingSession
{
StartTimeUtc = ...;
EndTimeUtc = ...;
}
The trading session object could then have a property IsInSession.
public bool IsInSession
{
get {
return DateTime.UTCNow >= StartTimeUtc && DateTime.UTCNow <= EndTimeUtc;
}
}
This uses UTC time to eliminate time zone issues.
You need to normalize your local times to UTC. You can then compare times across regions.
For each trading session, you need to know the session start and end time in UTC.
You need the current time in UTC. DateTime.UtcNow, for example.
You can then perform range comparisons for each trading session window:
if(tradingSession == TradingSession.Sydney)
return currentTimeUtc >= sydneyStartTimeUtc && currentTimeUtc <= sydneyEndTimeUtc;
etc...
If you're trying to validate that a transaction time is valid for a transaction on a particular trading session, this will work fine.
If however you're trying to figure out what trading session a trade belongs to based on its time, you will have multiple answers sometimes because the trading sessions overlap. Multiple trading sessions may be valid for a given time.

Algorithm to check whether a certain hour falls into a given time period

Assume I've got a start and stop hour in which some processing should take place:
Start 20:00
End 07:00
Now what is the best algorithm to check if a certain DateTime hour value falls within this range? Thanks in advance!
Please note that the start and end times mentioned above indicate that we are dealing with an "overnight-job". Meaning that the period to be checked starts at 20:00 in the evening and ends at 07:00 on the following morning.
Assume you only have the time and not the date.
if end_time >= start_time:
return start_time <= current_time <= end_time
else:
return start_time <= current_time or current_time <= end_time
If you are sure it is in the same day
you also do not seem to care for seconds
Transform everything in minutes
startminute = 20 * 60 + 0
endminute = 7 * 60 + 0
eventminute = x * 60 + y // with event having the form xx:yy
return startminute < eventminute && eventminute < endminute
Another option would be to get the 3 times in DateTime format
DateTime start, end, event
return (start < event && event < end);
Assuming you have a start, end and now DateTime, you could use
bool within = start.TimeOfDay.TotalHours <= now.TimeOfDay.TotalHours &&
now.TimeOfDay.TotalHours <= end.TimeOfDay.TotalHours;
Without knowing how to do it in C#, I'd go with converting start and end time to a timestamp and then do a simple if (end time >= given time AND start time <= given time) comparison. Maybe that'll get you started or give you a hint what to search for.
I think c# supports greater than/less than operators for DateTime variables, so just say
if ((beginDateTime<myDateTime)&&(myDateTime<endDateTime))
{
...
}
Also greater than or equal to and less than or equal to are supported.
With an overnight window, I don't think there's anything particularly clever to be done except to directly check your DateTime's TimeOfDay against the boundaries:
using System;
namespace Question2355777
{
class Program
{
private static bool IsInOvernightWindow(
DateTime dateTimeUnderTest,
TimeSpan morningEnd,
TimeSpan eveningStart)
{
TimeSpan timeOfDay = dateTimeUnderTest.TimeOfDay;
return timeOfDay <= morningEnd || timeOfDay >= eveningStart;
}
static void Main(string[] args)
{
TimeSpan eveningStart = TimeSpan.FromHours(20);
TimeSpan morningEnd = TimeSpan.FromHours(7);
Console.WriteLine("{0} {1}",
DateTime.Today.AddHours(3),
IsInOvernightWindow(
DateTime.Today.AddHours(3),
morningEnd,
eveningStart));
Console.WriteLine("{0} {1}",
DateTime.Today.AddHours(12),
IsInOvernightWindow(
DateTime.Today.AddHours(12),
morningEnd,
eveningStart));
Console.WriteLine("{0} {1}",
DateTime.Today.AddHours(21),
IsInOvernightWindow(
DateTime.Today.AddHours(21),
morningEnd,
eveningStart));
Console.ReadLine();
}
}
}
produces
01/03/2010 03:00:00 True
01/03/2010 12:00:00 False
01/03/2010 21:00:00 True
// initializing with some sample values
TimeSpan start = TimeSpan.FromHours(20);
TimeSpan end = TimeSpan.FromHours(7);
DateTime now = DateTime.Now.TimeOfDay;
return start<end
? start <= now.TotalHours && now.TotalHours <= end
: start <= now.TotalHours || now.TotalHours <= end;
Use the TimeOfDay method:
DateTime dtStart = new DateTime(0,0,0,20,0,0);
DateTime dtEnd = new DateTime(0,0,0,7,0,0);
if (DateTime.Now.TimeOfDay < dtEnd.TimeOfDay || DateTime.Now.TimeOfDay > dtStart.TimeOfDay)
{
// your code here
}
Count all the times in units of minutes beginning from the start day.
struct DateTime {
uint_8 hour_;
uint_8 minute_;
};
bool
isTimeWithin( DateTime start, DataTime stop, DateTime query ) {
// The following times are counted from the beginning of start day
uint_16 startInMins = (60 * start.hour_ + start.minute_);
// Added 24*60 since "stop" is always "overnight" from "start"
uint_16 stopInMins = 24 * 60 + (60 * stop.hour_ + stop.minute_);
// The ternary operator checks whether "query" is in the same day as
// "start" or the next day
uint_16 queryInMins = (query.hour_ < start.hour_ ? 24 * 60 : 0 ) +
(60 * query.hour_ + query.minute_);
return ((startInMins <= queryInMins) && (queryInMins <= stopInMins));
}
EDIT: Improved Formatting.
if ALL you have are those values for start and stop, don't you have an empty set?
Ignore the obvious assumption - start day X, end day X + Y.
[edit]
since the question has been edited, so shall be the answer....
for start time, end time and 'test' time get the number of milliseconds from the epoch (define that any way you would like)
and then check to see if test is >= start and <= end
[/edit]

Categories