简体   繁体   中英

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM