Lean  $LEAN_TAG$
MarketHoursSegment.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 using System.Collections.Generic;
18 using Newtonsoft.Json;
19 
21 {
22  /// <summary>
23  /// Represents the state of an exchange during a specified time range
24  /// </summary>
25  [JsonObject(MemberSerialization.OptIn)]
26  public class MarketHoursSegment
27  {
28  /// <summary>
29  /// Gets the start time for this segment
30  /// </summary>
31  [JsonProperty("start")]
32  public TimeSpan Start { get; private set; }
33 
34  /// <summary>
35  /// Gets the end time for this segment
36  /// </summary>
37  [JsonProperty("end")]
38  public TimeSpan End { get; private set; }
39 
40  /// <summary>
41  /// Gets the market hours state for this segment
42  /// </summary>
43  [JsonProperty("state")]
44  public MarketHoursState State { get; private set; }
45 
46  /// <summary>
47  /// Initializes a new instance of the <see cref="MarketHoursSegment"/> class
48  /// </summary>
49  /// <param name="state">The state of the market during the specified times</param>
50  /// <param name="start">The start time of the segment</param>
51  /// <param name="end">The end time of the segment</param>
52  public MarketHoursSegment(MarketHoursState state, TimeSpan start, TimeSpan end)
53  {
54  Start = start;
55  End = end;
56  State = state;
57  }
58 
59  /// <summary>
60  /// Gets a new market hours segment representing being open all day
61  /// </summary>
63  {
64  return new MarketHoursSegment(MarketHoursState.Market, TimeSpan.Zero, Time.OneDay);
65  }
66 
67  /// <summary>
68  /// Gets a new market hours segment representing being open all day
69  /// </summary>
71  {
72  return new MarketHoursSegment(MarketHoursState.Closed, TimeSpan.Zero, Time.OneDay);
73  }
74 
75  /// <summary>
76  /// Creates the market hours segments for the specified market open/close times
77  /// </summary>
78  /// <param name="extendedMarketOpen">The extended market open time. If no pre market, set to market open</param>
79  /// <param name="marketOpen">The regular market open time</param>
80  /// <param name="marketClose">The regular market close time</param>
81  /// <param name="extendedMarketClose">The extended market close time. If no post market, set to market close</param>
82  /// <returns>An array of <see cref="MarketHoursSegment"/> representing the specified market open/close times</returns>
84  TimeSpan extendedMarketOpen,
85  TimeSpan marketOpen,
86  TimeSpan marketClose,
87  TimeSpan extendedMarketClose
88  )
89  {
90  // perform some sanity checks
91  if (marketOpen < extendedMarketOpen)
92  {
93  throw new ArgumentException(Messages.MarketHoursSegment.InvalidExtendedMarketOpenTime);
94  }
95  if (marketClose < marketOpen)
96  {
97  throw new ArgumentException(Messages.MarketHoursSegment.InvalidMarketCloseTime);
98  }
99  if (extendedMarketClose < marketClose)
100  {
101  throw new ArgumentException(Messages.MarketHoursSegment.InvalidExtendedMarketCloseTime);
102  }
103 
104  var segments = new List<MarketHoursSegment>();
105 
106  if (extendedMarketOpen != marketOpen)
107  {
108  segments.Add(new MarketHoursSegment(MarketHoursState.PreMarket, extendedMarketOpen, marketOpen));
109  }
110 
111  if (marketOpen != TimeSpan.Zero || marketClose != TimeSpan.Zero)
112  {
113  segments.Add(new MarketHoursSegment(MarketHoursState.Market, marketOpen, marketClose));
114  }
115 
116  if (marketClose != extendedMarketClose)
117  {
118  segments.Add(new MarketHoursSegment(MarketHoursState.PostMarket, marketClose, extendedMarketClose));
119  }
120 
121  return segments.ToArray();
122  }
123 
124  /// <summary>
125  /// Determines whether or not the specified time is contained within this segment
126  /// </summary>
127  /// <param name="time">The time to check</param>
128  /// <returns>True if this segment contains the specified time, false otherwise</returns>
129  public bool Contains(TimeSpan time)
130  {
131  return time >= Start && time < End;
132  }
133 
134  /// <summary>
135  /// Determines whether or not the specified time range overlaps with this segment
136  /// </summary>
137  /// <param name="start">The start of the range</param>
138  /// <param name="end">The end of the range</param>
139  /// <returns>True if the specified range overlaps this time segment, false otherwise</returns>
140  public bool Overlaps(TimeSpan start, TimeSpan end)
141  {
142  return Start < end && End > start;
143  }
144 
145  /// <summary>
146  /// Returns a string that represents the current object.
147  /// </summary>
148  /// <returns>
149  /// A string that represents the current object.
150  /// </returns>
151  public override string ToString()
152  {
153  return Messages.MarketHoursSegment.ToString(this);
154  }
155  }
156 }