예제 #1
0
        public void IfChangeContainMarketDefinitionTheMarketDefinitionIsSet()
        {
            var mc = new MarketChangeStub().WithMarketDefinition(new MarketDefinition());

            _market.OnChange(_change.WithMarketChange(mc).Build());
            Assert.NotNull(_market.MarketDefinition);
        }
예제 #2
0
        public void OnMarketChangeThePublishedTimeOfTheMessageIsRecorded()
        {
            const int PublishTime = 123;
            var       mc          = new MarketChangeStub();

            _market.OnChange(_change.WithMarketChange(mc).WithPublishTime(PublishTime).Build());

            Assert.Equal(PublishTime, _market.LastPublishedTime);
        }
예제 #3
0
        public void OnRunnerChangePublishTimeIsSet()
        {
            var runnerChange = new RunnerChangeStub();
            var mc           = new MarketChangeStub().WithRunnerChange(runnerChange);

            _market.OnChange(_change.WithMarketChange(mc).WithPublishTime(98765).Build());

            Assert.Equal(98765, _market.Runners[12345].LastPublishTime);
        }
예제 #4
0
        public void DoNotProcessRunnerWithNullSelectionId()
        {
            var mc = new MarketChangeStub()
                     .WithRunnerChange(new RunnerChangeStub().WithSelectionId(null))
                     .WithRunnerChange(new RunnerChangeStub().WithSelectionId(2));

            _market.OnChange(_change.WithMarketChange(mc).Build());

            Assert.Single(_market.Runners);
        }
예제 #5
0
        public void ReturnOverroundForSingleRunner(double price)
        {
            var rc = new RunnerChangeStub().WithSelectionId(1).WithBestAvailableToBack(0, price, 100);
            var mc = new MarketChangeStub().WithMarketId("1.2345").WithRunnerChange(rc);

            _market.OnChange(_change.WithMarketChange(mc).Build());
            var expected = 1 / price;

            Assert.Equal(expected, _market.Overround());
        }
예제 #6
0
        public void IfChangeIsForDifferentMarketDoNotProcessTheChange()
        {
            var mc = new MarketChangeStub()
                     .WithMarketId("Different MarketId")
                     .WithMarketDefinition(new MarketDefinition());

            _market.OnChange(_change.WithMarketChange(mc).Build());

            Assert.Null(_market.MarketDefinition);
        }
예제 #7
0
        public void IfChangeContainsTotalMatchedUpdateTotalMatched()
        {
            const int TotalMatched = 20;
            var       mc           = new MarketChangeStub()
                                     .WithTotalMatched(TotalMatched);

            _market.OnChange(_change.WithMarketChange(mc).Build());

            Assert.Equal(TotalMatched, _market.TotalAmountMatched);
        }
예제 #8
0
        public async Task OnMarketCloseNotCalledIfNotCancelled()
        {
            var rc = new RunnerChangeStub().WithBestAvailableToBack(0, 2.5, 2.99);
            var mc = new MarketChangeStub().WithTotalMatched(10).WithRunnerChange(rc);

            _subscription.WithMarketChange(mc);

            await _trader.TradeMarket("1.2345", 0, default);

            Assert.False(_orderManager.OnMarketCloseCalled);
        }
예제 #9
0
        public async Task UpdateMarketCacheUsedInStrategies()
        {
            var rc = new RunnerChangeStub().WithSelectionId(1).WithBestAvailableToBack(0, 2.5, 9.99);
            var mc = new MarketChangeStub().WithRunnerChange(rc);

            _subscription.WithMarketChange(mc);
            await _trader.TradeMarket("1.2345", 0, CancellationToken.None);

            Assert.Equal("CASOMM", _subscription.Actions);
            Assert.Equal(1, _strategy.RunnerCount());
        }
예제 #10
0
        public void ReturnOverroundForMultipleRunners(double price1, double price2)
        {
            var rc  = new RunnerChangeStub().WithSelectionId(1).WithBestAvailableToBack(0, price1, 100);
            var rc2 = new RunnerChangeStub().WithSelectionId(2).WithBestAvailableToBack(0, price2, 100);
            var mc  = new MarketChangeStub().WithMarketId("1.2345").WithRunnerChange(rc).WithRunnerChange(rc2);

            _market.OnChange(_change.WithMarketChange(mc).Build());
            var expected = (1 / price1) + (1 / price2);

            Assert.Equal(expected, _market.Overround());
        }
예제 #11
0
        public void IfChangeDoesNotContainTotalMatchedDoNotClearTotalMatched()
        {
            const int TotalMatched = 20;
            var       mc           = new MarketChangeStub()
                                     .WithTotalMatched(TotalMatched);

            _market.OnChange(_change.WithMarketChange(mc).Build());

            _market.OnChange(_change.WithMarketChange(new MarketChangeStub()).Build());

            Assert.Equal(TotalMatched, _market.TotalAmountMatched);
        }
예제 #12
0
        public async Task UpdateMarketCacheWithPublishedTime(long pt)
        {
            _subscription.PublishTime = pt;
            var rc = new RunnerChangeStub().WithSelectionId(1).WithBestAvailableToBack(0, 2.5, 9.99);
            var mc = new MarketChangeStub().WithRunnerChange(rc);

            _subscription.WithMarketChange(mc);
            await _trader.TradeMarket("1.2345", 0, CancellationToken.None);

            Assert.Equal("CASOMM", _subscription.Actions);
            Assert.Equal(pt, _strategy.LastPublishedTime());
        }
예제 #13
0
        public void IfChangeContainsRunnersAddThemToTheCache()
        {
            var mc = new MarketChangeStub()
                     .WithRunnerChange(new RunnerChangeStub().WithSelectionId(1))
                     .WithRunnerChange(new RunnerChangeStub().WithSelectionId(2));

            _market.OnChange(_change.WithMarketChange(mc).Build());

            const int ExpectedRunnerCount = 2;

            Assert.Equal(ExpectedRunnerCount, _market.Runners.Count);
        }
예제 #14
0
        public void IfChangeContainsRunnerUpdateRunnerCache()
        {
            const int TotalMatched = 20;
            var       mc           = new MarketChangeStub()
                                     .WithRunnerChange(new RunnerChangeStub()
                                                       .WithTotalMatched(TotalMatched));

            _market.OnChange(_change.WithMarketChange(mc).Build());

            Assert.Equal(
                TotalMatched, _market.Runners[DefaultSelectionId].TotalMatched);
        }
예제 #15
0
        public void IfChangeAsksForCacheToBeReplacedTotalAmountMatchedIsCleared()
        {
            var mc1 = new MarketChangeStub().WithTotalMatched(20);

            _market.OnChange(_change.WithMarketChange(mc1).Build());

            var mc2 = new MarketChangeStub().WithReplaceCache();

            _market.OnChange(_change.WithMarketChange(mc2).Build());

            Assert.Equal(0, _market.TotalAmountMatched);
        }
예제 #16
0
        public void WhenMarketChangeIsForWrongMarketThePublishedTimeOfTheMessageIsNotUpdated()
        {
            const int PublishTime = 123;
            var       mc          = new MarketChangeStub();

            _market.OnChange(_change.WithMarketChange(mc).WithPublishTime(PublishTime).Build());

            var mc2 = new MarketChangeStub().WithMarketId("WrongId");

            _market.OnChange(_change.New().WithMarketChange(mc2).WithPublishTime(456).Build());

            Assert.Equal(PublishTime, _market.LastPublishedTime);
        }
예제 #17
0
        public void IfChangeAsksForCacheToBeReplacedRunnersAreCleared()
        {
            var mc1 = new MarketChangeStub()
                      .WithRunnerChange(new RunnerChangeStub());

            _market.OnChange(_change.WithMarketChange(mc1).Build());

            var mc2 = new MarketChangeStub().WithReplaceCache();

            _market.OnChange(_change.WithMarketChange(mc2).Build());

            Assert.Empty(_market.Runners);
        }
예제 #18
0
        public void IfChangeAsksForCacheToBeReplacedMarketDefinitionIsCleared()
        {
            var mc1 = new MarketChangeStub()
                      .WithMarketDefinition(new MarketDefinition());

            _market.OnChange(_change.WithMarketChange(mc1).Build());

            var mc2 = new MarketChangeStub().WithReplaceCache();

            _market.OnChange(_change.WithMarketChange(mc2).Build());

            Assert.Null(_market.MarketDefinition);
        }
