diff --git a/BTCPayServer.Tests/RateRulesTest.cs b/BTCPayServer.Tests/RateRulesTest.cs index 2d3ce1446..53e89f842 100644 --- a/BTCPayServer.Tests/RateRulesTest.cs +++ b/BTCPayServer.Tests/RateRulesTest.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Text; using BTCPayServer.Rating; using Xunit; +using System.Globalization; namespace BTCPayServer.Tests { @@ -127,7 +128,7 @@ namespace BTCPayServer.Tests rule2.ExchangeRates.SetRate("coinbase", CurrencyPair.Parse("BTC_CAD"), new BidAsk(1000m)); Assert.True(rule2.Reevaluate()); Assert.Equal("(1 / (2000 * (-3 + 1000 + 50 - 5))) * 1.1", rule2.ToString(true)); - Assert.Equal(( 1.0m / (2000m * (-3m + 1000m + 50m - 5m))) * 1.1m, rule2.Value.Value); + Assert.Equal((1.0m / (2000m * (-3m + 1000m + 50m - 5m))) * 1.1m, rule2.Value.Value); //////// // Make sure kraken is not converted to CurrencyPair @@ -151,7 +152,7 @@ namespace BTCPayServer.Tests rule2.ExchangeRates.SetRate("kraken", CurrencyPair.Parse("BTC_USD"), new BidAsk(6000m, 6100m)); Assert.True(rule2.Reevaluate()); Assert.Equal("1 / (6000, 6100)", rule2.ToString(true)); - Assert.Equal(1m/6100m, rule2.Value.Value); + Assert.Equal(1m / 6100m, rule2.Value.Value); // Make sure the inverse has more priority than X_X or CDNT_X builder = new StringBuilder(); @@ -164,6 +165,15 @@ namespace BTCPayServer.Tests rule2.ExchangeRates.SetRate("coinaverage", CurrencyPair.Parse("BTC_USD"), new BidAsk(6000m, 6100m)); Assert.True(rule2.Reevaluate()); Assert.Equal("1 / 10", rule2.ToString(false)); + + // Make sure an inverse can be solved on an exchange + builder = new StringBuilder(); + builder.AppendLine("X_X = coinaverage(X_X);"); + Assert.True(RateRules.TryParse(builder.ToString(), out rules)); + rule2 = rules.GetRuleFor(CurrencyPair.Parse("USD_BTC")); + rule2.ExchangeRates.SetRate("coinaverage", CurrencyPair.Parse("BTC_USD"), new BidAsk(6000m, 6100m)); + Assert.True(rule2.Reevaluate()); + Assert.Equal($"({(1m / 6100m).ToString(CultureInfo.InvariantCulture)}, {(1m / 6000m).ToString(CultureInfo.InvariantCulture)})", rule2.ToString(true)); } } } diff --git a/BTCPayServer/Rating/ExchangeRates.cs b/BTCPayServer/Rating/ExchangeRates.cs index 81eb92e35..67531c931 100644 --- a/BTCPayServer/Rating/ExchangeRates.cs +++ b/BTCPayServer/Rating/ExchangeRates.cs @@ -63,8 +63,16 @@ namespace BTCPayServer.Rating if (ByExchange.TryGetValue(exchangeName, out var rates)) { var rate = rates.FirstOrDefault(r => r.CurrencyPair == currencyPair); - if (rate != null) + if(rate != null) + { rate.BidAsk = bidAsk; + } + var invPair = currencyPair.Inverse(); + var invRate = rates.FirstOrDefault(r => r.CurrencyPair == invPair); + if (invRate != null) + { + invRate.BidAsk = bidAsk?.Inverse(); + } } } public BidAsk GetRate(string exchangeName, CurrencyPair currencyPair) @@ -135,7 +143,7 @@ namespace BTCPayServer.Rating return new BidAsk(1.0m / Ask, 1.0m / Bid); } - public static BidAsk operator+(BidAsk a, BidAsk b) + public static BidAsk operator +(BidAsk a, BidAsk b) { return new BidAsk(a.Bid + b.Bid, a.Ask + b.Ask); } @@ -169,7 +177,7 @@ namespace BTCPayServer.Rating return new BidAsk(a.Bid / b.Ask, a.Ask / b.Bid); } - public static BidAsk operator-(BidAsk a, BidAsk b) + public static BidAsk operator -(BidAsk a, BidAsk b) { return new BidAsk(a.Bid - b.Bid, a.Ask - b.Ask); }