17 using System.Collections.Generic;
18 using System.Globalization;
20 using Newtonsoft.Json;
21 using Newtonsoft.Json.Linq;
62 var jobject = (JObject) token;
70 [JsonObject(MemberSerialization.OptIn)]
76 [JsonProperty(
"entries")]
77 public Dictionary<string, MarketHoursDatabaseEntryJson>
Entries {
get;
set; }
85 if (database ==
null)
return;
86 Entries =
new Dictionary<string, MarketHoursDatabaseEntryJson>();
87 foreach (var kvp
in database.ExchangeHoursListing)
90 var entry = kvp.Value;
102 var entries =
new Dictionary<SecurityDatabaseKey, MarketHoursDatabaseEntryJson>(
Entries.Count);
110 entries[key] = entry.Value;
113 catch (Exception err)
121 foreach (var entry
in entries.OrderBy(kvp => kvp.Key.Symbol !=
null ? 1 : 0).ThenBy(kvp => kvp.Key.SecurityType.IsOption() ? 1 : 0))
125 result.TryGetValue(entry.Key.CreateCommonKey(), out var marketEntry);
126 var underlyingEntry = GetUnderlyingEntry(entry.Key, result);
127 result[entry.Key] = entry.Value.Convert(underlyingEntry, marketEntry);
129 catch (Exception err)
150 if (!result.TryGetValue(underlyingKey, out underlyingEntry)
155 result.TryGetValue(underlyingKeyWildCard, out underlyingEntry);
158 return underlyingEntry;
165 [JsonObject(MemberSerialization.OptIn)]
171 [JsonProperty(
"dataTimeZone")]
177 [JsonProperty(
"exchangeTimeZone")]
183 [JsonProperty(
"sunday")]
184 public List<MarketHoursSegment>
Sunday {
get;
set; }
189 [JsonProperty(
"monday")]
190 public List<MarketHoursSegment>
Monday {
get;
set; }
195 [JsonProperty(
"tuesday")]
196 public List<MarketHoursSegment>
Tuesday {
get;
set; }
201 [JsonProperty(
"wednesday")]
207 [JsonProperty(
"thursday")]
208 public List<MarketHoursSegment>
Thursday {
get;
set; }
213 [JsonProperty(
"friday")]
214 public List<MarketHoursSegment>
Friday {
get;
set; }
219 [JsonProperty(
"saturday")]
220 public List<MarketHoursSegment>
Saturday {
get;
set; }
225 [JsonProperty(
"holidays")]
226 public List<string>
Holidays {
get;
set; } =
new();
231 [JsonProperty(
"earlyCloses")]
232 public Dictionary<string, TimeSpan>
EarlyCloses {
get;
set; } =
new Dictionary<string, TimeSpan>();
237 [JsonProperty(
"lateOpens")]
238 public Dictionary<string, TimeSpan>
LateOpens {
get;
set; } =
new Dictionary<string, TimeSpan>();
246 if (entry ==
null)
return;
248 var hours = entry.ExchangeHours;
250 SetSegmentsForDay(hours, DayOfWeek.Sunday, out var sunday);
252 SetSegmentsForDay(hours, DayOfWeek.Monday, out var monday);
254 SetSegmentsForDay(hours, DayOfWeek.Tuesday, out var tuesday);
256 SetSegmentsForDay(hours, DayOfWeek.Wednesday, out var wednesday);
258 SetSegmentsForDay(hours, DayOfWeek.Thursday, out var thursday);
260 SetSegmentsForDay(hours, DayOfWeek.Friday, out var friday);
262 SetSegmentsForDay(hours, DayOfWeek.Saturday, out var saturday);
264 Holidays = hours.Holidays.Select(x => x.ToString(
"M/d/yyyy", CultureInfo.InvariantCulture)).ToList();
265 EarlyCloses = entry.ExchangeHours.EarlyCloses.ToDictionary(pair => pair.Key.ToString(
"M/d/yyyy", CultureInfo.InvariantCulture), pair => pair.Value);
266 LateOpens = entry.ExchangeHours.LateOpens.ToDictionary(pair => pair.Key.ToString(
"M/d/yyyy", CultureInfo.InvariantCulture), pair => pair.Value);
275 var hours =
new Dictionary<DayOfWeek, LocalMarketHours>
285 var holidayDates =
Holidays.Select(x => DateTime.ParseExact(x,
"M/d/yyyy", CultureInfo.InvariantCulture)).ToHashSet();
286 IReadOnlyDictionary<DateTime, TimeSpan> earlyCloses =
EarlyCloses.ToDictionary(x => DateTime.ParseExact(x.Key,
"M/d/yyyy", CultureInfo.InvariantCulture), x => x.Value);
287 IReadOnlyDictionary<DateTime, TimeSpan> lateOpens =
LateOpens.ToDictionary(x => DateTime.ParseExact(x.Key,
"M/d/yyyy", CultureInfo.InvariantCulture), x => x.Value);
289 if(underlyingEntry !=
null)
292 if (holidayDates.Count == 0)
294 holidayDates = underlyingEntry.ExchangeHours.Holidays;
296 if (earlyCloses.Count == 0)
298 earlyCloses = underlyingEntry.ExchangeHours.EarlyCloses;
300 if (lateOpens.Count == 0)
302 lateOpens = underlyingEntry.ExchangeHours.LateOpens;
306 if(marketEntry !=
null)
308 if (marketEntry.ExchangeHours.Holidays.Count > 0)
310 holidayDates.UnionWith(marketEntry.ExchangeHours.Holidays);
313 if (marketEntry.ExchangeHours.EarlyCloses.Count > 0 )
315 earlyCloses = MergeLateOpensAndEarlyCloses(marketEntry.ExchangeHours.EarlyCloses, earlyCloses);
318 if (marketEntry.ExchangeHours.LateOpens.Count > 0)
320 lateOpens = MergeLateOpensAndEarlyCloses(marketEntry.ExchangeHours.LateOpens, lateOpens);
328 private void SetSegmentsForDay(
SecurityExchangeHours hours, DayOfWeek day, out List<MarketHoursSegment> segments)
337 segments =
new List<MarketHoursSegment>();
346 private static Dictionary<DateTime, TimeSpan> MergeLateOpensAndEarlyCloses(IReadOnlyDictionary<DateTime, TimeSpan> common,
347 IReadOnlyDictionary<DateTime, TimeSpan> specific)
349 var result = common.ToDictionary();
350 foreach (var (key, value) in specific)