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>
EachDay(DateTime from, DateTime thru)
491 for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
503 public static IEnumerable<DateTime>
EachTradeableDay(ICollection<Security> securities, DateTime from, DateTime thru)
505 for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
537 for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
561 var currentExchangeTime = from;
562 thru = thru.Date.AddDays(1);
563 while (currentExchangeTime < thru)
566 var currentInTimeZone = currentExchangeTime.ConvertTo(exchange.
TimeZone, timeZone);
567 var currentInTimeZoneEod = currentInTimeZone.Date.AddDays(1);
569 var currentExchangeTimeEod = currentInTimeZoneEod.ConvertTo(timeZone, exchange.
TimeZone);
572 if (currentExchangeTimeEod > thru)
574 currentExchangeTimeEod = thru;
578 if (exchange.
IsOpen(currentExchangeTime, currentExchangeTimeEod, includeExtendedMarketHours))
580 yield
return currentInTimeZone.Date;
583 currentExchangeTime = currentExchangeTimeEod;
593 public static bool TradableDate(IEnumerable<Security> securities, DateTime day)
597 foreach (var security
in securities)
599 if (security.Exchange.DateIsOpen(day.Date))
return true;
602 catch (Exception err)
617 public static int TradeableDates(ICollection<Security> securities, DateTime start, DateTime finish)
620 Log.
Trace(Invariant($
"Time.TradeableDates(): {Messages.Time.SecurityCount(securities.Count)}"));
623 foreach (var day
in EachDay(start, finish))
631 catch (Exception err)
650 if (barSize <= TimeSpan.Zero)
652 throw new ArgumentException(
Messages.
Time.InvalidBarSize, nameof(barSize));
656 var current = end.RoundDownInTimeZone(barSize, exchangeHours.
TimeZone, dataTimeZone);
657 for (
int i = 0; i < barCount;)
659 var previous = current;
660 current = current - barSize;
661 if (exchangeHours.
IsOpen(current, previous, extendedMarketHours))
681 if (barSize <= TimeSpan.Zero)
683 throw new ArgumentException(
Messages.
Time.InvalidBarSize, nameof(barSize));
689 for (
int i = 0; i < barCount;)
691 current = current +
OneDay;
701 for (
int i = 0; i < barCount;)
703 var previous = current;
704 current = current + barSize;
705 if (exchangeHours.
IsOpen(previous, current, extendedMarketHours))
723 if (barSize <= TimeSpan.Zero)
725 throw new ArgumentException(
Messages.
Time.InvalidBarSize, nameof(barSize));
732 while (current < end)
739 current = current +
OneDay;
745 while (current < end)
747 var previous = current;
748 current = current + barSize;
749 if (exchangeHours.
IsOpen(previous, current,
false))
770 if (period == TimeSpan.Zero)
772 return start == current ? 1 : 0;
775 var delta = (current - start).TotalSeconds;
776 return delta / period.TotalSeconds;
788 if (period == TimeSpan.Zero)
793 return stepSize.TotalSeconds / period.TotalSeconds;
801 public static TimeSpan
Abs(
this TimeSpan timeSpan)
803 return TimeSpan.FromTicks(Math.Abs(timeSpan.Ticks));
816 DateTimeFormat =
@"MM/yy";