예제 #19
0
        public async Task OnMarketCloseCalledIfCancelled()
        {
            var rc = new RunnerChangeStub().WithBestAvailableToBack(0, 2.5, 2.99);
            var mc = new MarketChangeStub().WithTotalMatched(10).WithRunnerChange(rc);

            _subscription.WithMarketChange(mc);

            using var source = new CancellationTokenSource();
            source.Cancel();
            await _trader.TradeMarket("1.2345", 0, source.Token);

            Assert.True(_orderManager.OnMarketCloseCalled);
        }
예제 #20
0
        public void StrategyIsToldWhatHasBeenUpdated()
        {
            var rc = new RunnerChangeStub()
                     .WithSelectionId(1)
                     .WithBestAvailableToBack(0, 2.5, 100)
                     .WithBestAvailableToLay(0, 3.0, 200);
            var mc = new MarketChangeStub().WithRunnerChange(rc);

            _market.OnChange(_change.WithMarketChange(mc).Build());

            GetOrders(mc, 0);
            Assert.Single(Market.Runners);
            Assert.Equal(mc, _mChange);
        }
예제 #21
0
        public async Task UpdateMarketCacheWithMultipleChanges()
        {
            var rc  = new RunnerChangeStub().WithSelectionId(1).WithBestAvailableToBack(0, 2.5, 9.99);
            var mc  = new MarketChangeStub().WithRunnerChange(rc);
            var rc2 = new RunnerChangeStub().WithSelectionId(2).WithBestAvailableToBack(0, 2.5, 9.99);
            var mc2 = new MarketChangeStub().WithRunnerChange(rc2);

            _subscription.WithMarketChanges(new List <MarketChange> {
                mc, mc2
            });
            await _trader.TradeMarket("1.2345", 0, CancellationToken.None);

            Assert.Equal("CASOMM", _subscription.Actions);
            Assert.Equal(2, _strategy.RunnerCount());
        }
예제 #22
0
        public void HandleNullSelectionIdInRunnerDefinition()
        {
            var rd = new RunnerDefinition {
                AdjustmentFactor = 54.32
            };
            var md = new MarketDefinition
            {
                Runners = new List <RunnerDefinition> {
                    rd
                },
            };
            var mc = new MarketChangeStub().WithMarketDefinition(md);

            _market.OnChange(_change.WithMarketChange(mc).Build());
        }
예제 #23
0
        public void ReturnOverroundOnlyIfRunnerHasBestPriceAvailable(double price)
        {
            var rc  = new RunnerChangeStub().WithSelectionId(1).WithBestAvailableToBack(0, price, 100);
            var rc2 = new RunnerChangeStub().WithSelectionId(2).WithBestAvailableToBack(1, 2, 100);
            var rc3 = new RunnerChangeStub().WithSelectionId(3);
            var mc  = new MarketChangeStub()
                      .WithMarketId("1.2345")
                      .WithRunnerChange(rc)
                      .WithRunnerChange(rc2)
                      .WithRunnerChange(rc3);

            _market.OnChange(_change.WithMarketChange(mc).Build());
            var expected = 1 / price;

            Assert.Equal(expected, _market.Overround());
        }
예제 #24
0
        public void IfChangeDoesNotContainMarketDefinitionAnyPreviousMarketDefinitionShouldNotBeCleared()
        {
            var mc1 = new MarketChangeStub().WithMarketDefinition(new MarketDefinition {
                Venue = "Test Venue"
            });
            var c1 = new ChangeMessageStub().WithMarketChange(mc1).Build();

            _market.OnChange(c1);

            var mc = new MarketChange {
                MarketId = "1.2345"
            };
            var c2 = _change.WithMarketChange(mc).Build();

            _market.OnChange(c2);

            Assert.Equal("Test Venue", _market.MarketDefinition.Venue);
        }
