Files
TradeBlotter/Safe/PriceCache.cs
2024-02-23 06:58:53 -05:00

158 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using MarketData.MarketDataModel;
using MarketData.Helper;
using MarketData.DataAccess;
using MarketData.Utils;
namespace TradeBlotter.Cache
{
//public class CacheInfo
//{
// public CacheInfo()
// {
// }
// public Prices Prices { get; set; }
//}
public class PriceCache : IDisposable
{
private Dictionary<String, Prices> priceCache = new Dictionary<String, Prices>();
private Object thisLock = new Object();
private Thread cacheMonitorThread = null;
private bool threadRun = true;
private int cacheRefreshAfter = 30000;
private static PriceCache priceCacheInstance = null;
private PriceCache()
{
cacheMonitorThread = new Thread(new ThreadStart(ThreadProc));
cacheMonitorThread.Start();
}
public static PriceCache GetInstance()
{
lock (typeof(PriceCache))
{
if (null == priceCacheInstance) priceCacheInstance = new PriceCache();
return priceCacheInstance;
}
}
public void Dispose()
{
lock (thisLock)
{
threadRun = false;
if (null != cacheMonitorThread)
{
cacheMonitorThread.Join();
}
priceCache.Clear();
priceCacheInstance = null;
}
}
public Prices GetPrices(String symbol, int days)
{
lock (thisLock)
{
DateTime now = DateTime.Now;
Prices prices = null;
Price price = null;
if (priceCache.ContainsKey(symbol)) prices = priceCache[symbol];
if (null != prices)
{
if (prices.Count >= days)
{
Prices priceRange = null;
if (prices.Count == days) priceRange = prices;
else priceRange = new Prices(prices.GetRange(0, days).ToArray());
return priceRange;
}
if(prices.Count>0)price = prices[0];
prices = PricingDA.GetPrices(symbol, days);
if (null!=prices&&price.Date.Date.Equals(DateTime.Now.Date.Date)&&(prices.Count>0&&prices[0].Date.Date!=price.Date.Date)) prices.Insert(0,price);
return prices;
}
prices = PricingDA.GetPrices(symbol, days);
if (null != prices && 0 != prices.Count) priceCache.Add(symbol, prices);
return prices;
}
}
public Price GetLatestPrice(String symbol)
{
lock (thisLock)
{
DateTime now = DateTime.Now;
Price price = null;
Prices prices = null;
if (priceCache.ContainsKey(symbol)) prices = priceCache[symbol];
if (null!=prices)
{
if (0 == prices.Count)
{
price = MarketDataHelper.GetLatestPrice(symbol);
if (null != price) prices.Add(price);
}
else
{
price = prices[0];
if (price.Date.Date.Equals(now.Date.Date)) return price;
price = MarketDataHelper.GetLatestPrice(symbol);
if (null != price) prices.Insert(0,price);
}
return price;
}
price = MarketDataHelper.GetLatestPrice(symbol);
if (null != price)
{
prices = new Prices();
prices.Add(price);
priceCache.Add(symbol, prices);
}
return price;
}
}
public bool Contains(String symbol)
{
lock (thisLock)
{
return priceCache.ContainsKey(symbol);
}
}
private void ThreadProc()
{
int quantums = 0;
int quantumInterval = 500;
while (threadRun)
{
Thread.Sleep(quantumInterval);
quantums += quantumInterval;
if (quantums > cacheRefreshAfter)
{
quantums = 0;
lock (thisLock)
{
DateTime now = DateTime.Now;
List<String> symbols = new List<String>(priceCache.Keys);
foreach (String symbol in symbols)
{
Prices prices=priceCache[symbol];
if (null ==prices || 0 == prices.Count) continue;
Price price = prices[0];
if (price.Date.Date.Equals(now.Date.Date))
{
prices.Remove(price);
price=MarketDataHelper.GetLatestPrice(symbol);
if(null==price)prices.Insert(0,price);
}
//if (price.Date.Date.Equals(now.Date.Date)) prices.Remove(price);
}
}
}
}
}
}
}