From 67aa1bd0cf2b75f85fc771ffcccb308fd6a56a50 Mon Sep 17 00:00:00 2001 From: Sean Date: Thu, 26 Feb 2026 16:51:29 -0500 Subject: [PATCH] Merge MKDT_0003 --- MarketDataLib/Cache/GLPriceCache.cs | 18 ++++++++++-------- Program.cs | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/MarketDataLib/Cache/GLPriceCache.cs b/MarketDataLib/Cache/GLPriceCache.cs index 9e8269f..bbdcbd4 100644 --- a/MarketDataLib/Cache/GLPriceCache.cs +++ b/MarketDataLib/Cache/GLPriceCache.cs @@ -66,8 +66,12 @@ namespace MarketData.Cache List symbols = portfolioTrades.Symbols; DateTime today = DateTime.Today; - Dictionary minTradeDates = symbols.ToDictionary( - sym => sym, sym => portfolioTrades.GetMinTradeDate(sym)); + // Default: 3x logical cores, capped at 32 to avoid saturating the connection pool. + // I/O-bound DB calls benefit from more threads than CPU cores, but diminishing + // returns set in beyond ~32 concurrent connections for most DB workloads. + int defaultParallelism = Math.Min(Environment.ProcessorCount * 3, 32); + + Dictionary minTradeDates = symbols.ToDictionary(symbol => symbol, symbol => portfolioTrades.GetMinTradeDate(symbol)); // Symbols that need an intraday refresh: // - open positions (no close date), or @@ -78,15 +82,13 @@ namespace MarketData.Cache Dictionary minCacheDates; lock (thisLock) { - minCacheDates = symbols.ToDictionary( - sym => sym, - sym => priceCache.ContainsKey(sym) ? priceCache[sym].MinDate : DateTime.MaxValue); + minCacheDates = symbols.ToDictionary(symbol => symbol,symbol => priceCache.ContainsKey(symbol) ? priceCache[symbol].MinDate : DateTime.MaxValue); } ConcurrentDictionary fetchedPrices = new ConcurrentDictionary(); ConcurrentDictionary latestPrices = new ConcurrentDictionary(); - Parallel.ForEach(symbols, new ParallelOptions { MaxDegreeOfParallelism = 8 }, symbol => + Parallel.ForEach(symbols, new ParallelOptions { MaxDegreeOfParallelism = defaultParallelism }, symbol => { DateTime minTradeDate = minTradeDates[symbol]; DateTime minCacheDate = minCacheDates[symbol]; @@ -126,7 +128,7 @@ namespace MarketData.Cache lock (thisLock) { // Historical prices — idempotent, will not overwrite existing entries - foreach (var kvp in fetchedPrices) + foreach (KeyValuePair kvp in fetchedPrices) { foreach (var price in kvp.Value) { @@ -135,7 +137,7 @@ namespace MarketData.Cache } // Latest prices — unconditional overwrite to capture any intraday updates - foreach (var kvp in latestPrices) + foreach (KeyValuePair kvp in latestPrices) { if (!priceCache.TryGetValue(kvp.Key, out var pricesByDate)) { diff --git a/Program.cs b/Program.cs index 5aeb1d4..b9501cf 100644 --- a/Program.cs +++ b/Program.cs @@ -1857,6 +1857,7 @@ namespace MarketData { LocalPriceCache.GetInstance().Dispose(); GBPriceCache.GetInstance().Dispose(); + GLPriceCache.GetInstance().Dispose(); } } // main // *****************************************************************************************************************************************************************************