Lean  $LEAN_TAG$
BacktestProgressMonitor.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15 */
16 
17 using System;
18 using System.Threading;
20 
22 {
23  /// <summary>
24  /// Monitors and reports the progress of a backtest
25  /// </summary>
27  {
28  private const int ProcessedDaysCountInvalid = 0;
29  private const int ProcessedDaysCountValid = 1;
30 
31  private readonly ITimeKeeper _timeKeeper;
32 
33  private readonly DateTime _startUtcTime;
34 
35  private int _processedDays;
36  private int _isProcessedDaysCountValid;
37 
38  /// <summary>
39  /// Gets the total days the algorithm will run
40  /// </summary>
41  public int TotalDays { get; private set; }
42 
43  /// <summary>
44  /// Gets the current days the algorithm has been running for
45  /// </summary>
46  public int ProcessedDays {
47  get
48  {
49  if (Interlocked.CompareExchange(ref _isProcessedDaysCountValid, ProcessedDaysCountValid, ProcessedDaysCountInvalid) == ProcessedDaysCountInvalid)
50  {
51  try
52  {
53  // We use 'int' so it's thread safe
54  _processedDays = (int)(_timeKeeper.UtcTime - _startUtcTime).TotalDays;
55  }
56  catch (OverflowException)
57  {
58  }
59  }
60 
61  return _processedDays;
62  }
63  }
64 
65  /// <summary>
66  /// Gets the current progress of the backtest
67  /// </summary>
68  public decimal Progress
69  {
70  get { return Math.Min((decimal)ProcessedDays / TotalDays, 0.999m); }
71  }
72 
73  /// <summary>
74  /// Creates a new instance
75  /// </summary>
76  /// <param name="timeKeeper">The time keeper to use</param>
77  /// <param name="endUtcTime">The end UTC time</param>
78  public BacktestProgressMonitor(ITimeKeeper timeKeeper, DateTime endUtcTime)
79  {
80  _timeKeeper = timeKeeper;
81  _startUtcTime = _timeKeeper.UtcTime;
82  TotalDays = Convert.ToInt32((endUtcTime.Date - _startUtcTime.Date).TotalDays) + 1;
83  }
84 
85  /// <summary>
86  /// Invalidates the processed days count value so it gets recalculated next time it is needed
87  /// </summary>
89  {
90  Interlocked.Exchange(ref _isProcessedDaysCountValid, ProcessedDaysCountInvalid);
91  }
92  }
93 }