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;
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")]
189 [JsonProperty(
"monday")]
195 [JsonProperty(
"tuesday")]
201 [JsonProperty(
"wednesday")]
207 [JsonProperty(
"thursday")]
213 [JsonProperty(
"friday")]
219 [JsonProperty(
"saturday")]
225 [JsonProperty(
"holidays")]
231 [JsonProperty(
"earlyCloses")]
232 public Dictionary<string, TimeSpan>
EarlyCloses =
new Dictionary<string, TimeSpan>();
237 [JsonProperty(
"lateOpens")]
238 public Dictionary<string, TimeSpan>
LateOpens =
new Dictionary<string, TimeSpan>();
246 if (entry ==
null)
return;
248 var hours = entry.ExchangeHours;
250 SetSegmentsForDay(hours, DayOfWeek.Sunday, out
Sunday);
251 SetSegmentsForDay(hours, DayOfWeek.Monday, out
Monday);
252 SetSegmentsForDay(hours, DayOfWeek.Tuesday, out
Tuesday);
253 SetSegmentsForDay(hours, DayOfWeek.Wednesday, out
Wednesday);
254 SetSegmentsForDay(hours, DayOfWeek.Thursday, out
Thursday);
255 SetSegmentsForDay(hours, DayOfWeek.Friday, out
Friday);
256 SetSegmentsForDay(hours, DayOfWeek.Saturday, out
Saturday);
257 Holidays = hours.Holidays.Select(x => x.ToString(
"M/d/yyyy", CultureInfo.InvariantCulture)).ToList();
258 EarlyCloses = entry.ExchangeHours.EarlyCloses.ToDictionary(pair => pair.Key.ToString(
"M/d/yyyy", CultureInfo.InvariantCulture), pair => pair.Value);
259 LateOpens = entry.ExchangeHours.LateOpens.ToDictionary(pair => pair.Key.ToString(
"M/d/yyyy", CultureInfo.InvariantCulture), pair => pair.Value);
268 var hours =
new Dictionary<DayOfWeek, LocalMarketHours>
278 var holidayDates =
Holidays.Select(x => DateTime.ParseExact(x,
"M/d/yyyy", CultureInfo.InvariantCulture)).ToHashSet();
279 IReadOnlyDictionary<DateTime, TimeSpan> earlyCloses =
EarlyCloses.ToDictionary(x => DateTime.ParseExact(x.Key,
"M/d/yyyy", CultureInfo.InvariantCulture), x => x.Value);
280 IReadOnlyDictionary<DateTime, TimeSpan> lateOpens =
LateOpens.ToDictionary(x => DateTime.ParseExact(x.Key,
"M/d/yyyy", CultureInfo.InvariantCulture), x => x.Value);
282 if(underlyingEntry !=
null)
285 if (holidayDates.Count == 0)
287 holidayDates = underlyingEntry.ExchangeHours.Holidays;
289 if (earlyCloses.Count == 0)
291 earlyCloses = underlyingEntry.ExchangeHours.EarlyCloses;
293 if (lateOpens.Count == 0)
295 lateOpens = underlyingEntry.ExchangeHours.LateOpens;
299 if(marketEntry !=
null)
301 if (marketEntry.ExchangeHours.Holidays.Count > 0)
303 holidayDates.UnionWith(marketEntry.ExchangeHours.Holidays);
306 if (marketEntry.ExchangeHours.EarlyCloses.Count > 0 )
308 earlyCloses = MergeLateOpensAndEarlyCloses(marketEntry.ExchangeHours.EarlyCloses, earlyCloses);
311 if (marketEntry.ExchangeHours.LateOpens.Count > 0)
313 lateOpens = MergeLateOpensAndEarlyCloses(marketEntry.ExchangeHours.LateOpens, lateOpens);
321 private void SetSegmentsForDay(
SecurityExchangeHours hours, DayOfWeek day, out List<MarketHoursSegment> segments)
330 segments =
new List<MarketHoursSegment>();
339 private static Dictionary<DateTime, TimeSpan> MergeLateOpensAndEarlyCloses(IReadOnlyDictionary<DateTime, TimeSpan> common,
340 IReadOnlyDictionary<DateTime, TimeSpan> specific)
342 var result = common.ToDictionary();
343 foreach (var (key, value) in specific)