17 using System.Collections.Generic;
18 using System.Globalization;
19 using Newtonsoft.Json.Converters;
44 public static readonly DateTime
EndOfTime =
new DateTime(2050, 12, 31);
54 public static readonly DateTime
Start =
new DateTime(1998, 1, 2);
68 public static readonly TimeSpan
MaxTimeSpan = TimeSpan.FromDays(1000*365);
74 public static readonly TimeSpan
OneYear = TimeSpan.FromDays(365);
79 public static readonly TimeSpan
OneDay = TimeSpan.FromDays(1);
84 public static readonly TimeSpan
OneHour = TimeSpan.FromHours(1);
89 public static readonly TimeSpan
OneMinute = TimeSpan.FromMinutes(1);
94 public static readonly TimeSpan
OneSecond = TimeSpan.FromSeconds(1);
99 public static readonly TimeSpan
OneMillisecond = TimeSpan.FromMilliseconds(1);
106 private readonly DateTime utcDateTime;
107 private readonly TimeZoneInfo timeZone;
116 utcDateTime = TimeZoneInfo.ConvertTimeToUtc(dateTime, timeZone);
117 this.timeZone = timeZone;
130 public TimeZoneInfo
TimeZone {
get {
return timeZone; } }
140 return TimeZoneInfo.ConvertTime(utcDateTime, timeZone);
145 private static readonly DateTime EpochTime =
new DateTime(1970, 1, 1, 0, 0, 0, 0);
146 private const long SecondToMillisecond = 1000;
181 return DateTime.UtcNow.GetSecondUnevenWait(waitTimeMillis);
194 var wakeUpTime = now.AddMilliseconds(waitTimeMillis);
195 if (wakeUpTime.Millisecond < 100 || wakeUpTime.Millisecond > 900)
198 var offsetMillis = waitTimeMillis >= 1000 ? 500 : 100;
199 return waitTimeMillis + offsetMillis;
201 return waitTimeMillis;
214 var ticks = unixTimeStamp * TimeSpan.TicksPerSecond;
215 time = EpochTime.AddTicks((
long)ticks);
217 catch (Exception err)
219 Log.
Error(err, Invariant($
"UnixTimeStamp: {unixTimeStamp}"));
258 var ticks = Math.Ceiling(unixTimeStamp * TimeSpan.TicksPerMillisecond);
259 time = EpochTime.AddTicks((
long)ticks);
261 catch (Exception err)
263 Log.
Error(err, Invariant($
"UnixTimeStamp: {unixTimeStamp}"));
279 var ticks = unixTimeStamp / 100;
280 time = EpochTime.AddTicks(ticks);
282 catch (Exception err)
284 Log.
Error(err, Invariant($
"UnixTimeStamp: {unixTimeStamp}"));
297 double timestamp = 0;
300 timestamp = (time -
new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds;
302 catch (Exception err)
304 Log.
Error(err, Invariant($
"{time:o}"));
316 double timestamp = 0;
319 timestamp = (time -
new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds;
321 catch (Exception err)
323 Log.
Error(err, Invariant($
"{time:o}"));
338 timestamp = (time -
new DateTime(1970, 1, 1, 0, 0, 0, 0)).Ticks * 100;
340 catch (Exception err)
342 Log.
Error(err, Invariant($
"{time:o}"));
359 public static TimeSpan
Max(TimeSpan one, TimeSpan two)
361 return TimeSpan.FromTicks(Math.Max(one.Ticks, two.Ticks));
367 public static TimeSpan
Min(TimeSpan one, TimeSpan two)
369 return TimeSpan.FromTicks(Math.Min(one.Ticks, two.Ticks));
375 public static DateTime
Max(DateTime one, DateTime two)
377 return one > two ? one : two;
383 public static DateTime
Min(DateTime one, DateTime two)
385 return one < two ? one : two;
394 public static TimeSpan
Multiply(
this TimeSpan interval,
double multiplier)
396 return TimeSpan.FromTicks((
long) (interval.Ticks * multiplier));
410 if (DateTime.TryParseExact(dateToParse,
DateFormat.
SixCharacter, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
414 if (DateTime.TryParseExact(dateToParse,
DateFormat.
EightCharacter, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
418 if (DateTime.TryParseExact(dateToParse,
DateFormat.
TwelveCharacter, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
422 if (DateTime.TryParseExact(dateToParse.SafeSubstring(0, 19),
DateFormat.
JsonFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
426 if (DateTime.TryParseExact(dateToParse,
DateFormat.
USShort, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
430 if (DateTime.TryParseExact(dateToParse,
DateFormat.
USShortDateOnly, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
434 if (DateTime.TryParseExact(dateToParse,
DateFormat.
US, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
438 if (DateTime.TryParseExact(dateToParse,
DateFormat.
USDateOnly, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
442 if (DateTime.TryParse(dateToParse, out date))
447 catch (Exception err)
466 if (DateTime.TryParseExact(dateToParse,
DateFormat.
FIX, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
475 catch (Exception err)
480 return DateTime.UtcNow;
489 public static IEnumerable<DateTime>
DateTimeRange(DateTime from, DateTime thru, TimeSpan step)
491 for (var dateTime = from; dateTime <= thru; dateTime = dateTime.Add(step))
492 yield
return dateTime;
501 public static IEnumerable<DateTime>
EachDay(DateTime from, DateTime thru)
503 return DateTimeRange(from.Date, thru.Date, TimeSpan.FromDays(1));
514 public static IEnumerable<DateTime>
EachTradeableDay(ICollection<Security> securities, DateTime from, DateTime thru)
516 for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
534 public static IEnumerable<DateTime>
EachTradeableDay(
Security security, DateTime from, DateTime thru,
bool extendedMarketHours =
false)
549 for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
551 if (exchange.
IsDateOpen(day, extendedMarketHours))
573 var currentExchangeTime = from;
574 thru = thru.Date.AddDays(1);
575 while (currentExchangeTime < thru)
578 var currentInTimeZone = currentExchangeTime.ConvertTo(exchange.
TimeZone, timeZone);
579 var currentInTimeZoneEod = currentInTimeZone.Date.AddDays(1);
581 var currentExchangeTimeEod = currentInTimeZoneEod.ConvertTo(timeZone, exchange.
TimeZone);
584 if (currentExchangeTimeEod > thru)
586 currentExchangeTimeEod = thru;
590 if (exchange.
IsOpen(currentExchangeTime, currentExchangeTimeEod, includeExtendedMarketHours))
592 yield
return currentInTimeZone.Date;
595 currentExchangeTime = currentExchangeTimeEod;
605 public static bool TradableDate(IEnumerable<Security> securities, DateTime day)
609 foreach (var security
in securities)
611 if (security.Exchange.DateIsOpen(day.Date))
return true;
614 catch (Exception err)
629 public static int TradeableDates(ICollection<Security> securities, DateTime start, DateTime finish)
632 Log.
Trace(Invariant($
"Time.TradeableDates(): {Messages.Time.SecurityCount(securities.Count)}"));
635 foreach (var day
in EachDay(start, finish))
643 catch (Exception err)
662 bool extendedMarketHours, DateTimeZone dataTimeZone,
bool dailyPreciseEndTime =
false)
664 if (barSize <= TimeSpan.Zero)
670 if (dailyPreciseEndTime && barSize ==
OneDay)
676 current = end.RoundDownInTimeZone(barSize, exchangeHours.
TimeZone, dataTimeZone);
685 current = end.RoundDownInTimeZone(barSize, exchangeHours.
TimeZone, dataTimeZone);
688 for (
int i = 0; i < barCount;)
690 var previous = current;
691 current = current - barSize;
692 if (exchangeHours.
IsOpen(current, previous, extendedMarketHours))
712 if (barSize <= TimeSpan.Zero)
720 for (
int i = 0; i < barCount;)
722 current = current +
OneDay;
732 for (
int i = 0; i < barCount;)
734 var previous = current;
735 current = current + barSize;
736 if (exchangeHours.
IsOpen(previous, current, extendedMarketHours))
754 if (barSize <= TimeSpan.Zero)
763 while (current < end)
770 current = current +
OneDay;
776 while (current < end)
778 var previous = current;
779 current = current + barSize;
780 if (exchangeHours.
IsOpen(previous, current,
false))
801 if (period == TimeSpan.Zero)
803 return start == current ? 1 : 0;
806 var delta = (current - start).TotalSeconds;
807 return delta / period.TotalSeconds;
819 if (period == TimeSpan.Zero)
824 return stepSize.TotalSeconds / period.TotalSeconds;
832 public static TimeSpan
Abs(
this TimeSpan timeSpan)
834 return TimeSpan.FromTicks(Math.Abs(timeSpan.Ticks));
847 DateTimeFormat =
@"MM/yy";