diff --git a/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs b/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs index 674c535c..41d8d8f8 100644 --- a/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs +++ b/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs @@ -308,7 +308,7 @@ protected override async Task OnGetDeltaOrderBookWebSocketAsync(Acti protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { JToken obj = await MakeJsonRequestAsync($"/depth?symbol={marketSymbol}&limit={maxCount}", BaseUrlApi); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(obj, sequence: "lastUpdateId", maxCount: maxCount); + return obj.ParseOrderBookFromJTokenArrays(sequence: "lastUpdateId"); } protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) diff --git a/src/ExchangeSharp/API/Exchanges/Bithumb/ExchangeBithumbAPI.cs b/src/ExchangeSharp/API/Exchanges/Bithumb/ExchangeBithumbAPI.cs index 5d39f991..fe34860d 100644 --- a/src/ExchangeSharp/API/Exchanges/Bithumb/ExchangeBithumbAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Bithumb/ExchangeBithumbAPI.cs @@ -151,7 +151,7 @@ protected override async Task>> protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { var data = await MakeRequestBithumbAsync(marketSymbol, "/public/orderbook/$SYMBOL$"); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenDictionaries(data.Item1, amount: "quantity", sequence: "timestamp", maxCount: maxCount); + return data.Item1.ParseOrderBookFromJTokenDictionaries(amount: "quantity", sequence: "timestamp"); } protected override async Task>> OnGetOrderBooksAsync(int maxCount = 100) diff --git a/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs b/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs index fda5157c..9d385f7e 100644 --- a/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs @@ -133,7 +133,7 @@ protected override async Task OnGetTickerAsync(string marketSymb protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { JToken token = await MakeBitstampRequestAsync("/order_book/" + marketSymbol); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token, maxCount: maxCount); + return token.ParseOrderBookFromJTokenArrays(); } protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) @@ -254,7 +254,7 @@ protected override async Task OnGetOrderDetailsAsync(string // status can be 'Canceled', 'Open' or 'Finished' var statusCode = result.Value("status"); var status = GetOrderResultFromStatus(statusCode, anyTransaction); - + // empty transaction array means that order is InQueue or Open and AmountFilled == 0 // return empty order in this case. no any additional info available at this point if (!anyTransaction) diff --git a/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs b/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs index 7e588999..77f414a5 100644 --- a/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs @@ -271,7 +271,7 @@ protected override async Task OnGetOrderBookAsync(string mark } JToken token = await MakeJsonRequestAsync("/markets/" + marketSymbol + "/orderbook" + "?depth=" + maxCount); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenDictionaries(token, "ask", "bid", "rate", "quantity", maxCount: maxCount); + return token.ParseOrderBookFromJTokenDictionaries("ask", "bid", "rate", "quantity"); } /// Gets the deposit history for a symbol diff --git a/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs b/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs index 3e7c660a..a60c5872 100644 --- a/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs @@ -586,7 +586,7 @@ protected override async Task OnGetOrderBookAsync(string mark { string url = "/products/" + marketSymbol.ToUpperInvariant() + "/book?level=2"; JToken token = await MakeJsonRequestAsync(url); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token, maxCount: maxCount); + return token.ParseOrderBookFromJTokenArrays(); } protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) @@ -661,7 +661,7 @@ protected override async Task> OnGetFeesAsync() JObject token = await MakeJsonRequestAsync("/fees", null, await GetNoncePayloadAsync(), "GET"); /* * We can chose between maker and taker fee, but currently ExchangeSharp only supports 1 fee rate per symbol. - * Here, we choose taker fee, which are usually higher + * Here, we choose taker fee, which are usually higher */ decimal makerRate = token["taker_fee_rate"].Value(); //percentage between 0 and 1 diff --git a/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs b/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs index 8a8407ea..71b7c0ef 100644 --- a/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs @@ -211,7 +211,7 @@ protected override async Task OnGetTickerAsync(string marketSymb protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { JToken obj = await MakeJsonRequestAsync($"/order_book?symbol={marketSymbol}&limit={maxCount}"); - var result = ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(obj, sequence: "date", maxCount: maxCount); + var result = obj.ParseOrderBookFromJTokenArrays(sequence: "date"); result.LastUpdatedUtc = CryptoUtility.UnixTimeStampToDateTimeSeconds(obj["date"].ConvertInvariant()); result.MarketSymbol = marketSymbol; return result; diff --git a/src/ExchangeSharp/API/Exchanges/FTX/ExchangeFTXAPI.cs b/src/ExchangeSharp/API/Exchanges/FTX/ExchangeFTXAPI.cs index cca51d07..494ee2f8 100644 --- a/src/ExchangeSharp/API/Exchanges/FTX/ExchangeFTXAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/FTX/ExchangeFTXAPI.cs @@ -270,10 +270,10 @@ protected async override Task> OnGetOpenOrderDe { continue; } - + markets.Add(ParseOrder(token)); } - + return markets; } @@ -282,7 +282,7 @@ protected async override Task OnGetOrderBookAsync(string mark { JToken response = await MakeJsonRequestAsync($"/markets/{marketSymbol}/orderbook?depth={maxCount}"); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(response, maxCount: maxCount); + return response.ParseOrderBookFromJTokenArrays(); } /// @@ -519,8 +519,8 @@ private ExchangeOrderResult ParseOrder(JToken token) AmountFilled = token["filledSize"].ConvertInvariant(), ClientOrderId = token["clientId"].ToStringInvariant(), Result = token["status"].ToStringInvariant().ToExchangeAPIOrderResult(token["size"].ConvertInvariant() - token["filledSize"].ConvertInvariant()), - ResultCode = token["status"].ToStringInvariant() - }; + ResultCode = token["status"].ToStringInvariant() + }; } #endregion diff --git a/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs b/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs index d72df2bc..6dc67282 100644 --- a/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs @@ -206,7 +206,7 @@ protected override async Task OnGetOrderBookAsync(string symb } */ - var orderBook = ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(json, sequence: "current", maxCount: maxCount); + var orderBook = json.ParseOrderBookFromJTokenArrays(sequence: "current"); orderBook.LastUpdatedUtc = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(json["current"].ConvertInvariant()); return orderBook; } diff --git a/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs b/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs index c4c5d5ac..37891ce2 100644 --- a/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs @@ -248,7 +248,7 @@ protected override async Task OnGetTickerAsync(string marketSymb protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { JToken obj = await MakeJsonRequestAsync("/book/" + marketSymbol + "?limit_bids=" + maxCount + "&limit_asks=" + maxCount); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenDictionaries(obj, maxCount: maxCount); + return obj.ParseOrderBookFromJTokenDictionaries(); } protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) diff --git a/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs b/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs index 3e22b35b..e6d9fd8f 100644 --- a/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs @@ -186,7 +186,7 @@ protected override async Task> OnGetRecentTradesAsync protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { JToken token = await MakeJsonRequestAsync("/public/orderbook/" + marketSymbol + "?limit=" + maxCount.ToStringInvariant()); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenDictionaries(token, asks: "ask", bids: "bid", amount: "size", maxCount: maxCount); + return token.ParseOrderBookFromJTokenDictionaries(asks: "ask", bids: "bid", amount: "size"); } protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) @@ -195,11 +195,11 @@ protected override async Task OnGetHistoricalTradesAsync(Func 1000) ? 1000 : (int)limit; + var maxRequestLimit = (limit == null || limit < 1 || limit > 1000) ? 1000 : (int)limit; //note that sort must come after limit, else returns default 100 trades, sort default is DESC - JToken obj = await MakeJsonRequestAsync("/public/trades/" + marketSymbol + "?limit=" + maxRequestLimit + "?sort=DESC"); + JToken obj = await MakeJsonRequestAsync("/public/trades/" + marketSymbol + "?limit=" + maxRequestLimit + "?sort=DESC"); //JToken obj = await MakeJsonRequestAsync("/public/trades/" + marketSymbol); if (obj.HasValues) { diff --git a/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs b/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs index 7c27502f..44fa371b 100644 --- a/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs @@ -346,7 +346,7 @@ protected override async Task OnGetDeltaOrderBookWebSocketAsync(Acti var ch = token["ch"].ToStringInvariant(); var sArray = ch.Split('.'); var marketSymbol = sArray[1].ToStringInvariant(); - ExchangeOrderBook book = ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token["tick"], maxCount: maxCount); + ExchangeOrderBook book = token["tick"].ParseOrderBookFromJTokenArrays(); book.MarketSymbol = marketSymbol; callback(book); }, async (_socket) => @@ -433,7 +433,7 @@ protected override async Task OnGetOrderBookAsync(string mark [7995, 0.88], */ JToken obj = await MakeJsonRequestAsync("/market/depth?symbol=" + marketSymbol + "&type=step0", BaseUrl, null); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(obj["tick"], sequence: "ts", maxCount: maxCount); + return obj["tick"].ParseOrderBookFromJTokenArrays(sequence: "ts"); } protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) diff --git a/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs b/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs index b8d8c30e..db236753 100644 --- a/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs @@ -408,7 +408,7 @@ protected override async Task> OnGetMarketSymbolsAsync(bool } protected internal override async Task> OnGetMarketSymbolsMetadataAsync() - { + { var markets = new List(); JToken allPairs = await MakeJsonRequestAsync("/0/public/AssetPairs"); var res = (from prop in allPairs.Children() select prop).ToArray(); @@ -546,7 +546,7 @@ protected override Task OnInitializeAsync() protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { JToken obj = await MakeJsonRequestAsync("/0/public/Depth?pair=" + marketSymbol + "&count=" + maxCount); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(obj[marketSymbol], maxCount: maxCount); + return obj[marketSymbol].ParseOrderBookFromJTokenArrays(); } protected override async Task> OnGetRecentTradesAsync(string marketSymbol, int? limit = null) diff --git a/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs b/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs index 7c19ce30..7f3bd5e0 100644 --- a/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs @@ -159,7 +159,7 @@ protected internal override async Task> OnGetMarketS protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { JToken token = await MakeJsonRequestAsync("/market/orderbook/level2_" + maxCount + "?symbol=" + marketSymbol); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token, asks: "asks", bids: "bids", maxCount: maxCount); + return token.ParseOrderBookFromJTokenArrays(asks: "asks", bids: "bids"); } protected override async Task OnGetTickerAsync(string marketSymbol) diff --git a/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs b/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs index 93e5d8e4..2afc1bc5 100644 --- a/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs @@ -100,7 +100,7 @@ protected override async Task OnGetOrderBookAsync(string symb maxCount = Math.Min(maxCount, ORDER_BOOK_MAX_SIZE); JToken resp = await this.MakeJsonRequestAsync($"/depth.do?symbol={symbol}&size={maxCount}&merge=0"); CheckResponseToken(resp); - ExchangeOrderBook book = ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(resp, maxCount: maxCount); + ExchangeOrderBook book = resp.ParseOrderBookFromJTokenArrays(); book.SequenceId = resp["timestamp"].ConvertInvariant(); return book; } diff --git a/src/ExchangeSharp/API/Exchanges/OKGroup/ExchangeOKExAPI.cs b/src/ExchangeSharp/API/Exchanges/OKGroup/ExchangeOKExAPI.cs index dcba9bda..f02e84f0 100644 --- a/src/ExchangeSharp/API/Exchanges/OKGroup/ExchangeOKExAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/OKGroup/ExchangeOKExAPI.cs @@ -186,7 +186,7 @@ protected override async Task OnGetOrderBookAsync(string mark { var token = await MakeJsonRequestAsync($"/market/books?instId={marketSymbol}&sz={maxCount}", BaseUrlV5); - return token[0].ParseOrderBookFromJTokenArrays(maxCount: maxCount); + return token[0].ParseOrderBookFromJTokenArrays(); } protected override async Task> OnGetCandlesAsync(string marketSymbol, @@ -420,7 +420,7 @@ protected override async Task OnGetDeltaOrderBookWebSocketAsync(Acti marketSymbols = await AddMarketSymbolsToChannel(_socket, "books-l2-tbt", marketSymbols); }, (_socket, symbol, sArray, token) => { - ExchangeOrderBook book = token.ParseOrderBookFromJTokenArrays(maxCount: maxCount); + ExchangeOrderBook book = token.ParseOrderBookFromJTokenArrays(); book.MarketSymbol = symbol; callback(book); return Task.CompletedTask; diff --git a/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs b/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs index 73e1c009..df6fcbda 100644 --- a/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs +++ b/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs @@ -299,7 +299,7 @@ protected override async Task OnGetOrderBookAsync(string mark { var token = await MakeRequestOkexAsync(marketSymbol, $"/spot/v3/instruments/{marketSymbol}/book", BaseUrlV3); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token.Item1, maxCount: maxCount); + return token.Item1.ParseOrderBookFromJTokenArrays(); } protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) diff --git a/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs b/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs index d248e89b..b59db732 100644 --- a/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs +++ b/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs @@ -14,6 +14,7 @@ The above copyright notice and this permission notice shall be included in all c using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using ExchangeSharp.Kraken; using ExchangeSharp.BinanceGroup; @@ -155,9 +156,26 @@ async Task innerCallback(ExchangeOrderBook newOrderBook) } fullOrderBook.LastUpdatedUtc = CryptoUtility.UtcNow; + trimFullOrderBook(fullOrderBook); callback(fullOrderBook); } + void trimFullOrderBook(ExchangeOrderBook fBook) + { + var asks = fBook.Asks.Take(maxCount).ToList(); + var bids = fBook.Bids.Take(maxCount).ToList(); + fBook.Asks.Clear(); + fBook.Bids.Clear(); + foreach (var kvp in asks) + { + fBook.Asks.Add(kvp.Key, kvp.Value); + } + foreach (var kvp in bids) + { + fBook.Bids.Add(kvp.Key, kvp.Value); + } + } + IWebSocket socket = await api.GetDeltaOrderBookWebSocketAsync(async (b) => { try @@ -335,36 +353,26 @@ public static async Task PlaceSafeMarketOrderAsync(this Exc /// Token /// Asks key /// Bids key - /// Max count /// Order book internal static ExchangeOrderBook ParseOrderBookFromJTokenArrays ( this JToken token, string asks = "asks", string bids = "bids", - string sequence = "ts", - int maxCount = 100 + string sequence = "ts" ) { var book = new ExchangeOrderBook { SequenceId = token[sequence].ConvertInvariant() }; - foreach (JArray array in token[asks]) + foreach (var array in token[asks]) { var depth = new ExchangeOrderPrice { Price = array[0].ConvertInvariant(), Amount = array[1].ConvertInvariant() }; book.Asks[depth.Price] = depth; - if (book.Asks.Count == maxCount) - { - break; - } } - foreach (JArray array in token[bids]) + foreach (var array in token[bids]) { var depth = new ExchangeOrderPrice { Price = array[0].ConvertInvariant(), Amount = array[1].ConvertInvariant() }; book.Bids[depth.Price] = depth; - if (book.Bids.Count == maxCount) - { - break; - } } return book; @@ -378,7 +386,6 @@ internal static ExchangeOrderBook ParseOrderBookFromJTokenArrays /// Price key /// Quantity key /// Sequence key - /// Max count /// Order book internal static ExchangeOrderBook ParseOrderBookFromJTokenDictionaries ( @@ -387,8 +394,7 @@ internal static ExchangeOrderBook ParseOrderBookFromJTokenDictionaries string bids = "bids", string price = "price", string amount = "amount", - string sequence = "ts", - int maxCount = 100 + string sequence = "ts" ) { var book = new ExchangeOrderBook { SequenceId = token[sequence].ConvertInvariant() }; @@ -396,20 +402,12 @@ internal static ExchangeOrderBook ParseOrderBookFromJTokenDictionaries { var depth = new ExchangeOrderPrice { Price = ask[price].ConvertInvariant(), Amount = ask[amount].ConvertInvariant() }; book.Asks[depth.Price] = depth; - if (book.Asks.Count == maxCount) - { - break; - } } foreach (JToken bid in token[bids]) { var depth = new ExchangeOrderPrice { Price = bid[price].ConvertInvariant(), Amount = bid[amount].ConvertInvariant() }; book.Bids[depth.Price] = depth; - if (book.Bids.Count == maxCount) - { - break; - } } return book; @@ -727,7 +725,7 @@ internal static MarketCandle ParseCandle(this INamed named, JToken token, string { candle.WeightedAverage = token[weightedAverageKey].ConvertInvariant(); } - if( countKey != null) + if( countKey != null) { candle.Count = token[countKey].ConvertInvariant(); }