parliament
parliament

Reputation: 22914

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

enter image description here

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

Upvotes: 4

Views: 2570

Answers (3)

Kirk Broadhurst
Kirk Broadhurst

Reputation: 28718

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);

Upvotes: 3

bryanmac
bryanmac

Reputation: 39296

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.

Upvotes: 2

dthorpe
dthorpe

Reputation: 36082

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.

Upvotes: 0

Related Questions