예제 #1
0
        private Orderbook CalculateOrderbook(CrossRateCalcInfo info)
        {
            var sourceOrderbook1 = _orderbooks.GetValueOrDefault(info.Source1.Id); // ex: btcusd
            var sourceOrderbook2 = _orderbooks.GetValueOrDefault(info.Source2.Id); // ex: eurusd

            if (sourceOrderbook1 == null || sourceOrderbook2 == null)
            {
                var reason = "No orderbook for " + (sourceOrderbook1 == null
                                 ? info.Source1.Id
                                 : info.Source2.Id);
                Trace.Write(TraceLevelGroupEnum.WarnTrace, info.ResultingPairId,
                            "Skipping generating cross-rate: " + reason,
                            new { Event = "CrossRateSkipped", Reason = reason });
                return(null);
            }

            var bestPrices1 = _bestPricesService.Calc(sourceOrderbook1); // ex: btcusd
            var bestPrices2 = _bestPricesService.Calc(sourceOrderbook2); // ex: eurusd
            var crossBid    = GetCrossRate(bestPrices1, bestPrices2, info, true);
            var crossAsk    = GetCrossRate(bestPrices1, bestPrices2, info, false);

            Trace.Write(TraceLevelGroupEnum.Trace, info.ResultingPairId,
                        "Generating cross-rate",
                        new { Event = "CrossRateGenerated", Bid = crossBid, Ask = crossAsk });

            return(new Orderbook(info.ResultingPairId,
                                 ImmutableArray.Create(new OrderbookPosition(crossBid, 1)), // in future: calc whole orderbook
                                 ImmutableArray.Create(new OrderbookPosition(crossAsk, 1))));
        }
예제 #2
0
        private static decimal GetCrossRate(BestPrices bba1, BestPrices bba2, CrossRateCalcInfo info, bool bid)
        {
            var first  = GetRate(bba1, bid, !info.Source1.IsTransitoryAssetQuoting);
            var second = GetRate(bba2, bid, info.Source2.IsTransitoryAssetQuoting);

            return(first * second);
        }
예제 #3
0
 private CrossRateCalcInfoModel Convert([CanBeNull] CrossRateCalcInfo settings)
 {
     if (settings == null)
     {
         return(null);
     }
     return(_convertService.Convert <CrossRateCalcInfo, CrossRateCalcInfoModel>(settings));
 }
        public void IfSourceIsCrossRates_ShouldReturnCorrectResults()
        {
            //arrange
            var ethUsdCalcInfo = new CrossRateCalcInfo("ETHUSD",
                                                       new CrossRateSourceAssetPair("ETHBTC", true),
                                                       new CrossRateSourceAssetPair("BTCUSD", false));
            var btcEurCalcInfo = new CrossRateCalcInfo("BTCEUR",
                                                       new CrossRateSourceAssetPair("BTCUSD", true),
                                                       new CrossRateSourceAssetPair("EURUSD", true));
            var btcChfCalcInfo = new CrossRateCalcInfo("BTCCHF",
                                                       new CrossRateSourceAssetPair("BTCUSD", true),
                                                       new CrossRateSourceAssetPair("USDCHF", false));

            var ethBtcOrderbook = MakeOrderbook("ETHBTC");
            var eurUsdOrderbook = MakeOrderbook("EURUSD");
            var usdChfOrderbook = MakeOrderbook("USDCHF");
            var btcUsdOrderbook = MakeOrderbook("BTCUSD");

            _testSuit
            .Setup <ICrossRateCalcInfosService>(s => s.GetDependentAssetPairs("ETHBTC") == new[] { ethUsdCalcInfo })
            .Setup <ICrossRateCalcInfosService>(s => s.GetDependentAssetPairs("EURUSD") == new[] { btcEurCalcInfo })
            .Setup <ICrossRateCalcInfosService>(s => s.GetDependentAssetPairs("USDCHF") == new[] { btcChfCalcInfo })
            .Setup <ICrossRateCalcInfosService>(s =>
                                                s.GetDependentAssetPairs("BTCUSD") == new[] { ethUsdCalcInfo, btcEurCalcInfo, btcChfCalcInfo })
            .Setup <IBestPricesService>(s => s.Calc(ethBtcOrderbook) == new BestPrices(0.04m, 0.05m))
            .Setup <IBestPricesService>(s => s.Calc(eurUsdOrderbook) == new BestPrices(1.2m, 1.3m))
            .Setup <IBestPricesService>(s => s.Calc(usdChfOrderbook) == new BestPrices(0.98m, 0.99m))
            .Setup <IBestPricesService>(s => s.Calc(btcUsdOrderbook) == new BestPrices(6500, 6600))
            .Setup <IAssetPairSourceTypeService>(s => s.Get(It.IsNotNull <string>()) == AssetPairQuotesSourceTypeDomainEnum.CrossRates);

            //act
            var ethBtcResult = _testSuit.Sut.CalcDependentOrderbooks(ethBtcOrderbook);
            var eurUsdResult = _testSuit.Sut.CalcDependentOrderbooks(eurUsdOrderbook);
            var usdChfResult = _testSuit.Sut.CalcDependentOrderbooks(usdChfOrderbook);
            var btcUsdResult = _testSuit.Sut.CalcDependentOrderbooks(btcUsdOrderbook);

            //assert
            ethBtcResult.Should().BeEmpty();
            eurUsdResult.Should().BeEmpty();
            usdChfResult.Should().BeEmpty();
            //BTCEUR = BTCUSD * (ask EURUSD)^-1
            //BTCCHF = BTCUSD * USDCHF
            //ETHUSD = ETHBTC * BTCUSD
            btcUsdResult.Should().BeEquivalentTo(
                new[]
            {
                new Orderbook("BTCEUR",
                              ImmutableArray.Create(new OrderbookPosition(6500 * (1 / 1.3m), 1)),
                              ImmutableArray.Create(new OrderbookPosition(6600 * (1 / 1.2m), 1))),
                new Orderbook("BTCCHF",
                              ImmutableArray.Create(new OrderbookPosition(6500 * 0.98m, 1)),
                              ImmutableArray.Create(new OrderbookPosition(6600 * 0.99m, 1))),
                new Orderbook("ETHUSD",
                              ImmutableArray.Create(new OrderbookPosition(0.04m * 6500, 1)),
                              ImmutableArray.Create(new OrderbookPosition(0.05m * 6600, 1))),
            });
        }