예제 #25
0
        public async Task StopProcessingMessageIfCancelled()
        {
            var source = new CancellationTokenSource();

            _subscription.CancelAfterThisManyMessages(1, source);

            var rc  = new RunnerChangeStub().WithSelectionId(1).WithBestAvailableToBack(0, 2.5, 9.99);
            var mc  = new MarketChangeStub().WithRunnerChange(rc);
            var rc2 = new RunnerChangeStub().WithSelectionId(2).WithBestAvailableToBack(0, 2.5, 9.99);
            var mc2 = new MarketChangeStub().WithRunnerChange(rc2);

            _subscription.WithMarketChange(mc);
            _subscription.WithMarketChange(mc2);

            await _trader.TradeMarket("1.2345", 0, source.Token);

            Assert.Equal("CASOMD", _subscription.Actions);
        }
예제 #26
0
        public async Task ProcessLastMessageBeforeCancelling()
        {
            var source = new CancellationTokenSource();

            _subscription.CancelAfterThisManyMessages(2, source);

            var rc  = new RunnerChangeStub().WithSelectionId(1).WithBestAvailableToBack(0, 2.5, 9.99);
            var mc  = new MarketChangeStub().WithRunnerChange(rc);
            var rc2 = new RunnerChangeStub().WithSelectionId(2).WithBestAvailableToBack(0, 2.5, 9.99);
            var mc2 = new MarketChangeStub().WithRunnerChange(rc2);

            _subscription.WithMarketChange(mc);
            _subscription.WithMarketChange(mc2);

            await _trader.TradeMarket("1.2345", 0, source.Token);

            Assert.Equal(1, _strategy.MarketUpdateCount);
        }
예제 #27
0
        public void IfChangeAsksForCacheToBeReplacedRunnersAreReplaced()
        {
            var mc1 = new MarketChangeStub()
                      .WithRunnerChange(new RunnerChangeStub());

            _market.OnChange(_change.WithMarketChange(mc1).Build());

            const int TotalMatched = 20;
            var       mc2          = new MarketChangeStub()
                                     .WithReplaceCache()
                                     .WithRunnerChange(new RunnerChangeStub()
                                                       .WithTotalMatched(TotalMatched));

            _market.OnChange(_change.WithMarketChange(mc2).Build());

            Assert.Equal(
                TotalMatched, _market.Runners[DefaultSelectionId].TotalMatched);
        }
예제 #28
0
        public async Task AdjustBankForMarketLiability(double bank, double liability)
        {
            var rc = new RunnerChangeStub().WithBestAvailableToBack(0, 2.5, 2.99);
            var mc = new MarketChangeStub().WithTotalMatched(10).WithRunnerChange(rc);

            _subscription.WithMarketChange(mc);

            var orc = new OrderRunnerChangeStub().WithUnmatchedBack(2.5, liability);
            var oc  = new OrderChangeStub().WithOrderRunnerChange(orc);

            _subscription.WithOrderChange(oc);
            _subscription.WithMarketChange(mc);

            _trader.AddStrategy(new StrategySpy());
            await _trader.TradeMarket("1.2345", bank, default);

            Assert.Equal(Math.Round((bank - Math.Round(liability, 2)) / 2, 2), _strategy.Stake);
        }
예제 #29
0
        public void HandleRunnerDefinitionForRunnerThatDoesNotExist()
        {
            var rc = new RunnerChangeStub();
            var rd = new RunnerDefinition
            {
                SelectionId = 1, AdjustmentFactor = 54.32,
            };
            var md = new MarketDefinition
            {
                Runners = new List <RunnerDefinition> {
                    rd
                },
            };
            var mc = new MarketChangeStub()
                     .WithMarketDefinition(md)
                     .WithRunnerChange(rc);

            _market.OnChange(_change.WithMarketChange(mc).Build());
        }
예제 #30
0
        public void OnMarketDefinitionAdjustmentFactorIsSet()
        {
            var rc = new RunnerChangeStub();
            var rd = new RunnerDefinition
            {
                SelectionId = 12345, AdjustmentFactor = 54.32,
            };
            var md = new MarketDefinition
            {
                Runners = new List <RunnerDefinition> {
                    rd
                },
            };
            var mc = new MarketChangeStub()
                     .WithMarketDefinition(md).WithRunnerChange(rc);

            _market.OnChange(_change.WithMarketChange(mc).Build());
            Assert.Equal(54.32, _market.Runners[12345].AdjustmentFactor);
        }