From cecfbcba48b84ff56109c7d1c67f548ba0eabf22 Mon Sep 17 00:00:00 2001 From: Maxxx555 <73590368+Maxxx555@users.noreply.github.com> Date: Mon, 21 Sep 2026 12:54:15 +0300 Subject: [PATCH] ArrayConverter: parse string decimals in scientific notation (#292) --- .../ConverterTests/ArrayConverterTests.cs | 25 +++++++++++++++++++ .../SystemTextJson/ArrayConverter.cs | 3 +++ 2 files changed, 28 insertions(+) diff --git a/CryptoExchange.Net.UnitTests/ConverterTests/ArrayConverterTests.cs b/CryptoExchange.Net.UnitTests/ConverterTests/ArrayConverterTests.cs index 6069359f..638b750c 100644 --- a/CryptoExchange.Net.UnitTests/ConverterTests/ArrayConverterTests.cs +++ b/CryptoExchange.Net.UnitTests/ConverterTests/ArrayConverterTests.cs @@ -62,6 +62,31 @@ namespace CryptoExchange.Net.UnitTests.ConverterTests Assert.That(deserialized.Prop8!.Prop31, Is.EqualTo(5)); Assert.That(deserialized.Prop8.Prop32, Is.EqualTo("101")); } + + [TestCase("[\"4.803E-5\",\"9.623e-4\",\"0.0010025\"]", 0.00004803, 0.0009623, 0.0010025)] + [TestCase("[\"81251.5\",\"1E+2\",\"-2.5E-3\"]", 81251.5, 100, -0.0025)] + [TestCase("[4.803E-5,9.623e-4,0.0010025]", 0.00004803, 0.0009623, 0.0010025)] + public void TestArrayConverterDecimalInScientificNotation(string json, decimal expected1, decimal expected2, decimal expected3) + { + // Some exchanges send small prices as strings in scientific notation, for example the + // Kucoin futures kline stream: "candles":["1789830000","4.803E-5","4.807E-5",...] + var deserialized = JsonSerializer.Deserialize(json); + + Assert.That(deserialized!.Prop1, Is.EqualTo(expected1)); + Assert.That(deserialized.Prop2, Is.EqualTo(expected2)); + Assert.That(deserialized.Prop3, Is.EqualTo(expected3)); + } + } + + [JsonConverter(typeof(ArrayConverter))] + public record TestDecimal + { + [ArrayProperty(0)] + public decimal Prop1 { get; set; } + [ArrayProperty(1)] + public decimal? Prop2 { get; set; } + [ArrayProperty(2)] + public decimal Prop3 { get; set; } } [JsonConverter(typeof(ArrayConverter))] diff --git a/CryptoExchange.Net/Converters/SystemTextJson/ArrayConverter.cs b/CryptoExchange.Net/Converters/SystemTextJson/ArrayConverter.cs index 74f49158..51c02d0a 100644 --- a/CryptoExchange.Net/Converters/SystemTextJson/ArrayConverter.cs +++ b/CryptoExchange.Net/Converters/SystemTextJson/ArrayConverter.cs @@ -173,6 +173,9 @@ namespace CryptoExchange.Net.Converters.SystemTextJson if (targetType.IsAssignableFrom(value?.GetType())) attribute.PropertyInfo.SetValue(result, value); + else if (value is string stringValue && targetType == typeof(decimal)) + // Convert.ChangeType doesn't accept scientific notation, which some exchanges use for small values ("4.803E-5") + attribute.PropertyInfo.SetValue(result, ExchangeHelpers.ParseDecimal(stringValue)); else attribute.PropertyInfo.SetValue(result, value == null ? null : Convert.ChangeType(value, targetType, CultureInfo.InvariantCulture)); }