public void Unsub()
        {
            var internalTrackers = new Dictionary <string, TestTracker>();
            var snapshotRequests = new List <string>();
            var tracker          = new SyncDictDelegator <TestTracker>(
                (s, i) =>
            {
                var internalTracker = new TestTracker(s, i);
                internalTrackers[s] = internalTracker;
                return(internalTracker);
            }
                );

            tracker.RaiseSnapshotRequest += (_, pair) => snapshotRequests.Add(pair);
            var snapshot = TrackerTests.InitialSnapshot();

            tracker.NewSnapshot(in snapshot);
            var xbtTracker = internalTrackers["XBT/USDT"];

            tracker.NewUnsubscribe("XBT/USDT");
            var update = TrackerTests.AskUpdate(false);

            tracker.NewUpdate(in update);

            Assert.Empty(xbtTracker.MisMatches);
            Assert.Single(snapshotRequests);
            Assert.Single(xbtTracker.AskSides);
            Assert.Single(xbtTracker.BidSides);
            Assert.Single(xbtTracker.Timstamps);
        }
        public void Ask()
        {
            var internalTrackers = new Dictionary <string, TestTracker>();
            var snapshotRequests = new List <string>();
            var tracker          = new SyncDictDelegator <TestTracker>(
                (s, i) =>
            {
                var internalTracker = new TestTracker(s, i);
                internalTrackers[s] = internalTracker;
                return(internalTracker);
            }
                );

            tracker.RaiseSnapshotRequest += (_, pair) => snapshotRequests.Add(pair);

            // all snapshots
            var snapshot        = TrackerTests.InitialSnapshot();
            var initialSnapshot = TrackerTests.InitialSnapshot("ETH/USDT");

            tracker.NewSnapshot(in snapshot);
            tracker.NewSnapshot(in initialSnapshot);
            var xbtTracker = internalTrackers["XBT/USDT"];
            var ethTracker = internalTrackers["ETH/USDT"];

            // snapshots processed
            Assert.Single(xbtTracker.AskSides);
            Assert.Single(xbtTracker.BidSides);
            Assert.Single(xbtTracker.Timstamps);
            Assert.Single(ethTracker.AskSides);
            Assert.Single(ethTracker.BidSides);
            Assert.Single(ethTracker.Timstamps);

            // all updates
            var update = TrackerTests.AskUpdate(true);

            tracker.NewUpdate(in update);
            var ethUpdate = TrackerTests.AskUpdate(true, "ETH/USDT");

            tracker.NewUpdate(in ethUpdate);

            // updates processed
            foreach (var cTracker in new[] { xbtTracker, ethTracker })
            {
                Assert.Empty(cTracker.MisMatches);
                Assert.Equal(2, cTracker.AskSides.Count);
                Assert.Equal(2, cTracker.BidSides.Count);
                Assert.Equal(2, cTracker.Timstamps.Count);
                Assert.Equal("1700000001.000000", cTracker.Timstamps[1]);
                var updatedAsks = cTracker.AskSides[1];
                Assert.Equal(new ExactFloat("2.0"), updatedAsks[new ExactFloat("61100.40000")]);
                Assert.Equal(new ExactFloat("1.0"), updatedAsks[new ExactFloat("61102.50000")]);
            }
            Assert.Empty(snapshotRequests);
        }
        public void AskMismatchMultiplePairs()
        {
            var internalTrackers = new Dictionary <string, TestTracker>();
            var snapshotRequests = new List <string>();
            var tracker          = new SyncDictDelegator <TestTracker>(
                (s, i) =>
            {
                var internalTracker = new TestTracker(s, i);
                internalTrackers[s] = internalTracker;
                return(internalTracker);
            }
                );

            tracker.RaiseSnapshotRequest += (_, pair) => snapshotRequests.Add(pair);

            // all snapshots
            var snapshot        = TrackerTests.InitialSnapshot();
            var initialSnapshot = TrackerTests.InitialSnapshot("ETH/USDT");

            tracker.NewSnapshot(in snapshot);
            tracker.NewSnapshot(in initialSnapshot);
            var xbtTracker = internalTrackers["XBT/USDT"];
            var ethTracker = internalTrackers["ETH/USDT"];

            // snapshots processed
            Assert.Single(xbtTracker.AskSides);
            Assert.Single(xbtTracker.BidSides);
            Assert.Single(xbtTracker.Timstamps);
            Assert.Single(ethTracker.AskSides);
            Assert.Single(ethTracker.BidSides);
            Assert.Single(ethTracker.Timstamps);

            // all updates
            var update = TrackerTests.AskUpdate(false);

            tracker.NewUpdate(in update);
            var ethUpdate = TrackerTests.AskUpdate(false, "ETH/USDT");

            tracker.NewUpdate(in ethUpdate);

            // updates processed
            Assert.Single(xbtTracker.MisMatches);
            Assert.Single(ethTracker.MisMatches);

            Assert.Equal("XBT/USDT", snapshotRequests[0]);
            Assert.Equal("ETH/USDT", snapshotRequests[1]);

            Assert.Equal(2, snapshotRequests.Count);
        }