/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System; namespace QuantConnect.Lean.Engine.DataFeeds { /// /// Will generate time steps around the desired /// Provided step evaluator should return true when the next time step /// is valid and time can advance /// public class PredicateTimeProvider : ITimeProvider { private readonly ITimeProvider _underlyingTimeProvider; private readonly Func _customStepEvaluator; private DateTime _currentUtc = DateTime.MinValue; /// /// Creates a new instance /// /// The timer provider instance to wrap /// Function to evaluate whether or not /// to advance time. Should return true if provided is a /// valid new next time. False will avoid time advancing public PredicateTimeProvider(ITimeProvider underlyingTimeProvider, Func customStepEvaluator) { _underlyingTimeProvider = underlyingTimeProvider; _customStepEvaluator = customStepEvaluator; } /// /// Gets the current utc time step /// public DateTime GetUtcNow() { if (_currentUtc == DateTime.MinValue) { Initialize(); } var utcNow = _underlyingTimeProvider.GetUtcNow(); // we check if we should advance time based on the provided custom step evaluator if (_customStepEvaluator(utcNow)) { _currentUtc = utcNow; } return _currentUtc; } private void Initialize() { // to determine the current time we go backwards up to 2 days until we reach a valid time we don't want to start on an invalid time var utcNow = _underlyingTimeProvider.GetUtcNow(); for (var i = 0; i < 48; i++) { var before = utcNow.AddHours(-1 * i); if (_customStepEvaluator(before)) { _currentUtc = before; } } } } }