Lean  $LEAN_TAG$
Calendar.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 using System;
17 
19 {
20  /// <summary>
21  /// Helper class that provides <see cref="Func{DateTime,CalendarInfo}"/> used to define consolidation calendar
22  /// </summary>
23  public static class Calendar
24  {
25  /// <summary>
26  /// Computes the start of week (previous Monday) of given date/time
27  /// </summary>
28  public static Func<DateTime, CalendarInfo> Weekly
29  {
30  get
31  {
32  return dt =>
33  {
34  var start = Expiry.EndOfWeek(dt).AddDays(-7);
35  return new CalendarInfo(start, TimeSpan.FromDays(7));
36  };
37  }
38  }
39 
40  /// <summary>
41  /// Computes the start of month (1st of the current month) of given date/time
42  /// </summary>
43  public static Func<DateTime, CalendarInfo> Monthly
44  {
45  get
46  {
47  return dt =>
48  {
49  var start = dt.AddDays(1 - dt.Day).Date;
50  var end = Expiry.EndOfMonth(dt);
51  return new CalendarInfo(start, end - start);
52  };
53  }
54  }
55 
56  /// <summary>
57  /// Computes the start of quarter (1st of the starting month of current quarter) of given date/time
58  /// </summary>
59  public static Func<DateTime, CalendarInfo> Quarterly
60  {
61  get
62  {
63  return dt =>
64  {
65  var nthQuarter = (dt.Month - 1) / 3;
66  var firstMonthOfQuarter = nthQuarter * 3 + 1;
67  var start = new DateTime(dt.Year, firstMonthOfQuarter, 1);
68  var end = Expiry.EndOfQuarter(dt);
69  return new CalendarInfo(start, end - start);
70  };
71  }
72  }
73 
74  /// <summary>
75  /// Computes the start of year (1st of the current year) of given date/time
76  /// </summary>
77  public static Func<DateTime, CalendarInfo> Yearly
78  {
79  get
80  {
81  return dt =>
82  {
83  var start = dt.AddDays(1 - dt.DayOfYear).Date;
84  var end = Expiry.EndOfYear(dt);
85  return new CalendarInfo(start, end - start);
86  };
87  }
88  }
89  }
90 
91  /// <summary>
92  /// Calendar Info for storing information related to the start and period of a consolidator
93  /// </summary>
94  public readonly struct CalendarInfo
95  {
96  /// <summary>
97  /// Calendar Start
98  /// </summary>
99  public DateTime Start { get; init; }
100 
101  /// <summary>
102  /// Consolidation Period
103  /// </summary>
104  public TimeSpan Period { get; init; }
105 
106  /// <summary>
107  /// Calendar End
108  /// </summary>
109  public readonly DateTime End => Start + Period;
110 
111  /// <summary>
112  /// Constructor for CalendarInfo; used for consolidation calendar
113  /// </summary>
114  /// <param name="start">Calendar Start</param>
115  /// <param name="period">Consolidation Period</param>
116  public CalendarInfo(DateTime start, TimeSpan period)
117  {
118  Start = start;
119  Period = period;
120  }
121 
122  /// <summary>
123  /// Returns a string containing the Calendar start and the consolidation period
124  /// </summary>
125  public override string ToString()
126  {
127  return $"{Start} {Period}";
128  }
129 
130  /// <summary>
131  /// Indicates whether the given object is equal to this object, this is, the Calendar start
132  /// and consolidation period is the same for both
133  /// </summary>
134  public override bool Equals(object obj)
135  {
136  if (obj is not CalendarInfo other)
137  {
138  return false;
139  }
140  return Start == other.Start && Period == other.Period;
141  }
142 
143  /// <summary>
144  /// Returns the hash code for this object as an integer
145  /// </summary>
146  public override int GetHashCode()
147  {
148  unchecked
149  {
150  var hashCode = Start.GetHashCode();
151  return (hashCode * 397) ^ Period.GetHashCode();
152  }
153  }
154 
155  /// <summary>
156  /// Indicates whether the given object is equal to this object, this is, the Calendar start
157  /// and consolidation period is the same for both
158  /// </summary>
159  public static bool operator ==(CalendarInfo left, CalendarInfo right)
160  {
161  return left.Equals(right);
162  }
163 
164  /// <summary>
165  /// Indicates whether the given object is equal to this object, this is, the Calendar start
166  /// and consolidation period is the same for both
167  /// </summary>
168  public static bool operator !=(CalendarInfo left, CalendarInfo right)
169  {
170  return !(left == right);
171  }
172  }
173 }