/// <summary> /// Updates the current time of this time keeper /// </summary> /// <param name="utcDateTime">The current time in UTC</param> internal void UpdateTime(DateTime utcDateTime) { // redefine the lazy conversion each time this is set _localTime = new Lazy<DateTime>(() => utcDateTime.ConvertTo(DateTimeZone.Utc, _timeZone)); if (TimeUpdated != null) { TimeUpdated(this, new TimeUpdatedEventArgs(_localTime.Value, TimeZone)); } }
/// <summary> /// Updates the current time of this time keeper /// </summary> /// <param name="utcDateTime">The current time in UTC</param> internal void UpdateTime(DateTime utcDateTime) { // redefine the lazy conversion each time this is set _localTime = new Lazy<DateTime>(() => utcDateTime.ConvertTo(DateTimeZone.Utc, _timeZone)); }
/// <summary> /// Initializes a new instance of the <see cref="LocalTimeKeeper"/> class /// </summary> /// <param name="utcDateTime">The current time in UTC</param> /// <param name="timeZone">The time zone</param> internal LocalTimeKeeper(DateTime utcDateTime, DateTimeZone timeZone) { _timeZone = timeZone; _localTime = new Lazy<DateTime>(() => utcDateTime.ConvertTo(DateTimeZone.Utc, _timeZone)); }
public void convert_datetime_to_datetimeoffset() { var dt = new DateTime(2000, 1, 1); dt.ConvertTo<DateTimeOffset>().Should().Be(new DateTimeOffset(dt)); }
/// <summary> /// Define an enumerable date range of tradeable dates but expressed in a different time zone. /// </summary> /// <remarks> /// This is mainly used to bridge the gap between exchange time zone and data time zone for file written to disk. The returned /// enumerable of dates is gauranteed to be the same size or longer than those generated via <see cref="EachTradeableDay(ICollection{Security},DateTime,DateTime)"/> /// </remarks> /// <param name="exchange">The exchange hours</param> /// <param name="from">The start time in the exchange time zone</param> /// <param name="thru">The end time in the exchange time zone (inclusive of the final day)</param> /// <param name="timeZone">The timezone to project the dates into (inclusive of the final day)</param> /// <param name="includeExtendedMarketHours">True to include extended market hours trading in the search, false otherwise</param> /// <returns></returns> public static IEnumerable<DateTime> EachTradeableDayInTimeZone(SecurityExchangeHours exchange, DateTime from, DateTime thru, DateTimeZone timeZone, bool includeExtendedMarketHours = true) { var currentExchangeTime = from; thru = thru.Date.AddDays(1); // we want to include the full thru date while (currentExchangeTime < thru) { // take steps of max size of one day in the data time zone var currentInTimeZone = currentExchangeTime.ConvertTo(exchange.TimeZone, timeZone); var currentInTimeZoneEod = currentInTimeZone.Date.AddDays(1); // don't pass the end if (currentInTimeZoneEod.ConvertTo(timeZone, exchange.TimeZone) > thru) { currentInTimeZoneEod = thru.ConvertTo(exchange.TimeZone, timeZone); } // perform market open checks in the exchange time zone var currentExchangeTimeEod = currentInTimeZoneEod.ConvertTo(timeZone, exchange.TimeZone); if (exchange.IsOpen(currentExchangeTime, currentExchangeTimeEod, includeExtendedMarketHours)) { yield return currentInTimeZone.Date; } currentExchangeTime = currentInTimeZoneEod.ConvertTo(timeZone, exchange.TimeZone); } }
public void ConvertTo_NullableDateTime_ReturnsValue() { DateTime? value = new DateTime(1900, 1, 1); DateTime sample = value.ConvertTo<DateTime>(); sample.IsEqualTo(new DateTime(1900, 1, 1), "Incorrect value returned."); }
/// <summary> /// A time period has lapsed, trigger a save/queue of the current value of data. /// </summary> /// <param name="utcTriggerTime">The time we're triggering this archive for</param> /// <param name="fillForward">Data stream is a fillforward type</param> public void TriggerArchive(DateTime utcTriggerTime, bool fillForward) { var localTriggerTime = utcTriggerTime.ConvertTo(TimeZones.Utc, _config.TimeZone); lock (_lock) { try { //When there's nothing to do: if (_data == null && !fillForward) { Log.Debug("StreamStore.TriggerArchive(): No data to store, and not fill forward: " + Symbol); } if (_data != null) { //Create clone and reset original Log.Debug("StreamStore.TriggerArchive(): Enqueued new data: S:" + _data.Symbol + " V:" + _data.Value); _previousData = _data.Clone(); _queue.Enqueue(_data.Clone()); _data = null; } else if (fillForward && _data == null && _previousData != null) { // the time is actually the end time of a bar, check to see if the start time // is within market hours, which is really just checking the _previousData's EndTime if (!_security.Exchange.IsOpenDuringBar(localTriggerTime - _increment, localTriggerTime, _config.ExtendedMarketHours)) { Log.Debug("StreamStore.TriggerArchive(): Exchange is closed: " + Symbol); return; } //There was no other data in this timer period, and this is a fillforward subscription: Log.Debug("StreamStore.TriggerArchive(): Fillforward, Previous Enqueued: S:" + _previousData.Symbol + " V:" + _previousData.Value); var cloneForward = _previousData.Clone(true); cloneForward.Time = _previousData.Time.Add(_increment); _queue.Enqueue(cloneForward); _previousData = cloneForward.Clone(); } } catch (Exception err) { Log.Error("StreamStore.TriggerAchive(fillforward): Failed to archive: " + err.Message); } } }