public void OnUpdate <TB, TE>(TB buf) where TB : IDxEventBuf <TE> where TE : IDxOrder { var count = 0; int u = 0, a = 0, r = 0; using (var e = buf.GetEnumerator()) { if (!e.MoveNext()) { Console.WriteLine($"ERROR: Update for \"{buf.Symbol}#???\" without orders"); return; } var sym = $"{buf.Symbol}#{e.Current?.Source}"; if (!state.ContainsKey(sym)) { Console.WriteLine($"ERROR: Update for \"{sym}\" without snapshot"); return; } var s = state[sym]; foreach (var o in buf) { if (o.Size == 0) { if (s.ContainsKey(o.Index)) { Console.WriteLine($"\"{sym}\" removal of {o.Index}"); s.Remove(o.Index); r++; } } else if (s.ContainsKey(o.Index)) { var so = new SimpleOrder(o); Console.WriteLine($"\"{sym}\" replace {s[o.Index]} with {so}"); s[o.Index] = so; u++; } else { s[o.Index] = new SimpleOrder(o); Console.WriteLine($"\"{sym}\" add {s[o.Index]}"); a++; } count++; } Console.WriteLine($"\"{sym}\" update with {count} orders, A/U/R:{a}/{u}/{r}"); CheckBidAsk(sym, s); } }
private static void CheckBidAsk(string sym, Dictionary <long, SimpleOrder> s) { SimpleOrder ask = null; SimpleOrder bid = null; foreach (var o in s.Values) { if (o.side == Side.Buy && (bid == null || bid.price < o.price)) { bid = o; } if (o.side == Side.Sell && (ask == null || ask.price > o.price)) { ask = o; } } if (bid != null && ask != null && bid.price >= ask.price) { Console.WriteLine($"ERROR: \"{sym}\": Cross: Bid {bid} vs Ask {ask}"); } }