private static void UpdateRedisTick(IRedisTypedClient <Tick> redisTickClient, int secId, DateTime dtAyondoNow, IList <Quote> quotes, TickSize tickSize) { //redis tick list var list = redisTickClient.Lists[Ticks.GetTickListNamePrefix(tickSize) + secId]; if (quotes.Count == 0) //fill in non-changing ticks { if (list.Count > 0) { var last = list[list.Count - 1]; //redis last tick is newer if (last.T >= dtAyondoNow) { return;//impossible } //update last tick in redis if (Ticks.IsTickEqual(last.T, dtAyondoNow, tickSize)) { //do nothing } else //append new tick with the same price as redis last { list.Add(new Tick() { P = last.P, T = dtAyondoNow }); } } } else { var lastQuote = quotes.OrderByDescending(o => o.Time).First(); var newTick = new Tick { P = Quotes.GetLastPrice(lastQuote), T = dtAyondoNow }; if (list.Count == 0) //new products coming { list.Add(newTick); return; } var last = list[list.Count - 1]; //redis last tick is newer if (last.T >= dtAyondoNow) { return;//impossible } //update last tick in redis if (Ticks.IsTickEqual(last.T, dtAyondoNow, tickSize)) { ////last price dominate //list[list.Count - 1] = newTick; //first price dominate //do nothing } else //append new last tick { list.Add(newTick); } } //clear history/prevent data increasing for good var clearWhenSize = Ticks.GetClearWhenSize(tickSize); var clearToSize = Ticks.GetClearToSize(tickSize); if (list.Count > clearWhenSize) //data count at most possible size (in x days ) { YJYGlobal.LogLine("Tick " + tickSize + " " + secId + " Clearing data from " + list.Count + " to " + clearToSize); var ticks = list.GetAll(); var newTicks = ticks.Skip(ticks.Count - clearToSize); list.RemoveAll(); list.AddRange(newTicks); } }
private static void SaveRawTicks(object state) { while (true) { try { IList <Quote> quotes = new List <Quote>(); while (!myApp.QueueQuotesForRawTick.IsEmpty) { Quote obj; var tryDequeue = myApp.QueueQuotesForRawTick.TryDequeue(out obj); quotes.Add(obj); } if (quotes.Count > 0) { var quoteGroups = quotes.GroupBy(o => o.Id).ToList(); var dtBeginSave = DateTime.Now; var count = 0; //var entitiesToSaveToDB = new List<QuoteHistory>(); using (var redisClient = YJYGlobal.PooledRedisClientsManager.GetClient()) { var redisTickClient = redisClient.As <Tick>(); foreach (var quoteGroup in quoteGroups) { if (!myApp.ProdDefs.ContainsKey(quoteGroup.Key)) //no product definition { YJYGlobal.LogLine("SaveRawTicks: no prodDef. tick ignored " + quoteGroup.Key); continue; } var prodDef = myApp.ProdDefs[quoteGroup.Key]; if (prodDef.QuoteType != enmQuoteType.Open && prodDef.QuoteType != enmQuoteType.PhoneOnly) //not open not phoneOnly { YJYGlobal.LogLine("\tSaveRawTicks: prod not opening. tick ignored. " + prodDef.Id + " " + prodDef.Name); continue; } var list = redisTickClient.Lists[Ticks.GetTickListNamePrefix(TickSize.Raw) + quoteGroup.Key]; var ticksToAdd = quoteGroup.Select(o => new Tick { P = Quotes.GetLastPrice(o), T = o.Time }) .OrderBy(o => o.T) .ToList(); list.AddRange(ticksToAdd); count++; //clear history to prevent data size get too big var clearWhenSize = Ticks.GetClearWhenSize(TickSize.Raw); var clearToSize = Ticks.GetClearToSize(TickSize.Raw); if (list.Count > clearWhenSize) { YJYGlobal.LogLine("Raw Ticks " + quoteGroup.Key + " Clearing data from " + list.Count + " to " + clearToSize); var ticks = list.GetAll(); var newTicks = ticks.Skip(ticks.Count - clearToSize); list.RemoveAll(); list.AddRange(newTicks); } } } YJYGlobal.LogLine("\t" + TickSize.Raw + " Ticks " + count + "/" + quoteGroups.Count + "/" + quotes.Count + " " + " Time: " + quotes.Min(o => o.Time).ToString(YJYGlobal.DATETIME_MASK_MILLI_SECOND) + " ~ " + quotes.Max(o => o.Time).ToString(YJYGlobal.DATETIME_MASK_MILLI_SECOND) + " Saved to Redis " + (DateTime.Now - dtBeginSave).TotalMilliseconds); } } catch (Exception e) { YJYGlobal.LogException(e); } Thread.Sleep(_intervalRawTicks); } }