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>();
243 [JsonProperty(
"bankHolidays")]
252 if (entry ==
null)
return;
254 var hours = entry.ExchangeHours;
256 SetSegmentsForDay(hours, DayOfWeek.Sunday, out var sunday);
258 SetSegmentsForDay(hours, DayOfWeek.Monday, out var monday);
260 SetSegmentsForDay(hours, DayOfWeek.Tuesday, out var tuesday);
262 SetSegmentsForDay(hours, DayOfWeek.Wednesday, out var wednesday);
264 SetSegmentsForDay(hours, DayOfWeek.Thursday, out var thursday);
266 SetSegmentsForDay(hours, DayOfWeek.Friday, out var friday);
268 SetSegmentsForDay(hours, DayOfWeek.Saturday, out var saturday);
270 Holidays = hours.Holidays.Select(x => x.ToString(
"M/d/yyyy", CultureInfo.InvariantCulture)).ToList();
271 EarlyCloses = entry.ExchangeHours.EarlyCloses.ToDictionary(pair => pair.Key.ToString(
"M/d/yyyy", CultureInfo.InvariantCulture), pair => pair.Value);
272 LateOpens = entry.ExchangeHours.LateOpens.ToDictionary(pair => pair.Key.ToString(
"M/d/yyyy", CultureInfo.InvariantCulture), pair => pair.Value);
281 var hours =
new Dictionary<DayOfWeek, LocalMarketHours>
291 var holidayDates =
Holidays.Select(x => DateTime.ParseExact(x,
"M/d/yyyy", CultureInfo.InvariantCulture)).ToHashSet();
292 var bankHolidayDates =
BankHolidays.Select(x => DateTime.ParseExact(x,
"M/d/yyyy", CultureInfo.InvariantCulture)).ToHashSet();
293 IReadOnlyDictionary<DateTime, TimeSpan> earlyCloses =
EarlyCloses.ToDictionary(x => DateTime.ParseExact(x.Key,
"M/d/yyyy", CultureInfo.InvariantCulture), x => x.Value);
294 IReadOnlyDictionary<DateTime, TimeSpan> lateOpens =
LateOpens.ToDictionary(x => DateTime.ParseExact(x.Key,
"M/d/yyyy", CultureInfo.InvariantCulture), x => x.Value);
296 if(underlyingEntry !=
null)
299 if (holidayDates.Count == 0)
301 holidayDates = underlyingEntry.ExchangeHours.Holidays;
303 if (bankHolidayDates.Count == 0)
305 bankHolidayDates = underlyingEntry.ExchangeHours.BankHolidays;
307 if (earlyCloses.Count == 0)
309 earlyCloses = underlyingEntry.ExchangeHours.EarlyCloses;
311 if (lateOpens.Count == 0)
313 lateOpens = underlyingEntry.ExchangeHours.LateOpens;
317 if(marketEntry !=
null)
319 if (marketEntry.ExchangeHours.Holidays.Count > 0)
321 holidayDates.UnionWith(marketEntry.ExchangeHours.Holidays);
324 if (marketEntry.ExchangeHours.BankHolidays.Count > 0)
326 bankHolidayDates.UnionWith(marketEntry.ExchangeHours.BankHolidays);
329 if (marketEntry.ExchangeHours.EarlyCloses.Count > 0 )
331 earlyCloses = MergeLateOpensAndEarlyCloses(marketEntry.ExchangeHours.EarlyCloses, earlyCloses);
334 if (marketEntry.ExchangeHours.LateOpens.Count > 0)
336 lateOpens = MergeLateOpensAndEarlyCloses(marketEntry.ExchangeHours.LateOpens, lateOpens);
344 private void SetSegmentsForDay(
SecurityExchangeHours hours, DayOfWeek day, out List<MarketHoursSegment> segments)
353 segments =
new List<MarketHoursSegment>();
362 private static Dictionary<DateTime, TimeSpan> MergeLateOpensAndEarlyCloses(IReadOnlyDictionary<DateTime, TimeSpan> common,
363 IReadOnlyDictionary<DateTime, TimeSpan> specific)
365 var result = common.ToDictionary();
366 foreach (var (key, value) in specific)