예제 #5
0
 public AssetPairSettings(AssetPairQuotesSourceTypeDomainEnum quotesSourceType,
                          AssetPairExtPriceSettings extPriceSettings, CrossRateCalcInfo crossRateCalcInfo,
                          AggregateOrderbookSettings aggregateOrderbookSettings)
 {
     QuotesSourceType           = quotesSourceType;
     ExtPriceSettings           = extPriceSettings;
     CrossRateCalcInfo          = crossRateCalcInfo;
     AggregateOrderbookSettings = aggregateOrderbookSettings;
 }
예제 #6
0
 private void Validate(CrossRateCalcInfo crossRateCalcInfo)
 {
     crossRateCalcInfo.RequiredNotNull("crossRateCalcInfo for pair " + _assetPairId);
     crossRateCalcInfo.ResultingPairId.RequiredEqualsTo(_assetPairId,
                                                        "crossRateCalcInfo.ResultingPairId for pair " + _assetPairId);
     Validate(crossRateCalcInfo.Source1);
     Validate(crossRateCalcInfo.Source2);
     crossRateCalcInfo.Source1.Id.RequiredNotEqualsTo(crossRateCalcInfo.Source2.Id,
                                                      "crossRateCalcInfo.Source1.Id equals crossRateCalcInfo.Source2.Id for pair " + _assetPairId);
 }
        public void IfSourceIsNotCrossRates_ShouldNotCalculateCrossRates()
        {
            //arrange
            var ethUsdCalcInfo = new CrossRateCalcInfo("ETHUSD",
                                                       new CrossRateSourceAssetPair("ETHBTC", true),
                                                       new CrossRateSourceAssetPair("BTCUSD", false));
            var btcEurCalcInfo = new CrossRateCalcInfo("BTCEUR",
                                                       new CrossRateSourceAssetPair("BTCUSD", true),
                                                       new CrossRateSourceAssetPair("EURUSD", true));
            var btcChfCalcInfo = new CrossRateCalcInfo("BTCCHF",
                                                       new CrossRateSourceAssetPair("BTCUSD", true),
                                                       new CrossRateSourceAssetPair("USDCHF", false));

            var ethBtcOrderbook = MakeOrderbook("ETHBTC");
            var eurUsdOrderbook = MakeOrderbook("EURUSD");
            var usdChfOrderbook = MakeOrderbook("USDCHF");
            var btcUsdOrderbook = MakeOrderbook("BTCUSD");

            _testSuit
            .Setup <ICrossRateCalcInfosService>(s => s.GetDependentAssetPairs("ETHBTC") == new[] { ethUsdCalcInfo })
            .Setup <ICrossRateCalcInfosService>(s => s.GetDependentAssetPairs("EURUSD") == new[] { btcEurCalcInfo })
            .Setup <ICrossRateCalcInfosService>(s => s.GetDependentAssetPairs("USDCHF") == new[] { btcChfCalcInfo })
            .Setup <ICrossRateCalcInfosService>(s =>
                                                s.GetDependentAssetPairs("BTCUSD") == new[] { ethUsdCalcInfo, btcEurCalcInfo, btcChfCalcInfo })
            .Setup <IAssetPairSourceTypeService>(s => s.Get(It.IsNotNull <string>()) == AssetPairQuotesSourceTypeDomainEnum.External);

            //act
            var ethBtcResult = _testSuit.Sut.CalcDependentOrderbooks(ethBtcOrderbook);
            var eurUsdResult = _testSuit.Sut.CalcDependentOrderbooks(eurUsdOrderbook);
            var usdChfResult = _testSuit.Sut.CalcDependentOrderbooks(usdChfOrderbook);
            var btcUsdResult = _testSuit.Sut.CalcDependentOrderbooks(btcUsdOrderbook);

            //assert
            ethBtcResult.Should().BeEmpty();
            eurUsdResult.Should().BeEmpty();
            usdChfResult.Should().BeEmpty();
            btcUsdResult.Should().BeEmpty();
        }
 public void Update([NotNull] CrossRateCalcInfo info)
 {
     _settingsRootService.Update(info.ResultingPairId,
                                 old => new AssetPairSettings(old.QuotesSourceType, old.ExtPriceSettings, info, old.AggregateOrderbookSettings));
 }
예제 #9
0
 public AssetPairSettings(AssetPairQuotesSourceTypeDomainEnum quotesSourceType, AssetPairExtPriceSettings extPriceSettings, CrossRateCalcInfo crossRateCalcInfo)
 {
     QuotesSourceType  = quotesSourceType;
     ExtPriceSettings  = extPriceSettings;
     CrossRateCalcInfo = crossRateCalcInfo;
 }