GLPriceCache changes
Some checks failed
Build .NET Project / build (push) Has been cancelled

This commit is contained in:
2026-02-26 16:56:17 -05:00
parent eee0418271
commit 2fc472dbbb
2 changed files with 78 additions and 41 deletions

View File

@@ -162,55 +162,91 @@ namespace MarketData.Cache
public void Add(PortfolioTrades portfolioTrades)
{
List<string> symbols = portfolioTrades.Symbols;
Dictionary<string, DateTime> minTradeDates = symbols.ToDictionary(sym => sym, sym => portfolioTrades.GetMinTradeDate(sym));
List<string> symbols = portfolioTrades.Symbols;
DateTime today = DateTime.Today;
Dictionary<string, DateTime> minCacheDates;
lock (thisLock)
{
minCacheDates = symbols.ToDictionary(sym => sym, sym => priceCache.ContainsKey(sym) ? priceCache[sym].MinDate : DateTime.MaxValue);
}
Dictionary<string, DateTime> minTradeDates = symbols.ToDictionary(symbol => symbol, symbol => portfolioTrades.GetMinTradeDate(symbol));
ConcurrentDictionary<string, Prices> fetchedPrices = new ConcurrentDictionary<string, Prices>();
// Symbols that need an intraday refresh:
// - open positions (no close date), or
// *** REMOVED THIS - closed today (close price may still be settling) TODO *****
HashSet<string> mutableSymbols = new HashSet<string>(symbols.Where(symbol => portfolioTrades.HasOpenPositions(symbol)));
Parallel.ForEach(symbols, new ParallelOptions { MaxDegreeOfParallelism = 8 }, symbol =>
{
DateTime minTradeDate = minTradeDates[symbol];
DateTime minCacheDate = minCacheDates[symbol];
Prices prices = null;
try
Dictionary<string, DateTime> minCacheDates;
lock (thisLock)
{
if (minCacheDate == DateTime.MaxValue)
{
prices = PricingDA.GetPrices(symbol, minTradeDate);
}
else if (minTradeDate < minCacheDate)
{
prices = PricingDA.GetPrices(symbol, minCacheDate, minTradeDate);
}
minCacheDates = symbols.ToDictionary(symbol => symbol,symbol => priceCache.ContainsKey(symbol) ? priceCache[symbol].MinDate : DateTime.MaxValue);
}
if (prices != null && prices.Count > 0)
{
fetchedPrices[symbol] = prices;
}
}
catch (Exception ex)
{
MDTrace.WriteLine(LogLevel.DEBUG, $"Error fetching prices for {symbol}: {ex.Message}");
}
});
ConcurrentDictionary<string, Prices> fetchedPrices = new ConcurrentDictionary<string, Prices>();
ConcurrentDictionary<string, Price> latestPrices = new ConcurrentDictionary<string, Price>();
lock (thisLock)
{
foreach (KeyValuePair<string, Prices> kvp in fetchedPrices)
Parallel.ForEach(symbols, new ParallelOptions { MaxDegreeOfParallelism = 8 }, symbol =>
{
foreach (Price price in kvp.Value)
{
Add(price);
}
DateTime minTradeDate = minTradeDates[symbol];
DateTime minCacheDate = minCacheDates[symbol];
try
{
// Historical fetch <20> only when cache is missing or incomplete
Prices prices = null;
if (minCacheDate == DateTime.MaxValue)
{
prices = PricingDA.GetPrices(symbol, minTradeDate);
}
else if (minTradeDate < minCacheDate)
{
prices = PricingDA.GetPrices(symbol, minCacheDate, minTradeDate);
}
if (prices != null && prices.Count > 0)
{
fetchedPrices[symbol] = prices;
}
// Intraday refresh open positions and positions closed today only
if (mutableSymbols.Contains(symbol))
{
Price latestPrice = PricingDA.GetPrice(symbol);
if (latestPrice != null)
latestPrices[symbol] = latestPrice;
}
}
catch (Exception ex)
{
MDTrace.WriteLine(LogLevel.DEBUG, $"Error fetching prices for {symbol}: {ex.Message}");
}
});
lock (thisLock)
{
// Historical prices idempotent, will not overwrite existing entries
foreach (var kvp in fetchedPrices)
{
foreach (var price in kvp.Value)
{
Add(price);
}
}
// Latest prices unconditional overwrite to capture any intraday updates
foreach (var kvp in latestPrices)
{
if (!priceCache.TryGetValue(kvp.Key, out var pricesByDate))
{
pricesByDate = new PricesByDate();
priceCache[kvp.Key] = pricesByDate;
}
if (pricesByDate.ContainsKey(kvp.Value.Date))
pricesByDate.Remove(kvp.Value.Date);
pricesByDate.Add(kvp.Value.Date, kvp.Value);
}
}
}
MDTrace.WriteLine(LogLevel.DEBUG,
$"[GLPriceCache:Add] Symbols: {symbols.Count}, Mutable: {mutableSymbols.Count}, " +
$"Historical fetches: {fetchedPrices.Count}, Intraday updates: {latestPrices.Count}");
}
public void Add(Prices prices)