From b14987fa21edf13eabe6baef889a526e8c5ebf9c Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 16 Oct 2018 18:55:43 -0500 Subject: [PATCH 1/8] Rename ExchangeMarket.BaseCurrency to ExchangeMarket.QuoteCurrency and ExchangeMarket.MarketCurrency to ExchangeMarket.BaseCurrency. Update each implementation of OnGetSymbolsMetadataAsync to ensure they are all settings the correct properties. --- .../Exchanges/Abucoins/ExchangeAbucoinsAPI.cs | 9 +- .../Exchanges/Binance/ExchangeBinanceAPI.cs | 84 +++++++++++-------- .../API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs | 4 +- .../Exchanges/Bitfinex/ExchangeBitfinexAPI.cs | 22 ++--- .../Exchanges/Bittrex/ExchangeBittrexAPI.cs | 6 +- .../Bleutrade/ExchangeBleutradeAPI.cs | 5 +- .../Exchanges/Coinbase/ExchangeCoinbaseAPI.cs | 5 +- .../Cryptopia/ExchangeCryptopiaAPI.cs | 8 +- .../API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs | 4 +- .../API/Exchanges/Huobi/ExchangeHuobiAPI.cs | 36 ++++---- .../API/Exchanges/Kraken/ExchangeKrakenAPI.cs | 24 +++--- .../API/Exchanges/Kucoin/ExchangeKucoinAPI.cs | 8 +- .../Exchanges/Livecoin/ExchangeLivecoinAPI.cs | 8 +- .../API/Exchanges/Okex/ExchangeOkexAPI.cs | 9 +- .../Exchanges/Poloniex/ExchangePoloniexAPI.cs | 4 +- .../TuxExchange/ExchangeTuxExchangeAPI.cs | 5 +- .../API/Exchanges/Yobit/ExchangeYobitAPI.cs | 7 +- ExchangeSharp/Model/ExchangeMarket.cs | 29 +++++-- .../Console/ExchangeSharpConsole_Example.cs | 29 +++++++ .../ExchangeSharpConsole_Main.cs | 4 + 20 files changed, 188 insertions(+), 122 deletions(-) diff --git a/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs b/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs index 1936bd7d..7d176122 100644 --- a/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs +++ b/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs @@ -82,20 +82,17 @@ protected override async Task> OnGetSymbolsMetadataA { List markets = new List(); JToken obj = await MakeJsonRequestAsync("/products"); - const decimal StepSize = 0.00000001m; foreach (JToken token in obj) { markets.Add(new ExchangeMarket { MarketName = token["id"].ToStringInvariant(), BaseCurrency = token["base_currency"].ToStringInvariant(), - MarketCurrency = token["quote_currency"].ToStringInvariant(), + QuoteCurrency = token["quote_currency"].ToStringInvariant(), MinTradeSize = token["base_min_size"].ConvertInvariant(), MaxTradeSize = token["base_max_size"].ConvertInvariant(), - QuantityStepSize = token["quote_increment"].ConvertInvariant(), - MaxPrice = StepSize, - MinPrice = StepSize, - PriceStepSize = StepSize, + PriceStepSize = token["quote_increment"].ConvertInvariant(), + MinPrice = token["quote_increment"].ConvertInvariant(), IsActive = true }); } diff --git a/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs b/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs index 9345304e..2f9f385a 100644 --- a/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs +++ b/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs @@ -117,38 +117,40 @@ protected override async Task> OnGetSymbolsMetadataA { /* * { - "symbol": "QTUMETH", - "status": "TRADING", - "baseAsset": "QTUM", - "baseAssetPrecision": 8, - "quoteAsset": "ETH", - "quotePrecision": 8, - "orderTypes": [ - "LIMIT", - "LIMIT_MAKER", - "MARKET", - "STOP_LOSS_LIMIT", - "TAKE_PROFIT_LIMIT" - ], - "icebergAllowed": true, - "filters": [ - { - "filterType": "PRICE_FILTER", - "minPrice": "0.00000100", - "maxPrice": "100000.00000000", - "tickSize": "0.00000100" - }, - { - "filterType": "LOT_SIZE", - "minQty": "0.01000000", - "maxQty": "90000000.00000000", - "stepSize": "0.01000000" - }, - { - "filterType": "MIN_NOTIONAL", - "minNotional": "0.01000000" - } - ] + "symbol": "ETHBTC", + "status": "TRADING", + "baseAsset": "ETH", + "baseAssetPrecision": 8, + "quoteAsset": "BTC", + "quotePrecision": 8, + "orderTypes": [ + "LIMIT", + "MARKET", + "STOP_LOSS", + "STOP_LOSS_LIMIT", + "TAKE_PROFIT", + "TAKE_PROFIT_LIMIT", + "LIMIT_MAKER" + ], + "icebergAllowed": false, + "filters": [ + { + "filterType": "PRICE_FILTER", + "minPrice": "0.00000100", + "maxPrice": "100000.00000000", + "tickSize": "0.00000100" + }, + { + "filterType": "LOT_SIZE", + "minQty": "0.00100000", + "maxQty": "100000.00000000", + "stepSize": "0.00100000" + }, + { + "filterType": "MIN_NOTIONAL", + "minNotional": "0.00100000" + } + ] }, */ @@ -161,8 +163,8 @@ protected override async Task> OnGetSymbolsMetadataA { MarketName = symbol["symbol"].ToStringUpperInvariant(), IsActive = ParseMarketStatus(symbol["status"].ToStringUpperInvariant()), - BaseCurrency = symbol["quoteAsset"].ToStringUpperInvariant(), - MarketCurrency = symbol["baseAsset"].ToStringUpperInvariant() + QuoteCurrency = symbol["quoteAsset"].ToStringUpperInvariant(), + BaseCurrency = symbol["baseAsset"].ToStringUpperInvariant() }; // "LOT_SIZE" @@ -183,6 +185,13 @@ protected override async Task> OnGetSymbolsMetadataA market.MinPrice = priceFilter["minPrice"].ConvertInvariant(); market.PriceStepSize = priceFilter["tickSize"].ConvertInvariant(); } + + // MIN_NOTIONAL + JToken minNotionalFilter = filters?.FirstOrDefault(x => string.Equals(x["filterType"].ToStringUpperInvariant(), "MIN_NOTIONAL")); + if (minNotionalFilter != null) + { + market.MinTradeSizeInQuoteCurrency = minNotionalFilter["minNotional"].ConvertInvariant(); + } markets.Add(market); } @@ -688,11 +697,12 @@ private bool ParseMarketStatus(string status) switch (status) { case "TRADING": - case "PRE_TRADING": - case "POST_TRADING": isActive = true; break; - /* case "END_OF_DAY": + /* + case "PRE_TRADING": + case "POST_TRADING": + case "END_OF_DAY": case "HALT": case "AUCTION_MATCH": case "BREAK": */ diff --git a/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs b/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs index d3618944..bdbe6c8f 100644 --- a/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs +++ b/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs @@ -201,8 +201,8 @@ protected override async Task> OnGetSymbolsMetadataA { MarketName = symbol["symbol"].ToStringUpperInvariant(), IsActive = symbol["status"].ToStringInvariant().EqualsWithOption("Open"), - BaseCurrency = symbol["quoteCurrency"].ToStringUpperInvariant(), - MarketCurrency = symbol["underlying"].ToStringUpperInvariant(), + QuoteCurrency = symbol["quoteCurrency"].ToStringUpperInvariant(), + BaseCurrency = symbol["underlying"].ToStringUpperInvariant(), }; try diff --git a/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs b/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs index 61f8b495..8936ca0c 100644 --- a/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs @@ -115,29 +115,31 @@ protected override async Task> OnGetSymbolsMetadataA var market = new ExchangeMarket { IsActive = true, - MarketName = NormalizeSymbol(pair["pair"].ToStringInvariant()), + MarketName = pair["pair"].ToStringInvariant(), MinTradeSize = pair["minimum_order_size"].ConvertInvariant(), - MaxTradeSize = pair["maximum_order_size"].ConvertInvariant() + MaxTradeSize = pair["maximum_order_size"].ConvertInvariant(), + MarginEnabled = pair["margin"].ConvertInvariant(false) }; - m = Regex.Match(market.MarketName, "^(BTC|USD|ETH|GBP|JPY|EUR|EOS)"); + var pairPropertyVal = pair["pair"].ToStringUpperInvariant(); + m = Regex.Match(pairPropertyVal, "^(BTC|USD|ETH|GBP|JPY|EUR|EOS)"); if (m.Success) { - market.MarketCurrency = m.Value; - market.BaseCurrency = market.MarketName.Substring(m.Length); + market.BaseCurrency = m.Value; + market.QuoteCurrency = pairPropertyVal.Substring(m.Length); } else { - m = Regex.Match(market.MarketName, "(BTC|USD|ETH|GBP|JPY|EUR|EOS)$"); + m = Regex.Match(pairPropertyVal, "(BTC|USD|ETH|GBP|JPY|EUR|EOS)$"); if (m.Success) { - market.MarketCurrency = market.MarketName.Substring(0, m.Index); - market.BaseCurrency = m.Value; + market.BaseCurrency = pairPropertyVal.Substring(0, m.Index); + market.QuoteCurrency = m.Value; } else { // TODO: Figure out a nicer way to handle newly added pairs - market.MarketCurrency = market.MarketName.Substring(0, 3); - market.BaseCurrency = market.MarketName.Substring(3); + market.BaseCurrency = pairPropertyVal.Substring(0, 3); + market.QuoteCurrency = pairPropertyVal.Substring(3); } } int pricePrecision = pair["price_precision"].ConvertInvariant(); diff --git a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs index 8adbd1fd..5d0c3bb9 100644 --- a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs @@ -209,9 +209,11 @@ protected override async Task> OnGetSymbolsMetadataA { var market = new ExchangeMarket { - BaseCurrency = token["BaseCurrency"].ToStringUpperInvariant(), + //NOTE: Bittrex is weird in that they call the QuoteCurrency the "BaseCurrency" and the BaseCurrency the "MarketCurrency". + QuoteCurrency = token["BaseCurrency"].ToStringUpperInvariant(), IsActive = token["IsActive"].ConvertInvariant(), - MarketCurrency = token["MarketCurrency"].ToStringUpperInvariant(), + BaseCurrency = token["MarketCurrency"].ToStringUpperInvariant(), + //NOTE: They also reverse the order of the currencies in the MarketName MarketName = token["MarketName"].ToStringUpperInvariant(), MinTradeSize = token["MinTradeSize"].ConvertInvariant(), MinPrice = StepSize, diff --git a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs index b709fe91..6579268c 100644 --- a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs @@ -106,9 +106,10 @@ protected override async Task> OnGetSymbolsMetadataA { markets.Add(new ExchangeMarket() { + //NOTE: Bleutrade is another weird one that calls the QuoteCurrency the "BaseCurrency" and the BaseCurrency the "MarketCurrency". + QuoteCurrency = token["BaseCurrency"].ToStringInvariant(), + BaseCurrency = token["MarketCurrency"].ToStringInvariant(), MarketName = token["MarketName"].ToStringInvariant(), - BaseCurrency = token["BaseCurrency"].ToStringInvariant(), - MarketCurrency = token["MarketCurrency"].ToStringInvariant(), IsActive = token["IsActive"].ToStringInvariant().Equals("true"), MinTradeSize = token["MinTradeSize"].ConvertInvariant(), }); diff --git a/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs b/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs index 1154c822..4f1b8205 100644 --- a/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs +++ b/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs @@ -174,10 +174,11 @@ protected override async Task> OnGetSymbolsMetadataA var market = new ExchangeMarket { MarketName = product["id"].ToStringUpperInvariant(), - BaseCurrency = product["quote_currency"].ToStringUpperInvariant(), - MarketCurrency = product["base_currency"].ToStringUpperInvariant(), + QuoteCurrency = product["quote_currency"].ToStringUpperInvariant(), + BaseCurrency = product["base_currency"].ToStringUpperInvariant(), IsActive = string.Equals(product["status"].ToStringInvariant(), "online", StringComparison.OrdinalIgnoreCase), MinTradeSize = product["base_min_size"].ConvertInvariant(), + MaxTradeSize = product["base_max_size"].ConvertInvariant(), PriceStepSize = product["quote_increment"].ConvertInvariant() }; markets.Add(market); diff --git a/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs b/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs index 54734be6..c5b3d8eb 100644 --- a/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs +++ b/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs @@ -118,12 +118,16 @@ protected override async Task> OnGetSymbolsMetadataA { markets.Add(new ExchangeMarket() { + MarketId = token["Id"].ToStringInvariant(), MarketName = token["Label"].ToStringInvariant(), - BaseCurrency = token["BaseSymbol"].ToStringInvariant(), - MarketCurrency = token["Symbol"].ToStringInvariant(), + //NOTE: Cryptopia is calls the QuoteCurrency the "BaseSymbol" and the BaseCurrency the "Symbol".. not confusing at all! + QuoteCurrency = token["BaseSymbol"].ToStringInvariant(), + BaseCurrency = token["Symbol"].ToStringInvariant(), MaxTradeSize = token["MaximumTrade"].ConvertInvariant(), + MaxTradeSizeInQuoteCurrency = token["MaximumBaseTrade"].ConvertInvariant(), MaxPrice = token["MaximumPrice"].ConvertInvariant(), MinTradeSize = token["MinimumTrade"].ConvertInvariant(), + MinTradeSizeInQuoteCurrency = token["MinimumBaseTrade"].ConvertInvariant(), MinPrice = token["MinimumPrice"].ConvertInvariant(), IsActive = token["Status"].ToStringInvariant().Equals("OK") }); diff --git a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs index e768c953..f904d9c8 100644 --- a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs +++ b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs @@ -117,8 +117,8 @@ protected override async Task> OnGetSymbolsMetadataA markets.Add(new ExchangeMarket() { MarketName = token["id"].ToStringInvariant(), - MarketCurrency = token["baseCurrency"].ToStringInvariant(), // should be LTC in BTC-LTC. Hitbtc & ExchangeSharp definitions of base are reversed. - BaseCurrency = token["quoteCurrency"].ToStringInvariant(), // should be BTC in BTC-LTC + BaseCurrency = token["baseCurrency"].ToStringInvariant(), + QuoteCurrency = token["quoteCurrency"].ToStringInvariant(), QuantityStepSize = token["quantityIncrement"].ConvertInvariant(), PriceStepSize = token["tickSize"].ConvertInvariant(), IsActive = true diff --git a/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs b/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs index 10d36d45..c48242f0 100644 --- a/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs +++ b/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs @@ -148,25 +148,25 @@ protected override async Task> OnGetSymbolsMetadataA JToken allSymbols = await MakeJsonRequestAsync("/common/symbols", BaseUrlV1, null); foreach (var symbol in allSymbols) { - var marketCurrency = symbol["base-currency"].ToStringLowerInvariant(); - var baseCurrency = symbol["quote-currency"].ToStringLowerInvariant(); - var price_precision = symbol["price-precision"].ConvertInvariant(); - var priceStepSize = Math.Pow(10, -price_precision); - var amount_precision = symbol["amount-precision"].ConvertInvariant(); - var quantityStepSize = Math.Pow(10, -amount_precision); - - var market = new ExchangeMarket() - { - MarketCurrency = marketCurrency, - BaseCurrency = baseCurrency, - MarketName = marketCurrency + baseCurrency, - IsActive = true, - }; + var baseCurrency = symbol["base-currency"].ToStringLowerInvariant(); + var quoteCurrency = symbol["quote-currency"].ToStringLowerInvariant(); + var pricePrecision = symbol["price-precision"].ConvertInvariant(); + var priceStepSize = Math.Pow(10, -pricePrecision).ConvertInvariant(); + var amountPrecision = symbol["amount-precision"].ConvertInvariant(); + var quantityStepSize = Math.Pow(10, -amountPrecision).ConvertInvariant(); + + var market = new ExchangeMarket + { + BaseCurrency = baseCurrency, + QuoteCurrency = quoteCurrency, + MarketName = baseCurrency + quoteCurrency, + IsActive = true, + PriceStepSize = priceStepSize, + QuantityStepSize = quantityStepSize, + MinPrice = priceStepSize, + MinTradeSize = quantityStepSize, + }; - market.PriceStepSize = priceStepSize.ConvertInvariant(); - market.QuantityStepSize = quantityStepSize.ConvertInvariant(); - market.MinPrice = market.PriceStepSize.Value; - market.MinTradeSize = market.QuantityStepSize.Value; markets.Add(market); } diff --git a/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs b/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs index 3308caa8..17133713 100644 --- a/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs +++ b/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs @@ -335,20 +335,18 @@ protected override async Task> OnGetSymbolsMetadataA foreach (JToken pair in res) { - + var quantityStepSize = Math.Pow(0.1, pair["lot_decimals"].ConvertInvariant()).ConvertInvariant(); var market = new ExchangeMarket - { - IsActive = true, - MarketName = NormalizeSymbol(pair["altname"].ToStringInvariant()), - MinTradeSize = pair["lot_decimals"].ConvertInvariant() - - }; - market.MarketCurrency = pair["quote"].ToStringInvariant(); - market.BaseCurrency = pair["base"].ToStringInvariant(); - int quantityPrecision = pair["lot_decimals"].ConvertInvariant(); - market.QuantityStepSize = (decimal)Math.Pow(0.1, quantityPrecision); - int pricePrecision = pair["pair_decimals"].ConvertInvariant(); - market.PriceStepSize = (decimal)Math.Pow(0.1, pricePrecision); + { + IsActive = true, + MarketName = NormalizeSymbol(pair["altname"].ToStringInvariant()), + MinTradeSize = quantityStepSize, + MarginEnabled = pair["leverage_buy"].Children().Any() || pair["leverage_sell"].Children().Any(), + BaseCurrency = pair["base"].ToStringInvariant(), + QuoteCurrency = pair["quote"].ToStringInvariant(), + QuantityStepSize = quantityStepSize, + PriceStepSize = Math.Pow(0.1, pair["pair_decimals"].ConvertInvariant()).ConvertInvariant() + }; markets.Add(market); } diff --git a/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs b/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs index 9f3e7607..695d1fc1 100644 --- a/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs +++ b/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs @@ -121,17 +121,17 @@ protected override async Task> OnGetSymbolsAsync() protected override async Task> OnGetSymbolsMetadataAsync() { List markets = new List(); - // [ { "coinType": "KCS", "trading": true, "lastDealPrice": 4500,"buy": 4120, "sell": 4500, "coinTypePair": "BTC", "sort": 0,"feeRate": 0.001,"volValue": 324866889, "high": 6890, "datetime": 1506051488000, "vol": 5363831663913, "low": 4500, "changeRate": -0.3431 }, ... ] + // [ { "coinType": "ETH", "trading": true, "symbol": "ETH-BTC", "lastDealPrice": 0.03169122, "buy": 0.03165041, "sell": 0.03168714, "change": -0.00004678, "coinTypePair": "BTC", "sort": 100, "feeRate": 0.001, "volValue": 121.99939218, "plus": true, "high": 0.03203444, "datetime": 1539730948000, "vol": 3847.9028281, "low": 0.03153312, "changeRate": -0.0015 }, ... ] JToken token = await MakeJsonRequestAsync("/market/open/symbols"); foreach (JToken symbol in token) { ExchangeMarket market = new ExchangeMarket() { IsActive = symbol["trading"].ConvertInvariant(), - MarketCurrency = symbol["coinType"].ToStringInvariant(), - BaseCurrency = symbol["coinTypePair"].ToStringInvariant(), + BaseCurrency = symbol["coinType"].ToStringInvariant(), + QuoteCurrency = symbol["coinTypePair"].ToStringInvariant(), + MarketName = symbol["symbol"].ToStringInvariant() }; - market.MarketName = market.MarketCurrency + "-" + market.BaseCurrency; markets.Add(market); } return markets; diff --git a/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs b/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs index 2d0145c1..99ec39e0 100644 --- a/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs +++ b/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs @@ -90,11 +90,11 @@ protected override async Task> OnGetSymbolsMetadataA var exchangeMarket = new ExchangeMarket { MarketName = market["currencyPair"].ToStringInvariant(), - BaseCurrency = split[1], - MarketCurrency = split[0], + BaseCurrency = split[0], + QuoteCurrency = split[1], IsActive = true, - MinTradeSize = (decimal) market["minLimitQuantity"], - PriceStepSize = (decimal?) (1 / Math.Pow(10, (int) market["priceScale"])) + MinTradeSize = market["minLimitQuantity"].ConvertInvariant(), + PriceStepSize = Math.Pow(.1, market["priceScale"].ConvertInvariant()).ConvertInvariant() }; markets.Add(exchangeMarket); diff --git a/ExchangeSharp/API/Exchanges/Okex/ExchangeOkexAPI.cs b/ExchangeSharp/API/Exchanges/Okex/ExchangeOkexAPI.cs index b72d10fc..f7a85a39 100644 --- a/ExchangeSharp/API/Exchanges/Okex/ExchangeOkexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Okex/ExchangeOkexAPI.cs @@ -128,14 +128,15 @@ protected override async Task> OnGetSymbolsMetadataA JToken allSymbols = await MakeJsonRequestAsync("/markets/products", BaseUrlV2); foreach (JToken symbol in allSymbols) { - var marketName = symbol["symbol"].ToStringLowerInvariant(); - string[] pieces = marketName.Split('_'); + var marketName = symbol["symbol"].ToStringInvariant(); + string[] pieces = marketName.ToStringUpperInvariant().Split('_'); var market = new ExchangeMarket { MarketName = marketName, IsActive = symbol["online"].ConvertInvariant(), - BaseCurrency = pieces[1], - MarketCurrency = pieces[0], + QuoteCurrency = pieces[1], + BaseCurrency = pieces[0], + MarginEnabled = symbol["isMarginOpen"].ConvertInvariant(false) }; var quotePrecision = symbol["quotePrecision"].ConvertInvariant(); diff --git a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs index 1fd402e4..c36b6d4d 100644 --- a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs @@ -333,8 +333,8 @@ protected override async Task> OnGetSymbolsMetadataA string[] pairs = kvp.Key.Split('_'); if (pairs.Length == 2) { - market.BaseCurrency = pairs[0]; - market.MarketCurrency = pairs[1]; + market.QuoteCurrency = pairs[0]; + market.BaseCurrency = pairs[1]; market.PriceStepSize = StepSize; market.QuantityStepSize = StepSize; market.MinPrice = StepSize; diff --git a/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs b/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs index 38d52380..84ec3820 100644 --- a/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs +++ b/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs @@ -109,8 +109,9 @@ protected override async Task> OnGetSymbolsMetadataA { MarketName = prop.Name.ToStringInvariant(), IsActive = prop.First["isFrozen"].ConvertInvariant() == 0, - BaseCurrency = split[0], - MarketCurrency = split[1] + //NOTE: they list the quote currency first which is unusual + QuoteCurrency = split[0], + BaseCurrency = split[1] }); } return markets; diff --git a/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs b/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs index 08759a1c..166890a8 100644 --- a/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs +++ b/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs @@ -90,12 +90,13 @@ protected override async Task> OnGetSymbolsMetadataA markets.Add(new ExchangeMarket() { MarketName = prop.Name.ToStringInvariant(), - MarketCurrency = split[0], - BaseCurrency = split[1], + BaseCurrency = split[0], + QuoteCurrency = split[1], IsActive = prop.First["hidden"].ConvertInvariant().Equals(0), MaxPrice = prop.First["max_price"].ConvertInvariant(), MinPrice = prop.First["min_price"].ConvertInvariant(), - MinTradeSize = prop.First["min_amount"].ConvertInvariant() + MinTradeSize = prop.First["min_amount"].ConvertInvariant(), + PriceStepSize = Math.Pow(.1, prop.First["decimal_places"].ConvertInvariant()).ConvertInvariant() }); } return markets; diff --git a/ExchangeSharp/Model/ExchangeMarket.cs b/ExchangeSharp/Model/ExchangeMarket.cs index 4fe2ba33..916830db 100644 --- a/ExchangeSharp/Model/ExchangeMarket.cs +++ b/ExchangeSharp/Model/ExchangeMarket.cs @@ -24,19 +24,29 @@ public sealed class ExchangeMarket /// A value indicating whether the market is active. public bool IsActive { get; set; } - /// In a pair like ZRX/BTC, BTC is the base currency. - public string BaseCurrency { get; set; } + /// In a pair like ZRX/BTC, BTC is the quote currency. + public string QuoteCurrency { get; set; } - /// In a pair like ZRX/BTC, ZRX is the market currency. - public string MarketCurrency { get; set; } + /// In a pair like ZRX/BTC, ZRX is the base currency. + public string BaseCurrency { get; set; } - /// The minimum size of the trade in the unit of "MarketCurrency". For example, in + /// The minimum size of the trade in the unit of "BaseCurrency". For example, in /// DOGE/BTC the MinTradeSize is currently 423.72881356 DOGE public decimal MinTradeSize { get; set; } - /// The maximum size of the trade in the unit of "MarketCurrency". + /// The maximum size of the trade in the unit of "BaseCurrency". public decimal MaxTradeSize { get; set; } = decimal.MaxValue; + /// The minimum size of the trade in the unit of "QuoteCurrency". To determine an order's + /// trade size in terms of the Quote Currency, you need to calculate: price * quantity + /// NOTE: Not all exchanges provide this information + public decimal? MinTradeSizeInQuoteCurrency { get; set; } + + /// The maximum size of the trade in the unit of "QuoteCurrency". To determine an order's + /// trade size in terms of the Quote Currency, you need to calculate: price * quantity + /// NOTE: Not all exchanges provide this information + public decimal? MaxTradeSizeInQuoteCurrency { get; set; } + /// The minimum price of the pair. public decimal MinPrice { get; set; } @@ -52,9 +62,14 @@ public sealed class ExchangeMarket /// if unknown or not applicable. public decimal? QuantityStepSize { get; set; } + /// + /// Margin trading enabled for this market + /// + public bool MarginEnabled { get; set; } + public override string ToString() { - return $"{MarketName}, {MarketCurrency}-{BaseCurrency}"; + return $"{MarketName}, {BaseCurrency}-{QuoteCurrency}"; } } } \ No newline at end of file diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs index 088694b6..a046ee61 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs @@ -176,5 +176,34 @@ public static void RunProcessEncryptedAPIKeys(Dictionary dict) throw new ArgumentException("Invalid mode: " + dict["mode"]); } } + + public static void RunGetSymbolsMetadata(Dictionary dict) + { + RequireArgs(dict, "exchangeName"); + using (var api = ExchangeAPI.GetExchangeAPI(dict["exchangeName"])) + { + if (api == null) + { + throw new ArgumentException("Cannot find exchange with name {0}", dict["exchangeName"]); + } + + try + { + var symbols = api.GetSymbolsMetadataAsync().Sync(); + + foreach (var symbol in symbols) + { + Console.WriteLine(symbol); + } + + Console.WriteLine("Press any key to quit."); + Console.ReadKey(); + } + catch (Exception ex) + { + Logger.Error(ex); + } + } + } } } diff --git a/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs b/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs index 655667c1..a640c909 100644 --- a/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs +++ b/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs @@ -128,6 +128,10 @@ public static int ConsoleMain(string[] args) { RunGetOrderHistory(argsDictionary); } + else if (argsDictionary.ContainsKey("symbols-metadata")) + { + RunGetSymbolsMetadata(argsDictionary); + } else { Logger.Error("Unrecognized command line arguments."); From cd81669616b46e238e30d2df8105e05f4bce8425 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 16 Oct 2018 21:14:18 -0500 Subject: [PATCH 2/8] Fix baseCurrency / quoteCurrency naming in Bitstamp methods. Add "getOrderDetails" and "symbols" methods to Console project. --- .../Exchanges/Bitstamp/ExchangeBitstampAPI.cs | 51 ++++++++++--------- .../Console/ExchangeSharpConsole_Example.cs | 29 +++++++++++ .../Console/ExchangeSharpConsole_Orders.cs | 48 ++++++++++++++--- .../ExchangeSharpConsole_Main.cs | 10 ++++ 4 files changed, 106 insertions(+), 32 deletions(-) diff --git a/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs b/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs index 618a5fbc..1a7dd574 100644 --- a/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs @@ -229,31 +229,31 @@ protected override async Task OnGetOrderDetailsAsync(string JObject first = transactions.First() as JObject; List excludeStrings = new List() { "tid", "price", "fee", "datetime", "type", "btc", "usd", "eur" }; - string baseCurrency; - string marketCurrency = first.Properties().FirstOrDefault(p => !excludeStrings.Contains(p.Name, StringComparer.InvariantCultureIgnoreCase))?.Name; - if (string.IsNullOrWhiteSpace(marketCurrency)) + string quoteCurrency; + string baseCurrency = first.Properties().FirstOrDefault(p => !excludeStrings.Contains(p.Name, StringComparer.InvariantCultureIgnoreCase))?.Name; + if (string.IsNullOrWhiteSpace(baseCurrency)) { // the only 2 cases are BTC-USD and BTC-EUR - marketCurrency = "btc"; + baseCurrency = "btc"; excludeStrings.RemoveAll(s => s.Equals("usd") || s.Equals("eur")); - baseCurrency = first.Properties().FirstOrDefault(p => !excludeStrings.Contains(p.Name, StringComparer.InvariantCultureIgnoreCase))?.Name; + quoteCurrency = first.Properties().FirstOrDefault(p => !excludeStrings.Contains(p.Name, StringComparer.InvariantCultureIgnoreCase))?.Name; } else { excludeStrings.RemoveAll(s => s.Equals("usd") || s.Equals("eur") || s.Equals("btc")); - excludeStrings.Add(marketCurrency); - baseCurrency = first.Properties().FirstOrDefault(p => !excludeStrings.Contains(p.Name, StringComparer.InvariantCultureIgnoreCase))?.Name; + excludeStrings.Add(baseCurrency); + quoteCurrency = first.Properties().FirstOrDefault(p => !excludeStrings.Contains(p.Name, StringComparer.InvariantCultureIgnoreCase))?.Name; } - string _symbol = $"{marketCurrency}-{baseCurrency}"; + string _symbol = $"{baseCurrency}-{quoteCurrency}"; - decimal amountFilled = 0, spentBaseCurrency = 0, price = 0; + decimal amountFilled = 0, spentQuoteCurrency = 0, price = 0; foreach (var t in transactions) { int type = t["type"].ConvertInvariant(); if (type != 2) { continue; } - spentBaseCurrency += t[baseCurrency].ConvertInvariant(); - amountFilled += t[marketCurrency].ConvertInvariant(); + spentQuoteCurrency += t[quoteCurrency].ConvertInvariant(); + amountFilled += t[baseCurrency].ConvertInvariant(); //set price only one time if (price == 0) { @@ -266,7 +266,7 @@ protected override async Task OnGetOrderDetailsAsync(string { AmountFilled = amountFilled, Symbol = _symbol, - AveragePrice = spentBaseCurrency / amountFilled, + AveragePrice = spentQuoteCurrency / amountFilled, Price = price, }; } @@ -305,7 +305,7 @@ protected override async Task> OnGetCompletedOr // string url = string.IsNullOrWhiteSpace(symbol) ? "/user_transactions/" : "/user_transactions/" + symbol; string url = "/user_transactions/"; JToken result = await MakeJsonRequestAsync(url, null, await GetNoncePayloadAsync(), "POST"); - List orders = new List(); + List transactions = new List(); foreach (var transaction in result as JArray) { int type = transaction["type"].ConvertInvariant(); @@ -319,31 +319,34 @@ protected override async Task> OnGetCompletedOr { continue; } - string marketCurrency, baseCurrency; - baseCurrency = tradingPair.Trim().Substring(tradingPair.Length - 3).ToLowerInvariant(); - marketCurrency = tradingPair.Trim().ToLowerInvariant().Replace(baseCurrency, "").Replace("-", "").Replace("_", ""); - decimal resultMarketCurrency = transaction[marketCurrency].ConvertInvariant(); + var quoteCurrency = tradingPair.Trim().Substring(tradingPair.Length - 3).ToLowerInvariant(); + var baseCurrency = tradingPair.Trim().ToLowerInvariant().Replace(quoteCurrency, "").Replace("-", "").Replace("_", ""); + + decimal resultBaseCurrency = transaction[baseCurrency].ConvertInvariant(); ExchangeOrderResult order = new ExchangeOrderResult() { OrderId = transaction["order_id"].ToStringInvariant(), - IsBuy = resultMarketCurrency > 0, + IsBuy = resultBaseCurrency > 0, + Fees = transaction["fee"].ConvertInvariant(), + FeesCurrency = quoteCurrency.ToStringUpperInvariant(), Symbol = NormalizeSymbol(tradingPair), OrderDate = transaction["datetime"].ToDateTimeInvariant(), - AmountFilled = Math.Abs(resultMarketCurrency), - AveragePrice = Math.Abs(transaction[baseCurrency].ConvertInvariant() / resultMarketCurrency) + AmountFilled = Math.Abs(resultBaseCurrency), + AveragePrice = transaction[$"{baseCurrency}_{quoteCurrency}"].ConvertInvariant() }; - orders.Add(order); + transactions.Add(order); } // at this point one transaction transformed into one order, we need to consolidate parts into order // group by order id - var groupings = orders.GroupBy(o => o.OrderId); + var groupings = transactions.GroupBy(o => o.OrderId); + List orders = new List(); foreach (var group in groupings) { - decimal spentBaseCurrency = group.Sum(o => o.AveragePrice * o.AmountFilled); + decimal spentQuoteCurrency = group.Sum(o => o.AveragePrice * o.AmountFilled); ExchangeOrderResult order = group.First(); order.AmountFilled = group.Sum(o => o.AmountFilled); - order.AveragePrice = spentBaseCurrency / order.AmountFilled; + order.AveragePrice = spentQuoteCurrency / order.AmountFilled; order.Price = order.AveragePrice; orders.Add(order); } diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs index a046ee61..50679182 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs @@ -205,5 +205,34 @@ public static void RunGetSymbolsMetadata(Dictionary dict) } } } + + public static void RunGetSymbols(Dictionary dict) + { + RequireArgs(dict, "exchangeName"); + using (var api = ExchangeAPI.GetExchangeAPI(dict["exchangeName"])) + { + if (api == null) + { + throw new ArgumentException("Cannot find exchange with name {0}", dict["exchangeName"]); + } + + try + { + var symbols = api.GetSymbolsAsync().Sync(); + + foreach (var symbol in symbols) + { + Console.WriteLine(symbol); + } + + Console.WriteLine("Press any key to quit."); + Console.ReadKey(); + } + catch (Exception ex) + { + Logger.Error(ex); + } + } + } } } diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Orders.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Orders.cs index 550c2cf4..02810070 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Orders.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Orders.cs @@ -18,14 +18,7 @@ public static void RunGetOrderHistory(Dictionary dict) IExchangeAPI api = ExchangeAPI.GetExchangeAPI(exchangeName); string symbol = dict["symbol"]; - Console.Write("Enter Public Api Key: "); - var publicApiKey = GetSecureInput(); - api.PublicApiKey = publicApiKey; - Console.WriteLine(); - Console.Write("Enter Private Api Key: "); - var privateApiKey = GetSecureInput(); - api.PrivateApiKey = privateApiKey; - Console.WriteLine(); + Authenticate(api); DateTime? startDate = null; if (dict.ContainsKey("startDate")) @@ -43,6 +36,45 @@ public static void RunGetOrderHistory(Dictionary dict) Console.ReadLine(); } + public static void RunGetOrderDetails(Dictionary dict) + { + RequireArgs(dict, "exchangeName", "orderId"); + + string exchangeName = dict["exchangeName"]; + IExchangeAPI api = ExchangeAPI.GetExchangeAPI(exchangeName); + string orderId = dict["orderId"]; + + Authenticate(api); + + string symbol = null; + if (dict.ContainsKey("symbol")) + { + symbol = dict["symbol"]; + } + + var orderDetails = api.GetOrderDetailsAsync(orderId, symbol).Sync(); + Console.WriteLine(orderDetails); + + Console.Write("Press enter to exit.."); + Console.ReadLine(); + } + + private static void Authenticate(IExchangeAPI api) + { + Console.Write("Enter Public Api Key: "); + var publicApiKey = GetSecureInput(); + api.PublicApiKey = publicApiKey; + Console.WriteLine(); + Console.Write("Enter Private Api Key: "); + var privateApiKey = GetSecureInput(); + api.PrivateApiKey = privateApiKey; + Console.WriteLine(); + Console.Write("Enter Passphrase: "); + var passphrase = GetSecureInput(); + api.Passphrase = passphrase; + Console.WriteLine(); + } + private static SecureString GetSecureInput() { var pwd = new SecureString(); diff --git a/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs b/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs index a640c909..4a18fbc2 100644 --- a/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs +++ b/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs @@ -128,10 +128,18 @@ public static int ConsoleMain(string[] args) { RunGetOrderHistory(argsDictionary); } + else if (argsDictionary.ContainsKey("getOrderDetails")) + { + RunGetOrderDetails(argsDictionary); + } else if (argsDictionary.ContainsKey("symbols-metadata")) { RunGetSymbolsMetadata(argsDictionary); } + else if (argsDictionary.ContainsKey("symbols")) + { + RunGetSymbols(argsDictionary); + } else { Logger.Error("Unrecognized command line arguments."); @@ -147,6 +155,8 @@ public static int ConsoleMain(string[] args) finally { Logger.Info("ExchangeSharp console finished."); + Logger.Info("Press any key to exit"); + Console.ReadKey(true); } } } From 7a0318284e76054a95209b0e169f9f263c55f2d5 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 18 Oct 2018 18:18:18 -0500 Subject: [PATCH 3/8] Rename ExchangeVolume properties BaseSymbol, BaseVolume, ConvertSymbol, ConvertVolume to QuoteCurrency, QuoteVolume, BaseCurrency, and BaseVolume respectively. Update all usages. Add "tickers" method to Console project. --- .../Exchanges/Binance/ExchangeBinanceAPI.cs | 2 +- .../Exchanges/Bitfinex/ExchangeBitfinexAPI.cs | 34 ++++++--- .../Exchanges/Bittrex/ExchangeBittrexAPI.cs | 6 +- .../Bittrex/ExchangeBittrexAPI_WebSocket.cs | 14 ++-- .../Bleutrade/ExchangeBleutradeAPI.cs | 2 +- .../API/Exchanges/Gemini/ExchangeGeminiAPI.cs | 14 ++-- .../API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs | 2 +- .../API/Exchanges/Kraken/ExchangeKrakenAPI.cs | 44 +++++++++--- .../Exchanges/Poloniex/ExchangePoloniexAPI.cs | 2 +- .../API/Exchanges/ZBcom/ExchangeZBcomAPI.cs | 5 +- .../API/Exchanges/_Base/ExchangeAPI.cs | 67 ++++++++++++++++++ .../Exchanges/_Base/ExchangeAPIExtensions.cs | 69 ++++++++----------- ExchangeSharp/Model/ExchangeTicker.cs | 45 ++++++------ ExchangeSharp/Utility/CryptoUtility.cs | 1 + .../Console/ExchangeSharpConsole_Example.cs | 42 +++++++++++ .../ExchangeSharpConsole_ExchangeTests.cs | 2 +- .../Console/ExchangeSharpConsole_Stats.cs | 8 +-- .../ExchangeSharpConsole_Main.cs | 6 +- 18 files changed, 263 insertions(+), 102 deletions(-) diff --git a/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs b/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs index 2f9f385a..921db8a3 100644 --- a/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs +++ b/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs @@ -250,7 +250,7 @@ protected override IWebSocket OnGetTickersWebSocket(Action(ticker.Volume.BaseSymbol, ticker)); + tickerList.Add(new KeyValuePair(ticker.Volume.QuoteCurrency, ticker)); } if (tickerList.Count != 0) { diff --git a/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs b/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs index 8936ca0c..81ded89a 100644 --- a/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs @@ -158,11 +158,11 @@ protected override async Task OnGetTickerAsync(string symbol) protected override async Task>> OnGetTickersAsync() { List> tickers = new List>(); - IReadOnlyCollection symbols = (await GetSymbolsAsync()).ToArray(); - if (symbols != null && symbols.Count != 0) + IReadOnlyDictionary marketsBySymbol = (await GetSymbolsMetadataAsync()).ToDictionary(market => market.MarketName, market => market); + if (marketsBySymbol != null && marketsBySymbol.Count != 0) { StringBuilder symbolString = new StringBuilder(); - foreach (string symbol in symbols) + foreach (var symbol in marketsBySymbol.Keys) { symbolString.Append('t'); symbolString.Append(symbol.ToUpperInvariant()); @@ -173,17 +173,35 @@ protected override async Task>> DateTime now = CryptoUtility.UtcNow; foreach (JArray array in token) { - tickers.Add(new KeyValuePair(array[0].ToStringInvariant().Substring(1), new ExchangeTicker + #region Return Values + //[ + // SYMBOL, + // BID, float Price of last highest bid + // BID_SIZE, float Sum of the 25 highest bid sizes + // ASK, float Price of last lowest ask + // ASK_SIZE, float Sum of the 25 lowest ask sizes + // DAILY_CHANGE, float Amount that the last price has changed since yesterday + // DAILY_CHANGE_PERC, float Amount that the price has changed expressed in percentage terms + // LAST_PRICE, float Price of the last trade + // VOLUME, float Daily volume + // HIGH, float Daily high + // LOW float Daily low + //] + #endregion + var symbol = array[0].ToStringInvariant().Substring(1); + var market = marketsBySymbol[symbol.ToLowerInvariant()]; + tickers.Add(new KeyValuePair(symbol, new ExchangeTicker { + Symbol = symbol, Ask = array[3].ConvertInvariant(), Bid = array[1].ConvertInvariant(), Last = array[7].ConvertInvariant(), Volume = new ExchangeVolume { - BaseVolume = array[8].ConvertInvariant(), - BaseSymbol = array[0].ToStringInvariant(), - ConvertedVolume = array[8].ConvertInvariant() * array[7].ConvertInvariant(), - ConvertedSymbol = array[0].ToStringInvariant(), + QuoteCurrencyVolume = array[8].ConvertInvariant() * array[7].ConvertInvariant(), + QuoteCurrency = market.QuoteCurrency, + BaseCurrencyVolume = array[8].ConvertInvariant(), + BaseCurrency = market.BaseCurrency, Timestamp = now } })); diff --git a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs index 5d0c3bb9..64393888 100644 --- a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs @@ -235,7 +235,8 @@ protected override async Task> OnGetSymbolsAsync() protected override async Task OnGetTickerAsync(string symbol) { JToken ticker = await MakeJsonRequestAsync("/public/getmarketsummary?market=" + symbol); - return this.ParseTicker(ticker[0], symbol, "Ask", "Bid", "Last", "BaseVolume", "Volume", "Timestamp", TimestampType.Iso8601); + //NOTE: Bittrex uses the term "BaseVolume" when referring to the QuoteCurrencyVolume + return this.ParseTicker(ticker[0], symbol, "Ask", "Bid", "Last", "Volume", "BaseVolume", "Timestamp", TimestampType.Iso8601); } protected override async Task>> OnGetTickersAsync() @@ -246,7 +247,8 @@ protected override async Task>> foreach (JToken ticker in tickers) { symbol = ticker["MarketName"].ToStringInvariant(); - ExchangeTicker tickerObj = this.ParseTicker(ticker, symbol, "Ask", "Bid", "Last", "BaseVolume", "Volume", "Timestamp", TimestampType.Iso8601); + //NOTE: Bittrex uses the term "BaseVolume" when referring to the QuoteCurrencyVolume + ExchangeTicker tickerObj = this.ParseTicker(ticker, symbol, "Ask", "Bid", "Last", "Volume", "BaseVolume", "Timestamp", TimestampType.Iso8601); tickerList.Add(new KeyValuePair(symbol, tickerObj)); } return tickerList; diff --git a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI_WebSocket.cs b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI_WebSocket.cs index 2752bcec..f7d47801 100644 --- a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI_WebSocket.cs +++ b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI_WebSocket.cs @@ -120,23 +120,25 @@ void innerCallback(string json) foreach (JToken ticker in token) { string marketName = ticker["M"].ToStringInvariant(); + var (baseCurrency, quoteCurrency) = ExchangeSymbolToCurrencies(marketName); decimal last = ticker["l"].ConvertInvariant(); decimal ask = ticker["A"].ConvertInvariant(); decimal bid = ticker["B"].ConvertInvariant(); - decimal volume = ticker["V"].ConvertInvariant(); - decimal baseVolume = ticker["m"].ConvertInvariant(); + decimal baseCurrencyVolume = ticker["V"].ConvertInvariant(); + decimal quoteCurrencyVolume = ticker["m"].ConvertInvariant();//NOTE: Bittrex uses the term BaseVolume when referring to QuoteCurrencyVolume DateTime timestamp = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(ticker["T"].ConvertInvariant()); var t = new ExchangeTicker { + Symbol = marketName, Ask = ask, Bid = bid, Last = last, Volume = new ExchangeVolume { - ConvertedVolume = volume, - ConvertedSymbol = marketName, - BaseVolume = baseVolume, - BaseSymbol = marketName, + BaseCurrencyVolume = baseCurrencyVolume, + BaseCurrency = baseCurrency, + QuoteCurrencyVolume = quoteCurrencyVolume, + QuoteCurrency = quoteCurrency, Timestamp = timestamp } }; diff --git a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs index 6579268c..000b441e 100644 --- a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs @@ -130,7 +130,7 @@ protected override async Task>> JToken result = await MakeJsonRequestAsync("/public/getmarketsummaries"); foreach (JToken token in result) { - var ticker = this.ParseTicker(result, token["MarketName"].ToStringInvariant(), "Ask", "Bid", "Last", "Volume", "BaseVolume", "Timestamp", TimestampType.Iso8601); + var ticker = this.ParseTicker(token, token["MarketName"].ToStringInvariant(), "Ask", "Bid", "Last", "Volume", "BaseVolume", "Timestamp", TimestampType.Iso8601); tickers.Add(new KeyValuePair(token["MarketName"].ToStringInvariant(), ticker)); } return tickers; diff --git a/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs b/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs index 88d4bd86..93dbfd1a 100644 --- a/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs +++ b/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs @@ -32,16 +32,17 @@ public ExchangeGeminiAPI() SymbolSeparator = string.Empty; } - private ExchangeVolume ParseVolume(JToken token) + private ExchangeVolume ParseVolume(JToken token, string symbol) { ExchangeVolume vol = new ExchangeVolume(); JProperty[] props = token.Children().ToArray(); if (props.Length == 3) { - vol.BaseSymbol = props[0].Name; - vol.BaseVolume = props[0].Value.ConvertInvariant(); - vol.ConvertedSymbol = props[1].Name; - vol.ConvertedVolume = props[1].Value.ConvertInvariant(); + var (baseCurrency, quoteCurrency) = ExchangeSymbolToCurrencies(symbol); + vol.QuoteCurrency = quoteCurrency.ToUpperInvariant(); + vol.QuoteCurrencyVolume = token[quoteCurrency.ToUpperInvariant()].ConvertInvariant(); + vol.BaseCurrency = baseCurrency.ToUpperInvariant(); + vol.BaseCurrencyVolume = token[baseCurrency.ToUpperInvariant()].ConvertInvariant(); vol.Timestamp = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(props[2].Value.ConvertInvariant()); } @@ -99,11 +100,12 @@ protected override async Task OnGetTickerAsync(string symbol) } ExchangeTicker t = new ExchangeTicker { + Symbol = symbol, Ask = obj["ask"].ConvertInvariant(), Bid = obj["bid"].ConvertInvariant(), Last = obj["last"].ConvertInvariant() }; - t.Volume = ParseVolume(obj["volume"]); + t.Volume = ParseVolume(obj["volume"], symbol); return t; } diff --git a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs index f904d9c8..336b1408 100644 --- a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs +++ b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs @@ -480,7 +480,7 @@ public async Task AccountTransfer(string Symbol, decimal Amount, bool ToBa private ExchangeTicker ParseTicker(JToken token, string symbol) { // [ {"ask": "0.050043","bid": "0.050042","last": "0.050042","open": "0.047800","low": "0.047052","high": "0.051679","volume": "36456.720","volumeQuote": "1782.625000","timestamp": "2017-05-12T14:57:19.999Z","symbol": "ETHBTC"} ] - return this.ParseTicker(token, symbol, "ask", "bid", "last", "volumeQuote", "volume", "timestamp", TimestampType.Iso8601); + return this.ParseTicker(token, symbol, "ask", "bid", "last", "volume", "volumeQuote", "timestamp", TimestampType.Iso8601); } private ExchangeTrade ParseExchangeTrade(JToken token) diff --git a/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs b/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs index 17133713..953cd1dd 100644 --- a/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs +++ b/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs @@ -16,6 +16,7 @@ The above copyright notice and this permission notice shall be included in all c using System.Net; using System.Security.Cryptography; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; using Newtonsoft.Json.Linq; @@ -227,6 +228,28 @@ protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dicti } } + protected override async Task> OnGetCurrenciesAsync() + { + // https://api.kraken.com/0/public/Assets + Dictionary allCoins = new Dictionary(StringComparer.OrdinalIgnoreCase); + + var currencies = new Dictionary(StringComparer.OrdinalIgnoreCase); + JToken array = await MakeJsonRequestAsync("/0/public/Assets"); + foreach (JProperty token in array) + { + var coin = new ExchangeCurrency + { + CoinType = token.Value["aclass"].ToStringInvariant(), + Name = token.Name, + FullName = token.Value["altname"].ToStringInvariant() + }; + + currencies[coin.Name] = coin; + } + + return currencies; + } + protected override async Task> OnGetSymbolsAsync() { JToken result = await MakeJsonRequestAsync("/0/public/AssetPairs"); @@ -331,15 +354,16 @@ protected override async Task> OnGetSymbolsMetadataA //} var markets = new List(); JToken allPairs = await MakeJsonRequestAsync("/0/public/AssetPairs"); - var res = (from prop in allPairs.Children() select prop.Value).ToArray(); + var res = (from prop in allPairs.Children() select prop).ToArray(); - foreach (JToken pair in res) + foreach (JProperty prop in res) { + JToken pair = prop.Value; var quantityStepSize = Math.Pow(0.1, pair["lot_decimals"].ConvertInvariant()).ConvertInvariant(); var market = new ExchangeMarket { - IsActive = true, - MarketName = NormalizeSymbol(pair["altname"].ToStringInvariant()), + IsActive = !prop.Name.Contains(".d"), + MarketName = prop.Name, MinTradeSize = quantityStepSize, MarginEnabled = pair["leverage_buy"].Children().Any() || pair["leverage_sell"].Children().Any(), BaseCurrency = pair["base"].ToStringInvariant(), @@ -377,20 +401,22 @@ protected override async Task OnGetTickerAsync(string symbol) return ConvertToExchangeTicker(symbol, ticker); } - private static ExchangeTicker ConvertToExchangeTicker(string symbol, JToken ticker) + private ExchangeTicker ConvertToExchangeTicker(string symbol, JToken ticker) { decimal last = ticker["c"][0].ConvertInvariant(); + var (baseCurrency, quoteCurrency) = ExchangeSymbolToCurrencies(symbol); return new ExchangeTicker { + Symbol = symbol, Ask = ticker["a"][0].ConvertInvariant(), Bid = ticker["b"][0].ConvertInvariant(), Last = last, Volume = new ExchangeVolume { - BaseVolume = ticker["v"][1].ConvertInvariant(), - BaseSymbol = symbol, - ConvertedVolume = ticker["v"][1].ConvertInvariant() * last, - ConvertedSymbol = symbol, + QuoteCurrencyVolume = ticker["v"][1].ConvertInvariant(), + QuoteCurrency = quoteCurrency, + BaseCurrencyVolume = ticker["v"][1].ConvertInvariant() * ticker["p"][1].ConvertInvariant(), + BaseCurrency = baseCurrency, Timestamp = CryptoUtility.UtcNow } }; diff --git a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs index c36b6d4d..6f45dea1 100644 --- a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs @@ -370,7 +370,7 @@ protected override async Task>> string symbol = prop.Name; JToken values = prop.Value; ExchangeTicker ticker = this.ParseTicker(values, symbol, "lowestAsk", "highestBid", "last", "baseVolume", "quoteVolume", idKey: "id"); - tickers.Add(new KeyValuePair(symbol, this.ParseTicker(values, symbol, "lowestAsk", "highestBid", "last", "baseVolume", "quoteVolume", idKey: "id"))); + tickers.Add(new KeyValuePair(symbol, ticker)); } return tickers; } diff --git a/ExchangeSharp/API/Exchanges/ZBcom/ExchangeZBcomAPI.cs b/ExchangeSharp/API/Exchanges/ZBcom/ExchangeZBcomAPI.cs index 2476bafe..844f4698 100644 --- a/ExchangeSharp/API/Exchanges/ZBcom/ExchangeZBcomAPI.cs +++ b/ExchangeSharp/API/Exchanges/ZBcom/ExchangeZBcomAPI.cs @@ -12,6 +12,7 @@ The above copyright notice and this permission notice shall be included in all c using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Newtonsoft.Json.Linq; @@ -79,10 +80,12 @@ protected override async Task>> var data = await MakeRequestZBcomAsync(null, "/allTicker", BaseUrl); List> tickers = new List>(); + var symbols = (await GetSymbolsAsync()).ToArray(); string symbol; foreach (JToken token in data.Item1) { - symbol = token.Path; + //for some reason when returning tickers, the api doesn't include the symbol separator like it does everywhere else so we need to convert it to the correct format + symbol = symbols.First(s => s.Replace(SymbolSeparator, string.Empty).Equals(token.Path)); tickers.Add(new KeyValuePair(symbol, ParseTickerV2(symbol, token))); } return tickers; diff --git a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs index 60e646fd..c6e62e81 100644 --- a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs +++ b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs @@ -13,6 +13,7 @@ The above copyright notice and this permission notice shall be included in all c using System; using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -195,6 +196,7 @@ public ExchangeAPI() { if (UseDefaultMethodCachePolicy) { + MethodCachePolicy.Add(nameof(GetCurrenciesAsync), TimeSpan.FromHours(1.0)); MethodCachePolicy.Add(nameof(GetSymbolsAsync), TimeSpan.FromHours(1.0)); MethodCachePolicy.Add(nameof(GetSymbolsMetadataAsync), TimeSpan.FromHours(1.0)); MethodCachePolicy.Add(nameof(GetTickerAsync), TimeSpan.FromSeconds(10.0)); @@ -381,6 +383,71 @@ public virtual string ExchangeSymbolToGlobalSymbol(string symbol) return ExchangeSymbolToGlobalSymbolWithSeparator(symbol, SymbolSeparator[0]); } + public virtual string CurrenciesToExchangeSymbol(string baseCurrency, string quoteCurrency) + { + var symbol = SymbolIsReversed + ? $"{quoteCurrency}{SymbolSeparator}{baseCurrency}" + : $"{baseCurrency}{SymbolSeparator}{quoteCurrency}"; + + return SymbolIsUppercase + ? symbol.ToUpperInvariant() + : symbol; + } + + /// + /// NOTE: This method can potentially make a call to GetSymbolsMetadataAsync + /// + /// + /// + public virtual (string BaseCurrency, string QuoteCurrency) ExchangeSymbolToCurrencies(string symbol) + { + string baseCurrency, quoteCurrency; + if (string.IsNullOrWhiteSpace(SymbolSeparator)) + { + if (symbol.Length != 6) + { + var errorMessage = Name + " symbol must be 6 chars: '" + symbol + "' is not. Override this method to handle symbols that are not 6 chars in length."; + try + { + //let's try looking this up by the metadata.. + var symbols = GetSymbolsMetadataAsync().Sync().ToArray();//.ToDictionary(market => market.MarketName, market => market); + var symbolMetadata = symbols.First( + market => market.MarketName.Equals(symbol, StringComparison.InvariantCultureIgnoreCase) || CurrenciesToExchangeSymbol(market.BaseCurrency, market.QuoteCurrency) + .Equals(symbol, StringComparison.InvariantCultureIgnoreCase) + ); + + return (symbolMetadata.BaseCurrency, symbolMetadata.QuoteCurrency); + } + catch (Exception e) + { + throw new InvalidOperationException(errorMessage, e); + } + throw new InvalidOperationException(errorMessage); + } + + if (SymbolIsReversed) + { + quoteCurrency = symbol.Substring(0, symbol.Length - 3); + baseCurrency = symbol.Substring(symbol.Length - 3, 3); + } + else + { + baseCurrency = symbol.Substring(0, symbol.Length - 3); + quoteCurrency = symbol.Substring(symbol.Length - 3, 3); + } + } + else + { + var pieces = symbol.Split(SymbolSeparator[0]); + if (pieces.Length != 2) + throw new InvalidOperationException($"Splitting {Name} symbol '{symbol}' with symbol separator '{SymbolSeparator}' must result in exactly 2 pieces."); + quoteCurrency = SymbolIsReversed ? pieces[0] : pieces[1]; + baseCurrency = SymbolIsReversed ? pieces[1] : pieces[0]; + } + + return (baseCurrency, quoteCurrency); + } + /// /// Convert a global symbol into an exchange symbol, which will potentially be different from other exchanges. /// diff --git a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs index 7e6b3c48..d159ec2f 100644 --- a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs +++ b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs @@ -391,18 +391,18 @@ internal static ExchangeOrderBook ParseOrderBookFromJTokenDictionaries /// Ask key /// Bid key /// Last key - /// Base volume key - /// Convert volume key + /// Base currency volume key + /// Quote currency volume key /// Timestamp key /// Timestamp type /// Base currency key - /// Convert currency key + /// Quote currency key /// Id key /// ExchangeTicker internal static ExchangeTicker ParseTicker(this ExchangeAPI api, JToken token, string symbol, object askKey, object bidKey, object lastKey, object baseVolumeKey, - object convertVolumeKey = null, object timestampKey = null, TimestampType timestampType = TimestampType.None, - object baseCurrencyKey = null, object convertCurrencyKey = null, object idKey = null) + object quoteVolumeKey = null, object timestampKey = null, TimestampType timestampType = TimestampType.None, + object baseCurrencyKey = null, object quoteCurrencyKey = null, object idKey = null) { if (token == null || !token.HasValues) { @@ -411,36 +411,26 @@ internal static ExchangeTicker ParseTicker(this ExchangeAPI api, JToken token, s decimal last = token[lastKey].ConvertInvariant(); // parse out volumes, handle cases where one or both do not exist - token.ParseVolumes(baseVolumeKey, convertVolumeKey, last, out decimal baseVolume, out decimal convertVolume); + token.ParseVolumes(baseVolumeKey, quoteVolumeKey, last, out decimal baseCurrencyVolume, out decimal quoteCurrencyVolume); // pull out timestamp DateTime timestamp = (timestampKey == null ? CryptoUtility.UtcNow : CryptoUtility.ParseTimestamp(token[timestampKey], timestampType)); // split apart the symbol if we have a separator, otherwise just put the symbol for base and convert symbol - string baseSymbol; - string convertSymbol; - if (baseCurrencyKey != null && convertCurrencyKey != null) + string baseCurrency; + string quoteCurrency; + if (baseCurrencyKey != null && quoteCurrencyKey != null) { - baseSymbol = token[baseCurrencyKey].ToStringInvariant(); - convertSymbol = token[convertCurrencyKey].ToStringInvariant(); + baseCurrency = token[baseCurrencyKey].ToStringInvariant(); + quoteCurrency = token[quoteCurrencyKey].ToStringInvariant(); } else if (string.IsNullOrWhiteSpace(symbol)) { throw new ArgumentNullException(nameof(symbol)); } - else if (api.SymbolSeparator.Length != 0) - { - string[] pieces = symbol.Split(api.SymbolSeparator[0]); - if (pieces.Length != 2) - { - throw new ArgumentException($"Symbol does not have the correct symbol separator of '{api.SymbolSeparator}'"); - } - baseSymbol = pieces[0]; - convertSymbol = pieces[1]; - } else { - baseSymbol = convertSymbol = symbol; + (baseCurrency, quoteCurrency) = api.ExchangeSymbolToCurrencies(symbol); } // create the ticker and return it @@ -456,16 +446,17 @@ internal static ExchangeTicker ParseTicker(this ExchangeAPI api, JToken token, s } ExchangeTicker ticker = new ExchangeTicker { + Symbol = symbol, Ask = askValue.ConvertInvariant(), Bid = bidValue.ConvertInvariant(), Id = (idKey == null ? null : token[idKey].ToStringInvariant()), Last = last, Volume = new ExchangeVolume { - BaseVolume = baseVolume, - BaseSymbol = baseSymbol, - ConvertedVolume = convertVolume, - ConvertedSymbol = convertSymbol, + BaseCurrencyVolume = baseCurrencyVolume, + BaseCurrency = baseCurrency, + QuoteCurrencyVolume = quoteCurrencyVolume, + QuoteCurrency = quoteCurrency, Timestamp = timestamp } }; @@ -516,36 +507,36 @@ internal static ExchangeTrade ParseTrade(this JToken token, object amountKey, ob /// Parse volume from JToken /// /// JToken - /// Base volume key - /// Convert volume key + /// Base currency volume key + /// Quote currency volume key /// Last volume value - /// Receive base volume - /// Receive convert volume - internal static void ParseVolumes(this JToken token, object baseVolumeKey, object convertVolumeKey, decimal last, out decimal baseVolume, out decimal convertVolume) + /// Receive base currency volume + /// Receive quote currency volume + internal static void ParseVolumes(this JToken token, object baseVolumeKey, object quoteVolumeKey, decimal last, out decimal baseCurrencyVolume, out decimal quoteCurrencyVolume) { // parse out volumes, handle cases where one or both do not exist if (baseVolumeKey == null) { - if (convertVolumeKey == null) + if (quoteVolumeKey == null) { - baseVolume = convertVolume = 0m; + baseCurrencyVolume = quoteCurrencyVolume = 0m; } else { - convertVolume = token[convertVolumeKey].ConvertInvariant(); - baseVolume = (last <= 0m ? 0m : convertVolume / last); + quoteCurrencyVolume = token[quoteVolumeKey].ConvertInvariant(); + baseCurrencyVolume = (last <= 0m ? 0m : quoteCurrencyVolume / last); } } else { - baseVolume = token[baseVolumeKey].ConvertInvariant(); - if (convertVolumeKey == null) + baseCurrencyVolume = token[baseVolumeKey].ConvertInvariant(); + if (quoteVolumeKey == null) { - convertVolume = baseVolume * last; + quoteCurrencyVolume = baseCurrencyVolume * last; } else { - convertVolume = token[convertVolumeKey].ConvertInvariant(); + quoteCurrencyVolume = token[quoteVolumeKey].ConvertInvariant(); } } } diff --git a/ExchangeSharp/Model/ExchangeTicker.cs b/ExchangeSharp/Model/ExchangeTicker.cs index 5e978585..3f04b37d 100644 --- a/ExchangeSharp/Model/ExchangeTicker.cs +++ b/ExchangeSharp/Model/ExchangeTicker.cs @@ -31,6 +31,11 @@ public sealed class ExchangeTicker /// public string Id { get; set; } + /// + /// The currency pair symbol that this ticker is in reference to + /// + public string Symbol { get; set; } + /// /// The bid is the price to sell at /// @@ -97,28 +102,28 @@ public sealed class ExchangeVolume public DateTime Timestamp { get; set; } /// - /// Price symbol - will equal quantity symbol if exchange doesn't break it out by price unit and quantity unit - /// In BTC-USD, this would be BTC + /// Quote / Price currency - will equal base currency if exchange doesn't break it out by price unit and quantity unit + /// In BTC-USD, this would be USD /// - public string BaseSymbol { get; set; } + public string QuoteCurrency { get; set; } /// - /// Price amount - will equal QuantityAmount if exchange doesn't break it out by price unit and quantity unit - /// In BTC-USD, this would be BTC volume + /// Amount in units of the QuoteCurrency - will equal BaseCurrencyVolume if exchange doesn't break it out by price unit and quantity unit + /// In BTC-USD, this would be USD volume /// - public decimal BaseVolume { get; set; } + public decimal QuoteCurrencyVolume { get; set; } /// - /// Quantity symbol (converted into this unit) - /// In BTC-USD, this would be USD + /// Base currency + /// In BTC-USD, this would be BTC /// - public string ConvertedSymbol { get; set; } + public string BaseCurrency { get; set; } /// - /// Quantity amount (this many units total) - /// In BTC-USD this would be USD volume + /// Base currency amount (this many units total) + /// In BTC-USD this would be BTC volume /// - public decimal ConvertedVolume { get; set; } + public decimal BaseCurrencyVolume { get; set; } /// /// Write to a binary writer @@ -127,10 +132,10 @@ public sealed class ExchangeVolume public void ToBinary(BinaryWriter writer) { writer.Write(Timestamp.ToUniversalTime().Ticks); - writer.Write(BaseSymbol); - writer.Write((double)BaseVolume); - writer.Write(ConvertedSymbol); - writer.Write((double)ConvertedVolume); + writer.Write(QuoteCurrency); + writer.Write((double)QuoteCurrencyVolume); + writer.Write(BaseCurrency); + writer.Write((double)BaseCurrencyVolume); } /// @@ -140,10 +145,10 @@ public void ToBinary(BinaryWriter writer) public void FromBinary(BinaryReader reader) { Timestamp = new DateTime(reader.ReadInt64(), DateTimeKind.Utc); - BaseSymbol = reader.ReadString(); - BaseVolume = (decimal)reader.ReadDouble(); - ConvertedSymbol = reader.ReadString(); - ConvertedVolume = (decimal)reader.ReadDouble(); + QuoteCurrency = reader.ReadString(); + QuoteCurrencyVolume = (decimal)reader.ReadDouble(); + BaseCurrency = reader.ReadString(); + BaseCurrencyVolume = (decimal)reader.ReadDouble(); } } } diff --git a/ExchangeSharp/Utility/CryptoUtility.cs b/ExchangeSharp/Utility/CryptoUtility.cs index 6f188179..a4027f14 100644 --- a/ExchangeSharp/Utility/CryptoUtility.cs +++ b/ExchangeSharp/Utility/CryptoUtility.cs @@ -206,6 +206,7 @@ public static T ConvertInvariant(this object obj, T defaultValue = default) { // fallback to float conversion, i.e. 1E-1 for a decimal conversion will fail string stringValue = (jValue == null ? obj.ToStringInvariant() : jValue.Value.ToStringInvariant()); + if (string.IsNullOrWhiteSpace(stringValue)) return defaultValue; decimal decimalValue = decimal.Parse(stringValue, System.Globalization.NumberStyles.Float); return (T)Convert.ChangeType(decimalValue, typeof(T), CultureInfo.InvariantCulture); } diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs index 50679182..f16ff77b 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs @@ -234,5 +234,47 @@ public static void RunGetSymbols(Dictionary dict) } } } + + public static void RunGetTickers(Dictionary dict) + { + RequireArgs(dict, "exchangeName"); + using (var api = ExchangeAPI.GetExchangeAPI(dict["exchangeName"])) + { + if (api == null) + { + throw new ArgumentException("Cannot find exchange with name {0}", dict["exchangeName"]); + } + + try + { + IEnumerable> tickers; + if (dict.ContainsKey("symbol")) + { + var symbol = dict["symbol"]; + var ticker = api.GetTickerAsync(symbol).Sync(); + tickers = new List>() + { + new KeyValuePair(symbol, ticker) + }; + } + else + { + tickers = api.GetTickersAsync().Sync(); + } + + foreach (var ticker in tickers) + { + Console.WriteLine(ticker); + } + + Console.WriteLine("Press any key to quit."); + Console.ReadKey(); + } + catch (Exception ex) + { + Logger.Error(ex); + } + } + } } } diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs index 14e74676..dd1a74b5 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs @@ -120,7 +120,7 @@ bool histTradeCallback(IEnumerable tradeEnum) Console.Write("Test {0} GetTickerAsync... ", api.Name); var ticker = api.GetTickerAsync(symbol).Sync(); Assert(ticker != null && ticker.Ask > 0m && ticker.Bid > 0m && ticker.Last > 0m && - ticker.Volume != null && ticker.Volume.BaseVolume > 0m && ticker.Volume.ConvertedVolume > 0m); + ticker.Volume != null && ticker.Volume.QuoteCurrencyVolume > 0m && ticker.Volume.BaseCurrencyVolume > 0m); Console.WriteLine($"OK (ask: {ticker.Ask}, bid: {ticker.Bid}, last: {ticker.Last})"); } catch diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Stats.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Stats.cs index b9e7ab35..a9647507 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Stats.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Stats.cs @@ -60,10 +60,10 @@ public static void RunShowExchangeStats(Dictionary dict) decimal bidPriceSum4 = orders4.Bids.Values.Sum(o => o.Price); Console.Clear(); - Console.WriteLine("GDAX: {0:0.00}, {1:0.00}, {2:0.00}, {3:0.00}, {4:0.00}, {5:0.00}", ticker.Last, ticker.Volume.BaseVolume, askAmountSum, askPriceSum, bidAmountSum, bidPriceSum); - Console.WriteLine("GEMI: {0:0.00}, {1:0.00}, {2:0.00}, {3:0.00}, {4:0.00}, {5:0.00}", ticker2.Last, ticker2.Volume.BaseVolume, askAmountSum2, askPriceSum2, bidAmountSum2, bidPriceSum2); - Console.WriteLine("KRAK: {0:0.00}, {1:0.00}, {2:0.00}, {3:0.00}, {4:0.00}, {5:0.00}", ticker3.Last, ticker3.Volume.BaseVolume, askAmountSum3, askPriceSum3, bidAmountSum3, bidPriceSum3); - Console.WriteLine("BITF: {0:0.00}, {1:0.00}, {2:0.00}, {3:0.00}, {4:0.00}, {5:0.00}", ticker4.Last, ticker4.Volume.BaseVolume, askAmountSum4, askPriceSum4, bidAmountSum4, bidPriceSum4); + Console.WriteLine("GDAX: {0:0.00}, {1:0.00}, {2:0.00}, {3:0.00}, {4:0.00}, {5:0.00}", ticker.Last, ticker.Volume.QuoteCurrencyVolume, askAmountSum, askPriceSum, bidAmountSum, bidPriceSum); + Console.WriteLine("GEMI: {0:0.00}, {1:0.00}, {2:0.00}, {3:0.00}, {4:0.00}, {5:0.00}", ticker2.Last, ticker2.Volume.QuoteCurrencyVolume, askAmountSum2, askPriceSum2, bidAmountSum2, bidPriceSum2); + Console.WriteLine("KRAK: {0:0.00}, {1:0.00}, {2:0.00}, {3:0.00}, {4:0.00}, {5:0.00}", ticker3.Last, ticker3.Volume.QuoteCurrencyVolume, askAmountSum3, askPriceSum3, bidAmountSum3, bidPriceSum3); + Console.WriteLine("BITF: {0:0.00}, {1:0.00}, {2:0.00}, {3:0.00}, {4:0.00}, {5:0.00}", ticker4.Last, ticker4.Volume.QuoteCurrencyVolume, askAmountSum4, askPriceSum4, bidAmountSum4, bidPriceSum4); Thread.Sleep(5000); } } diff --git a/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs b/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs index 4a18fbc2..feb4c197 100644 --- a/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs +++ b/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs @@ -140,6 +140,10 @@ public static int ConsoleMain(string[] args) { RunGetSymbols(argsDictionary); } + else if (argsDictionary.ContainsKey("tickers")) + { + RunGetTickers(argsDictionary); + } else { Logger.Error("Unrecognized command line arguments."); @@ -155,8 +159,6 @@ public static int ConsoleMain(string[] args) finally { Logger.Info("ExchangeSharp console finished."); - Logger.Info("Press any key to exit"); - Console.ReadKey(true); } } } From c2e8e2b9628c03ac8cfec1e3bb30c5f90f92fbc6 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 18 Oct 2018 18:42:47 -0500 Subject: [PATCH 4/8] Rename ExchangeTransaction property Symbol to Currency. Update all usages. --- .../API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs | 6 +++--- .../API/Exchanges/Binance/ExchangeBinanceAPI.cs | 10 +++++----- .../API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs | 12 ++++++------ .../API/Exchanges/Bittrex/ExchangeBittrexAPI.cs | 8 ++++---- .../API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs | 4 ++-- .../API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs | 8 ++++---- .../API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs | 8 ++++---- .../API/Exchanges/Huobi/ExchangeHuobiAPI.cs | 2 +- .../API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs | 2 +- .../API/Exchanges/Poloniex/ExchangePoloniexAPI.cs | 6 +++--- .../Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs | 6 +++--- .../API/Exchanges/Yobit/ExchangeYobitAPI.cs | 2 +- ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs | 7 +++---- ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs | 6 +++--- ExchangeSharp/Model/ExchangeTransaction.cs | 6 +++--- 15 files changed, 46 insertions(+), 47 deletions(-) diff --git a/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs b/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs index 7d176122..5f5522d2 100644 --- a/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs +++ b/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs @@ -359,7 +359,7 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = await MakeJsonRequestAsync("/orders/" + orderId, null, await GetNoncePayloadAsync(), "DELETE"); } - protected override async Task> OnGetDepositHistoryAsync(string symbol) + protected override async Task> OnGetDepositHistoryAsync(string currency) { List deposits = new List(); @@ -373,7 +373,7 @@ protected override async Task> OnGetDepositHist { ExchangeTransaction deposit = new ExchangeTransaction() { - Symbol = token["currency"].ToStringInvariant(), + Currency = token["currency"].ToStringInvariant(), Amount = token["amount"].ConvertInvariant(), Timestamp = token["date"].ToDateTimeInvariant(), PaymentId = token["deposit_id"].ToStringInvariant(), @@ -385,7 +385,7 @@ protected override async Task> OnGetDepositHist case "pending": deposit.Status = TransactionStatus.Processing; break; default: deposit.Status = TransactionStatus.AwaitingApproval; break; } - if (deposit.Symbol == symbol) deposits.Add(deposit); + if (deposit.Currency == currency) deposits.Add(deposit); } return deposits; } diff --git a/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs b/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs index 921db8a3..b621e9ba 100644 --- a/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs +++ b/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs @@ -933,15 +933,15 @@ protected override async Task OnGetDepositAddressAsync(s } /// Gets the deposit history for a symbol - /// The symbol to check. Null for all symbols. + /// The symbol to check. Null for all symbols. /// Collection of ExchangeCoinTransfers - protected override async Task> OnGetDepositHistoryAsync(string symbol) + protected override async Task> OnGetDepositHistoryAsync(string currency) { // TODO: API supports searching on status, startTime, endTime Dictionary payload = await GetNoncePayloadAsync(); - if (symbol.Length != 0) + if (currency.Length != 0) { - payload["asset"] = symbol; + payload["asset"] = currency; } JToken response = await MakeJsonRequestAsync("/depositHistory.html", WithdrawalUrlPrivate, payload); @@ -952,7 +952,7 @@ protected override async Task> OnGetDepositHist { Timestamp = token["insertTime"].ConvertInvariant().UnixTimeStampToDateTimeMilliseconds(), Amount = token["amount"].ConvertInvariant(), - Symbol = token["asset"].ToStringUpperInvariant(), + Currency = token["asset"].ToStringUpperInvariant(), Address = token["address"].ToStringInvariant(), AddressTag = token["addressTag"].ToStringInvariant(), BlockchainTxId = token["txId"].ToStringInvariant() diff --git a/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs b/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs index 81ded89a..ae363c0f 100644 --- a/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs @@ -575,17 +575,17 @@ protected override async Task OnGetDepositAddressAsync(s } /// Gets the deposit history for a symbol - /// The symbol to check. Must be specified. + /// The symbol to check. Must be specified. /// Collection of ExchangeCoinTransfers - protected override async Task> OnGetDepositHistoryAsync(string symbol) + protected override async Task> OnGetDepositHistoryAsync(string currency) { - if (symbol.Length == 0) + if (currency.Length == 0) { - throw new ArgumentNullException(nameof(symbol)); + throw new ArgumentNullException(nameof(currency)); } Dictionary payload = await GetNoncePayloadAsync(); - payload["currency"] = symbol; + payload["currency"] = currency; JToken result = await MakeJsonRequestAsync("/history/movements", BaseUrlV1, payload, "POST"); var transactions = new List(); @@ -600,7 +600,7 @@ protected override async Task> OnGetDepositHist { PaymentId = token["id"].ToStringInvariant(), BlockchainTxId = token["txid"].ToStringInvariant(), - Symbol = token["currency"].ToStringUpperInvariant(), + Currency = token["currency"].ToStringUpperInvariant(), Notes = token["description"].ToStringInvariant() + ", method: " + token["method"].ToStringInvariant(), Amount = token["amount"].ConvertInvariant(), Address = token["address"].ToStringInvariant() diff --git a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs index 64393888..02c10b02 100644 --- a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs @@ -261,12 +261,12 @@ protected override async Task OnGetOrderBookAsync(string symb } /// Gets the deposit history for a symbol - /// The symbol to check. May be null. + /// The symbol to check. May be null. /// Collection of ExchangeTransactions - protected override async Task> OnGetDepositHistoryAsync(string symbol) + protected override async Task> OnGetDepositHistoryAsync(string currency) { var transactions = new List(); - string url = $"/account/getdeposithistory{(string.IsNullOrWhiteSpace(symbol) ? string.Empty : $"?currency={symbol}")}"; + string url = $"/account/getdeposithistory{(string.IsNullOrWhiteSpace(currency) ? string.Empty : $"?currency={currency}")}"; JToken result = await MakeJsonRequestAsync(url, null, await GetNoncePayloadAsync()); foreach (JToken token in result) { @@ -274,7 +274,7 @@ protected override async Task> OnGetDepositHist { Amount = token["Amount"].ConvertInvariant(), Address = token["CryptoAddress"].ToStringInvariant(), - Symbol = token["Currency"].ToStringInvariant(), + Currency = token["Currency"].ToStringInvariant(), PaymentId = token["Id"].ToStringInvariant(), BlockchainTxId = token["TxId"].ToStringInvariant(), Status = TransactionStatus.Complete // As soon as it shows up in this list it is complete (verified manually) diff --git a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs index 000b441e..b0b4cabe 100644 --- a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs @@ -290,7 +290,7 @@ protected override async Task OnGetDepositAddressAsync(s return null; } - protected override async Task> OnGetDepositHistoryAsync(string symbol) + protected override async Task> OnGetDepositHistoryAsync(string currency) { List transactions = new List(); @@ -303,7 +303,7 @@ protected override async Task> OnGetDepositHist PaymentId = token["Id"].ToStringInvariant(), BlockchainTxId = token["TransactionId"].ToStringInvariant(), Timestamp = token["TimeStamp"].ToDateTimeInvariant(), - Symbol = token["Coin"].ToStringInvariant(), + Currency = token["Coin"].ToStringInvariant(), Amount = token["Amount"].ConvertInvariant(), Notes = token["Label"].ToStringInvariant(), TxFee = token["fee"].ConvertInvariant(), diff --git a/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs b/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs index c5b3d8eb..6f2e75a4 100644 --- a/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs +++ b/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs @@ -349,9 +349,9 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = /// Cryptopia does support filtering by Transaction Type (deposits and withdraws), but here we're returning both. The Tx Type will be returned in the Message field /// By Symbol isn't supported, so we'll filter. Also, the default limit is 100 transactions, we could possibly increase this to support the extra data we have to return for Symbol /// - /// + /// /// - protected override async Task> OnGetDepositHistoryAsync(string symbol) + protected override async Task> OnGetDepositHistoryAsync(string currency) { List deposits = new List(); var payload = await GetNoncePayloadAsync(); @@ -365,7 +365,7 @@ protected override async Task> OnGetDepositHist JToken token = await MakeJsonRequestAsync("/GetTransactions", null, payload, "POST"); foreach (JToken data in token) { - if (data["Currency"].ToStringInvariant().Equals(symbol)) + if (data["Currency"].ToStringInvariant().Equals(currency)) { ExchangeTransaction tx = new ExchangeTransaction() { @@ -375,7 +375,7 @@ protected override async Task> OnGetDepositHist Notes = data["Type"].ToStringInvariant(), PaymentId = data["Id"].ToStringInvariant(), Timestamp = data["TimeStamp"].ToDateTimeInvariant(), - Symbol = data["Currency"].ToStringInvariant(), + Currency = data["Currency"].ToStringInvariant(), TxFee = data["Fee"].ConvertInvariant() }; // They may support more status types, but it's not documented diff --git a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs index 336b1408..4bd1a729 100644 --- a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs +++ b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs @@ -379,9 +379,9 @@ protected override async Task OnGetDepositAddressAsync(s /// This returns both Deposit and Withdawl history for the Bank and Trading Accounts. Currently returning everything and not filtering. /// There is no support for retrieving by Symbol, so we'll filter that after reteiving all symbols /// - /// + /// /// - protected override async Task> OnGetDepositHistoryAsync(string symbol) + protected override async Task> OnGetDepositHistoryAsync(string currency) { List transactions = new List(); // [ {"id": "6a2fb54d-7466-490c-b3a6-95d8c882f7f7","index": 20400458,"currency": "ETH","amount": "38.616700000000000000000000","fee": "0.000880000000000000000000", "address": "0xfaEF4bE10dDF50B68c220c9ab19381e20B8EEB2B", "hash": "eece4c17994798939cea9f6a72ee12faa55a7ce44860cfb95c7ed71c89522fe8","status": "pending","type": "payout", "createdAt": "2017-05-18T18:05:36.957Z", "updatedAt": "2017-05-18T19:21:05.370Z" }, ... ] @@ -390,12 +390,12 @@ protected override async Task> OnGetDepositHist { foreach (JToken token in result) { - if (token["currency"].ToStringInvariant().Equals(symbol)) + if (token["currency"].ToStringInvariant().Equals(currency)) { ExchangeTransaction transaction = new ExchangeTransaction { PaymentId = token["id"].ToStringInvariant(), - Symbol = token["currency"].ToStringInvariant(), + Currency = token["currency"].ToStringInvariant(), Address = token["address"].ToStringInvariant(), // Address Tag isn't returned BlockchainTxId = token["hash"].ToStringInvariant(), // not sure about this Amount = token["amount"].ConvertInvariant(), diff --git a/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs b/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs index c48242f0..426d2a0a 100644 --- a/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs +++ b/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs @@ -675,7 +675,7 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = await MakeJsonRequestAsync($"/order/orders/{orderId}/submitcancel", PrivateUrlV1, payload, "POST"); } - protected override Task> OnGetDepositHistoryAsync(string symbol) + protected override Task> OnGetDepositHistoryAsync(string currency) { throw new NotImplementedException("Huobi does not provide a deposit API"); } diff --git a/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs b/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs index 99ec39e0..c9627b33 100644 --- a/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs +++ b/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs @@ -291,7 +291,7 @@ await MakeJsonRequestAsync("/exchange/cancel_limit?currencyPair=" + } } - protected override async Task> OnGetDepositHistoryAsync(string symbol) + protected override async Task> OnGetDepositHistoryAsync(string currency) { List deposits = new List(); diff --git a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs index 6f45dea1..1faabb68 100644 --- a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs @@ -878,9 +878,9 @@ protected override async Task OnGetDepositAddressAsync(s } /// Gets the deposit history for a symbol - /// (ignored) The symbol to check. + /// (ignored) The symbol to check. /// Collection of ExchangeCoinTransfers - protected override async Task> OnGetDepositHistoryAsync(string symbol) + protected override async Task> OnGetDepositHistoryAsync(string currency) { JToken result = await MakePrivateAPIRequestAsync("returnDepositsWithdrawals", new object[] @@ -895,7 +895,7 @@ protected override async Task> OnGetDepositHist { var deposit = new ExchangeTransaction { - Symbol = token["currency"].ToStringUpperInvariant(), + Currency = token["currency"].ToStringUpperInvariant(), Address = token["address"].ToStringInvariant(), Amount = token["amount"].ConvertInvariant(), BlockchainTxId = token["txid"].ToStringInvariant(), diff --git a/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs b/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs index 84ec3820..dea11e7f 100644 --- a/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs +++ b/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs @@ -325,7 +325,7 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = // nothing is returned on this call } - protected override async Task> OnGetDepositHistoryAsync(string symbol) + protected override async Task> OnGetDepositHistoryAsync(string currency) { List deposits = new List(); var payload = await GetNoncePayloadAsync(); @@ -336,9 +336,9 @@ protected override async Task> OnGetDepositHist JToken token = await MakeJsonRequestAsync("/api", null, payload, "POST"); foreach (JToken deposit in token.First) { - if (deposit["symbol"].ToStringInvariant().Equals(symbol)) deposits.Add(new ExchangeTransaction() + if (deposit["symbol"].ToStringInvariant().Equals(currency)) deposits.Add(new ExchangeTransaction() { - Symbol = symbol, + Currency = currency, Timestamp = deposit["date"].ToDateTimeInvariant(), Address = deposit["coin"].ToStringInvariant(), BlockchainTxId = deposit["txid"].ToStringInvariant(), diff --git a/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs b/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs index 166890a8..5fe240b2 100644 --- a/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs +++ b/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs @@ -285,7 +285,7 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = await MakeJsonRequestAsync("/", PrivateURL, payload, "POST"); } - protected override Task> OnGetDepositHistoryAsync(string symbol) + protected override Task> OnGetDepositHistoryAsync(string currency) { throw new NotImplementedException("Yobit does not provide a deposit history via the API"); // I don't wonder why } diff --git a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs index c6e62e81..c563311e 100644 --- a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs +++ b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs @@ -87,7 +87,7 @@ await GetHistoricalTradesAsync((e) => protected virtual Task OnGetOrderBookAsync(string symbol, int maxCount = 100) => throw new NotImplementedException(); protected virtual Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) => throw new NotImplementedException(); protected virtual Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) => throw new NotImplementedException(); - protected virtual Task> OnGetDepositHistoryAsync(string symbol) => throw new NotImplementedException(); + protected virtual Task> OnGetDepositHistoryAsync(string currency) => throw new NotImplementedException(); protected virtual Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) => throw new NotImplementedException(); protected virtual Task> OnGetAmountsAsync() => throw new NotImplementedException(); protected virtual Task> OnGetFeesAsync() => throw new NotImplementedException(); @@ -635,10 +635,9 @@ public virtual async Task GetDepositAddressAsync(string /// Gets the deposit history for a symbol /// /// Collection of ExchangeCoinTransfers - public virtual async Task> GetDepositHistoryAsync(string symbol) + public virtual async Task> GetDepositHistoryAsync(string currency) { - symbol = NormalizeSymbol(symbol); - return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetDepositHistoryAsync(symbol), nameof(GetDepositHistoryAsync), nameof(symbol), symbol); + return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetDepositHistoryAsync(currency), nameof(GetDepositHistoryAsync), nameof(currency), currency); } /// diff --git a/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs b/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs index f4ea62dc..59804f83 100644 --- a/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs +++ b/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs @@ -74,11 +74,11 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider Task GetDepositAddressAsync(string symbol, bool forceRegenerate = false); /// - /// Gets the deposit history for a symbol + /// Gets the deposit history for a currency /// - /// The symbol to check. May be null. + /// The currency to check. May be null. /// Collection of ExchangeCoinTransfers - Task> GetDepositHistoryAsync(string symbol); + Task> GetDepositHistoryAsync(string currency); /// /// Get symbols for the exchange diff --git a/ExchangeSharp/Model/ExchangeTransaction.cs b/ExchangeSharp/Model/ExchangeTransaction.cs index 2ae506bd..d4bf96e1 100644 --- a/ExchangeSharp/Model/ExchangeTransaction.cs +++ b/ExchangeSharp/Model/ExchangeTransaction.cs @@ -44,13 +44,13 @@ public sealed class ExchangeTransaction /// The fee on the transaction public decimal TxFee { get; set; } - /// The currency symbol (ex. BTC) - public string Symbol { get; set; } + /// The currency name (ex. BTC) + public string Currency { get; set; } public override string ToString() { return - $"{Amount} {Symbol} (fee: {TxFee}) sent to Address: {Address ?? "null"} with AddressTag: {AddressTag ?? "null"} BlockchainTxId: {BlockchainTxId ?? "null"} sent at {Timestamp} UTC. Status: {Status}. Exchange paymentId: {PaymentId ?? "null"}. Notes: {Notes ?? "null"}"; + $"{Amount} {Currency} (fee: {TxFee}) sent to Address: {Address ?? "null"} with AddressTag: {AddressTag ?? "null"} BlockchainTxId: {BlockchainTxId ?? "null"} sent at {Timestamp} UTC. Status: {Status}. Exchange paymentId: {PaymentId ?? "null"}. Notes: {Notes ?? "null"}"; } } } \ No newline at end of file From c72711856a1f7c0316df393b97cf0be2c6a4b0f0 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 18 Oct 2018 19:09:46 -0500 Subject: [PATCH 5/8] Rename ExchangeDepositDetails property Symbol to Currency. Update all usages. --- .../Exchanges/Abucoins/ExchangeAbucoinsAPI.cs | 8 ++--- .../Exchanges/Binance/ExchangeBinanceAPI.cs | 8 ++--- .../Exchanges/Bitfinex/ExchangeBitfinexAPI.cs | 14 ++++---- .../Exchanges/Bittrex/ExchangeBittrexAPI.cs | 12 +++---- .../Bleutrade/ExchangeBleutradeAPI.cs | 8 ++--- .../Cryptopia/ExchangeCryptopiaAPI.cs | 6 ++-- .../API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs | 6 ++-- .../API/Exchanges/Huobi/ExchangeHuobiAPI.cs | 2 +- .../API/Exchanges/Kucoin/ExchangeKucoinAPI.cs | 6 ++-- .../Exchanges/Livecoin/ExchangeLivecoinAPI.cs | 8 ++--- .../Exchanges/Poloniex/ExchangePoloniexAPI.cs | 32 +++++++++---------- .../TuxExchange/ExchangeTuxExchangeAPI.cs | 8 ++--- .../API/Exchanges/Yobit/ExchangeYobitAPI.cs | 6 ++-- .../API/Exchanges/_Base/ExchangeAPI.cs | 11 +++---- .../API/Exchanges/_Base/IExchangeAPI.cs | 4 +-- ExchangeSharp/Model/ExchangeDepositDetails.cs | 6 ++-- 16 files changed, 72 insertions(+), 73 deletions(-) diff --git a/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs b/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs index 5f5522d2..e28fec68 100644 --- a/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs +++ b/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs @@ -390,21 +390,21 @@ protected override async Task> OnGetDepositHist return deposits; } - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { var payload = await GetNoncePayloadAsync(); JArray array = await MakeJsonRequestAsync("/payment-methods", null, await GetNoncePayloadAsync()); if (array != null) { - var rc = array.Where(t => t["currency"].ToStringInvariant() == symbol).FirstOrDefault(); + var rc = array.Where(t => t["currency"].ToStringInvariant() == currency).FirstOrDefault(); payload = await GetNoncePayloadAsync(); - payload["currency"] = symbol; + payload["currency"] = currency; payload["method"] = rc["id"].ToStringInvariant(); JToken token = await MakeJsonRequestAsync("/deposits/make", null, payload, "POST"); ExchangeDepositDetails deposit = new ExchangeDepositDetails() { - Symbol = symbol, + Currency = currency, Address = token["address"].ToStringInvariant(), AddressTag = token["tag"].ToStringInvariant() }; diff --git a/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs b/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs index b621e9ba..382e0a4b 100644 --- a/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs +++ b/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs @@ -905,12 +905,12 @@ protected override Uri ProcessRequestUrl(UriBuilder url, Dictionary /// Gets the address to deposit to and applicable details. /// - /// Symbol to get address for + /// Currency to get address for /// (ignored) Binance does not provide the ability to generate new addresses /// /// Deposit address details (including tag if applicable, such as XRP) /// - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { /* * TODO: Binance does not offer a "regenerate" option in the API, but a second IOTA deposit to the same address will not be credited @@ -919,12 +919,12 @@ protected override async Task OnGetDepositAddressAsync(s */ Dictionary payload = await GetNoncePayloadAsync(); - payload["asset"] = symbol; + payload["asset"] = currency; JToken response = await MakeJsonRequestAsync("/depositAddress.html", WithdrawalUrlPrivate, payload); ExchangeDepositDetails depositDetails = new ExchangeDepositDetails { - Symbol = response["asset"].ToStringInvariant(), + Currency = response["asset"].ToStringInvariant(), Address = response["address"].ToStringInvariant(), AddressTag = response["addressTag"].ToStringInvariant() }; diff --git a/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs b/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs index ae363c0f..8b9c3ded 100644 --- a/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs @@ -532,23 +532,23 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = await MakeJsonRequestAsync("/order/cancel", BaseUrlV1, payload); } - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { - if (symbol.Length == 0) + if (currency.Length == 0) { - throw new ArgumentNullException(nameof(symbol)); + throw new ArgumentNullException(nameof(currency)); } // IOTA addresses should never be used more than once - if (symbol.Equals("MIOTA", StringComparison.OrdinalIgnoreCase)) + if (currency.Equals("MIOTA", StringComparison.OrdinalIgnoreCase)) { forceRegenerate = true; } // symbol needs to be translated to full name of coin: bitcoin/litecoin/ethereum - if (!DepositMethodLookup.TryGetValue(symbol, out string fullName)) + if (!DepositMethodLookup.TryGetValue(currency, out string fullName)) { - fullName = symbol.ToLowerInvariant(); + fullName = currency.ToLowerInvariant(); } Dictionary payload = await GetNoncePayloadAsync(); @@ -559,7 +559,7 @@ protected override async Task OnGetDepositAddressAsync(s JToken result = await MakeJsonRequestAsync("/deposit/new", BaseUrlV1, payload, "POST"); var details = new ExchangeDepositDetails { - Symbol = result["currency"].ToStringInvariant(), + Currency = result["currency"].ToStringInvariant(), }; if (result["address_pool"] != null) { diff --git a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs index 02c10b02..8414683b 100644 --- a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs @@ -513,28 +513,28 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = /// Gets the address to deposit to and applicable details. /// If one does not exist, the call will fail and return ADDRESS_GENERATING until one is available. /// - /// Symbol to get address for. + /// Currency to get address for. /// (ignored) Bittrex does not support regenerating deposit addresses. /// /// Deposit address details (including tag if applicable, such as with XRP) /// - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { IReadOnlyDictionary updatedCurrencies = (await GetCurrenciesAsync()); - string url = "/account/getdepositaddress?currency=" + NormalizeSymbol(symbol); + string url = "/account/getdepositaddress?currency=" + NormalizeSymbol(currency); JToken result = await MakeJsonRequestAsync(url, null, await GetNoncePayloadAsync()); // NOTE API 1.1 does not include the the static wallet address for currencies with tags such as XRP & NXT (API 2.0 does!) // We are getting the static addresses via the GetCurrencies() api. ExchangeDepositDetails depositDetails = new ExchangeDepositDetails { - Symbol = result["Currency"].ToStringInvariant(), + Currency = result["Currency"].ToStringInvariant(), }; - if (!updatedCurrencies.TryGetValue(depositDetails.Symbol, out ExchangeCurrency coin)) + if (!updatedCurrencies.TryGetValue(depositDetails.Currency, out ExchangeCurrency coin)) { - Logger.Warn($"Unable to find {depositDetails.Symbol} in existing list of coins."); + Logger.Warn($"Unable to find {depositDetails.Currency} in existing list of coins."); return null; } diff --git a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs index b0b4cabe..4403b2dd 100644 --- a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs @@ -275,15 +275,15 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = await MakeJsonRequestAsync("/market/cancel?orderid=" + orderId, null, await GetNoncePayloadAsync()); } - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { - JToken token = await MakeJsonRequestAsync("/account/getdepositaddress?" + "currency=" + NormalizeSymbol(symbol), BaseUrl, await GetNoncePayloadAsync()); - if (token["Currency"].ToStringInvariant().Equals(symbol) && token["Address"] != null) + JToken token = await MakeJsonRequestAsync("/account/getdepositaddress?" + "currency=" + NormalizeSymbol(currency), BaseUrl, await GetNoncePayloadAsync()); + if (token["Currency"].ToStringInvariant().Equals(currency) && token["Address"] != null) { // At this time, according to Bleutrade support, they don't support any currency requiring an Address Tag, but they will add this feature in the future return new ExchangeDepositDetails() { - Symbol = token["Currency"].ToStringInvariant(), + Currency = token["Currency"].ToStringInvariant(), Address = token["Address"].ToStringInvariant() }; } diff --git a/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs b/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs index 6f2e75a4..6f5c3405 100644 --- a/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs +++ b/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs @@ -391,15 +391,15 @@ protected override async Task> OnGetDepositHist return deposits; } - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { var payload = await GetNoncePayloadAsync(); - payload["Currency"] = symbol; + payload["Currency"] = currency; JToken token = await MakeJsonRequestAsync("/GetDepositAddress", null, payload, "POST"); if (token["Address"] == null) return null; return new ExchangeDepositDetails() { - Symbol = symbol, + Currency = currency, Address = token["Address"].ToStringInvariant(), AddressTag = token["BaseAddress"].ToStringInvariant() }; diff --git a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs index 4bd1a729..d23f1f73 100644 --- a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs +++ b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs @@ -358,10 +358,10 @@ private void ParseAveragePriceAndFeesFromFills(ExchangeOrderResult result, JToke result.AveragePrice = (totalQuantity == 0 ? 0 : totalCost / totalQuantity); } - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { - ExchangeDepositDetails deposit = new ExchangeDepositDetails() { Symbol = symbol }; - JToken token = await MakeJsonRequestAsync("/payment/address/" + symbol, null, await GetNoncePayloadAsync()); + ExchangeDepositDetails deposit = new ExchangeDepositDetails() { Currency = currency }; + JToken token = await MakeJsonRequestAsync("/payment/address/" + currency, null, await GetNoncePayloadAsync()); if (token != null) { deposit.Address = token["address"].ToStringInvariant(); diff --git a/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs b/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs index 426d2a0a..5b363839 100644 --- a/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs +++ b/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs @@ -680,7 +680,7 @@ protected override Task> OnGetDepositHistoryAsy throw new NotImplementedException("Huobi does not provide a deposit API"); } - protected override Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { throw new NotImplementedException("Huobi does not provide a deposit API"); diff --git a/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs b/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs index 695d1fc1..5efdb15c 100644 --- a/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs +++ b/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs @@ -357,15 +357,15 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = JToken token = await MakeJsonRequestAsync("/cancel-order?" + CryptoUtility.GetFormForPayload(payload, false), null, payload, "POST"); } - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { // { "oid": "598aeb627da3355fa3e851ca", "address": "598aeb627da3355fa3e851ca", "context": null, "userOid": "5969ddc96732d54312eb960e", "coinType": "KCS", "createdAt": 1502276446000, "deletedAt": null, "updatedAt": 1502276446000, "lastReceivedAt": 1502276446000 } - JToken token = await MakeJsonRequestAsync("/account/" + symbol + "/wallet/address", null, await GetNoncePayloadAsync()); + JToken token = await MakeJsonRequestAsync("/account/" + currency + "/wallet/address", null, await GetNoncePayloadAsync()); if (token != null && token.HasValues) { return new ExchangeDepositDetails() { - Symbol = symbol, + Currency = currency, Address = token["address"].ToStringInvariant(), AddressTag = token["userOid"].ToStringInvariant() // this isn't in their documentation, but is how it's being used on other interfaces }; diff --git a/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs b/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs index c9627b33..c7532192 100644 --- a/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs +++ b/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs @@ -307,12 +307,12 @@ protected override async Task> OnGetDepositHist return deposits; } - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { - JToken token = await MakeJsonRequestAsync("/payment/get/address?" + "currency=" + symbol.UrlEncode(), BaseUrl, await GetNoncePayloadAsync()); - if (token != null && token.HasValues && token["currency"].ToStringInvariant() == symbol && token["wallet"].ToStringInvariant().Length != 0) + JToken token = await MakeJsonRequestAsync("/payment/get/address?" + "currency=" + currency.UrlEncode(), BaseUrl, await GetNoncePayloadAsync()); + if (token != null && token.HasValues && token["currency"].ToStringInvariant() == currency && token["wallet"].ToStringInvariant().Length != 0) { - ExchangeDepositDetails address = new ExchangeDepositDetails() {Symbol = symbol }; + ExchangeDepositDetails address = new ExchangeDepositDetails() {Currency = currency }; if (token["wallet"].ToStringInvariant().Contains("::")) { // address tags are separated with a '::' diff --git a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs index 1faabb68..337cdf8f 100644 --- a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs @@ -854,24 +854,24 @@ protected override async Task OnWithdrawAsync(Exchan return resp; } - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { // Never reuse IOTA addresses - if (symbol.Equals("MIOTA", StringComparison.OrdinalIgnoreCase)) + if (currency.Equals("MIOTA", StringComparison.OrdinalIgnoreCase)) { forceRegenerate = true; } IReadOnlyDictionary currencies = await GetCurrenciesAsync(); var depositAddresses = new Dictionary(StringComparer.OrdinalIgnoreCase); - if (!forceRegenerate && !(await TryFetchExistingAddresses(symbol, currencies, depositAddresses))) + if (!forceRegenerate && !(await TryFetchExistingAddresses(currency, currencies, depositAddresses))) { return null; } - if (!depositAddresses.TryGetValue(symbol, out var depositDetails)) + if (!depositAddresses.TryGetValue(currency, out var depositDetails)) { - depositDetails = await CreateDepositAddress(symbol, currencies); + depositDetails = await CreateDepositAddress(currency, currencies); } return depositDetails; @@ -937,28 +937,28 @@ private static string ParseFeesCurrency(bool isBuy, string symbol) return feesCurrency; } - private async Task TryFetchExistingAddresses(string symbol, IReadOnlyDictionary currencies, Dictionary depositAddresses) + private async Task TryFetchExistingAddresses(string currency, IReadOnlyDictionary currencies, Dictionary depositAddresses) { JToken result = await MakePrivateAPIRequestAsync("returnDepositAddresses"); foreach (JToken jToken in result) { var token = (JProperty)jToken; - var details = new ExchangeDepositDetails { Symbol = token.Name }; + var details = new ExchangeDepositDetails { Currency = token.Name }; - if (!TryPopulateAddressAndTag(symbol, currencies, details, token.Value.ToStringInvariant())) + if (!TryPopulateAddressAndTag(currency, currencies, details, token.Value.ToStringInvariant())) { return false; } - depositAddresses[details.Symbol] = details; + depositAddresses[details.Currency] = details; } return true; } - private static bool TryPopulateAddressAndTag(string symbol, IReadOnlyDictionary currencies, ExchangeDepositDetails details, string address) + private static bool TryPopulateAddressAndTag(string currency, IReadOnlyDictionary currencies, ExchangeDepositDetails details, string address) { - if (currencies.TryGetValue(symbol, out ExchangeCurrency coin)) + if (currencies.TryGetValue(currency, out ExchangeCurrency coin)) { if (!string.IsNullOrWhiteSpace(coin.BaseAddress)) { @@ -982,18 +982,18 @@ private static bool TryPopulateAddressAndTag(string symbol, IReadOnlyDictionary< /// /// Create a deposit address /// - /// Symbol to create an address for + /// Currency to create an address for /// Lookup of existing currencies /// ExchangeDepositDetails with an address or a BaseAddress/AddressTag pair. - private async Task CreateDepositAddress(string symbol, IReadOnlyDictionary currencies) + private async Task CreateDepositAddress(string currency, IReadOnlyDictionary currencies) { - JToken result = await MakePrivateAPIRequestAsync("generateNewAddress", new object[] { "currency", symbol }); + JToken result = await MakePrivateAPIRequestAsync("generateNewAddress", new object[] { "currency", currency }); var details = new ExchangeDepositDetails { - Symbol = symbol, + Currency = currency, }; - if (!TryPopulateAddressAndTag(symbol, currencies, details, result["response"].ToStringInvariant())) + if (!TryPopulateAddressAndTag(currency, currencies, details, result["response"].ToStringInvariant())) { return null; } diff --git a/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs b/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs index dea11e7f..dd1819e2 100644 --- a/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs +++ b/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs @@ -350,19 +350,19 @@ protected override async Task> OnGetDepositHist } - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { var payload = await GetNoncePayloadAsync(); payload.Add("method", "getmyaddresses"); // "addresses": { "BTC": "14iuWRBwB35HYG98vBxmVJoJZG73BZy4bZ", "LTC": "LXLWHFLpPbcKx69diMVEXVLAzSMXsyrQH2", "DOGE": "DGon17FjjTTVXaHeotm1gvw6ewUZ49WeZr", } JToken token = await MakeJsonRequestAsync("/api", null, payload, "POST"); - if (token != null && token.HasValues && token["addresses"][symbol] != null) + if (token != null && token.HasValues && token["addresses"][currency] != null) { return new ExchangeDepositDetails() { - Symbol = symbol, - Address = token["addresses"][symbol].ToStringInvariant() + Currency = currency, + Address = token["addresses"][currency].ToStringInvariant() }; } return null; diff --git a/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs b/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs index 5fe240b2..18ec07f7 100644 --- a/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs +++ b/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs @@ -290,18 +290,18 @@ protected override Task> OnGetDepositHistoryAsy throw new NotImplementedException("Yobit does not provide a deposit history via the API"); // I don't wonder why } - protected override async Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) + protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { var payload = await GetNoncePayloadAsync(); payload.Add("need_new", forceRegenerate ? 1 : 0); payload.Add("method", "GetDepositAddress"); - payload.Add("coinName", symbol); + payload.Add("coinName", currency); // "return":{"address": 1UHAnAWvxDB9XXETsi7z483zRRBmcUZxb3,"processed_amount": 1.00000000,"server_time": 1437146228 } JToken token = await MakeJsonRequestAsync("/", PrivateURL, payload, "POST"); return new ExchangeDepositDetails() { Address = token["address"].ToStringInvariant(), - Symbol = symbol + Currency = currency }; } diff --git a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs index c563311e..f8c2bb73 100644 --- a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs +++ b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs @@ -86,7 +86,7 @@ await GetHistoricalTradesAsync((e) => protected virtual Task OnGetTickerAsync(string symbol) => throw new NotImplementedException(); protected virtual Task OnGetOrderBookAsync(string symbol, int maxCount = 100) => throw new NotImplementedException(); protected virtual Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) => throw new NotImplementedException(); - protected virtual Task OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false) => throw new NotImplementedException(); + protected virtual Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) => throw new NotImplementedException(); protected virtual Task> OnGetDepositHistoryAsync(string currency) => throw new NotImplementedException(); protected virtual Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) => throw new NotImplementedException(); protected virtual Task> OnGetAmountsAsync() => throw new NotImplementedException(); @@ -614,20 +614,19 @@ public virtual async Task> GetRecentTradesAsync(strin /// /// Gets the address to deposit to and applicable details. /// - /// Symbol to get address for. + /// Currency to get address for. /// Regenerate the address /// Deposit address details (including tag if applicable, such as XRP) - public virtual async Task GetDepositAddressAsync(string symbol, bool forceRegenerate = false) + public virtual async Task GetDepositAddressAsync(string currency, bool forceRegenerate = false) { - symbol = NormalizeSymbol(symbol); if (forceRegenerate) { // force regenetate, do not cache - return await OnGetDepositAddressAsync(symbol, forceRegenerate); + return await OnGetDepositAddressAsync(currency, forceRegenerate); } else { - return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetDepositAddressAsync(symbol, forceRegenerate), nameof(GetDepositAddressAsync), nameof(symbol), symbol); + return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetDepositAddressAsync(currency, forceRegenerate), nameof(GetDepositAddressAsync), nameof(currency), currency); } } diff --git a/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs b/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs index 59804f83..a91878df 100644 --- a/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs +++ b/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs @@ -68,10 +68,10 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider /// /// Gets the address to deposit to and applicable details. /// - /// Symbol to get address for. + /// Currency to get address for. /// True to regenerate the address /// Deposit address details (including tag if applicable, such as XRP) - Task GetDepositAddressAsync(string symbol, bool forceRegenerate = false); + Task GetDepositAddressAsync(string currency, bool forceRegenerate = false); /// /// Gets the deposit history for a currency diff --git a/ExchangeSharp/Model/ExchangeDepositDetails.cs b/ExchangeSharp/Model/ExchangeDepositDetails.cs index 71ecdb99..3a8e066b 100644 --- a/ExchangeSharp/Model/ExchangeDepositDetails.cs +++ b/ExchangeSharp/Model/ExchangeDepositDetails.cs @@ -15,8 +15,8 @@ namespace ExchangeSharp /// Class to encapsulate details required to make a deposit. public sealed class ExchangeDepositDetails { - /// The symbol of the currency. Ex. ETH - public string Symbol; + /// The name of the currency. Ex. ETH + public string Currency; /// The address to deposit to public string Address; @@ -29,7 +29,7 @@ public sealed class ExchangeDepositDetails /// A that represents this instance. public override string ToString() { - return $"{Symbol}: Address: {Address} AddressTag: {AddressTag}"; + return $"{Currency}: Address: {Address} AddressTag: {AddressTag}"; } } } \ No newline at end of file From 2992d67e0d8b25e74a7729a0ce907fe462e9a14f Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 18 Oct 2018 20:41:52 -0500 Subject: [PATCH 6/8] Rename MarketCandle properties BaseVolume and ConvertVolume to BaseCurrencyVolume and QuoteCurrencyVolume respectively. Update all usages. Add "candles" method to Console project. --- .../Exchanges/Bittrex/ExchangeBittrexAPI.cs | 3 +- .../Bleutrade/ExchangeBleutradeAPI.cs | 3 +- .../API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs | 2 +- .../API/Exchanges/Kucoin/ExchangeKucoinAPI.cs | 4 +-- .../Exchanges/Poloniex/ExchangePoloniexAPI.cs | 5 ++-- .../Exchanges/_Base/ExchangeAPIExtensions.cs | 12 ++++---- ExchangeSharp/Model/MarketCandle.cs | 8 ++--- .../Console/ExchangeSharpConsole_Example.cs | 30 +++++++++++++++++++ .../ExchangeSharpConsole_ExchangeTests.cs | 4 +-- .../ExchangeSharpConsole_Main.cs | 4 +++ 10 files changed, 56 insertions(+), 19 deletions(-) diff --git a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs index 8414683b..7f8a63b5 100644 --- a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs @@ -368,7 +368,8 @@ protected override async Task> OnGetCandlesAsync(strin { foreach (JToken jsonCandle in array) { - MarketCandle candle = this.ParseCandle(jsonCandle, symbol, periodSeconds, "O", "H", "L", "C", "T", TimestampType.Iso8601, "BV", "V"); + //NOTE: Bittrex uses the term "BaseVolume" when referring to the QuoteCurrencyVolume + MarketCandle candle = this.ParseCandle(jsonCandle, symbol, periodSeconds, "O", "H", "L", "C", "T", TimestampType.Iso8601, "V", "BV"); if (candle.Timestamp >= startDate && candle.Timestamp <= endDate) { candles.Add(candle); diff --git a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs index 4403b2dd..ba9c5d08 100644 --- a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs @@ -149,7 +149,8 @@ protected override async Task> OnGetCandlesAsync(strin JToken result = await MakeJsonRequestAsync("/public/getcandles?market=" + symbol + "&period=" + periodString + (limit == null ? string.Empty : "&lasthours=" + limit)); foreach (JToken jsonCandle in result) { - MarketCandle candle = this.ParseCandle(jsonCandle, symbol, periodSeconds, "Open", "High", "Low", "Close", "Timestamp", TimestampType.Iso8601, "BaseVolume", "Volume"); + //NOTE: Bleutrade uses the term "BaseVolume" when referring to the QuoteCurrencyVolume + MarketCandle candle = this.ParseCandle(jsonCandle, symbol, periodSeconds, "Open", "High", "Low", "Close", "Timestamp", TimestampType.Iso8601, "Volume", "BaseVolume"); if (candle.Timestamp >= startDate && candle.Timestamp <= endDate) { candles.Add(candle); diff --git a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs index d23f1f73..e8a28276 100644 --- a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs +++ b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs @@ -155,7 +155,7 @@ protected override async Task> OnGetCandlesAsync(strin JToken obj = await MakeJsonRequestAsync("/public/candles/" + symbol + "?period=" + periodString + "&limit=" + limit); foreach (JToken token in obj) { - candles.Add(this.ParseCandle(token, symbol, periodSeconds, "open", "max", "min", "close", "timestamp", TimestampType.Iso8601, "volumeQuote", "volume")); + candles.Add(this.ParseCandle(token, symbol, periodSeconds, "open", "max", "min", "close", "timestamp", TimestampType.Iso8601, "volume", "volumeQuote")); } return candles; } diff --git a/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs b/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs index 5efdb15c..c9321c43 100644 --- a/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs +++ b/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs @@ -231,8 +231,8 @@ protected override async Task> OnGetCandlesAsync(strin HighPrice = token["h"][i].ConvertInvariant(), LowPrice = token["l"][i].ConvertInvariant(), OpenPrice = token["o"][i].ConvertInvariant(), - ConvertedVolume = token["v"][i].ConvertInvariant(), - BaseVolume = token["v"][i].ConvertInvariant() * token["c"][i].ConvertInvariant() + BaseCurrencyVolume = token["v"][i].ConvertInvariant(), + QuoteCurrencyVolume = token["v"][i].ConvertInvariant() * token["c"][i].ConvertInvariant() }); } } diff --git a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs index 337cdf8f..3c871bdb 100644 --- a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs @@ -369,7 +369,8 @@ protected override async Task>> { string symbol = prop.Name; JToken values = prop.Value; - ExchangeTicker ticker = this.ParseTicker(values, symbol, "lowestAsk", "highestBid", "last", "baseVolume", "quoteVolume", idKey: "id"); + //NOTE: Poloniex uses the term "caseVolume" when referring to the QuoteCurrencyVolume + ExchangeTicker ticker = this.ParseTicker(values, symbol, "lowestAsk", "highestBid", "last", "quoteVolume", "baseVolume", idKey: "id"); tickers.Add(new KeyValuePair(symbol, ticker)); } return tickers; @@ -615,7 +616,7 @@ protected override async Task> OnGetCandlesAsync(strin List candles = new List(); foreach (JToken candle in token) { - candles.Add(this.ParseCandle(candle, symbol, periodSeconds, "open", "high", "low", "close", "date", TimestampType.UnixSeconds, "volume", "quoteVolume", "weightedAverage")); + candles.Add(this.ParseCandle(candle, symbol, periodSeconds, "open", "high", "low", "close", "date", TimestampType.UnixSeconds, "quoteVolume", "volume", "weightedAverage")); } return candles; } diff --git a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs index d159ec2f..3c87c60e 100644 --- a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs +++ b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs @@ -554,12 +554,12 @@ internal static void ParseVolumes(this JToken token, object baseVolumeKey, objec /// Close key /// Timestamp key /// Timestamp type - /// Base volume key - /// Convert volume key + /// Base currency volume key + /// Quote currency volume key /// Weighted average key /// MarketCandle internal static MarketCandle ParseCandle(this INamed named, JToken token, string symbol, int periodSeconds, object openKey, object highKey, object lowKey, - object closeKey, object timestampKey, TimestampType timestampType, object baseVolumeKey, object convertVolumeKey = null, object weightedAverageKey = null) + object closeKey, object timestampKey, TimestampType timestampType, object baseVolumeKey, object quoteVolumeKey = null, object weightedAverageKey = null) { MarketCandle candle = new MarketCandle { @@ -573,9 +573,9 @@ internal static MarketCandle ParseCandle(this INamed named, JToken token, string Timestamp = CryptoUtility.ParseTimestamp(token[timestampKey], timestampType) }; - token.ParseVolumes(baseVolumeKey, convertVolumeKey, candle.ClosePrice, out decimal baseVolume, out decimal convertVolume); - candle.BaseVolume = (double)baseVolume; - candle.ConvertedVolume = (double)convertVolume; + token.ParseVolumes(baseVolumeKey, quoteVolumeKey, candle.ClosePrice, out decimal baseVolume, out decimal convertVolume); + candle.BaseCurrencyVolume = (double)baseVolume; + candle.QuoteCurrencyVolume = (double)convertVolume; if (weightedAverageKey != null) { candle.WeightedAverage = token[weightedAverageKey].ConvertInvariant(); diff --git a/ExchangeSharp/Model/MarketCandle.cs b/ExchangeSharp/Model/MarketCandle.cs index 19c86082..684b8cae 100644 --- a/ExchangeSharp/Model/MarketCandle.cs +++ b/ExchangeSharp/Model/MarketCandle.cs @@ -66,12 +66,12 @@ public class MarketCandle /// /// Base currency volume (i.e. in BTC-USD, this would be BTC volume) /// - public double BaseVolume { get; set; } + public double BaseCurrencyVolume { get; set; } /// - /// Conversion currency volume (i.e. in BTC-USD, this would be USD volume) + /// Quote currency volume (i.e. in BTC-USD, this would be USD volume) /// - public double ConvertedVolume { get; set; } + public double QuoteCurrencyVolume { get; set; } /// /// The weighted average price if provided @@ -84,7 +84,7 @@ public class MarketCandle /// String public override string ToString() { - return string.Format("{0}/{1}: {2}, {3}, {4}, {5}, {6}, {7}, {8}", Timestamp, PeriodSeconds, OpenPrice, HighPrice, LowPrice, ClosePrice, BaseVolume, ConvertedVolume, WeightedAverage); + return string.Format("{0}/{1}: {2}, {3}, {4}, {5}, {6}, {7}, {8}", Timestamp, PeriodSeconds, OpenPrice, HighPrice, LowPrice, ClosePrice, BaseCurrencyVolume, QuoteCurrencyVolume, WeightedAverage); } } } diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs index f16ff77b..1fc0654f 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs @@ -276,5 +276,35 @@ public static void RunGetTickers(Dictionary dict) } } } + + public static void RunGetCandles(Dictionary dict) + { + RequireArgs(dict, "exchangeName", "symbol"); + using (var api = ExchangeAPI.GetExchangeAPI(dict["exchangeName"])) + { + if (api == null) + { + throw new ArgumentException("Cannot find exchange with name {0}", dict["exchangeName"]); + } + + try + { + var symbol = dict["symbol"]; + var candles = api.GetCandlesAsync(symbol, 1800, DateTime.UtcNow.AddDays(-12), DateTime.UtcNow).Sync(); + + foreach (var candle in candles) + { + Console.WriteLine(candle); + } + + Console.WriteLine("Press any key to quit."); + Console.ReadKey(); + } + catch (Exception ex) + { + Logger.Error(ex); + } + } + } } } diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs index dd1a74b5..eb8c5d69 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs @@ -157,8 +157,8 @@ bool histTradeCallback(IEnumerable tradeEnum) var candles = api.GetCandlesAsync(symbol, 86400, CryptoUtility.UtcNow.Subtract(TimeSpan.FromDays(7.0)), null).Sync().ToArray(); Assert(candles.Length != 0 && candles[0].ClosePrice > 0m && candles[0].HighPrice > 0m && candles[0].LowPrice > 0m && candles[0].OpenPrice > 0m && candles[0].HighPrice >= candles[0].LowPrice && candles[0].HighPrice >= candles[0].ClosePrice && candles[0].HighPrice >= candles[0].OpenPrice && - !string.IsNullOrWhiteSpace(candles[0].Name) && candles[0].ExchangeName == api.Name && candles[0].PeriodSeconds == 86400 && candles[0].BaseVolume > 0.0 && - candles[0].ConvertedVolume > 0.0 && candles[0].WeightedAverage >= 0m); + !string.IsNullOrWhiteSpace(candles[0].Name) && candles[0].ExchangeName == api.Name && candles[0].PeriodSeconds == 86400 && candles[0].BaseCurrencyVolume > 0.0 && + candles[0].QuoteCurrencyVolume > 0.0 && candles[0].WeightedAverage >= 0m); Console.WriteLine($"OK ({candles.Length})"); } diff --git a/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs b/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs index feb4c197..b38ecc3c 100644 --- a/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs +++ b/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs @@ -144,6 +144,10 @@ public static int ConsoleMain(string[] args) { RunGetTickers(argsDictionary); } + else if (argsDictionary.ContainsKey("candles")) + { + RunGetCandles(argsDictionary); + } else { Logger.Error("Unrecognized command line arguments."); From a10c9f49023da9e8a52cedaec84621055bb3119c Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 24 Oct 2018 14:02:47 -0500 Subject: [PATCH 7/8] Rename 'symbol' to 'marketSymbol', and 'Symbol' to 'MarketSymbol' where necessary --- .../Exchanges/Abucoins/ExchangeAbucoinsAPI.cs | 60 ++-- .../Exchanges/Binance/ExchangeBinanceAPI.cs | 158 ++++----- .../Binance/Models/MarketDepthDiffUpdate.cs | 2 +- .../API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs | 80 ++--- .../Exchanges/Bitfinex/ExchangeBitfinexAPI.cs | 110 +++--- .../Exchanges/Bithumb/ExchangeBithumbAPI.cs | 52 +-- .../Exchanges/Bitstamp/ExchangeBitstampAPI.cs | 42 +-- .../Exchanges/Bittrex/ExchangeBittrexAPI.cs | 68 ++-- .../Bittrex/ExchangeBittrexAPI_WebSocket.cs | 30 +- .../Bleutrade/ExchangeBleutradeAPI.cs | 48 +-- .../Exchanges/Coinbase/ExchangeCoinbaseAPI.cs | 80 ++--- .../Cryptopia/ExchangeCryptopiaAPI.cs | 56 ++-- .../API/Exchanges/Gemini/ExchangeGeminiAPI.cs | 38 +-- .../API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs | 60 ++-- .../API/Exchanges/Huobi/ExchangeHuobiAPI.cs | 110 +++--- .../API/Exchanges/Kraken/ExchangeKrakenAPI.cs | 84 ++--- .../API/Exchanges/Kucoin/ExchangeKucoinAPI.cs | 82 ++--- .../Exchanges/Livecoin/ExchangeLivecoinAPI.cs | 56 ++-- .../API/Exchanges/Okex/ExchangeOkexAPI.cs | 120 +++---- .../Exchanges/Poloniex/ExchangePoloniexAPI.cs | 136 ++++---- .../TuxExchange/ExchangeTuxExchangeAPI.cs | 46 +-- .../API/Exchanges/Yobit/ExchangeYobitAPI.cs | 58 ++-- .../API/Exchanges/ZBcom/ExchangeZBcomAPI.cs | 34 +- .../API/Exchanges/_Base/ExchangeAPI.cs | 316 +++++++++--------- .../Exchanges/_Base/ExchangeAPIDefinitions.cs | 6 +- .../Exchanges/_Base/ExchangeAPIExtensions.cs | 38 +-- .../_Base/ExchangeHistoricalTradeHelper.cs | 8 +- .../API/Exchanges/_Base/ExchangeLogger.cs | 16 +- .../API/Exchanges/_Base/IExchangeAPI.cs | 63 ++-- .../_Base/Interfaces/IOrderBookProvider.cs | 8 +- ExchangeSharp/API/Services/CryptowatchAPI.cs | 4 +- .../ExchangeCloseMarginPositionResult.cs | 2 +- ExchangeSharp/Model/ExchangeInfo.cs | 12 +- .../Model/ExchangeMarginPositionResult.cs | 4 +- ExchangeSharp/Model/ExchangeMarket.cs | 6 +- ExchangeSharp/Model/ExchangeOrderBook.cs | 4 +- ExchangeSharp/Model/ExchangeOrderRequest.cs | 4 +- ExchangeSharp/Model/ExchangeOrderResult.cs | 12 +- ExchangeSharp/Model/ExchangeTicker.cs | 2 +- ExchangeSharp/Model/ExchangeTradeInfo.cs | 16 +- ExchangeSharp/Traders/Trader.cs | 6 +- ExchangeSharp/Traders/TraderExchangeExport.cs | 8 +- .../Console/ExchangeSharpConsole_Example.cs | 64 ++-- .../ExchangeSharpConsole_ExchangeTests.cs | 18 +- .../Console/ExchangeSharpConsole_Export.cs | 6 +- .../Console/ExchangeSharpConsole_Orders.cs | 14 +- .../Console/ExchangeSharpConsole_Stats.cs | 20 +- .../ExchangeSharpConsole_Main.cs | 2 +- ExchangeSharpTests/ExchangeBinanceAPITests.cs | 2 +- .../ExchangePoloniexAPITests.cs | 8 +- ExchangeSharpTests/ExchangeTests.cs | 20 +- README.md | 6 +- 52 files changed, 1153 insertions(+), 1152 deletions(-) diff --git a/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs b/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs index e28fec68..ad9f5140 100644 --- a/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs +++ b/ExchangeSharp/API/Exchanges/Abucoins/ExchangeAbucoinsAPI.cs @@ -67,7 +67,7 @@ protected override Task> OnGetCurr throw new NotSupportedException("Abucoins does not provide data about its currencies via the API"); } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { List symbols = new List(); JToken obj = await MakeJsonRequestAsync("/products"); @@ -78,7 +78,7 @@ protected override async Task> OnGetSymbolsAsync() return symbols; } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { List markets = new List(); JToken obj = await MakeJsonRequestAsync("/products"); @@ -86,7 +86,7 @@ protected override async Task> OnGetSymbolsMetadataA { markets.Add(new ExchangeMarket { - MarketName = token["id"].ToStringInvariant(), + MarketSymbol = token["id"].ToStringInvariant(), BaseCurrency = token["base_currency"].ToStringInvariant(), QuoteCurrency = token["quote_currency"].ToStringInvariant(), MinTradeSize = token["base_min_size"].ConvertInvariant(), @@ -99,10 +99,10 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken token = await MakeJsonRequestAsync("/products/" + symbol + "/ticker"); - return ParseTicker(token, symbol); + JToken token = await MakeJsonRequestAsync("/products/" + marketSymbol + "/ticker"); + return ParseTicker(token, marketSymbol); } protected override async Task>> OnGetTickersAsync() @@ -113,34 +113,34 @@ protected override async Task>> { foreach (JToken token in obj) { - string symbol = token["product_id"].ToStringInvariant(); - ExchangeTicker ticker = ParseTicker(token, symbol); + string marketSymbol = token["product_id"].ToStringInvariant(); + ExchangeTicker ticker = ParseTicker(token, marketSymbol); if (ticker != null) { - tickers.Add(new KeyValuePair(symbol, ticker)); + tickers.Add(new KeyValuePair(marketSymbol, ticker)); } } } return tickers; } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - JToken token = await MakeJsonRequestAsync("/products/" + symbol + "/book?level=" + (maxCount > 50 ? "0" : "2")); + JToken token = await MakeJsonRequestAsync("/products/" + marketSymbol + "/book?level=" + (maxCount > 50 ? "0" : "2")); return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token, maxCount: maxCount); } - protected override async Task> OnGetRecentTradesAsync(string symbol) + protected override async Task> OnGetRecentTradesAsync(string marketSymbol) { List trades = new List(); // { "time": "2017-09-21T12:33:03Z", "trade_id": "553794", "price": "14167.99328000", "size": "0.00035000", "side": "buy"} - JToken obj = await MakeJsonRequestAsync("/products/" + symbol + "/trades"); + JToken obj = await MakeJsonRequestAsync("/products/" + marketSymbol + "/trades"); if (obj.HasValues) foreach (JToken token in obj) trades.Add(ParseExchangeTrade(token)); return trades; } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { List trades = new List(); long? lastTradeId = null; @@ -150,7 +150,7 @@ protected override async Task OnGetHistoricalTradesAsync(Func("/products/" + symbol + "/trades" + (lastTradeId == null ? string.Empty : "?before=" + lastTradeId)); + obj = await MakeJsonRequestAsync("/products/" + marketSymbol + "/trades" + (lastTradeId == null ? string.Empty : "?before=" + lastTradeId)); if ((running = obj.HasValues)) { lastTradeId = obj.First()["trade_id"].ConvertInvariant(); @@ -178,7 +178,7 @@ protected override async Task OnGetHistoricalTradesAsync(Func> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { //if (limit != null) throw new APIException("Limit parameter not supported"); Really? You want to throw an exception instead of ignoring the parm? List candles = new List(); @@ -187,12 +187,12 @@ protected override async Task> OnGetCandlesAsync(strin startDate = startDate ?? endDate.Value.Subtract(TimeSpan.FromDays(1.0)); //[time, low, high, open, close, volume], ["1505984400","14209.92500000","14209.92500000","14209.92500000","14209.92500000","0.001"] - JToken obj = await MakeJsonRequestAsync("/products/" + symbol + "/candles?granularity=" + periodSeconds.ToStringInvariant() + "&start=" + ((DateTime)startDate).ToString("o") + "&end=" + ((DateTime)endDate).ToString("o")); + JToken obj = await MakeJsonRequestAsync("/products/" + marketSymbol + "/candles?granularity=" + periodSeconds.ToStringInvariant() + "&start=" + ((DateTime)startDate).ToString("o") + "&end=" + ((DateTime)endDate).ToString("o")); if (obj.HasValues) { foreach (JToken token in obj) { - candles.Add(this.ParseCandle(token, symbol, periodSeconds, 3, 2, 1, 4, 0, TimestampType.UnixSeconds, 5)); + candles.Add(this.ParseCandle(token, marketSymbol, periodSeconds, 3, 2, 1, 4, 0, TimestampType.UnixSeconds, 5)); } } return candles; @@ -226,7 +226,7 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { JToken token = await MakeJsonRequestAsync("/orders?orderID", null, await GetNoncePayloadAsync()); ExchangeOrderResult eor = new ExchangeOrderResult() @@ -236,7 +236,7 @@ protected override async Task OnGetOrderDetailsAsync(string AmountFilled = token["filled_size"].ConvertInvariant(), AveragePrice = token["price"].ConvertInvariant(), IsBuy = token["side"].ToStringInvariant().Equals("buy"), - Symbol = token["product_id"].ToStringInvariant(), + MarketSymbol = token["product_id"].ToStringInvariant(), }; if (DateTime.TryParse(token["created_at"].ToStringInvariant(), out DateTime dt)) eor.OrderDate = dt; @@ -250,7 +250,7 @@ protected override async Task OnGetOrderDetailsAsync(string return eor; } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { List result = new List(); JArray array = await MakeJsonRequestAsync("/orders?status=done", null, await GetNoncePayloadAsync()); @@ -263,7 +263,7 @@ protected override async Task> OnGetCompletedOr AmountFilled = token["filled_size"].ConvertInvariant(), AveragePrice = token["price"].ConvertInvariant(), IsBuy = token["side"].ConvertInvariant().Equals("buy"), - Symbol = token["product_id"].ToStringInvariant(), + MarketSymbol = token["product_id"].ToStringInvariant(), }; if (DateTime.TryParse(token["created_at"].ToStringInvariant(), out DateTime dt)) eor.OrderDate = dt; @@ -279,7 +279,7 @@ protected override async Task> OnGetCompletedOr return result; } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List result = new List(); JArray array = await MakeJsonRequestAsync("/orders?status=open", null, await GetNoncePayloadAsync()); @@ -292,7 +292,7 @@ protected override async Task> OnGetOpenOrderDe AmountFilled = token["filled_size"].ConvertInvariant(), AveragePrice = token["price"].ConvertInvariant(), IsBuy = token["side"].ToStringInvariant().Equals("buy"), - Symbol = token["product_id"].ToStringInvariant(), + MarketSymbol = token["product_id"].ToStringInvariant(), }; if (DateTime.TryParse(token["created_at"].ToStringInvariant(), out DateTime dt)) eor.OrderDate = dt; @@ -312,7 +312,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd { ExchangeOrderResult result = new ExchangeOrderResult() { Result = ExchangeAPIOrderResult.Error }; var payload = await GetNoncePayloadAsync(); - payload["priduct_id"] = order.Symbol; + payload["priduct_id"] = order.MarketSymbol; payload["side"] = order.IsBuy ? "buy" : "sell"; payload["size"] = order.Amount; if (order.OrderType == OrderType.Limit) @@ -338,7 +338,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd result.IsBuy = token["buy"].ToStringInvariant().Equals("buy"); result.OrderDate = token["created_at"].ToDateTimeInvariant(); result.Price = token["price"].ConvertInvariant(); - result.Symbol = token["product_id"].ToStringInvariant(); + result.MarketSymbol = token["product_id"].ToStringInvariant(); result.Message = token["reject_reason"].ToStringInvariant(); switch (token["status"].ToStringInvariant()) { @@ -354,7 +354,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd } // This should have a return value for success - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { await MakeJsonRequestAsync("/orders/" + orderId, null, await GetNoncePayloadAsync(), "DELETE"); } @@ -460,7 +460,7 @@ protected override IWebSocket OnGetCompletedOrderDetailsWebSocket(Action> { - new KeyValuePair(symbol, this.ParseTicker(token, symbol, "best_ask", "best_bid", "price", "last_size", null, "time", TimestampType.Iso8601)) + new KeyValuePair(marketSymbol, this.ParseTicker(token, marketSymbol, "best_ask", "best_bid", "price", "last_size", null, "time", TimestampType.Iso8601)) }); } return Task.CompletedTask; diff --git a/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs b/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs index 382e0a4b..df10dbed 100644 --- a/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs +++ b/ExchangeSharp/API/Exchanges/Binance/ExchangeBinanceAPI.cs @@ -44,18 +44,18 @@ static ExchangeBinanceAPI() }; } - private string GetWebSocketStreamUrlForSymbols(string suffix, params string[] symbols) + private string GetWebSocketStreamUrlForSymbols(string suffix, params string[] marketSymbols) { - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = GetSymbolsAsync().Sync().ToArray(); + marketSymbols = GetMarketSymbolsAsync().Sync().ToArray(); } StringBuilder streams = new StringBuilder("/stream?streams="); - for (int i = 0; i < symbols.Length; i++) + for (int i = 0; i < marketSymbols.Length; i++) { - string symbol = NormalizeSymbol(symbols[i]).ToLowerInvariant(); - streams.Append(symbol); + string marketSymbol = NormalizeMarketSymbol(marketSymbols[i]).ToLowerInvariant(); + streams.Append(marketSymbol); streams.Append(suffix); streams.Append('/'); } @@ -70,39 +70,39 @@ public ExchangeBinanceAPI() RequestWindow = TimeSpan.FromMinutes(15.0); NonceStyle = NonceStyle.UnixMilliseconds; NonceOffset = TimeSpan.FromSeconds(10.0); - SymbolSeparator = string.Empty; + MarketSymbolSeparator = string.Empty; WebSocketOrderBookType = WebSocketOrderBookType.DeltasOnly; } - public override string ExchangeSymbolToGlobalSymbol(string symbol) + public override string ExchangeMarketSymbolToGlobalMarketSymbol(string marketSymbol) { // All pairs in Binance end with BTC, ETH, BNB or USDT - if (symbol.EndsWith("BTC") || symbol.EndsWith("ETH") || symbol.EndsWith("BNB")) + if (marketSymbol.EndsWith("BTC") || marketSymbol.EndsWith("ETH") || marketSymbol.EndsWith("BNB")) { - string baseSymbol = symbol.Substring(symbol.Length - 3); - return ExchangeSymbolToGlobalSymbolWithSeparator((symbol.Replace(baseSymbol, "") + GlobalSymbolSeparator + baseSymbol), GlobalSymbolSeparator); + string baseSymbol = marketSymbol.Substring(marketSymbol.Length - 3); + return ExchangeMarketSymbolToGlobalMarketSymbolWithSeparator((marketSymbol.Replace(baseSymbol, "") + GlobalMarketSymbolSeparator + baseSymbol), GlobalMarketSymbolSeparator); } - if (symbol.EndsWith("USDT")) + if (marketSymbol.EndsWith("USDT")) { - string baseSymbol = symbol.Substring(symbol.Length - 4); - return ExchangeSymbolToGlobalSymbolWithSeparator((symbol.Replace(baseSymbol, "") + GlobalSymbolSeparator + baseSymbol), GlobalSymbolSeparator); + string baseSymbol = marketSymbol.Substring(marketSymbol.Length - 4); + return ExchangeMarketSymbolToGlobalMarketSymbolWithSeparator((marketSymbol.Replace(baseSymbol, "") + GlobalMarketSymbolSeparator + baseSymbol), GlobalMarketSymbolSeparator); } - return ExchangeSymbolToGlobalSymbolWithSeparator(symbol.Substring(0, symbol.Length - 3) + GlobalSymbolSeparator + (symbol.Substring(symbol.Length - 3, 3)), GlobalSymbolSeparator); + return ExchangeMarketSymbolToGlobalMarketSymbolWithSeparator(marketSymbol.Substring(0, marketSymbol.Length - 3) + GlobalMarketSymbolSeparator + (marketSymbol.Substring(marketSymbol.Length - 3, 3)), GlobalMarketSymbolSeparator); } /// /// Get the details of all trades /// - /// Symbol to get trades for or null for all + /// Symbol to get trades for or null for all /// All trades for the specified symbol, or all if null symbol - public async Task> GetMyTradesAsync(string symbol = null, DateTime? afterDate = null) + public async Task> GetMyTradesAsync(string marketSymbol = null, DateTime? afterDate = null) { await new SynchronizationContextRemover(); - return await OnGetMyTradesAsync(symbol, afterDate); + return await OnGetMyTradesAsync(marketSymbol, afterDate); } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { List symbols = new List(); JToken obj = await MakeJsonRequestAsync("/ticker/allPrices"); @@ -113,7 +113,7 @@ protected override async Task> OnGetSymbolsAsync() return symbols; } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { /* * { @@ -157,18 +157,18 @@ protected override async Task> OnGetSymbolsMetadataA var markets = new List(); JToken obj = await MakeJsonRequestAsync("/exchangeInfo"); JToken allSymbols = obj["symbols"]; - foreach (JToken symbol in allSymbols) + foreach (JToken marketSymbolToken in allSymbols) { var market = new ExchangeMarket { - MarketName = symbol["symbol"].ToStringUpperInvariant(), - IsActive = ParseMarketStatus(symbol["status"].ToStringUpperInvariant()), - QuoteCurrency = symbol["quoteAsset"].ToStringUpperInvariant(), - BaseCurrency = symbol["baseAsset"].ToStringUpperInvariant() + MarketSymbol = marketSymbolToken["symbol"].ToStringUpperInvariant(), + IsActive = ParseMarketStatus(marketSymbolToken["status"].ToStringUpperInvariant()), + QuoteCurrency = marketSymbolToken["quoteAsset"].ToStringUpperInvariant(), + BaseCurrency = marketSymbolToken["baseAsset"].ToStringUpperInvariant() }; // "LOT_SIZE" - JToken filters = symbol["filters"]; + JToken filters = marketSymbolToken["filters"]; JToken lotSizeFilter = filters?.FirstOrDefault(x => string.Equals(x["filterType"].ToStringUpperInvariant(), "LOT_SIZE")); if (lotSizeFilter != null) { @@ -221,21 +221,21 @@ protected override async Task> OnG return allCoins; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken obj = await MakeJsonRequestAsync("/ticker/24hr?symbol=" + symbol); - return ParseTicker(symbol, obj); + JToken obj = await MakeJsonRequestAsync("/ticker/24hr?symbol=" + marketSymbol); + return ParseTicker(marketSymbol, obj); } protected override async Task>> OnGetTickersAsync() { List> tickers = new List>(); - string symbol; + string marketSymbol; JToken obj = await MakeJsonRequestAsync("/ticker/24hr"); foreach (JToken child in obj) { - symbol = child["symbol"].ToStringInvariant(); - tickers.Add(new KeyValuePair(symbol, ParseTicker(symbol, child))); + marketSymbol = child["symbol"].ToStringInvariant(); + tickers.Add(new KeyValuePair(marketSymbol, ParseTicker(marketSymbol, child))); } return tickers; } @@ -260,7 +260,7 @@ protected override IWebSocket OnGetTickersWebSocket(Action> callback, params string[] symbols) + protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] marketSymbols) { /* { @@ -278,38 +278,38 @@ protected override IWebSocket OnGetTradesWebSocket(Action { JToken token = JToken.Parse(msg.ToStringFromUTF8()); string name = token["stream"].ToStringInvariant(); token = token["data"]; - string symbol = NormalizeSymbol(name.Substring(0, name.IndexOf('@'))); + string marketSymbol = NormalizeMarketSymbol(name.Substring(0, name.IndexOf('@'))); // buy=0 -> m = true (The buyer is maker, while the seller is taker). // buy=1 -> m = false(The seller is maker, while the buyer is taker). - callback(new KeyValuePair(symbol, token.ParseTrade("q", "p", "m", "E", TimestampType.UnixMilliseconds, "t", "false"))); + callback(new KeyValuePair(marketSymbol, token.ParseTrade("q", "p", "m", "E", TimestampType.UnixMilliseconds, "t", "false"))); return Task.CompletedTask; }); } - protected override IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] symbols) + protected override IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] marketSymbols) { - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = GetSymbolsAsync().Sync().ToArray(); + marketSymbols = GetMarketSymbolsAsync().Sync().ToArray(); } - string combined = string.Join("/", symbols.Select(s => this.NormalizeSymbol(s).ToLowerInvariant() + "@depth")); + string combined = string.Join("/", marketSymbols.Select(s => this.NormalizeMarketSymbol(s).ToLowerInvariant() + "@depth")); return ConnectWebSocket($"/stream?streams={combined}", (_socket, msg) => { string json = msg.ToStringFromUTF8(); var update = JsonConvert.DeserializeObject(json); - string symbol = update.Data.Symbol; - ExchangeOrderBook book = new ExchangeOrderBook { SequenceId = update.Data.FinalUpdate, Symbol = symbol }; + string marketSymbol = update.Data.MarketSymbol; + ExchangeOrderBook book = new ExchangeOrderBook { SequenceId = update.Data.FinalUpdate, MarketSymbol = marketSymbol }; foreach (List ask in update.Data.Asks) { var depth = new ExchangeOrderPrice { Price = ask[0].ConvertInvariant(), Amount = ask[1].ConvertInvariant() }; @@ -325,13 +325,13 @@ protected override IWebSocket OnGetOrderBookWebSocket(Action }); } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - JToken obj = await MakeJsonRequestAsync("/depth?symbol=" + symbol + "&limit=" + maxCount); + JToken obj = await MakeJsonRequestAsync("/depth?symbol=" + marketSymbol + "&limit=" + maxCount); return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(obj, sequence: "lastUpdateId", maxCount: maxCount); } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { /* [ { "a": 26129, // Aggregate tradeId @@ -350,14 +350,14 @@ protected override async Task OnGetHistoricalTradesAsync(Func token.ParseTrade("q", "p", "m", "T", TimestampType.UnixMilliseconds, "a", "false"), StartDate = startDate, - Symbol = symbol, + MarketSymbol = marketSymbol, TimestampFunction = (DateTime dt) => ((long)CryptoUtility.UnixTimestampFromDateTimeMilliseconds(dt)).ToStringInvariant(), - Url = "/aggTrades?symbol=[symbol]&startTime={0}&endTime={1}", + Url = "/aggTrades?symbol=[marketSymbol]&startTime={0}&endTime={1}", }; await state.ProcessHistoricalTrades(); } - protected override async Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { /* [ [ @@ -376,7 +376,7 @@ protected override async Task> OnGetCandlesAsync(strin ]] */ List candles = new List(); - string url = "/klines?symbol=" + symbol; + string url = "/klines?symbol=" + marketSymbol; if (startDate != null) { url += "&startTime=" + (long)startDate.Value.UnixTimestampFromDateTimeMilliseconds(); @@ -390,7 +390,7 @@ protected override async Task> OnGetCandlesAsync(strin JToken obj = await MakeJsonRequestAsync(url); foreach (JToken token in obj) { - candles.Add(this.ParseCandle(token, symbol, periodSeconds, 1, 2, 3, 4, 0, TimestampType.UnixMilliseconds, 5, 7)); + candles.Add(this.ParseCandle(token, marketSymbol, periodSeconds, 1, 2, 3, 4, 0, TimestampType.UnixMilliseconds, 5, 7)); } return candles; @@ -429,7 +429,7 @@ protected override async Task> OnGetAmountsAvailable protected override async Task OnPlaceOrderAsync(ExchangeOrderRequest order) { Dictionary payload = await GetNoncePayloadAsync(); - payload["symbol"] = order.Symbol; + payload["symbol"] = order.MarketSymbol; payload["side"] = order.IsBuy ? "BUY" : "SELL"; if (order.OrderType == OrderType.Stop) payload["type"] = "STOP_LOOSE";//if order type is stop loose/limit, then binance expect word 'STOP_LOOSE' inestead of 'STOP' @@ -437,8 +437,8 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd payload["type"] = order.OrderType.ToStringUpperInvariant(); // Binance has strict rules on which prices and quantities are allowed. They have to match the rules defined in the market definition. - decimal outputQuantity = await ClampOrderQuantity(order.Symbol, order.Amount); - decimal outputPrice = await ClampOrderPrice(order.Symbol, order.Price); + decimal outputQuantity = await ClampOrderQuantity(order.MarketSymbol, order.Amount); + decimal outputPrice = await ClampOrderPrice(order.MarketSymbol, order.Price); // Binance does not accept quantities with more than 20 decimal places. payload["quantity"] = Math.Round(outputQuantity, 20); @@ -455,21 +455,21 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(token); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { Dictionary payload = await GetNoncePayloadAsync(); - if (string.IsNullOrEmpty(symbol)) + if (string.IsNullOrEmpty(marketSymbol)) { throw new InvalidOperationException("Binance single order details request requires symbol"); } - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; payload["orderId"] = orderId; JToken token = await MakeJsonRequestAsync("/order", BaseUrlPrivate, payload); ExchangeOrderResult result = ParseOrder(token); // Add up the fees from each trade in the order Dictionary feesPayload = await GetNoncePayloadAsync(); - feesPayload["symbol"] = symbol; + feesPayload["symbol"] = marketSymbol; JToken feesToken = await MakeJsonRequestAsync("/myTrades", BaseUrlPrivate, feesPayload); ParseFees(feesToken, result); @@ -497,13 +497,13 @@ private static void ParseFees(JToken feesToken, ExchangeOrderResult result) } } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); Dictionary payload = await GetNoncePayloadAsync(); - if (symbol.Length != 0) + if (marketSymbol.Length != 0) { - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; } JToken token = await MakeJsonRequestAsync("/openOrders", BaseUrlPrivate, payload); foreach (JToken order in token) @@ -520,7 +520,7 @@ private async Task> GetCompletedOrdersForAllSym List orders = new List(); Exception ex = null; string failedSymbol = null; - Parallel.ForEach((await GetSymbolsAsync()).Where(s => s.IndexOf("BTC", StringComparison.OrdinalIgnoreCase) >= 0), async (s) => + Parallel.ForEach((await GetMarketSymbolsAsync()).Where(s => s.IndexOf("BTC", StringComparison.OrdinalIgnoreCase) >= 0), async (s) => { try { @@ -552,17 +552,17 @@ private async Task> GetCompletedOrdersForAllSym return orders; } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { List orders = new List(); - if (symbol.Length == 0) + if (marketSymbol.Length == 0) { orders.AddRange(await GetCompletedOrdersForAllSymbolsAsync(afterDate)); } else { Dictionary payload = await GetNoncePayloadAsync(); - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; if (afterDate != null) { payload["startTime"] = afterDate.Value.UnixTimestampFromDateTimeMilliseconds(); @@ -582,7 +582,7 @@ private async Task> GetMyTradesForAllSymbols(Da List trades = new List(); Exception ex = null; string failedSymbol = null; - Parallel.ForEach((await GetSymbolsAsync()).Where(s => s.IndexOf("BTC", StringComparison.OrdinalIgnoreCase) >= 0), async (s) => + Parallel.ForEach((await GetMarketSymbolsAsync()).Where(s => s.IndexOf("BTC", StringComparison.OrdinalIgnoreCase) >= 0), async (s) => { try { @@ -614,17 +614,17 @@ private async Task> GetMyTradesForAllSymbols(Da return trades; } - private async Task> OnGetMyTradesAsync(string symbol = null, DateTime? afterDate = null) + private async Task> OnGetMyTradesAsync(string marketSymbol = null, DateTime? afterDate = null) { List trades = new List(); - if (symbol.Length == 0) + if (marketSymbol.Length == 0) { trades.AddRange(await GetCompletedOrdersForAllSymbolsAsync(afterDate)); } else { Dictionary payload = await GetNoncePayloadAsync(); - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; if (afterDate != null) { payload["timestamp"] = afterDate.Value.UnixTimestampFromDateTimeMilliseconds(); @@ -632,20 +632,20 @@ private async Task> OnGetMyTradesAsync(string s JToken token = await MakeJsonRequestAsync("/myTrades", BaseUrlPrivate, payload); foreach (JToken trade in token) { - trades.Add(ParseTrade(trade, symbol)); + trades.Add(ParseTrade(trade, marketSymbol)); } } return trades; } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { Dictionary payload = await GetNoncePayloadAsync(); - if (symbol.Length == 0) + if (marketSymbol.Length == 0) { throw new InvalidOperationException("Binance cancel order request requires symbol"); } - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; payload["orderId"] = orderId; JToken token = await MakeJsonRequestAsync("/order", BaseUrlPrivate, payload, "DELETE"); } @@ -720,8 +720,8 @@ private ExchangeTicker ParseTicker(string symbol, JToken token) private ExchangeTicker ParseTickerWebSocket(JToken token) { - string symbol = token["s"].ToStringInvariant(); - return this.ParseTicker(token, symbol, "a", "b", "c", "v", "q", "E", TimestampType.UnixMilliseconds); + string marketSymbol = token["s"].ToStringInvariant(); + return this.ParseTicker(token, marketSymbol, "a", "b", "c", "v", "q", "E", TimestampType.UnixMilliseconds); } private ExchangeOrderResult ParseOrder(JToken token) @@ -779,7 +779,7 @@ private ExchangeOrderResult ParseOrder(JToken token) IsBuy = token["side"].ToStringInvariant() == "BUY", OrderDate = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(token["time"].ConvertInvariant(token["transactTime"].ConvertInvariant())), OrderId = token["orderId"].ToStringInvariant(), - Symbol = token["symbol"].ToStringInvariant() + MarketSymbol = token["symbol"].ToStringInvariant() }; switch (token["status"].ToStringInvariant()) @@ -843,7 +843,7 @@ private ExchangeOrderResult ParseTrade(JToken token, string symbol) OrderId = token["orderId"].ToStringInvariant(), Fees = token["commission"].ConvertInvariant(), FeesCurrency = token["commissionAsset"].ToStringInvariant(), - Symbol = symbol + MarketSymbol = symbol }; return result; @@ -933,7 +933,7 @@ protected override async Task OnGetDepositAddressAsync(s } /// Gets the deposit history for a symbol - /// The symbol to check. Null for all symbols. + /// The currency to check. Null for all symbols. /// Collection of ExchangeCoinTransfers protected override async Task> OnGetDepositHistoryAsync(string currency) { diff --git a/ExchangeSharp/API/Exchanges/Binance/Models/MarketDepthDiffUpdate.cs b/ExchangeSharp/API/Exchanges/Binance/Models/MarketDepthDiffUpdate.cs index 10aa9639..a704a594 100644 --- a/ExchangeSharp/API/Exchanges/Binance/Models/MarketDepthDiffUpdate.cs +++ b/ExchangeSharp/API/Exchanges/Binance/Models/MarketDepthDiffUpdate.cs @@ -25,7 +25,7 @@ internal class MarketDepthDiffUpdate public long EventTime { get; set; } [JsonProperty("s")] - public string Symbol { get; set; } + public string MarketSymbol { get; set; } [JsonProperty("U")] public int FirstUpdate { get; set; } diff --git a/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs b/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs index bdbe6c8f..795ac54b 100644 --- a/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs +++ b/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs @@ -42,19 +42,19 @@ public ExchangeBitMEXAPI() // this will give us an api-expires 60 seconds into the future NonceOffset = TimeSpan.FromSeconds(-60.0); - SymbolSeparator = string.Empty; + MarketSymbolSeparator = string.Empty; RequestContentType = "application/json"; WebSocketOrderBookType = WebSocketOrderBookType.FullBookFirstThenDeltas; RateLimit = new RateGate(300, TimeSpan.FromMinutes(5)); } - public override string ExchangeSymbolToGlobalSymbol(string symbol) + public override string ExchangeMarketSymbolToGlobalMarketSymbol(string marketSymbol) { throw new NotImplementedException(); } - public override string GlobalSymbolToExchangeSymbol(string symbol) + public override string GlobalMarketSymbolToExchangeMarketSymbol(string marketSymbol) { throw new NotImplementedException(); } @@ -78,14 +78,14 @@ protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dicti } } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { - var m = await GetSymbolsMetadataAsync(); - return m.Select(x => x.MarketName); + var m = await GetMarketSymbolsMetadataAsync(); + return m.Select(x => x.MarketSymbol); } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { /* {{ @@ -195,23 +195,23 @@ protected override async Task> OnGetSymbolsMetadataA List markets = new List(); JToken allSymbols = await MakeJsonRequestAsync("/instrument"); - foreach (JToken symbol in allSymbols) + foreach (JToken marketSymbolToken in allSymbols) { var market = new ExchangeMarket { - MarketName = symbol["symbol"].ToStringUpperInvariant(), - IsActive = symbol["status"].ToStringInvariant().EqualsWithOption("Open"), - QuoteCurrency = symbol["quoteCurrency"].ToStringUpperInvariant(), - BaseCurrency = symbol["underlying"].ToStringUpperInvariant(), + MarketSymbol = marketSymbolToken["symbol"].ToStringUpperInvariant(), + IsActive = marketSymbolToken["status"].ToStringInvariant().EqualsWithOption("Open"), + QuoteCurrency = marketSymbolToken["quoteCurrency"].ToStringUpperInvariant(), + BaseCurrency = marketSymbolToken["underlying"].ToStringUpperInvariant(), }; try { - market.PriceStepSize = symbol["tickSize"].ConvertInvariant(); - market.MaxPrice = symbol["maxPrice"].ConvertInvariant(); + market.PriceStepSize = marketSymbolToken["tickSize"].ConvertInvariant(); + market.MaxPrice = marketSymbolToken["maxPrice"].ConvertInvariant(); //market.MinPrice = symbol["minPrice"].ConvertInvariant(); - market.MaxTradeSize = symbol["maxOrderQty"].ConvertInvariant(); + market.MaxTradeSize = marketSymbolToken["maxOrderQty"].ConvertInvariant(); //market.MinTradeSize = symbol["minQty"].ConvertInvariant(); //market.QuantityStepSize = symbol["stepSize"].ConvertInvariant(); } @@ -224,7 +224,7 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] symbols) + protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] marketSymbols) { /* {"table":"trade","action":"partial","keys":[], @@ -249,21 +249,21 @@ protected override IWebSocket OnGetTradesWebSocket(Action(symbol, t.ParseTrade("size", "price", "size", "timestamp", TimestampType.Iso8601, "trdMatchID"))); + var marketSymbol = t["symbol"].ToStringInvariant(); + callback(new KeyValuePair(marketSymbol, t.ParseTrade("size", "price", "size", "timestamp", TimestampType.Iso8601, "trdMatchID"))); } return Task.CompletedTask; }, async (_socket) => { - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = (await GetSymbolsAsync()).ToArray(); + marketSymbols = (await GetMarketSymbolsAsync()).ToArray(); } - await _socket.SendMessageAsync(new { op = "subscribe", args = symbols.Select(s => "\"trade:" + this.NormalizeSymbol(s) + "\"").ToArray() }); + await _socket.SendMessageAsync(new { op = "subscribe", args = marketSymbols.Select(s => "\"trade:" + this.NormalizeMarketSymbol(s) + "\"").ToArray() }); }); } - protected override IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] symbols) + protected override IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] marketSymbols) { /* {"info":"Welcome to the BitMEX Realtime API.","version":"2018-06-29T18:05:14.000Z","timestamp":"2018-07-05T14:22:26.267Z","docs":"https://www.bitmex.com/app/wsAPI","limit":{"remaining":39}} @@ -271,9 +271,9 @@ protected override IWebSocket OnGetOrderBookWebSocket(Action {"table":"orderBookL2","action":"update","data":[{"symbol":"XBTUSD","id":8799343000,"side":"Buy","size":350544}]} */ - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = GetSymbolsAsync().Sync().ToArray(); + marketSymbols = GetMarketSymbolsAsync().Sync().ToArray(); } return ConnectWebSocket(string.Empty, (_socket, msg) => { @@ -293,7 +293,7 @@ protected override IWebSocket OnGetOrderBookWebSocket(Action var size = 0m; foreach (var d in data) { - var symbol = d["symbol"].ToStringInvariant(); + var marketSymbol = d["symbol"].ToStringInvariant(); var id = d["id"].ConvertInvariant(); if (d["price"] == null) { @@ -330,25 +330,25 @@ protected override IWebSocket OnGetOrderBookWebSocket(Action { book.Asks[depth.Price] = depth; } - book.Symbol = symbol; + book.MarketSymbol = marketSymbol; } - if (!string.IsNullOrEmpty(book.Symbol)) + if (!string.IsNullOrEmpty(book.MarketSymbol)) { callback(book); } return Task.CompletedTask; }, async (_socket) => { - if (symbols.Length == 0) + if (marketSymbols.Length == 0) { - symbols = (await GetSymbolsAsync()).ToArray(); + marketSymbols = (await GetMarketSymbolsAsync()).ToArray(); } - await _socket.SendMessageAsync(new { op = "subscribe", args = symbols.Select(s => "\"orderBookL2:" + this.NormalizeSymbol(s) + "\"").ToArray() }); + await _socket.SendMessageAsync(new { op = "subscribe", args = marketSymbols.Select(s => "\"orderBookL2:" + this.NormalizeMarketSymbol(s) + "\"").ToArray() }); }); } - protected override async Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { /* [ @@ -358,7 +358,7 @@ protected override async Task> OnGetCandlesAsync(strin List candles = new List(); string periodString = PeriodSecondsToString(periodSeconds); - string url = $"/trade/bucketed?binSize={periodString}&partial=false&symbol={symbol}&reverse=true" + symbol; + string url = $"/trade/bucketed?binSize={periodString}&partial=false&symbol={marketSymbol}&reverse=true" + marketSymbol; if (startDate != null) { url += "&startTime=" + startDate.Value.ToString("yyyy-MM-dd"); @@ -375,7 +375,7 @@ protected override async Task> OnGetCandlesAsync(strin var obj = await MakeJsonRequestAsync(url); foreach (var t in obj) { - candles.Add(this.ParseCandle(t, symbol, periodSeconds, "open", "high", "low", "close", "timestamp", TimestampType.Iso8601, "volume", "turnover", "vwap")); + candles.Add(this.ParseCandle(t, marketSymbol, periodSeconds, "open", "high", "low", "close", "timestamp", TimestampType.Iso8601, "volume", "turnover", "vwap")); } candles.Reverse(); @@ -475,15 +475,15 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); Dictionary payload = await GetNoncePayloadAsync(); //string query = "/order"; string query = "/order?filter={\"open\": true}"; - if (!string.IsNullOrWhiteSpace(symbol)) + if (!string.IsNullOrWhiteSpace(marketSymbol)) { - query += "&symbol=" + NormalizeSymbol(symbol); + query += "&symbol=" + NormalizeMarketSymbol(marketSymbol); } JToken token = await MakeJsonRequestAsync(query, BaseUrl, payload, "GET"); foreach (JToken order in token) @@ -494,7 +494,7 @@ protected override async Task> OnGetOpenOrderDe return orders; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { List orders = new List(); Dictionary payload = await GetNoncePayloadAsync(); @@ -508,7 +508,7 @@ protected override async Task OnGetOrderDetailsAsync(string return orders[0]; } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { Dictionary payload = await GetNoncePayloadAsync(); payload["orderID"] = orderId; @@ -545,7 +545,7 @@ protected override async Task OnPlaceOrdersAsync(params E private void AddOrderToPayload(ExchangeOrderRequest order, Dictionary payload) { - payload["symbol"] = order.Symbol; + payload["symbol"] = order.MarketSymbol; payload["ordType"] = order.OrderType.ToStringInvariant(); payload["side"] = order.IsBuy ? "Buy" : "Sell"; payload["orderQty"] = order.Amount; @@ -601,7 +601,7 @@ private ExchangeOrderResult ParseOrder(JToken token) IsBuy = token["side"].ToStringInvariant().EqualsWithOption("Buy"), OrderDate = token["transactTime"].ConvertInvariant(), OrderId = token["orderID"].ToStringInvariant(), - Symbol = token["symbol"].ToStringInvariant() + MarketSymbol = token["symbol"].ToStringInvariant() }; // http://www.onixs.biz/fix-dictionary/5.0.SP2/tagNum_39.html diff --git a/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs b/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs index 8b9c3ded..04347d99 100644 --- a/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs @@ -60,15 +60,15 @@ public ExchangeBitfinexAPI() ["ZEC"] = "zcash", }; - SymbolSeparator = string.Empty; + MarketSymbolSeparator = string.Empty; } - public string NormalizeSymbolV1(string symbol) + public string NormalizeMarketSymbolV1(string marketSymbol) { - return (symbol ?? string.Empty).Replace("-", string.Empty).ToLowerInvariant(); + return (marketSymbol ?? string.Empty).Replace("-", string.Empty).ToLowerInvariant(); } - public async Task> GetOrderDetailsInternalV2(string url, string symbol = null) + public async Task> GetOrderDetailsInternalV2(string url, string marketSymbol = null) { Dictionary payload = await GetNoncePayloadAsync(); payload["limit"] = 250; @@ -80,7 +80,7 @@ public async Task> GetOrderDetailsInternalV2(st { foreach (JToken token in array) { - if (symbol == null || token[1].ToStringInvariant() == "t" + symbol.ToUpperInvariant()) + if (marketSymbol == null || token[1].ToStringInvariant() == "t" + marketSymbol.ToUpperInvariant()) { string lookup = token[1].ToStringInvariant().Substring(1).ToLowerInvariant(); if (!trades.TryGetValue(lookup, out List tradeList)) @@ -99,13 +99,13 @@ public override string PeriodSecondsToString(int seconds) return base.PeriodSecondsToString(seconds).Replace("d", "D"); // WTF Bitfinex, capital D??? } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { - var m = await GetSymbolsMetadataAsync(); - return m.Select(x => x.MarketName); + var m = await GetMarketSymbolsMetadataAsync(); + return m.Select(x => x.MarketSymbol); } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { var markets = new List(); JToken allPairs = await MakeJsonRequestAsync("/symbols_details", BaseUrlV1); @@ -115,7 +115,7 @@ protected override async Task> OnGetSymbolsMetadataA var market = new ExchangeMarket { IsActive = true, - MarketName = pair["pair"].ToStringInvariant(), + MarketSymbol = pair["pair"].ToStringInvariant(), MinTradeSize = pair["minimum_order_size"].ConvertInvariant(), MaxTradeSize = pair["maximum_order_size"].ConvertInvariant(), MarginEnabled = pair["margin"].ConvertInvariant(false) @@ -149,23 +149,23 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken ticker = await MakeJsonRequestAsync("/ticker/t" + symbol); - return this.ParseTicker(ticker, symbol, 2, 0, 6, 7); + JToken ticker = await MakeJsonRequestAsync("/ticker/t" + marketSymbol); + return this.ParseTicker(ticker, marketSymbol, 2, 0, 6, 7); } protected override async Task>> OnGetTickersAsync() { List> tickers = new List>(); - IReadOnlyDictionary marketsBySymbol = (await GetSymbolsMetadataAsync()).ToDictionary(market => market.MarketName, market => market); + IReadOnlyDictionary marketsBySymbol = (await GetMarketSymbolsMetadataAsync()).ToDictionary(market => market.MarketSymbol, market => market); if (marketsBySymbol != null && marketsBySymbol.Count != 0) { StringBuilder symbolString = new StringBuilder(); - foreach (var symbol in marketsBySymbol.Keys) + foreach (var marketSymbol in marketsBySymbol.Keys) { symbolString.Append('t'); - symbolString.Append(symbol.ToUpperInvariant()); + symbolString.Append(marketSymbol.ToUpperInvariant()); symbolString.Append(','); } symbolString.Length--; @@ -188,11 +188,11 @@ protected override async Task>> // LOW float Daily low //] #endregion - var symbol = array[0].ToStringInvariant().Substring(1); - var market = marketsBySymbol[symbol.ToLowerInvariant()]; - tickers.Add(new KeyValuePair(symbol, new ExchangeTicker + var marketSymbol = array[0].ToStringInvariant().Substring(1); + var market = marketsBySymbol[marketSymbol.ToLowerInvariant()]; + tickers.Add(new KeyValuePair(marketSymbol, new ExchangeTicker { - Symbol = symbol, + MarketSymbol = marketSymbol, Ask = array[3].ConvertInvariant(), Bid = array[1].ConvertInvariant(), Last = array[7].ConvertInvariant(), @@ -240,15 +240,15 @@ protected override IWebSocket OnGetTickersWebSocket(Action { - var symbols = await GetSymbolsAsync(); - foreach (var symbol in symbols) + var marketSymbols = await GetMarketSymbolsAsync(); + foreach (var marketSymbol in marketSymbols) { - await _socket.SendMessageAsync(new { @event = "subscribe", channel = "ticker", pair = symbol }); + await _socket.SendMessageAsync(new { @event = "subscribe", channel = "ticker", pair = marketSymbol }); } }); } - protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] symbols) + protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] marketSymbols) { Dictionary channelIdToSymbol = new Dictionary(); return ConnectWebSocket("/2", (_socket, msg) => //use websocket V2 (beta, but millisecond timestamp) @@ -290,9 +290,9 @@ protected override IWebSocket OnGetTradesWebSocket(Action { - foreach (var symbol in symbols) + foreach (var marketSymbol in marketSymbols) { - await _socket.SendMessageAsync(new { @event = "subscribe", channel = "trades", symbol }); + await _socket.SendMessageAsync(new { @event = "subscribe", channel = "trades", symbol = marketSymbol }); } }); } @@ -310,10 +310,10 @@ private ExchangeTrade ParseTradeWebSocket(JToken token) }; } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { ExchangeOrderBook orders = new ExchangeOrderBook(); - decimal[][] books = await MakeJsonRequestAsync("/book/t" + symbol + "/P0?len=" + maxCount); + decimal[][] books = await MakeJsonRequestAsync("/book/t" + marketSymbol + "/P0?len=" + maxCount); foreach (decimal[] book in books) { if (book[2] > 0m) @@ -328,10 +328,10 @@ protected override async Task OnGetOrderBookAsync(string symb return orders; } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { const int maxCount = 100; - string baseUrl = "/trades/t" + symbol + "/hist?sort=" + (startDate == null ? "-1" : "1") + "&limit=" + maxCount; + string baseUrl = "/trades/t" + marketSymbol + "/hist?sort=" + (startDate == null ? "-1" : "1") + "&limit=" + maxCount; string url; List trades = new List(); decimal[][] tradeChunk; @@ -369,12 +369,12 @@ protected override async Task OnGetHistoricalTradesAsync(Func> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { // https://api.bitfinex.com/v2/candles/trade:1d:btcusd/hist?start=ms_start&end=ms_end List candles = new List(); string periodString = PeriodSecondsToString(periodSeconds); - string url = "/candles/trade:" + periodString + ":t" + symbol + "/hist?sort=1"; + string url = "/candles/trade:" + periodString + ":t" + marketSymbol + "/hist?sort=1"; if (startDate != null || endDate != null) { endDate = endDate ?? CryptoUtility.UtcNow; @@ -391,7 +391,7 @@ protected override async Task> OnGetCandlesAsync(strin /* MTS, OPEN, CLOSE, HIGH, LOW, VOL */ foreach (JToken candle in token) { - candles.Add(this.ParseCandle(candle, symbol, periodSeconds, 1, 3, 4, 2, 0, TimestampType.UnixMilliseconds, 5)); + candles.Add(this.ParseCandle(candle, marketSymbol, periodSeconds, 1, 3, 4, 2, 0, TimestampType.UnixMilliseconds, 5)); } return candles; @@ -435,10 +435,10 @@ protected override async Task> OnGetAmountsAvailable protected override async Task OnPlaceOrderAsync(ExchangeOrderRequest order) { - string symbol = NormalizeSymbolV1(order.Symbol); + string marketSymbol = NormalizeMarketSymbolV1(order.MarketSymbol); Dictionary payload = await GetNoncePayloadAsync(); - payload["symbol"] = symbol; - payload["amount"] = (await ClampOrderQuantity(symbol, order.Amount)).ToStringInvariant(); + payload["symbol"] = marketSymbol; + payload["amount"] = (await ClampOrderQuantity(marketSymbol, order.Amount)).ToStringInvariant(); payload["side"] = (order.IsBuy ? "buy" : "sell"); if (order.IsMargin) @@ -452,7 +452,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd if (order.OrderType != OrderType.Market) { - payload["price"] = (await ClampOrderPrice(symbol, order.Price)).ToStringInvariant(); + payload["price"] = (await ClampOrderPrice(marketSymbol, order.Price)).ToStringInvariant(); } else { @@ -463,7 +463,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(obj); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { if (string.IsNullOrWhiteSpace(orderId)) { @@ -476,23 +476,23 @@ protected override async Task OnGetOrderDetailsAsync(string return ParseOrder(result); } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { - return await GetOrderDetailsInternalAsync("/orders", symbol); + return await GetOrderDetailsInternalAsync("/orders", marketSymbol); } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { - if (string.IsNullOrWhiteSpace(symbol)) + if (string.IsNullOrWhiteSpace(marketSymbol)) { // HACK: Bitfinex does not provide a way to get all historical order details beyond a few days in one call, so we have to // get the historical details one by one for each symbol. - var symbols = (await GetSymbolsAsync()).Where(s => s.IndexOf("usd", StringComparison.OrdinalIgnoreCase) < 0 && s.IndexOf("btc", StringComparison.OrdinalIgnoreCase) >= 0); + var symbols = (await GetMarketSymbolsAsync()).Where(s => s.IndexOf("usd", StringComparison.OrdinalIgnoreCase) < 0 && s.IndexOf("btc", StringComparison.OrdinalIgnoreCase) >= 0); return await GetOrderDetailsInternalV1(symbols, afterDate); } // retrieve orders for the one symbol - return await GetOrderDetailsInternalV1(new string[] { symbol }, afterDate); + return await GetOrderDetailsInternalV1(new string[] { marketSymbol }, afterDate); } protected override IWebSocket OnGetCompletedOrderDetailsWebSocket(Action callback) @@ -525,7 +525,7 @@ protected override IWebSocket OnGetCompletedOrderDetailsWebSocket(Action payload = await GetNoncePayloadAsync(); payload["order_id"] = orderId.ConvertInvariant(); @@ -720,16 +720,16 @@ protected override Task> OnGetCurr throw new NotSupportedException("Bitfinex does not provide data about its currencies via the API"); } - private async Task> GetOrderDetailsInternalAsync(string url, string symbol = null) + private async Task> GetOrderDetailsInternalAsync(string url, string marketSymbol = null) { List orders = new List(); - symbol = NormalizeSymbolV1(symbol); + marketSymbol = NormalizeMarketSymbolV1(marketSymbol); JToken result = await MakeJsonRequestAsync(url, BaseUrlV1, await GetNoncePayloadAsync()); if (result is JArray array) { foreach (JToken token in array) { - if (symbol == null || token["symbol"].ToStringInvariant() == symbol) + if (marketSymbol == null || token["symbol"].ToStringInvariant() == marketSymbol) { orders.Add(ParseOrder(token)); } @@ -738,12 +738,12 @@ private async Task> GetOrderDetailsInternalAsyn return orders; } - private async Task> GetOrderDetailsInternalV1(IEnumerable symbols, DateTime? afterDate) + private async Task> GetOrderDetailsInternalV1(IEnumerable marketSymbols, DateTime? afterDate) { Dictionary orders = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (string symbol in symbols) + foreach (string marketSymbol in marketSymbols) { - string normalizedSymbol = NormalizeSymbol(symbol); + string normalizedSymbol = NormalizeMarketSymbol(marketSymbol); Dictionary payload = await GetNoncePayloadAsync(); payload["symbol"] = normalizedSymbol; payload["limit_trades"] = 250; @@ -787,7 +787,7 @@ private ExchangeOrderResult ParseOrder(JToken order) OrderId = order["id"].ToStringInvariant(), Result = (amountFilled == amount ? ExchangeAPIOrderResult.Filled : (amountFilled == 0 ? ExchangeAPIOrderResult.Pending : ExchangeAPIOrderResult.FilledPartially)), OrderDate = CryptoUtility.UnixTimeStampToDateTimeSeconds(order["timestamp"].ConvertInvariant()), - Symbol = order["symbol"].ToStringInvariant(), + MarketSymbol = order["symbol"].ToStringInvariant(), IsBuy = order["side"].ToStringInvariant() == "buy" }; } @@ -822,7 +822,7 @@ private ExchangeOrderResult ParseOrderWebSocket(JToken order) OrderDate = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(order[8].ConvertInvariant()), OrderId = order[0].ToStringInvariant(), Result = ExchangeAPIOrderResult.Filled, - Symbol = order[1].ToStringInvariant() + MarketSymbol = order[1].ToStringInvariant() }; } @@ -850,7 +850,7 @@ FEE_CURRENCY string Fee currency ExchangeOrderResult order = new ExchangeOrderResult { Result = ExchangeAPIOrderResult.Filled }; foreach (JToken trade in kv.Value) { - ExchangeOrderResult append = new ExchangeOrderResult { Symbol = kv.Key, OrderId = trade[3].ToStringInvariant() }; + ExchangeOrderResult append = new ExchangeOrderResult { MarketSymbol = kv.Key, OrderId = trade[3].ToStringInvariant() }; append.Amount = append.AmountFilled = Math.Abs(trade[4].ConvertInvariant()); append.Price = trade[7].ConvertInvariant(); append.AveragePrice = trade[5].ConvertInvariant(); @@ -887,7 +887,7 @@ private ExchangeOrderResult ParseTrade(JToken trade, string symbol) OrderDate = CryptoUtility.UnixTimeStampToDateTimeSeconds(trade["timestamp"].ConvertInvariant()), OrderId = trade["order_id"].ToStringInvariant(), Result = ExchangeAPIOrderResult.Filled, - Symbol = symbol + MarketSymbol = symbol }; } diff --git a/ExchangeSharp/API/Exchanges/Bithumb/ExchangeBithumbAPI.cs b/ExchangeSharp/API/Exchanges/Bithumb/ExchangeBithumbAPI.cs index 666309d7..f1642f70 100644 --- a/ExchangeSharp/API/Exchanges/Bithumb/ExchangeBithumbAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bithumb/ExchangeBithumbAPI.cs @@ -24,28 +24,28 @@ public sealed partial class ExchangeBithumbAPI : ExchangeAPI public ExchangeBithumbAPI() { - SymbolIsUppercase = true; + MarketSymbolIsUppercase = true; } - public override string NormalizeSymbol(string symbol) + public override string NormalizeMarketSymbol(string marketSymbol) { - symbol = base.NormalizeSymbol(symbol); - int pos = symbol.IndexOf(SymbolSeparator); + marketSymbol = base.NormalizeMarketSymbol(marketSymbol); + int pos = marketSymbol.IndexOf(MarketSymbolSeparator); if (pos >= 0) { - symbol = symbol.Substring(0, pos); + marketSymbol = marketSymbol.Substring(0, pos); } - return symbol; + return marketSymbol; } - public override string ExchangeSymbolToGlobalSymbol(string symbol) + public override string ExchangeMarketSymbolToGlobalMarketSymbol(string marketSymbol) { - return "KRW" + GlobalSymbolSeparator + symbol; + return "KRW" + GlobalMarketSymbolSeparator + marketSymbol; } - public override string GlobalSymbolToExchangeSymbol(string symbol) + public override string GlobalMarketSymbolToExchangeMarketSymbol(string marketSymbol) { - return symbol.Substring(symbol.IndexOf(GlobalSymbolSeparator) + 1); + return marketSymbol.Substring(marketSymbol.IndexOf(GlobalMarketSymbolSeparator) + 1); } private string StatusToError(string status) @@ -73,36 +73,36 @@ protected override JToken CheckJsonResponse(JToken result) return result["data"]; } - private async Task> MakeRequestBithumbAsync(string symbol, string subUrl) + private async Task> MakeRequestBithumbAsync(string marketSymbol, string subUrl) { - symbol = NormalizeSymbol(symbol); - JToken obj = await MakeJsonRequestAsync(subUrl.Replace("$SYMBOL$", symbol ?? string.Empty)); - return new Tuple(obj, symbol); + marketSymbol = NormalizeMarketSymbol(marketSymbol); + JToken obj = await MakeJsonRequestAsync(subUrl.Replace("$SYMBOL$", marketSymbol ?? string.Empty)); + return new Tuple(obj, marketSymbol); } - private ExchangeTicker ParseTicker(string symbol, JToken data) + private ExchangeTicker ParseTicker(string marketSymbol, JToken data) { - return this.ParseTicker(data, symbol, "sell_price", "buy_price", "buy_price", "average_price", "units_traded", "date", TimestampType.UnixMilliseconds); + return this.ParseTicker(data, marketSymbol, "sell_price", "buy_price", "buy_price", "average_price", "units_traded", "date", TimestampType.UnixMilliseconds); } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { - List symbols = new List(); - string symbol = "all"; - var data = await MakeRequestBithumbAsync(symbol, "/public/ticker/$SYMBOL$"); + List marketSymbols = new List(); + string marketSymbol = "all"; + var data = await MakeRequestBithumbAsync(marketSymbol, "/public/ticker/$SYMBOL$"); foreach (JProperty token in data.Item1) { if (token.Name != "date") { - symbols.Add(token.Name); + marketSymbols.Add(token.Name); } } - return symbols; + return marketSymbols; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - var data = await MakeRequestBithumbAsync(symbol, "/public/ticker/$SYMBOL$"); + var data = await MakeRequestBithumbAsync(marketSymbol, "/public/ticker/$SYMBOL$"); return ParseTicker(data.Item2, data.Item1); } @@ -124,9 +124,9 @@ protected override async Task>> return tickers; } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - var data = await MakeRequestBithumbAsync(symbol, "/public/orderbook/$SYMBOL$"); + var data = await MakeRequestBithumbAsync(marketSymbol, "/public/orderbook/$SYMBOL$"); return ExchangeAPIExtensions.ParseOrderBookFromJTokenDictionaries(data.Item1, amount: "quantity", sequence: "timestamp", maxCount: maxCount); } diff --git a/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs b/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs index 1a7dd574..ff74a66b 100644 --- a/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs @@ -42,8 +42,8 @@ public ExchangeBitstampAPI() { RequestContentType = "application/x-www-form-urlencoded"; NonceStyle = NonceStyle.UnixMilliseconds; - SymbolIsUppercase = false; - SymbolSeparator = string.Empty; + MarketSymbolIsUppercase = false; + MarketSymbolSeparator = string.Empty; } /// @@ -85,7 +85,7 @@ private async Task MakeBitstampRequestAsync(string subUrl) return token; } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { List symbols = new List(); foreach (JToken token in (await MakeBitstampRequestAsync("/trading-pairs-info"))) @@ -95,23 +95,23 @@ protected override async Task> OnGetSymbolsAsync() return symbols; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { // {"high": "0.10948945", "last": "0.10121817", "timestamp": "1513387486", "bid": "0.10112165", "vwap": "0.09958913", "volume": "9954.37332614", "low": "0.09100000", "ask": "0.10198408", "open": "0.10250028"} - JToken token = await MakeBitstampRequestAsync("/ticker/" + symbol); - return this.ParseTicker(token, symbol, "ask", "bid", "last", "volume", null, "timestamp", TimestampType.UnixSeconds); + JToken token = await MakeBitstampRequestAsync("/ticker/" + marketSymbol); + return this.ParseTicker(token, marketSymbol, "ask", "bid", "last", "volume", null, "timestamp", TimestampType.UnixSeconds); } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - JToken token = await MakeBitstampRequestAsync("/order_book/" + symbol); + JToken token = await MakeBitstampRequestAsync("/order_book/" + marketSymbol); return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token, maxCount: maxCount); } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { // [{"date": "1513387997", "tid": "33734815", "price": "0.01724547", "type": "1", "amount": "5.56481714"}] - JToken token = await MakeBitstampRequestAsync("/transactions/" + symbol); + JToken token = await MakeBitstampRequestAsync("/transactions/" + marketSymbol); List trades = new List(); foreach (JToken trade in token) { @@ -169,7 +169,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd { string action = order.IsBuy ? "buy" : "sell"; string market = order.OrderType == OrderType.Market ? "/market" : ""; - string url = $"/{action}{market}/{order.Symbol}/"; + string url = $"/{action}{market}/{order.MarketSymbol}/"; Dictionary payload = await GetNoncePayloadAsync(); if (order.OrderType != OrderType.Market) @@ -192,11 +192,11 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd OrderDate = CryptoUtility.UtcNow, OrderId = responseObject["id"].ToStringInvariant(), IsBuy = order.IsBuy, - Symbol = order.Symbol + MarketSymbol = order.MarketSymbol }; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { //{ // "status": "Finished", @@ -265,13 +265,13 @@ protected override async Task OnGetOrderDetailsAsync(string return new ExchangeOrderResult() { AmountFilled = amountFilled, - Symbol = _symbol, + MarketSymbol = _symbol, AveragePrice = spentQuoteCurrency / amountFilled, Price = price, }; } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); // TODO: Bitstamp bug: bad request if url contains symbol, so temporarily using url for all symbols @@ -282,7 +282,7 @@ protected override async Task> OnGetOpenOrderDe { //This request doesn't give info about amount filled, use GetOrderDetails(orderId) string tokenSymbol = token["currency_pair"].ToStringLowerInvariant().Replace("/", ""); - if (!string.IsNullOrWhiteSpace(tokenSymbol) && !string.IsNullOrWhiteSpace(symbol) && !tokenSymbol.Equals(symbol, StringComparison.InvariantCultureIgnoreCase)) + if (!string.IsNullOrWhiteSpace(tokenSymbol) && !string.IsNullOrWhiteSpace(marketSymbol) && !tokenSymbol.Equals(marketSymbol, StringComparison.InvariantCultureIgnoreCase)) { continue; } @@ -293,13 +293,13 @@ protected override async Task> OnGetOpenOrderDe IsBuy = token["type"].ConvertInvariant() == 0, Price = token["price"].ConvertInvariant(), Amount = token["amount"].ConvertInvariant(), - Symbol = tokenSymbol ?? symbol + MarketSymbol = tokenSymbol ?? marketSymbol }); } return orders; } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { // TODO: Bitstamp bug: bad request if url contains symbol, so temporarily using url for all symbols // string url = string.IsNullOrWhiteSpace(symbol) ? "/user_transactions/" : "/user_transactions/" + symbol; @@ -315,7 +315,7 @@ protected override async Task> OnGetCompletedOr string tradingPair = ((JObject)transaction).Properties().FirstOrDefault(p => !p.Name.Equals("order_id", StringComparison.InvariantCultureIgnoreCase) && p.Name.Contains("_"))?.Name.Replace("_", "-"); - if (!string.IsNullOrWhiteSpace(tradingPair) && !string.IsNullOrWhiteSpace(symbol) && !NormalizeSymbol(tradingPair).Equals(symbol)) + if (!string.IsNullOrWhiteSpace(tradingPair) && !string.IsNullOrWhiteSpace(marketSymbol) && !NormalizeMarketSymbol(tradingPair).Equals(marketSymbol)) { continue; } @@ -330,7 +330,7 @@ protected override async Task> OnGetCompletedOr IsBuy = resultBaseCurrency > 0, Fees = transaction["fee"].ConvertInvariant(), FeesCurrency = quoteCurrency.ToStringUpperInvariant(), - Symbol = NormalizeSymbol(tradingPair), + MarketSymbol = NormalizeMarketSymbol(tradingPair), OrderDate = transaction["datetime"].ToDateTimeInvariant(), AmountFilled = Math.Abs(resultBaseCurrency), AveragePrice = transaction[$"{baseCurrency}_{quoteCurrency}"].ConvertInvariant() @@ -354,7 +354,7 @@ protected override async Task> OnGetCompletedOr return orders; } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { if (string.IsNullOrWhiteSpace(orderId)) { diff --git a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs index 7f8a63b5..a6b047b5 100644 --- a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs @@ -65,7 +65,7 @@ public ExchangeBittrexAPI() "WAVES_ASSET", }; - SymbolIsReversed = true; + MarketSymbolIsReversed = true; WebSocketOrderBookType = WebSocketOrderBookType.DeltasOnly; } @@ -124,7 +124,7 @@ private ExchangeOrderResult ParseOrder(JToken token) order.Result = ExchangeAPIOrderResult.FilledPartially; } order.OrderDate = token["Opened"].ToDateTimeInvariant(token["TimeStamp"].ToDateTimeInvariant()); - order.Symbol = token["Exchange"].ToStringInvariant(); + order.MarketSymbol = token["Exchange"].ToStringInvariant(); order.Fees = token["Commission"].ConvertInvariant(); // This is always in the base pair (e.g. BTC, ETH, USDT) string exchangePair = token["Exchange"].ToStringInvariant(); @@ -198,7 +198,7 @@ protected override async Task> OnG /// Get exchange symbols including available metadata such as min trade size and whether the market is active /// /// Collection of ExchangeMarkets - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { var markets = new List(); JToken array = await MakeJsonRequestAsync("/public/getmarkets"); @@ -214,7 +214,7 @@ protected override async Task> OnGetSymbolsMetadataA IsActive = token["IsActive"].ConvertInvariant(), BaseCurrency = token["MarketCurrency"].ToStringUpperInvariant(), //NOTE: They also reverse the order of the currencies in the MarketName - MarketName = token["MarketName"].ToStringUpperInvariant(), + MarketSymbol = token["MarketName"].ToStringUpperInvariant(), MinTradeSize = token["MinTradeSize"].ConvertInvariant(), MinPrice = StepSize, PriceStepSize = StepSize, @@ -227,36 +227,36 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { - return (await GetSymbolsMetadataAsync()).Select(x => x.MarketName); + return (await GetMarketSymbolsMetadataAsync()).Select(x => x.MarketSymbol); } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken ticker = await MakeJsonRequestAsync("/public/getmarketsummary?market=" + symbol); + JToken ticker = await MakeJsonRequestAsync("/public/getmarketsummary?market=" + marketSymbol); //NOTE: Bittrex uses the term "BaseVolume" when referring to the QuoteCurrencyVolume - return this.ParseTicker(ticker[0], symbol, "Ask", "Bid", "Last", "Volume", "BaseVolume", "Timestamp", TimestampType.Iso8601); + return this.ParseTicker(ticker[0], marketSymbol, "Ask", "Bid", "Last", "Volume", "BaseVolume", "Timestamp", TimestampType.Iso8601); } protected override async Task>> OnGetTickersAsync() { JToken tickers = await MakeJsonRequestAsync("public/getmarketsummaries"); - string symbol; + string marketSymbol; List> tickerList = new List>(); foreach (JToken ticker in tickers) { - symbol = ticker["MarketName"].ToStringInvariant(); + marketSymbol = ticker["MarketName"].ToStringInvariant(); //NOTE: Bittrex uses the term "BaseVolume" when referring to the QuoteCurrencyVolume - ExchangeTicker tickerObj = this.ParseTicker(ticker, symbol, "Ask", "Bid", "Last", "Volume", "BaseVolume", "Timestamp", TimestampType.Iso8601); - tickerList.Add(new KeyValuePair(symbol, tickerObj)); + ExchangeTicker tickerObj = this.ParseTicker(ticker, marketSymbol, "Ask", "Bid", "Last", "Volume", "BaseVolume", "Timestamp", TimestampType.Iso8601); + tickerList.Add(new KeyValuePair(marketSymbol, tickerObj)); } return tickerList; } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - JToken token = await MakeJsonRequestAsync("public/getorderbook?market=" + symbol + "&type=both&limit_bids=" + maxCount + "&limit_asks=" + maxCount); + JToken token = await MakeJsonRequestAsync("public/getorderbook?market=" + marketSymbol + "&type=both&limit_bids=" + maxCount + "&limit_asks=" + maxCount); return ExchangeAPIExtensions.ParseOrderBookFromJTokenDictionaries(token, "sell", "buy", "Rate", "Quantity", maxCount: maxCount); } @@ -289,11 +289,11 @@ protected override async Task> OnGetDepositHist return transactions; } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { // TODO: sinceDateTime is ignored // https://bittrex.com/Api/v2.0/pub/market/GetTicks?marketName=BTC-WAVES&tickInterval=oneMin&_=1499127220008 - string baseUrl = "/pub/market/GetTicks?marketName=" + symbol + "&tickInterval=oneMin"; + string baseUrl = "/pub/market/GetTicks?marketName=" + marketSymbol + "&tickInterval=oneMin"; string url; List trades = new List(); while (true) @@ -338,10 +338,10 @@ protected override async Task OnGetHistoricalTradesAsync(Func> OnGetRecentTradesAsync(string symbol) + protected override async Task> OnGetRecentTradesAsync(string marketSymbol) { List trades = new List(); - string baseUrl = "/public/getmarkethistory?market=" + symbol; + string baseUrl = "/public/getmarkethistory?market=" + marketSymbol; JToken array = await MakeJsonRequestAsync(baseUrl); foreach (JToken token in array) { @@ -350,7 +350,7 @@ protected override async Task> OnGetRecentTradesAsync return trades; } - protected override async Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { if (limit != null) { @@ -363,13 +363,13 @@ protected override async Task> OnGetCandlesAsync(strin List candles = new List(); endDate = endDate ?? CryptoUtility.UtcNow; startDate = startDate ?? endDate.Value.Subtract(TimeSpan.FromDays(1.0)); - JToken result = await MakeJsonRequestAsync("pub/market/GetTicks?marketName=" + symbol + "&tickInterval=" + periodString, BaseUrl2); + JToken result = await MakeJsonRequestAsync("pub/market/GetTicks?marketName=" + marketSymbol + "&tickInterval=" + periodString, BaseUrl2); if (result is JArray array) { foreach (JToken jsonCandle in array) { //NOTE: Bittrex uses the term "BaseVolume" when referring to the QuoteCurrencyVolume - MarketCandle candle = this.ParseCandle(jsonCandle, symbol, periodSeconds, "O", "H", "L", "C", "T", TimestampType.Iso8601, "V", "BV"); + MarketCandle candle = this.ParseCandle(jsonCandle, marketSymbol, periodSeconds, "O", "H", "L", "C", "T", TimestampType.Iso8601, "V", "BV"); if (candle.Timestamp >= startDate && candle.Timestamp <= endDate) { candles.Add(candle); @@ -419,9 +419,9 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd throw new NotSupportedException("Order type " + order.OrderType + " not supported"); } - decimal orderAmount = await ClampOrderQuantity(order.Symbol, order.Amount); - decimal orderPrice = await ClampOrderPrice(order.Symbol, order.Price); - string url = (order.IsBuy ? "/market/buylimit" : "/market/selllimit") + "?market=" + order.Symbol + "&quantity=" + + decimal orderAmount = await ClampOrderQuantity(order.MarketSymbol, order.Amount); + decimal orderPrice = await ClampOrderPrice(order.MarketSymbol, order.Price); + string url = (order.IsBuy ? "/market/buylimit" : "/market/selllimit") + "?market=" + order.MarketSymbol + "&quantity=" + orderAmount.ToStringInvariant() + "&rate=" + orderPrice.ToStringInvariant(); foreach (var kv in order.ExtraParameters) { @@ -436,12 +436,12 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd OrderDate = CryptoUtility.UtcNow, OrderId = orderId, Result = ExchangeAPIOrderResult.Pending, - Symbol = order.Symbol, + MarketSymbol = order.MarketSymbol, Price = order.Price }; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { if (string.IsNullOrWhiteSpace(orderId)) { @@ -453,10 +453,10 @@ protected override async Task OnGetOrderDetailsAsync(string return ParseOrder(result); } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); - string url = "/market/getopenorders" + (string.IsNullOrWhiteSpace(symbol) ? string.Empty : "?market=" + NormalizeSymbol(symbol)); + string url = "/market/getopenorders" + (string.IsNullOrWhiteSpace(marketSymbol) ? string.Empty : "?market=" + NormalizeMarketSymbol(marketSymbol)); JToken result = await MakeJsonRequestAsync(url, null, await GetNoncePayloadAsync()); foreach (JToken token in result.Children()) { @@ -466,10 +466,10 @@ protected override async Task> OnGetOpenOrderDe return orders; } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { List orders = new List(); - string url = "/account/getorderhistory" + (string.IsNullOrWhiteSpace(symbol) ? string.Empty : "?market=" + NormalizeSymbol(symbol)); + string url = "/account/getorderhistory" + (string.IsNullOrWhiteSpace(marketSymbol) ? string.Empty : "?market=" + NormalizeMarketSymbol(marketSymbol)); JToken result = await MakeJsonRequestAsync(url, null, await GetNoncePayloadAsync()); foreach (JToken token in result.Children()) { @@ -489,7 +489,7 @@ protected override async Task OnWithdrawAsync(Exchan { // Example: https://bittrex.com/api/v1.1/account/withdraw?apikey=API_KEY¤cy=EAC&quantity=20.40&address=EAC_ADDRESS - string url = $"/account/withdraw?currency={NormalizeSymbol(withdrawalRequest.Currency)}&quantity={withdrawalRequest.Amount.ToStringInvariant()}&address={withdrawalRequest.Address}"; + string url = $"/account/withdraw?currency={NormalizeMarketSymbol(withdrawalRequest.Currency)}&quantity={withdrawalRequest.Amount.ToStringInvariant()}&address={withdrawalRequest.Address}"; if (!string.IsNullOrWhiteSpace(withdrawalRequest.AddressTag)) { url += $"&paymentid={withdrawalRequest.AddressTag}"; @@ -505,7 +505,7 @@ protected override async Task OnWithdrawAsync(Exchan return withdrawalResponse; } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { await MakeJsonRequestAsync("/market/cancel?uuid=" + orderId, null, await GetNoncePayloadAsync()); } @@ -523,7 +523,7 @@ protected override async Task OnGetDepositAddressAsync(s { IReadOnlyDictionary updatedCurrencies = (await GetCurrenciesAsync()); - string url = "/account/getdepositaddress?currency=" + NormalizeSymbol(currency); + string url = "/account/getdepositaddress?currency=" + NormalizeMarketSymbol(currency); JToken result = await MakeJsonRequestAsync(url, null, await GetNoncePayloadAsync()); // NOTE API 1.1 does not include the the static wallet address for currencies with tags such as XRP & NXT (API 2.0 does!) diff --git a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI_WebSocket.cs b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI_WebSocket.cs index f7d47801..4f53c63a 100644 --- a/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI_WebSocket.cs +++ b/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI_WebSocket.cs @@ -63,15 +63,15 @@ public IWebSocket SubscribeToSummaryDeltas(Action callback) /// Subscribe to order book updates /// /// Callback - /// The ticker to subscribe to + /// The market symbols to subscribe to /// IDisposable to close the socket - public IWebSocket SubscribeToExchangeDeltas(Action callback, params string[] symbols) + public IWebSocket SubscribeToExchangeDeltas(Action callback, params string[] marketSymbols) { SignalrManager.SignalrSocketConnection conn = new SignalrManager.SignalrSocketConnection(this); List paramList = new List(); - foreach (string symbol in symbols) + foreach (string marketSymbol in marketSymbols) { - paramList.Add(new object[] { symbol }); + paramList.Add(new object[] { marketSymbol }); } Task.Run(async () => await conn.OpenAsync("uE", (s) => { @@ -120,7 +120,7 @@ void innerCallback(string json) foreach (JToken ticker in token) { string marketName = ticker["M"].ToStringInvariant(); - var (baseCurrency, quoteCurrency) = ExchangeSymbolToCurrencies(marketName); + var (baseCurrency, quoteCurrency) = ExchangeMarketSymbolToCurrencies(marketName); decimal last = ticker["l"].ConvertInvariant(); decimal ask = ticker["A"].ConvertInvariant(); decimal bid = ticker["B"].ConvertInvariant(); @@ -129,7 +129,7 @@ void innerCallback(string json) DateTime timestamp = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(ticker["T"].ConvertInvariant()); var t = new ExchangeTicker { - Symbol = marketName, + MarketSymbol = marketName, Ask = ask, Bid = bid, Last = last, @@ -154,12 +154,12 @@ protected override IWebSocket OnGetOrderBookWebSocket ( Action callback, int maxCount = 20, - params string[] symbols + params string[] marketSymbols ) { - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = GetSymbolsAsync().Sync().ToArray(); + marketSymbols = GetMarketSymbolsAsync().Sync().ToArray(); } void innerCallback(string json) { @@ -212,19 +212,19 @@ void innerCallback(string json) book.Bids[depth.Price] = depth; } - book.Symbol = ordersUpdates.MarketName; + book.MarketSymbol = ordersUpdates.MarketName; book.SequenceId = ordersUpdates.Nonce; callback(book); } - return this.SocketManager.SubscribeToExchangeDeltas(innerCallback, symbols); + return this.SocketManager.SubscribeToExchangeDeltas(innerCallback, marketSymbols); } - protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] symbols) + protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] marketSymbols) { - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = GetSymbolsAsync().Sync().ToArray(); + marketSymbols = GetMarketSymbolsAsync().Sync().ToArray(); } void innerCallback(string json) { @@ -245,7 +245,7 @@ void innerCallback(string json) } } - return this.SocketManager.SubscribeToExchangeDeltas(innerCallback, symbols); + return this.SocketManager.SubscribeToExchangeDeltas(innerCallback, marketSymbols); } /// diff --git a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs index ba9c5d08..f72cc1d2 100644 --- a/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs +++ b/ExchangeSharp/API/Exchanges/Bleutrade/ExchangeBleutradeAPI.cs @@ -36,7 +36,7 @@ static ExchangeBleutradeAPI() public ExchangeBleutradeAPI() { NonceStyle = NonceStyle.UnixMillisecondsString; - SymbolSeparator = "_"; + MarketSymbolSeparator = "_"; } #region ProcessRequest @@ -89,7 +89,7 @@ protected override async Task> OnG return currencies; } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { List symbols = new List(); JToken result = await MakeJsonRequestAsync("/public/getmarkets", null, null); @@ -97,7 +97,7 @@ protected override async Task> OnGetSymbolsAsync() return symbols; } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { List markets = new List(); // "result" : [{"MarketCurrency" : "DOGE","BaseCurrency" : "BTC","MarketCurrencyLong" : "Dogecoin","BaseCurrencyLong" : "Bitcoin", "MinTradeSize" : 0.10000000, "MarketName" : "DOGE_BTC", "IsActive" : true, }, ... @@ -109,7 +109,7 @@ protected override async Task> OnGetSymbolsMetadataA //NOTE: Bleutrade is another weird one that calls the QuoteCurrency the "BaseCurrency" and the BaseCurrency the "MarketCurrency". QuoteCurrency = token["BaseCurrency"].ToStringInvariant(), BaseCurrency = token["MarketCurrency"].ToStringInvariant(), - MarketName = token["MarketName"].ToStringInvariant(), + MarketSymbol = token["MarketName"].ToStringInvariant(), IsActive = token["IsActive"].ToStringInvariant().Equals("true"), MinTradeSize = token["MinTradeSize"].ConvertInvariant(), }); @@ -117,10 +117,10 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken result = await MakeJsonRequestAsync("/public/getmarketsummary?market=" + symbol); - return this.ParseTicker(result, symbol, "Ask", "Bid", "Last", "Volume", "BaseVolume", "Timestamp", TimestampType.Iso8601); + JToken result = await MakeJsonRequestAsync("/public/getmarketsummary?market=" + marketSymbol); + return this.ParseTicker(result, marketSymbol, "Ask", "Bid", "Last", "Volume", "BaseVolume", "Timestamp", TimestampType.Iso8601); } protected override async Task>> OnGetTickersAsync() @@ -136,7 +136,7 @@ protected override async Task>> return tickers; } - protected override async Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { List candles = new List(); string periodString = PeriodSecondsToString(periodSeconds); @@ -146,11 +146,11 @@ protected override async Task> OnGetCandlesAsync(strin //market period(15m, 20m, 30m, 1h, 2h, 3h, 4h, 6h, 8h, 12h, 1d) count(default: 1000, max: 999999) lasthours(default: 24, max: 2160) //"result":[{"TimeStamp":"2014-07-31 10:15:00","Open":"0.00000048","High":"0.00000050","Low":"0.00000048","Close":"0.00000049","Volume":"594804.73036048","BaseVolume":"0.11510368" }, ... - JToken result = await MakeJsonRequestAsync("/public/getcandles?market=" + symbol + "&period=" + periodString + (limit == null ? string.Empty : "&lasthours=" + limit)); + JToken result = await MakeJsonRequestAsync("/public/getcandles?market=" + marketSymbol + "&period=" + periodString + (limit == null ? string.Empty : "&lasthours=" + limit)); foreach (JToken jsonCandle in result) { //NOTE: Bleutrade uses the term "BaseVolume" when referring to the QuoteCurrencyVolume - MarketCandle candle = this.ParseCandle(jsonCandle, symbol, periodSeconds, "Open", "High", "Low", "Close", "Timestamp", TimestampType.Iso8601, "Volume", "BaseVolume"); + MarketCandle candle = this.ParseCandle(jsonCandle, marketSymbol, periodSeconds, "Open", "High", "Low", "Close", "Timestamp", TimestampType.Iso8601, "Volume", "BaseVolume"); if (candle.Timestamp >= startDate && candle.Timestamp <= endDate) { candles.Add(candle); @@ -160,20 +160,20 @@ protected override async Task> OnGetCandlesAsync(strin } - protected override async Task> OnGetRecentTradesAsync(string symbol) + protected override async Task> OnGetRecentTradesAsync(string marketSymbol) { List trades = new List(); //"result" : [{ "TimeStamp" : "2014-07-29 18:08:00","Quantity" : 654971.69417461,"Price" : 0.00000055,"Total" : 0.360234432,"OrderType" : "BUY"}, ... ] - JToken result = await MakeJsonRequestAsync("/public/getmarkethistory?market=" + symbol); + JToken result = await MakeJsonRequestAsync("/public/getmarkethistory?market=" + marketSymbol); foreach (JToken token in result) trades.Add(ParseTrade(token)); return trades; } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { List trades = new List(); // TODO: Not directly supported so the best we can do is get their Max 200 and check the timestamp if necessary - JToken result = await MakeJsonRequestAsync("/public/getmarkethistory?market=" + symbol + "&count=200"); + JToken result = await MakeJsonRequestAsync("/public/getmarkethistory?market=" + marketSymbol + "&count=200"); foreach (JToken token in result) { ExchangeTrade trade = ParseTrade(token); @@ -188,10 +188,10 @@ protected override async Task OnGetHistoricalTradesAsync(Func OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { //"result" : { "buy" : [{"Quantity" : 4.99400000,"Rate" : 3.00650900}, {"Quantity" : 50.00000000, "Rate" : 3.50000000 } ] ... - JToken token = await MakeJsonRequestAsync("/public/getorderbook?market=" + symbol + "&type=ALL&depth=" + maxCount); + JToken token = await MakeJsonRequestAsync("/public/getorderbook?market=" + marketSymbol + "&type=ALL&depth=" + maxCount); return ExchangeAPIExtensions.ParseOrderBookFromJTokenDictionaries(token, "sell", "buy", "Rate", "Quantity", maxCount: maxCount); } @@ -225,17 +225,17 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { // "result" : { "OrderId" : "65489","Exchange" : "LTC_BTC", "Type" : "BUY", "Quantity" : 20.00000000, "QuantityRemaining" : 5.00000000, "QuantityBaseTraded" : "0.16549400", "Price" : 0.01268311, "Status" : "OPEN", "Created" : "2014-08-03 13:55:20", "Comments" : "My optional comment, eg function id #123" } JToken result = await MakeJsonRequestAsync("/account/getorder?orderid=" + orderId, null, await GetNoncePayloadAsync()); return ParseOrder(result); } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { List orders = new List(); - JToken result = await MakeJsonRequestAsync("/account/getorders?market=" + (string.IsNullOrEmpty(symbol) ? "ALL" : symbol) + "&orderstatus=OK&ordertype=ALL", null, await GetNoncePayloadAsync()); + JToken result = await MakeJsonRequestAsync("/account/getorders?market=" + (string.IsNullOrEmpty(marketSymbol) ? "ALL" : marketSymbol) + "&orderstatus=OK&ordertype=ALL", null, await GetNoncePayloadAsync()); foreach (JToken token in result) { ExchangeOrderResult order = ParseOrder(token); @@ -245,7 +245,7 @@ protected override async Task> OnGetCompletedOr return orders; } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); JToken result = await MakeJsonRequestAsync("/market/getopenorders", null, await GetNoncePayloadAsync()); @@ -260,7 +260,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd order.ExtraParameters.CopyTo(payload); // Only limit order is supported - no indication on how it is filled - JToken token = await MakeJsonRequestAsync((order.IsBuy ? "/market/buylimit?" : "market/selllimit?") + "market=" + order.Symbol + + JToken token = await MakeJsonRequestAsync((order.IsBuy ? "/market/buylimit?" : "market/selllimit?") + "market=" + order.MarketSymbol + "&rate=" + order.Price.ToStringInvariant() + "&quantity=" + order.RoundAmount().ToStringInvariant(), null, payload); if (token.HasValues) { @@ -271,14 +271,14 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return result; } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { await MakeJsonRequestAsync("/market/cancel?orderid=" + orderId, null, await GetNoncePayloadAsync()); } protected override async Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) { - JToken token = await MakeJsonRequestAsync("/account/getdepositaddress?" + "currency=" + NormalizeSymbol(currency), BaseUrl, await GetNoncePayloadAsync()); + JToken token = await MakeJsonRequestAsync("/account/getdepositaddress?" + "currency=" + NormalizeMarketSymbol(currency), BaseUrl, await GetNoncePayloadAsync()); if (token["Currency"].ToStringInvariant().Equals(currency) && token["Address"] != null) { // At this time, according to Bleutrade support, they don't support any currency requiring an Address Tag, but they will add this feature in the future @@ -344,7 +344,7 @@ private ExchangeOrderResult ParseOrder(JToken token) { OrderId = token["OrderId"].ToStringInvariant(), IsBuy = token["Type"].ToStringInvariant().Equals("BUY"), - Symbol = token["Exchange"].ToStringInvariant(), + MarketSymbol = token["Exchange"].ToStringInvariant(), Amount = token["Quantity"].ConvertInvariant(), OrderDate = token["Created"].ToDateTimeInvariant(), AveragePrice = token["Price"].ConvertInvariant(), diff --git a/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs b/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs index 4f1b8205..fb804fb1 100644 --- a/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs +++ b/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs @@ -46,7 +46,7 @@ private ExchangeOrderResult ParseOrder(JToken result) decimal stop_price = result["stop_price"].ConvertInvariant(); decimal averagePrice = (amountFilled <= 0m ? 0m : executedValue / amountFilled); decimal fees = result["fill_fees"].ConvertInvariant(); - string symbol = result["id"].ToStringInvariant(result["product_id"].ToStringInvariant()); + string marketSymbol = result["id"].ToStringInvariant(result["product_id"].ToStringInvariant()); ExchangeOrderResult order = new ExchangeOrderResult { @@ -54,12 +54,12 @@ private ExchangeOrderResult ParseOrder(JToken result) AmountFilled = amountFilled, Price = price <= 0m ? stop_price : price, Fees = fees, - FeesCurrency = symbol.Substring(0, symbol.IndexOf('-')), + FeesCurrency = marketSymbol.Substring(0, marketSymbol.IndexOf('-')), AveragePrice = averagePrice, IsBuy = (result["side"].ToStringInvariant() == "buy"), OrderDate = result["created_at"].ToDateTimeInvariant(), FillDate = result["done_at"].ToDateTimeInvariant(), - Symbol = symbol, + MarketSymbol = marketSymbol, OrderId = result["id"].ToStringInvariant() }; switch (result["status"].ToStringInvariant()) @@ -165,7 +165,7 @@ public ExchangeCoinbaseAPI() WebSocketOrderBookType = WebSocketOrderBookType.FullBookFirstThenDeltas; } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { var markets = new List(); JToken products = await MakeJsonRequestAsync("/products"); @@ -173,7 +173,7 @@ protected override async Task> OnGetSymbolsMetadataA { var market = new ExchangeMarket { - MarketName = product["id"].ToStringUpperInvariant(), + MarketSymbol = product["id"].ToStringUpperInvariant(), QuoteCurrency = product["quote_currency"].ToStringUpperInvariant(), BaseCurrency = product["base_currency"].ToStringUpperInvariant(), IsActive = string.Equals(product["status"].ToStringInvariant(), "online", StringComparison.OrdinalIgnoreCase), @@ -187,9 +187,9 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { - return (await GetSymbolsMetadataAsync()).Select(market => market.MarketName); + return (await GetMarketSymbolsMetadataAsync()).Select(market => market.MarketSymbol); } protected override async Task> OnGetCurrenciesAsync() @@ -212,17 +212,17 @@ protected override async Task> OnG return currencies; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken ticker = await MakeJsonRequestAsync("/products/" + symbol + "/ticker"); - return this.ParseTicker(ticker, symbol, "ask", "bid", "price", "volume", null, "time", TimestampType.Iso8601); + JToken ticker = await MakeJsonRequestAsync("/products/" + marketSymbol + "/ticker"); + return this.ParseTicker(ticker, marketSymbol, "ask", "bid", "price", "volume", null, "time", TimestampType.Iso8601); } protected override async Task>> OnGetTickersAsync() { List> tickers = new List>(); System.Threading.ManualResetEvent evt = new System.Threading.ManualResetEvent(false); - List symbols = (await GetSymbolsAsync()).ToList(); + List symbols = (await GetMarketSymbolsAsync()).ToList(); // stupid Coinbase does not have a one shot API call for tickers outside of web sockets using (var socket = GetTickersWebSocket((t) => @@ -252,7 +252,7 @@ protected override async Task>> } } - protected override IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] symbols) + protected override IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] marketSymbols) { return ConnectWebSocket(string.Empty, (_socket, msg) => { @@ -265,7 +265,7 @@ protected override IWebSocket OnGetOrderBookWebSocket(Action { // parse delta update var delta = JsonConvert.DeserializeObject(message); - book.Symbol = delta.ProductId; + book.MarketSymbol = delta.ProductId; book.SequenceId = delta.Time.Ticks; foreach (string[] change in delta.Changes) { @@ -285,7 +285,7 @@ protected override IWebSocket OnGetOrderBookWebSocket(Action { // parse snapshot var snapshot = JsonConvert.DeserializeObject(message); - book.Symbol = snapshot.ProductId; + book.MarketSymbol = snapshot.ProductId; foreach (decimal[] ask in snapshot.Asks) { decimal price = ask[0]; @@ -311,11 +311,11 @@ protected override IWebSocket OnGetOrderBookWebSocket(Action }, async (_socket) => { // subscribe to order book channel for each symbol - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = (await GetSymbolsAsync()).ToArray(); + marketSymbols = (await GetMarketSymbolsAsync()).ToArray(); } - var chan = new Channel { Name = ChannelType.Level2, ProductIds = symbols.ToList() }; + var chan = new Channel { Name = ChannelType.Level2, ProductIds = marketSymbols.ToList() }; var channelAction = new ChannelAction { Type = ActionType.Subscribe, Channels = new List { chan } }; await _socket.SendMessageAsync(channelAction); }); @@ -334,7 +334,7 @@ protected override IWebSocket OnGetTickersWebSocket(Action { - var symbols = await GetSymbolsAsync(); + var symbols = await GetMarketSymbolsAsync(); var subscribeRequest = new { type = "subscribe", @@ -352,7 +352,7 @@ protected override IWebSocket OnGetTickersWebSocket(Action> callback, params string[] symbols) + protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] marketSymbols) { return ConnectWebSocket("/", (_socket, msg) => { @@ -360,21 +360,21 @@ protected override IWebSocket OnGetTradesWebSocket(Action(symbol, trade)); + string marketSymbol = token["product_id"].ToStringInvariant(); + callback(new KeyValuePair(marketSymbol, trade)); return Task.CompletedTask; }, async (_socket) => { var subscribeRequest = new { type = "subscribe", - product_ids = symbols, + product_ids = marketSymbols, channels = new object[] { new { name = "ticker", - product_ids = symbols + product_ids = marketSymbols } } }; @@ -387,7 +387,7 @@ private ExchangeTrade ParseTradeWebSocket(JToken token) return token.ParseTrade("last_size", "price", "side", "time", TimestampType.Iso8601, "sequence"); } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { /* [{ @@ -411,8 +411,8 @@ protected override async Task OnGetHistoricalTradesAsync(Func token.ParseTrade("size", "price", "side", "time", TimestampType.Iso8601, "trade_id"), StartDate = startDate, - Symbol = symbol, - Url = "/products/[symbol]/trades", + MarketSymbol = marketSymbol, + Url = "/products/[marketSymbol]/trades", UrlFunction = (ExchangeHistoricalTradeHelper _state) => { return _state.Url + (string.IsNullOrWhiteSpace(cursorBefore) ? string.Empty : "?before=" + cursorBefore.ToStringInvariant()); @@ -421,9 +421,9 @@ protected override async Task OnGetHistoricalTradesAsync(Func> OnGetRecentTradesAsync(string symbol) + protected override async Task> OnGetRecentTradesAsync(string marketSymbol) { - string baseUrl = "/products/" + symbol.ToUpperInvariant() + "/trades"; + string baseUrl = "/products/" + marketSymbol.ToUpperInvariant() + "/trades"; JToken trades = await MakeJsonRequestAsync(baseUrl); List tradeList = new List(); foreach (JToken trade in trades) @@ -433,14 +433,14 @@ protected override async Task> OnGetRecentTradesAsync return tradeList; } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 50) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 50) { - string url = "/products/" + symbol.ToUpperInvariant() + "/book?level=2"; + string url = "/products/" + marketSymbol.ToUpperInvariant() + "/book?level=2"; JToken token = await MakeJsonRequestAsync(url); return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token, maxCount: maxCount); } - protected override async Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { if (limit != null) { @@ -450,7 +450,7 @@ protected override async Task> OnGetCandlesAsync(strin // /products//candles // https://api.pro.coinbase.com/products/LTC-BTC/candles?granularity=86400&start=2017-12-04T18:15:33&end=2017-12-11T18:15:33 List candles = new List(); - string url = "/products/" + symbol + "/candles?granularity=" + periodSeconds; + string url = "/products/" + marketSymbol + "/candles?granularity=" + periodSeconds; if (startDate == null) { startDate = CryptoUtility.UtcNow.Subtract(TimeSpan.FromDays(1.0)); @@ -466,7 +466,7 @@ protected override async Task> OnGetCandlesAsync(strin JToken token = await MakeJsonRequestAsync(url); foreach (JToken candle in token) { - candles.Add(this.ParseCandle(candle, symbol, periodSeconds, 3, 2, 1, 4, 0, TimestampType.UnixSeconds, 5)); + candles.Add(this.ParseCandle(candle, marketSymbol, periodSeconds, 3, 2, 1, 4, 0, TimestampType.UnixSeconds, 5)); } // re-sort in ascending order candles.Sort((c1, c2) => c1.Timestamp.CompareTo(c2.Timestamp)); @@ -511,7 +511,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd { "nonce", nonce }, { "type", order.OrderType.ToStringLowerInvariant() }, { "side", (order.IsBuy ? "buy" : "sell") }, - { "product_id", order.Symbol }, + { "product_id", order.MarketSymbol }, { "size", order.RoundAmount().ToStringInvariant() } }; payload["time_in_force"] = "GTC"; // good til cancel @@ -538,16 +538,16 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(result); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { JToken obj = await MakeJsonRequestAsync("/orders/" + orderId, null, await GetNoncePayloadAsync(), "GET"); return ParseOrder(obj); } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); - JArray array = await MakeJsonRequestAsync("orders?status=all" + (string.IsNullOrWhiteSpace(symbol) ? string.Empty : "&product_id=" + symbol), null, await GetNoncePayloadAsync(), "GET"); + JArray array = await MakeJsonRequestAsync("orders?status=all" + (string.IsNullOrWhiteSpace(marketSymbol) ? string.Empty : "&product_id=" + marketSymbol), null, await GetNoncePayloadAsync(), "GET"); foreach (JToken token in array) { orders.Add(ParseOrder(token)); @@ -556,10 +556,10 @@ protected override async Task> OnGetOpenOrderDe return orders; } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { List orders = new List(); - JArray array = await MakeJsonRequestAsync("orders?status=done" + (string.IsNullOrWhiteSpace(symbol) ? string.Empty : "&product_id=" + symbol), null, await GetNoncePayloadAsync(), "GET"); + JArray array = await MakeJsonRequestAsync("orders?status=done" + (string.IsNullOrWhiteSpace(marketSymbol) ? string.Empty : "&product_id=" + marketSymbol), null, await GetNoncePayloadAsync(), "GET"); foreach (JToken token in array) { ExchangeOrderResult result = ParseOrder(token); @@ -572,7 +572,7 @@ protected override async Task> OnGetCompletedOr return orders; } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { await MakeJsonRequestAsync("orders/" + orderId, null, await GetNoncePayloadAsync(), "DELETE"); } diff --git a/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs b/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs index 6f5c3405..bc552237 100644 --- a/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs +++ b/ExchangeSharp/API/Exchanges/Cryptopia/ExchangeCryptopiaAPI.cs @@ -31,14 +31,14 @@ public ExchangeCryptopiaAPI() { RequestContentType = "application/json"; NonceStyle = NonceStyle.UnixMillisecondsString; - SymbolSeparator = "/"; + MarketSymbolSeparator = "/"; } #region ProcessRequest public string NormalizeSymbolForUrl(string symbol) { - return NormalizeSymbol(symbol).Replace(SymbolSeparator, "_"); + return NormalizeMarketSymbol(symbol).Replace(MarketSymbolSeparator, "_"); } protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dictionary payload) @@ -98,7 +98,7 @@ protected override async Task> OnG return currencies; } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { List symbols = new List(); JToken result = await MakeJsonRequestAsync("/GetTradePairs"); @@ -109,7 +109,7 @@ protected override async Task> OnGetSymbolsAsync() return symbols; } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { List markets = new List(); //[{ "Id":104, "Label":"LTC/BTC", "Currency":"Litecoin", "Symbol":"LTC", "BaseCurrency":"Bitcoin", "BaseSymbol":"BTC", "Status":"OK", "StatusMessage":"", "TradeFee":"0.20000000", "MinimumTrade":"0.00000001, "MaximumTrade":"1000000000.00000000", "MinimumBaseTrade":"0.00000500", "MaximumBaseTrade":"1000000000.00000000", "MinimumPrice":"0.00000001", "MaximumPrice":"1000000000.00000000" }, ... ] @@ -119,7 +119,7 @@ protected override async Task> OnGetSymbolsMetadataA markets.Add(new ExchangeMarket() { MarketId = token["Id"].ToStringInvariant(), - MarketName = token["Label"].ToStringInvariant(), + MarketSymbol = token["Label"].ToStringInvariant(), //NOTE: Cryptopia is calls the QuoteCurrency the "BaseSymbol" and the BaseCurrency the "Symbol".. not confusing at all! QuoteCurrency = token["BaseSymbol"].ToStringInvariant(), BaseCurrency = token["Symbol"].ToStringInvariant(), @@ -135,9 +135,9 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken result = await MakeJsonRequestAsync("/GetMarket/" + NormalizeSymbolForUrl(symbol)); + JToken result = await MakeJsonRequestAsync("/GetMarket/" + NormalizeSymbolForUrl(marketSymbol)); return ParseTicker(result); } @@ -149,27 +149,27 @@ protected override async Task>> return tickers; } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { // {"TradePairId":100,"Label":"DOT/BTC","Price":0.00000317,"Volume":333389.57231468,"Total":1.05684494} - JToken token = await MakeJsonRequestAsync("/GetMarketOrders/" + NormalizeSymbolForUrl(symbol) + "/" + maxCount.ToStringInvariant()); + JToken token = await MakeJsonRequestAsync("/GetMarketOrders/" + NormalizeSymbolForUrl(marketSymbol) + "/" + maxCount.ToStringInvariant()); return ExchangeAPIExtensions.ParseOrderBookFromJTokenDictionaries(token, "Sell", "Buy", "Price", "Volume", maxCount: maxCount); } - protected override async Task> OnGetRecentTradesAsync(string symbol) + protected override async Task> OnGetRecentTradesAsync(string marketSymbol) { List trades = new List(); // [{ "TradePairId":100,"Label":"LTC/BTC","Type":"Sell","Price":0.00006000, "Amount":499.99640000,"Total":0.02999978,"Timestamp": 1418297368}, ...] - JToken token = await MakeJsonRequestAsync("/GetMarketHistory/" + NormalizeSymbolForUrl(symbol)); // Default is last 24 hours + JToken token = await MakeJsonRequestAsync("/GetMarketHistory/" + NormalizeSymbolForUrl(marketSymbol)); // Default is last 24 hours foreach (JToken trade in token) trades.Add(ParseTrade(trade)); return trades; } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { string hours = startDate == null ? "24" : ((CryptoUtility.UtcNow - startDate.Value.ToUniversalTime()).TotalHours).ToStringInvariant(); List trades = new List(); - JToken token = await MakeJsonRequestAsync("/GetMarketHistory/" + NormalizeSymbolForUrl(symbol) + "/" + hours); + JToken token = await MakeJsonRequestAsync("/GetMarketHistory/" + NormalizeSymbolForUrl(marketSymbol) + "/" + hours); foreach (JToken trade in token) trades.Add(ParseTrade(trade)); var rc = callback?.Invoke(trades); // should we loop here to get additional more recent trades after a delay? @@ -180,13 +180,13 @@ protected override async Task OnGetHistoricalTradesAsync(Func - /// + /// /// /// /// /// /// - protected override Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { throw new NotImplementedException(); } @@ -235,14 +235,14 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { List orders = new List(); var payload = await GetNoncePayloadAsync(); - if (symbol.Length != 0) + if (marketSymbol.Length != 0) { - payload["Market"] = symbol; + payload["Market"] = marketSymbol; } else { @@ -256,7 +256,7 @@ protected override async Task> OnGetCompletedOr orders.Add(new ExchangeOrderResult() { OrderId = order["TradeId"].ConvertInvariant().ToStringInvariant(), - Symbol = order["Market"].ToStringInvariant(), + MarketSymbol = order["Market"].ToStringInvariant(), Amount = order["Amount"].ConvertInvariant(), AmountFilled = order["Amount"].ConvertInvariant(), // It doesn't look like partial fills are supplied on closed orders Price = order["Rate"].ConvertInvariant(), @@ -270,12 +270,12 @@ protected override async Task> OnGetCompletedOr return orders; } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); var payload = await GetNoncePayloadAsync(); - payload["Market"] = string.IsNullOrEmpty(symbol) ? string.Empty : NormalizeSymbol(symbol); + payload["Market"] = string.IsNullOrEmpty(marketSymbol) ? string.Empty : NormalizeMarketSymbol(marketSymbol); //[ {"OrderId": 23467,"TradePairId": 100,"Market": "DOT/BTC","Type": "Buy","Rate": 0.00000034,"Amount": 145.98000000, "Total": "0.00004963", "Remaining": "23.98760000", "TimeStamp":"2014-12-07T20:04:05.3947572" }, ... ] JToken token = await MakeJsonRequestAsync("/GetOpenOrders", null, payload, "POST"); @@ -285,7 +285,7 @@ protected override async Task> OnGetOpenOrderDe { OrderId = data["OrderId"].ConvertInvariant().ToStringInvariant(), OrderDate = data["TimeStamp"].ToDateTimeInvariant(), - Symbol = data["Market"].ToStringInvariant(), + MarketSymbol = data["Market"].ToStringInvariant(), Amount = data["Amount"].ConvertInvariant(), Price = data["Rate"].ConvertInvariant(), IsBuy = data["Type"].ToStringInvariant() == "Buy" @@ -308,9 +308,9 @@ protected override async Task> OnGetOpenOrderDe /// /// /// - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { - var orders = await GetCompletedOrderDetailsAsync(symbol); + var orders = await GetCompletedOrderDetailsAsync(marketSymbol); return orders.Where(o => o.OrderId == orderId).FirstOrDefault(); } @@ -319,7 +319,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd ExchangeOrderResult newOrder = new ExchangeOrderResult() { Result = ExchangeAPIOrderResult.Error }; var payload = await GetNoncePayloadAsync(); - payload["Market"] = order.Symbol; + payload["Market"] = order.MarketSymbol; payload["Type"] = order.IsBuy ? "Buy" : "Sell"; payload["Rate"] = order.Price; payload["Amount"] = order.Amount; @@ -336,7 +336,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd } // This should have a return value for success - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { var payload = await GetNoncePayloadAsync(); payload["Type"] = "Trade"; // Cancel All by Market is supported. Here we're canceling by single Id @@ -428,8 +428,8 @@ protected override async Task OnWithdrawAsync(Exchan private ExchangeTicker ParseTicker(JToken token) { // [{ "TradePairId":100,"Label":"LTC/BTC","AskPrice":0.00006000,"BidPrice":0.02000000,"Low":0.00006000,"High":0.00006000,"Volume":1000.05639978,"LastPrice":0.00006000,"BuyVolume":34455.678,"SellVolume":67003436.37658233,"Change":-400.00000000,"Open": 0.00000500,"Close": 0.00000600, "BaseVolume": 3.58675866,"BaseBuyVolume": 11.25364758, "BaseSellVolume": 3456.06746543 }, ... ] - string symbol = token["Label"].ToStringInvariant(); - return this.ParseTicker(token, symbol, "AskPrice", "BidPrice", "LastPrice", "Volume", "BaseVolume"); + string marketSymbol = token["Label"].ToStringInvariant(); + return this.ParseTicker(token, marketSymbol, "AskPrice", "BidPrice", "LastPrice", "Volume", "BaseVolume"); } private ExchangeTrade ParseTrade(JToken token) diff --git a/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs b/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs index 93dbfd1a..cfec1b04 100644 --- a/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs +++ b/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs @@ -28,8 +28,8 @@ public sealed partial class ExchangeGeminiAPI : ExchangeAPI public ExchangeGeminiAPI() { - SymbolIsUppercase = false; - SymbolSeparator = string.Empty; + MarketSymbolIsUppercase = false; + MarketSymbolSeparator = string.Empty; } private ExchangeVolume ParseVolume(JToken token, string symbol) @@ -38,7 +38,7 @@ private ExchangeVolume ParseVolume(JToken token, string symbol) JProperty[] props = token.Children().ToArray(); if (props.Length == 3) { - var (baseCurrency, quoteCurrency) = ExchangeSymbolToCurrencies(symbol); + var (baseCurrency, quoteCurrency) = ExchangeMarketSymbolToCurrencies(symbol); vol.QuoteCurrency = quoteCurrency.ToUpperInvariant(); vol.QuoteCurrencyVolume = token[quoteCurrency.ToUpperInvariant()].ConvertInvariant(); vol.BaseCurrency = baseCurrency.ToUpperInvariant(); @@ -63,7 +63,7 @@ private ExchangeOrderResult ParseOrder(JToken result) OrderId = result["id"].ToStringInvariant(), Result = (amountFilled == amount ? ExchangeAPIOrderResult.Filled : (amountFilled == 0 ? ExchangeAPIOrderResult.Pending : ExchangeAPIOrderResult.FilledPartially)), OrderDate = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(result["timestampms"].ConvertInvariant()), - Symbol = result["symbol"].ToStringInvariant(), + MarketSymbol = result["symbol"].ToStringInvariant(), IsBuy = result["side"].ToStringInvariant() == "buy" }; } @@ -86,36 +86,36 @@ protected override Task ProcessRequestAsync(IHttpWebRequest request, Dictionary< return base.ProcessRequestAsync(request, payload); } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { return await MakeJsonRequestAsync("/symbols"); } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken obj = await MakeJsonRequestAsync("/pubticker/" + symbol); + JToken obj = await MakeJsonRequestAsync("/pubticker/" + marketSymbol); if (obj == null || obj.Count() == 0) { return null; } ExchangeTicker t = new ExchangeTicker { - Symbol = symbol, + MarketSymbol = marketSymbol, Ask = obj["ask"].ConvertInvariant(), Bid = obj["bid"].ConvertInvariant(), Last = obj["last"].ConvertInvariant() }; - t.Volume = ParseVolume(obj["volume"], symbol); + t.Volume = ParseVolume(obj["volume"], marketSymbol); return t; } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - JToken obj = await MakeJsonRequestAsync("/book/" + symbol + "?limit_bids=" + maxCount + "&limit_asks=" + maxCount); + JToken obj = await MakeJsonRequestAsync("/book/" + marketSymbol + "?limit_bids=" + maxCount + "&limit_asks=" + maxCount); return ExchangeAPIExtensions.ParseOrderBookFromJTokenDictionaries(obj, maxCount: maxCount); } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { ExchangeHistoricalTradeHelper state = new ExchangeHistoricalTradeHelper(this) { @@ -124,9 +124,9 @@ protected override async Task OnGetHistoricalTradesAsync(Func token.ParseTrade("amount", "price", "type", "timestampms", TimestampType.UnixMilliseconds), StartDate = startDate, - Symbol = symbol, + MarketSymbol = marketSymbol, TimestampFunction = (DateTime dt) => ((long)CryptoUtility.UnixTimestampFromDateTimeMilliseconds(dt)).ToStringInvariant(), - Url = "/trades/[symbol]?limit_trades=100×tamp={0}" + Url = "/trades/[marketSymbol]?limit_trades=100×tamp={0}" }; await state.ProcessHistoricalTrades(); } @@ -175,7 +175,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd { { "nonce", nonce }, { "client_order_id", "ExchangeSharp_" + CryptoUtility.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture) }, - { "symbol", order.Symbol }, + { "symbol", order.MarketSymbol }, { "amount", order.RoundAmount().ToStringInvariant() }, { "price", order.Price.ToStringInvariant() }, { "side", (order.IsBuy ? "buy" : "sell") }, @@ -186,7 +186,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(obj); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { if (string.IsNullOrWhiteSpace(orderId)) { @@ -198,7 +198,7 @@ protected override async Task OnGetOrderDetailsAsync(string return ParseOrder(result); } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); object nonce = await GenerateNonceAsync(); @@ -207,7 +207,7 @@ protected override async Task> OnGetOpenOrderDe { foreach (JToken token in array) { - if (symbol == null || token["symbol"].ToStringInvariant() == symbol) + if (marketSymbol == null || token["symbol"].ToStringInvariant() == marketSymbol) { orders.Add(ParseOrder(token)); } @@ -217,7 +217,7 @@ protected override async Task> OnGetOpenOrderDe return orders; } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { object nonce = await GenerateNonceAsync(); await MakeJsonRequestAsync("/order/cancel", null, new Dictionary{ { "nonce", nonce }, { "order_id", orderId } }); diff --git a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs index e8a28276..ce9220fc 100644 --- a/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs +++ b/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs @@ -32,7 +32,7 @@ public ExchangeHitbtcAPI() { RequestContentType = "application/json"; NonceStyle = NonceStyle.UnixMillisecondsString; - SymbolSeparator = string.Empty; + MarketSymbolSeparator = string.Empty; } public override string PeriodSecondsToString(int seconds) @@ -98,7 +98,7 @@ protected override async Task> OnG return currencies; } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { List symbols = new List(); // [ {"id": "ETHBTC","baseCurrency": "ETH","quoteCurrency": "BTC", "quantityIncrement": "0.001", "tickSize": "0.000001", "takeLiquidityRate": "0.001", "provideLiquidityRate": "-0.0001", "feeCurrency": "BTC" } ... ] @@ -107,7 +107,7 @@ protected override async Task> OnGetSymbolsAsync() return symbols; } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { List markets = new List(); // [ {"id": "ETHBTC","baseCurrency": "ETH","quoteCurrency": "BTC", "quantityIncrement": "0.001", "tickSize": "0.000001", "takeLiquidityRate": "0.001", "provideLiquidityRate": "-0.0001", "feeCurrency": "BTC" } ... ] @@ -116,7 +116,7 @@ protected override async Task> OnGetSymbolsMetadataA { markets.Add(new ExchangeMarket() { - MarketName = token["id"].ToStringInvariant(), + MarketSymbol = token["id"].ToStringInvariant(), BaseCurrency = token["baseCurrency"].ToStringInvariant(), QuoteCurrency = token["quoteCurrency"].ToStringInvariant(), QuantityStepSize = token["quantityIncrement"].ConvertInvariant(), @@ -128,10 +128,10 @@ protected override async Task> OnGetSymbolsMetadataA } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken obj = await MakeJsonRequestAsync("/public/ticker/" + symbol); - return ParseTicker(obj, symbol); + JToken obj = await MakeJsonRequestAsync("/public/ticker/" + marketSymbol); + return ParseTicker(obj, marketSymbol); } protected override async Task>> OnGetTickersAsync() @@ -140,48 +140,48 @@ protected override async Task>> JToken obj = await MakeJsonRequestAsync("/public/ticker"); foreach (JToken token in obj) { - string symbol = NormalizeSymbol(token["symbol"].ToStringInvariant()); - tickers.Add(new KeyValuePair(symbol, ParseTicker(token, symbol))); + string marketSymbol = NormalizeMarketSymbol(token["symbol"].ToStringInvariant()); + tickers.Add(new KeyValuePair(marketSymbol, ParseTicker(token, marketSymbol))); } return tickers; } - protected override async Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { // [ {"timestamp": "2017-10-20T20:00:00.000Z","open": "0.050459","close": "0.050087","min": "0.050000","max": "0.050511","volume": "1326.628", "volumeQuote": "66.555987736"}, ... ] List candles = new List(); string periodString = PeriodSecondsToString(periodSeconds); limit = limit ?? 100; - JToken obj = await MakeJsonRequestAsync("/public/candles/" + symbol + "?period=" + periodString + "&limit=" + limit); + JToken obj = await MakeJsonRequestAsync("/public/candles/" + marketSymbol + "?period=" + periodString + "&limit=" + limit); foreach (JToken token in obj) { - candles.Add(this.ParseCandle(token, symbol, periodSeconds, "open", "max", "min", "close", "timestamp", TimestampType.Iso8601, "volume", "volumeQuote")); + candles.Add(this.ParseCandle(token, marketSymbol, periodSeconds, "open", "max", "min", "close", "timestamp", TimestampType.Iso8601, "volume", "volumeQuote")); } return candles; } - protected override async Task> OnGetRecentTradesAsync(string symbol) + protected override async Task> OnGetRecentTradesAsync(string marketSymbol) { List trades = new List(); // Putting an arbitrary limit of 10 for 'recent' - JToken obj = await MakeJsonRequestAsync("/public/trades/" + symbol + "?limit=10"); + JToken obj = await MakeJsonRequestAsync("/public/trades/" + marketSymbol + "?limit=10"); foreach (JToken token in obj) trades.Add(ParseExchangeTrade(token)); return trades; } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - JToken token = await MakeJsonRequestAsync("/public/orderbook/" + symbol + "?limit=" + maxCount.ToStringInvariant()); + JToken token = await MakeJsonRequestAsync("/public/orderbook/" + marketSymbol + "?limit=" + maxCount.ToStringInvariant()); return ExchangeAPIExtensions.ParseOrderBookFromJTokenDictionaries(token, asks: "ask", bids: "bid", amount: "size", maxCount: maxCount); } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { List trades = new List(); long? lastTradeID = null; // TODO: Can't get Hitbtc to return other than the last 50 trades even though their API says it should (by orderid or timestamp). When passing either of these parms, it still returns the last 50 // So until there is an update, that's what we'll go with - JToken obj = await MakeJsonRequestAsync("/public/trades/" + symbol); + JToken obj = await MakeJsonRequestAsync("/public/trades/" + marketSymbol); if (obj.HasValues) { foreach (JToken token in obj) @@ -238,20 +238,20 @@ protected override async Task> OnGetAmountsAvailable /// /// /// - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { JToken obj = await MakeJsonRequestAsync("/history/order/" + orderId + "/trades", null, await GetNoncePayloadAsync()); if (obj != null && obj.HasValues) return ParseCompletedOrder(obj); return null; } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { List orders = new List(); var payload = await GetNoncePayloadAsync(); - if (!string.IsNullOrEmpty(symbol)) + if (!string.IsNullOrEmpty(marketSymbol)) { - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; } if (afterDate != null) { @@ -268,13 +268,13 @@ protected override async Task> OnGetCompletedOr return orders; } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); var payload = await GetNoncePayloadAsync(); - if (!string.IsNullOrEmpty(symbol)) + if (!string.IsNullOrEmpty(marketSymbol)) { - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; } JToken obj = await MakeJsonRequestAsync("/order", null, payload); if (obj != null && obj.HasValues) @@ -292,7 +292,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd var payload = await GetNoncePayloadAsync(); //payload["clientOrderId"] = "neuMedia" + payload["nonce"]; Currently letting hitbtc assign this, but may not be unique for more than 24 hours payload["quantity"] = order.Amount; - payload["symbol"] = order.Symbol; + payload["symbol"] = order.MarketSymbol; payload["side"] = order.IsBuy ? "buy" : "sell"; payload["type"] = order.OrderType == OrderType.Limit ? "limit" : "market"; if (order.OrderType == OrderType.Limit) @@ -307,7 +307,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd ExchangeOrderResult result = new ExchangeOrderResult { OrderId = token["clientOrderId"].ToStringInvariant(), - Symbol = token["symbol"].ToStringInvariant(), + MarketSymbol = token["symbol"].ToStringInvariant(), OrderDate = token["createdAt"].ToDateTimeInvariant(), Amount = token["quantity"].ConvertInvariant(), Price = token["price"].ConvertInvariant(), @@ -331,7 +331,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return result; } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { // this call returns info about the success of the cancel. Sure would be nice have a return type on this method. JToken token = await MakeJsonRequestAsync("/order/" + orderId, null, await GetNoncePayloadAsync(), "DELETE"); @@ -495,7 +495,7 @@ private ExchangeOrderResult ParseCompletedOrder(JToken token) return new ExchangeOrderResult() { OrderId = token["orderId"].ToStringInvariant(), - Symbol = token["symbol"].ToStringInvariant(), + MarketSymbol = token["symbol"].ToStringInvariant(), IsBuy = token["side"].ToStringInvariant().Equals("buy"), Amount = token["quantity"].ConvertInvariant(), AmountFilled = token["quantity"].ConvertInvariant(), // these are closed, so I guess the filled quantity matches the order quantiity @@ -512,7 +512,7 @@ private ExchangeOrderResult ParseOpenOrder(JToken token) ExchangeOrderResult result = new ExchangeOrderResult() { OrderId = token["clientOrderId"].ToStringInvariant(), // here we're using ClientOrderId in order to get order details by open orders - Symbol = token["symbol"].ToStringInvariant(), + MarketSymbol = token["symbol"].ToStringInvariant(), IsBuy = token["side"].ToStringInvariant().Equals("buy"), Amount = token["quantity"].ConvertInvariant(), AmountFilled = token["cumQuantity"].ConvertInvariant(), diff --git a/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs b/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs index 5b363839..f7510a00 100644 --- a/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs +++ b/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs @@ -37,22 +37,22 @@ public ExchangeHuobiAPI() { RequestContentType = "application/x-www-form-urlencoded"; NonceStyle = NonceStyle.UnixMilliseconds; - SymbolSeparator = string.Empty; - SymbolIsUppercase = false; + MarketSymbolSeparator = string.Empty; + MarketSymbolIsUppercase = false; WebSocketOrderBookType = WebSocketOrderBookType.FullBookAlways; } - public override string ExchangeSymbolToGlobalSymbol(string symbol) + public override string ExchangeMarketSymbolToGlobalMarketSymbol(string marketSymbol) { - if (symbol.Length < 6) + if (marketSymbol.Length < 6) { - throw new ArgumentException("Invalid symbol " + symbol); + throw new ArgumentException("Invalid market symbol " + marketSymbol); } - else if (symbol.Length == 6) + else if (marketSymbol.Length == 6) { - return ExchangeSymbolToGlobalSymbolWithSeparator(symbol.Substring(0, 3) + GlobalSymbolSeparator + symbol.Substring(3, 3), GlobalSymbolSeparator); + return ExchangeMarketSymbolToGlobalMarketSymbolWithSeparator(marketSymbol.Substring(0, 3) + GlobalMarketSymbolSeparator + marketSymbol.Substring(3, 3), GlobalMarketSymbolSeparator); } - return ExchangeSymbolToGlobalSymbolWithSeparator(symbol.Substring(3) + GlobalSymbolSeparator + symbol.Substring(0, 3), GlobalSymbolSeparator); + return ExchangeMarketSymbolToGlobalMarketSymbolWithSeparator(marketSymbol.Substring(3) + GlobalMarketSymbolSeparator + marketSymbol.Substring(0, 3), GlobalMarketSymbolSeparator); } public override string PeriodSecondsToString(int seconds) @@ -115,13 +115,13 @@ protected override Uri ProcessRequestUrl(UriBuilder url, Dictionary> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { - var m = await GetSymbolsMetadataAsync(); - return m.Select(x => x.MarketName); + var m = await GetMarketSymbolsMetadataAsync(); + return m.Select(x => x.MarketSymbol); } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { /* { @@ -145,21 +145,21 @@ protected override async Task> OnGetSymbolsMetadataA */ List markets = new List(); - JToken allSymbols = await MakeJsonRequestAsync("/common/symbols", BaseUrlV1, null); - foreach (var symbol in allSymbols) + JToken allMarketSymbols = await MakeJsonRequestAsync("/common/symbols", BaseUrlV1, null); + foreach (var marketSymbol in allMarketSymbols) { - var baseCurrency = symbol["base-currency"].ToStringLowerInvariant(); - var quoteCurrency = symbol["quote-currency"].ToStringLowerInvariant(); - var pricePrecision = symbol["price-precision"].ConvertInvariant(); + var baseCurrency = marketSymbol["base-currency"].ToStringLowerInvariant(); + var quoteCurrency = marketSymbol["quote-currency"].ToStringLowerInvariant(); + var pricePrecision = marketSymbol["price-precision"].ConvertInvariant(); var priceStepSize = Math.Pow(10, -pricePrecision).ConvertInvariant(); - var amountPrecision = symbol["amount-precision"].ConvertInvariant(); + var amountPrecision = marketSymbol["amount-precision"].ConvertInvariant(); var quantityStepSize = Math.Pow(10, -amountPrecision).ConvertInvariant(); var market = new ExchangeMarket { BaseCurrency = baseCurrency, QuoteCurrency = quoteCurrency, - MarketName = baseCurrency + quoteCurrency, + MarketSymbol = baseCurrency + quoteCurrency, IsActive = true, PriceStepSize = priceStepSize, QuantityStepSize = quantityStepSize, @@ -173,7 +173,7 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { /* {{ @@ -201,8 +201,8 @@ protected override async Task OnGetTickerAsync(string symbol) } }} */ - JToken ticker = await MakeJsonRequestAsync("/market/detail/merged?symbol=" + symbol); - return this.ParseTicker(ticker["tick"], symbol, "ask", "bid", "close", "amount", "vol", "ts", TimestampType.UnixMillisecondsDouble, idKey: "id"); + JToken ticker = await MakeJsonRequestAsync("/market/detail/merged?symbol=" + marketSymbol); + return this.ParseTicker(ticker["tick"], marketSymbol, "ask", "bid", "close", "amount", "vol", "ts", TimestampType.UnixMillisecondsDouble, idKey: "id"); } protected override Task>> OnGetTickersAsync() @@ -210,7 +210,7 @@ protected override Task>> OnGet throw new NotImplementedException("Too many pairs and this exchange does not support a single call to get all the tickers"); } - protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] symbols) + protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] marketSymbols) { return ConnectWebSocket(string.Empty, async (_socket, msg) => { @@ -251,7 +251,7 @@ protected override IWebSocket OnGetTradesWebSocket(Action(); @@ -261,24 +261,24 @@ protected override IWebSocket OnGetTradesWebSocket(Action(symbol, trade)); + callback(new KeyValuePair(marketSymbol, trade)); } }, async (_socket) => { - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = (await GetSymbolsAsync()).ToArray(); + marketSymbols = (await GetMarketSymbolsAsync()).ToArray(); } - foreach (string symbol in symbols) + foreach (string marketSymbol in marketSymbols) { long id = System.Threading.Interlocked.Increment(ref webSocketId); - string channel = $"market.{symbol}.trade.detail"; + string channel = $"market.{marketSymbol}.trade.detail"; await _socket.SendMessageAsync(new { sub = channel, id = "id" + id.ToStringInvariant() }); } }); } - protected override IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] symbols) + protected override IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] marketSymbols) { return ConnectWebSocket(string.Empty, async (_socket, msg) => { @@ -336,27 +336,27 @@ protected override IWebSocket OnGetOrderBookWebSocket(Action } var ch = token["ch"].ToStringInvariant(); var sArray = ch.Split('.'); - var symbol = sArray[1].ToStringInvariant(); + var marketSymbol = sArray[1].ToStringInvariant(); ExchangeOrderBook book = ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token["tick"], maxCount: maxCount); - book.Symbol = symbol; + book.MarketSymbol = marketSymbol; callback(book); }, async (_socket) => { - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = (await GetSymbolsAsync()).ToArray(); + marketSymbols = (await GetMarketSymbolsAsync()).ToArray(); } - foreach (string symbol in symbols) + foreach (string symbol in marketSymbols) { long id = System.Threading.Interlocked.Increment(ref webSocketId); - var normalizedSymbol = NormalizeSymbol(symbol); + var normalizedSymbol = NormalizeMarketSymbol(symbol); string channel = $"market.{normalizedSymbol}.depth.step0"; await _socket.SendMessageAsync(new { sub = channel, id = "id" + id.ToStringInvariant() }); } }); } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { /* { @@ -397,11 +397,11 @@ protected override async Task OnGetOrderBookAsync(string symb [7995, 0.88], */ ExchangeOrderBook orders = new ExchangeOrderBook(); - JToken obj = await MakeJsonRequestAsync("/market/depth?symbol=" + symbol + "&type=step0", BaseUrl, null); + JToken obj = await MakeJsonRequestAsync("/market/depth?symbol=" + marketSymbol + "&type=step0", BaseUrl, null); return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(obj["tick"], sequence: "ts", maxCount: maxCount); } - protected override async Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { /* { @@ -422,7 +422,7 @@ protected override async Task> OnGetCandlesAsync(strin */ List candles = new List(); - string url = "/market/history/kline?symbol=" + symbol; + string url = "/market/history/kline?symbol=" + marketSymbol; if (limit != null) { // default is 150, max: 2000 @@ -433,7 +433,7 @@ protected override async Task> OnGetCandlesAsync(strin JToken allCandles = await MakeJsonRequestAsync(url, BaseUrl, null); foreach (var token in allCandles) { - candles.Add(this.ParseCandle(token, symbol, periodSeconds, "open", "high", "low", "close", "id", TimestampType.UnixSeconds, null, "vol")); + candles.Add(this.ParseCandle(token, marketSymbol, periodSeconds, "open", "high", "low", "close", "id", TimestampType.UnixSeconds, null, "vol")); } candles.Reverse(); @@ -572,7 +572,7 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { /* {{ @@ -600,13 +600,13 @@ protected override async Task OnGetOrderDetailsAsync(string return ParseOrder(data); } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { - if (symbol == null) { throw new APIException("symbol cannot be null"); } + if (marketSymbol == null) { throw new APIException("symbol cannot be null"); } List orders = new List(); var payload = await GetNoncePayloadAsync(); - payload.Add("symbol", symbol); + payload.Add("symbol", marketSymbol); payload.Add("states", "partial-canceled,filled,canceled"); if (afterDate != null) { @@ -620,13 +620,13 @@ protected override async Task> OnGetCompletedOr return orders; } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { - if (symbol == null) { throw new APIException("symbol cannot be null"); } + if (marketSymbol == null) { throw new APIException("symbol cannot be null"); } List orders = new List(); var payload = await GetNoncePayloadAsync(); - payload.Add("symbol", symbol); + payload.Add("symbol", marketSymbol); payload.Add("states", "pre-submitted,submitting,submitted,partial-filled"); JToken data = await MakeJsonRequestAsync("/order/orders", PrivateUrlV1, payload); foreach (var prop in data) @@ -638,16 +638,16 @@ protected override async Task> OnGetOpenOrderDe protected override async Task OnPlaceOrderAsync(ExchangeOrderRequest order) { - var account_id = await GetAccountID(order.IsMargin, order.Symbol); + var account_id = await GetAccountID(order.IsMargin, order.MarketSymbol); var payload = await GetNoncePayloadAsync(); payload.Add("account-id", account_id); - payload.Add("symbol", order.Symbol); + payload.Add("symbol", order.MarketSymbol); payload.Add("type", order.IsBuy ? "buy" : "sell"); payload.Add("source", order.IsMargin ? "margin-api" : "api"); - decimal outputQuantity = await ClampOrderQuantity(order.Symbol, order.Amount); - decimal outputPrice = await ClampOrderPrice(order.Symbol, order.Price); + decimal outputQuantity = await ClampOrderQuantity(order.MarketSymbol, order.Amount); + decimal outputPrice = await ClampOrderPrice(order.MarketSymbol, order.Price); payload["amount"] = outputQuantity.ToStringInvariant(); @@ -669,7 +669,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParsePlaceOrder(obj, order); } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { var payload = await GetNoncePayloadAsync(); await MakeJsonRequestAsync($"/order/orders/{orderId}/submitcancel", PrivateUrlV1, payload, "POST"); @@ -733,7 +733,7 @@ private ExchangeOrderResult ParsePlaceOrder(JToken token, ExchangeOrderRequest o Price = order.Price, IsBuy = order.IsBuy, OrderId = token.ToStringInvariant(), - Symbol = order.Symbol + MarketSymbol = order.MarketSymbol }; result.AveragePrice = result.Price; result.Result = ExchangeAPIOrderResult.Pending; @@ -766,7 +766,7 @@ private ExchangeOrderResult ParseOrder(JToken token) ExchangeOrderResult result = new ExchangeOrderResult() { OrderId = token["id"].ToStringInvariant(), - Symbol = token["symbol"].ToStringInvariant(), + MarketSymbol = token["symbol"].ToStringInvariant(), Amount = token["amount"].ConvertInvariant(), AmountFilled = token["field-amount"].ConvertInvariant(), Price = token["price"].ConvertInvariant(), diff --git a/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs b/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs index 953cd1dd..68eb4bef 100644 --- a/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs +++ b/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs @@ -43,35 +43,35 @@ public ExchangeKrakenAPI() { RequestMethod = "POST"; RequestContentType = "application/x-www-form-urlencoded"; - SymbolSeparator = string.Empty; + MarketSymbolSeparator = string.Empty; NonceStyle = NonceStyle.UnixMilliseconds; } - public override string ExchangeSymbolToGlobalSymbol(string symbol) + public override string ExchangeMarketSymbolToGlobalMarketSymbol(string marketSymbol) { - if (exchangeSymbolToNormalizedSymbol.TryGetValue(symbol, out string normalizedSymbol)) + if (exchangeSymbolToNormalizedSymbol.TryGetValue(marketSymbol, out string normalizedSymbol)) { - return base.ExchangeSymbolToGlobalSymbolWithSeparator(normalizedSymbol.Substring(0, 3) + GlobalSymbolSeparator + normalizedSymbol.Substring(3), GlobalSymbolSeparator); + return base.ExchangeMarketSymbolToGlobalMarketSymbolWithSeparator(normalizedSymbol.Substring(0, 3) + GlobalMarketSymbolSeparator + normalizedSymbol.Substring(3), GlobalMarketSymbolSeparator); } - throw new ArgumentException($"Symbol {symbol} not found in Kraken lookup table"); + throw new ArgumentException($"Symbol {marketSymbol} not found in Kraken lookup table"); } - public override string GlobalSymbolToExchangeSymbol(string symbol) + public override string GlobalMarketSymbolToExchangeMarketSymbol(string marketSymbol) { - if (normalizedSymbolToExchangeSymbol.TryGetValue(symbol.Replace(GlobalSymbolSeparator.ToString(), string.Empty), out string exchangeSymbol)) + if (normalizedSymbolToExchangeSymbol.TryGetValue(marketSymbol.Replace(GlobalMarketSymbolSeparator.ToString(), string.Empty), out string exchangeSymbol)) { return exchangeSymbol; } // not found, reverse the pair - int idx = symbol.IndexOf(GlobalSymbolSeparator); - symbol = symbol.Substring(idx + 1) + symbol.Substring(0, idx); - if (normalizedSymbolToExchangeSymbol.TryGetValue(symbol.Replace(GlobalSymbolSeparator.ToString(), string.Empty), out exchangeSymbol)) + int idx = marketSymbol.IndexOf(GlobalMarketSymbolSeparator); + marketSymbol = marketSymbol.Substring(idx + 1) + marketSymbol.Substring(0, idx); + if (normalizedSymbolToExchangeSymbol.TryGetValue(marketSymbol.Replace(GlobalMarketSymbolSeparator.ToString(), string.Empty), out exchangeSymbol)) { return exchangeSymbol; } - throw new ArgumentException($"Symbol {symbol} not found in Kraken lookup table"); + throw new ArgumentException($"Symbol {marketSymbol} not found in Kraken lookup table"); } /// @@ -165,7 +165,7 @@ private ExchangeOrderResult ParseOrder(string orderId, JToken order) } orderResult.Message = (orderResult.Message ?? order["reason"].ToStringInvariant()); orderResult.OrderDate = CryptoUtility.UnixTimeStampToDateTimeSeconds(order["opentm"].ConvertInvariant()); - orderResult.Symbol = order["descr"]["pair"].ToStringInvariant(); + orderResult.MarketSymbol = order["descr"]["pair"].ToStringInvariant(); orderResult.IsBuy = (order["descr"]["type"].ToStringInvariant() == "buy"); orderResult.Amount = order["vol"].ConvertInvariant(); orderResult.AmountFilled = order["vol_exec"].ConvertInvariant(); @@ -250,13 +250,13 @@ protected override async Task> OnG return currencies; } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { JToken result = await MakeJsonRequestAsync("/0/public/AssetPairs"); return (from prop in result.Children() where !prop.Name.Contains(".d") select prop.Name).ToArray(); } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { // { // "BCHEUR": { @@ -363,7 +363,7 @@ protected override async Task> OnGetSymbolsMetadataA var market = new ExchangeMarket { IsActive = !prop.Name.Contains(".d"), - MarketName = prop.Name, + MarketSymbol = prop.Name, MinTradeSize = quantityStepSize, MarginEnabled = pair["leverage_buy"].Children().Any() || pair["leverage_sell"].Children().Any(), BaseCurrency = pair["base"].ToStringInvariant(), @@ -381,33 +381,33 @@ protected override async Task> OnGetSymbolsMetadataA protected override async Task>> OnGetTickersAsync() { - var symbols = await GetSymbolsAsync(); - var normalizedPairsList = symbols.Select(symbol => NormalizeSymbol(symbol)).ToList(); + var marketSymbols = (await GetMarketSymbolsAsync()).ToArray(); + var normalizedPairsList = marketSymbols.Select(symbol => NormalizeMarketSymbol(symbol)).ToList(); var csvPairsList = string.Join(",", normalizedPairsList); JToken apiTickers = await MakeJsonRequestAsync("/0/public/Ticker", null, new Dictionary { { "pair", csvPairsList } }); var tickers = new List>(); - foreach (string symbol in symbols) + foreach (string marketSymbol in marketSymbols) { - JToken ticker = apiTickers[symbol]; - tickers.Add(new KeyValuePair(symbol, ConvertToExchangeTicker(symbol, ticker))); + JToken ticker = apiTickers[marketSymbol]; + tickers.Add(new KeyValuePair(marketSymbol, ConvertToExchangeTicker(marketSymbol, ticker))); } return tickers; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken apiTickers = await MakeJsonRequestAsync("/0/public/Ticker", null, new Dictionary { { "pair", NormalizeSymbol(symbol) } }); - JToken ticker = apiTickers[symbol]; - return ConvertToExchangeTicker(symbol, ticker); + JToken apiTickers = await MakeJsonRequestAsync("/0/public/Ticker", null, new Dictionary { { "pair", NormalizeMarketSymbol(marketSymbol) } }); + JToken ticker = apiTickers[marketSymbol]; + return ConvertToExchangeTicker(marketSymbol, ticker); } private ExchangeTicker ConvertToExchangeTicker(string symbol, JToken ticker) { decimal last = ticker["c"][0].ConvertInvariant(); - var (baseCurrency, quoteCurrency) = ExchangeSymbolToCurrencies(symbol); + var (baseCurrency, quoteCurrency) = ExchangeMarketSymbolToCurrencies(symbol); return new ExchangeTicker { - Symbol = symbol, + MarketSymbol = symbol, Ask = ticker["a"][0].ConvertInvariant(), Bid = ticker["b"][0].ConvertInvariant(), Last = last, @@ -422,15 +422,15 @@ private ExchangeTicker ConvertToExchangeTicker(string symbol, JToken ticker) }; } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - JToken obj = await MakeJsonRequestAsync("/0/public/Depth?pair=" + symbol + "&count=" + maxCount); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(obj[symbol], maxCount: maxCount); + JToken obj = await MakeJsonRequestAsync("/0/public/Depth?pair=" + marketSymbol + "&count=" + maxCount); + return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(obj[marketSymbol], maxCount: maxCount); } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { - string baseUrl = "/0/public/Trades?pair=" + symbol; + string baseUrl = "/0/public/Trades?pair=" + marketSymbol; string url; List trades = new List(); while (true) @@ -445,7 +445,7 @@ protected override async Task OnGetHistoricalTradesAsync(Func> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { if (limit != null) { @@ -483,14 +483,14 @@ protected override async Task> OnGetCandlesAsync(strin // array of array entries( - /// + /// /// /// /// /// /// - protected override async Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { List candles = new List(); @@ -207,7 +207,7 @@ protected override async Task> OnGetCandlesAsync(strin // this is a little tricky. The call is private, but not a POST. We need the payload for the sig, but also for the uri // so, we'll do both... This is the only ExchangeAPI public call (private on Kucoin) like this. var payload = await GetNoncePayloadAsync(); - payload.Add("symbol", symbol); + payload.Add("symbol", marketSymbol); payload.Add("resolution", periodString); payload.Add("from", (long)startDate.Value.UnixTimestampFromDateTimeSeconds()); // the nonce is milliseconds, this is seconds without decimal payload.Add("to", (long)endDate.Value.UnixTimestampFromDateTimeSeconds()); // the nonce is milliseconds, this is seconds without decimal @@ -224,7 +224,7 @@ protected override async Task> OnGetCandlesAsync(strin candles.Add(new MarketCandle { ExchangeName = this.Name, - Name = symbol, + Name = marketSymbol, PeriodSeconds = periodSeconds, Timestamp = DateTimeOffset.FromUnixTimeSeconds(token["t"][i].ConvertInvariant()).DateTime, ClosePrice = token["c"][i].ConvertInvariant(), @@ -253,18 +253,18 @@ protected override async Task> OnGetAmountsAvailable return await OnGetAmountsInternalAsync(false); } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { List orders = new List(); // "datas": [ {"createdAt": 1508219588000, "amount": 92.79323381, "dealValue": 0.00927932, "dealPrice": 0.0001, "fee": 1e-8,"feeRate": 0, "oid": "59e59ac49bd8d31d09f85fa8", "orderOid": "59e59ac39bd8d31d093d956a", "coinType": "KCS", "coinTypePair": "BTC", "direction": "BUY", "dealDirection": "BUY" }, ... ] var payload = await GetNoncePayloadAsync(); - if (string.IsNullOrWhiteSpace(symbol)) + if (string.IsNullOrWhiteSpace(marketSymbol)) { payload["limit"] = 100; } else { - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; payload["limit"] = 20; } @@ -279,15 +279,15 @@ protected override async Task> OnGetCompletedOr return orders; } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); // { "SELL": [{ "oid": "59e59b279bd8d31d093d956e", "type": "SELL", "userOid": null, "coinType": "KCS", "coinTypePair": "BTC", "direction": "SELL","price": 0.1,"dealAmount": 0,"pendingAmount": 100, "createdAt": 1508219688000, "updatedAt": 1508219688000 } ... ], // "BUY": [{ "oid": "59e42bf09bd8d374c9956caa", "type": "BUY", "userOid": null, "coinType": "KCS", "coinTypePair": "BTC", "direction": "BUY", "price": 0.00009727,"dealAmount": 31.14503, "pendingAmount": 16.94827, "createdAt": 1508125681000, "updatedAt": 1508125681000 } ... ] var payload = await GetNoncePayloadAsync(); - if (symbol != null) + if (marketSymbol != null) { - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; } JToken token = await MakeJsonRequestAsync("/order/active-map?" + CryptoUtility.GetFormForPayload(payload, false), null, payload); @@ -312,10 +312,10 @@ protected override async Task> OnGetOpenOrderDe /// /// /// - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { - var orders = await GetCompletedOrderDetailsAsync(symbol); - orders = orders.Concat(await GetOpenOrderDetailsAsync(symbol)).ToList(); + var orders = await GetCompletedOrderDetailsAsync(marketSymbol); + orders = orders.Concat(await GetOpenOrderDetailsAsync(marketSymbol)).ToList(); return orders?.Where(o => o.OrderId == orderId).FirstOrDefault(); } @@ -325,7 +325,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd var payload = await GetNoncePayloadAsync(); payload["amount"] = order.Amount; payload["price"] = order.Price; - payload["symbol"] = order.Symbol; + payload["symbol"] = order.MarketSymbol; payload["type"] = order.IsBuy ? "BUY" : "SELL"; order.ExtraParameters.CopyTo(payload); @@ -339,10 +339,10 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd /// /// The Original Order Id return from Place Order /// - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { // Find order detail - ExchangeOrderResult order = await GetOrderDetailsAsync(orderId, symbol); + ExchangeOrderResult order = await GetOrderDetailsAsync(orderId, marketSymbol); // There is no order to be cancelled if (order == null) @@ -352,7 +352,7 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = var payload = await GetNoncePayloadAsync(); payload["orderOid"] = order.OrderId; - payload["symbol"] = order.Symbol; + payload["symbol"] = order.MarketSymbol; payload["type"] = order.IsBuy ? "BUY" : "SELL"; JToken token = await MakeJsonRequestAsync("/cancel-order?" + CryptoUtility.GetFormForPayload(payload, false), null, payload, "POST"); } @@ -405,7 +405,7 @@ private ExchangeOrderResult ParseOpenOrder(JToken token) ExchangeOrderResult order = new ExchangeOrderResult() { OrderId = token["oid"].ToStringInvariant(), - Symbol = token["coinType"].ToStringInvariant() + "-" + token["coinTypePair"].ToStringInvariant(), + MarketSymbol = token["coinType"].ToStringInvariant() + "-" + token["coinTypePair"].ToStringInvariant(), IsBuy = token["direction"].ToStringInvariant().Equals("BUY"), Price = token["price"].ConvertInvariant(), AveragePrice = token["price"].ConvertInvariant(), @@ -430,7 +430,7 @@ private ExchangeOrderResult ParseCompletedOrder(JToken token) return new ExchangeOrderResult() { OrderId = token["oid"].ToStringInvariant(), - Symbol = token["coinType"].ToStringInvariant() + "-" + token["coinTypePair"].ToStringInvariant(), + MarketSymbol = token["coinType"].ToStringInvariant() + "-" + token["coinTypePair"].ToStringInvariant(), IsBuy = token["direction"].ToStringInvariant().Equals("BUY"), Amount = token["amount"].ConvertInvariant(), AmountFilled = token["amount"].ConvertInvariant(), diff --git a/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs b/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs index c7532192..574fc6ff 100644 --- a/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs +++ b/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs @@ -26,7 +26,7 @@ public sealed partial class ExchangeLivecoinAPI : ExchangeAPI public ExchangeLivecoinAPI() { RequestContentType = "application/x-www-form-urlencoded"; - SymbolSeparator = "/"; + MarketSymbolSeparator = "/"; } #region ProcessRequest @@ -70,7 +70,7 @@ protected override async Task> OnG return currencies; } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { List symbols = new List(); // {"success": true,"minBtcVolume": 0.0005,"restrictions": [{"currencyPair": "BTC/USD","priceScale": 5}, ... ]} @@ -79,7 +79,7 @@ protected override async Task> OnGetSymbolsAsync() return symbols; } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { List markets = new List(); // {"success": true,"minBtcVolume": 0.0005,"restrictions": [{"currencyPair": "BTC/USD","priceScale": 5}, ... ]} @@ -89,7 +89,7 @@ protected override async Task> OnGetSymbolsMetadataA var split = market["currencyPair"].ToStringInvariant().Split('/'); var exchangeMarket = new ExchangeMarket { - MarketName = market["currencyPair"].ToStringInvariant(), + MarketSymbol = market["currencyPair"].ToStringInvariant(), BaseCurrency = split[0], QuoteCurrency = split[1], IsActive = true, @@ -102,9 +102,9 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken token = await MakeJsonRequestAsync("/exchange/ticker?currencyPair=" + symbol.UrlEncode()); + JToken token = await MakeJsonRequestAsync("/exchange/ticker?currencyPair=" + marketSymbol.UrlEncode()); return ParseTicker(token); } @@ -116,21 +116,21 @@ protected override async Task>> return tickers; } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - JToken token = await MakeJsonRequestAsync("/exchange/order_book?currencyPair=" + symbol.UrlEncode() + "&depth=" + maxCount.ToStringInvariant()); + JToken token = await MakeJsonRequestAsync("/exchange/order_book?currencyPair=" + marketSymbol.UrlEncode() + "&depth=" + maxCount.ToStringInvariant()); return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token); } /// /// Returns trades from the last minute /// - /// + /// /// - protected override async Task> OnGetRecentTradesAsync(string symbol) + protected override async Task> OnGetRecentTradesAsync(string marketSymbol) { List trades = new List(); - JToken token = await MakeJsonRequestAsync("/exchange/last_trades?currencyPair=" + symbol.UrlEncode()); + JToken token = await MakeJsonRequestAsync("/exchange/last_trades?currencyPair=" + marketSymbol.UrlEncode()); foreach (JToken trade in token) { trades.Add(ParseTrade(trade)); @@ -142,14 +142,14 @@ protected override async Task> OnGetRecentTradesAsync /// Max returns is trades from the last hour only /// /// - /// + /// /// /// - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { List trades = new List(); // Not directly supported so we'll return what they have and filter if necessary - JToken token = await MakeJsonRequestAsync("/exchange/last_trades?currencyPair=" + symbol.UrlEncode() + "&minutesOrHour=false"); + JToken token = await MakeJsonRequestAsync("/exchange/last_trades?currencyPair=" + marketSymbol.UrlEncode() + "&minutesOrHour=false"); foreach (JToken trade in token) { ExchangeTrade rc = ParseTrade(trade); @@ -163,13 +163,13 @@ protected override async Task OnGetHistoricalTradesAsync(Func - /// + /// /// /// /// /// /// - protected override Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { throw new NotImplementedException(); } @@ -214,19 +214,19 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { JToken token = await MakeJsonRequestAsync("/exchange/order?orderId=" + orderId, null, await GetNoncePayloadAsync()); return ParseOrder(token); } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { // We can increase the number of orders returned by including a limit parameter if desired List orders = new List(); var payload = await GetNoncePayloadAsync(); payload.Add("openClosed", "CLOSED"); // returns both closed and cancelled - if (symbol != null) payload.Add("currencyPair", symbol); + if (marketSymbol != null) payload.Add("currencyPair", marketSymbol); if (afterDate != null) payload.Add("issuedFrom", ((DateTime)afterDate).UnixTimestampFromDateTimeMilliseconds()); JToken token = await MakeJsonRequestAsync("/exchange/client_orders?" + CryptoUtility.GetFormForPayload(payload, false), null, await GetNoncePayloadAsync()); @@ -240,14 +240,14 @@ protected override async Task> OnGetCompletedOr /// /// Limited to the last 100 open orders /// - /// + /// /// - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); var payload = await GetNoncePayloadAsync(); payload.Add("openClosed", "OPEM"); - if (symbol != null) payload.Add("currencyPair", symbol); + if (marketSymbol != null) payload.Add("currencyPair", marketSymbol); JToken token = await MakeJsonRequestAsync("/exchange/client_orders?" + CryptoUtility.GetFormForPayload(payload, false), null, await GetNoncePayloadAsync()); foreach (JToken order in token) @@ -270,7 +270,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd orderType += order.IsBuy ? "buylimit" : "selllimit"; payload["price"] = order.Price; } - payload["currencyPair"] = order.Symbol; + payload["currencyPair"] = order.MarketSymbol; payload["quantity"] = order.Amount; order.ExtraParameters.CopyTo(payload); @@ -279,7 +279,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return new ExchangeOrderResult() { OrderId = token["orderId"].ToStringInvariant(), Result = ExchangeAPIOrderResult.Pending }; } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { // can only cancel limit orders, which kinda makes sense, but we also need the currency pair, which requires a lookup var order = await OnGetOrderDetailsAsync(orderId); @@ -287,7 +287,7 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = { // { "success": true,"cancelled": true,"message": null,"quantity": 0.0005,"tradeQuantity": 0} await MakeJsonRequestAsync("/exchange/cancel_limit?currencyPair=" + - NormalizeSymbol(order.Symbol).UrlEncode() + "&orderId=" + orderId, null, await GetNoncePayloadAsync()); + NormalizeMarketSymbol(order.MarketSymbol).UrlEncode() + "&orderId=" + orderId, null, await GetNoncePayloadAsync()); } } @@ -345,8 +345,8 @@ protected override async Task OnWithdrawAsync(Exchan private ExchangeTicker ParseTicker(JToken token) { // [{"symbol": "LTC/BTC","last": 0.00805061,"high": 0.00813633,"low": 0.00784855,"volume": 14729.48452951,"vwap": 0.00795126,"max_bid": 0.00813633,"min_ask": 0.00784855,"best_bid": 0.00798,"best_ask": 0.00811037}, ... ] - string symbol = token["symbol"].ToStringInvariant(); - return this.ParseTicker(token, symbol, "best_ask", "best_bid", "last", "volume"); + string marketSymbol = token["symbol"].ToStringInvariant(); + return this.ParseTicker(token, marketSymbol, "best_ask", "best_bid", "last", "volume"); } private ExchangeTrade ParseTrade(JToken token) @@ -376,7 +376,7 @@ private ExchangeOrderResult ParseClientOrder(JToken token) ExchangeOrderResult order = new ExchangeOrderResult() { OrderId = token["id"].ToStringInvariant(), - Symbol = token["currencyPair"].ToStringInvariant(), + MarketSymbol = token["currencyPair"].ToStringInvariant(), OrderDate = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(token["issueTime"].ConvertInvariant()), IsBuy = token["type"].ToStringInvariant().Contains("BUY"), Price = token["price"].ConvertInvariant(), diff --git a/ExchangeSharp/API/Exchanges/Okex/ExchangeOkexAPI.cs b/ExchangeSharp/API/Exchanges/Okex/ExchangeOkexAPI.cs index f7a85a39..3f1f7fdd 100644 --- a/ExchangeSharp/API/Exchanges/Okex/ExchangeOkexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Okex/ExchangeOkexAPI.cs @@ -33,8 +33,8 @@ public sealed partial class ExchangeOkexAPI : ExchangeAPI public ExchangeOkexAPI() { RequestContentType = "application/x-www-form-urlencoded"; - SymbolSeparator = "_"; - SymbolIsUppercase = false; + MarketSymbolSeparator = "_"; + MarketSymbolIsUppercase = false; WebSocketOrderBookType = WebSocketOrderBookType.FullBookFirstThenDeltas; } @@ -90,21 +90,21 @@ protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dicti } } - private async Task> MakeRequestOkexAsync(string symbol, string subUrl, string baseUrl = null) + private async Task> MakeRequestOkexAsync(string marketSymbol, string subUrl, string baseUrl = null) { - symbol = NormalizeSymbol(symbol); - JToken obj = await MakeJsonRequestAsync(subUrl.Replace("$SYMBOL$", symbol ?? string.Empty), baseUrl); - return new Tuple(obj, symbol); + marketSymbol = NormalizeMarketSymbol(marketSymbol); + JToken obj = await MakeJsonRequestAsync(subUrl.Replace("$SYMBOL$", marketSymbol ?? string.Empty), baseUrl); + return new Tuple(obj, marketSymbol); } #endregion #region Public APIs - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { - var m = await GetSymbolsMetadataAsync(); - return m.Select(x => x.MarketName); + var m = await GetMarketSymbolsMetadataAsync(); + return m.Select(x => x.MarketSymbol); } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { /* {"code":0,"data":[{"baseCurrency":1,"collect":"0","isMarginOpen":false,"listDisplay": 0, @@ -125,31 +125,31 @@ protected override async Task> OnGetSymbolsMetadataA }, */ List markets = new List(); - JToken allSymbols = await MakeJsonRequestAsync("/markets/products", BaseUrlV2); - foreach (JToken symbol in allSymbols) + JToken allMarketSymbolTokens = await MakeJsonRequestAsync("/markets/products", BaseUrlV2); + foreach (JToken marketSymbolToken in allMarketSymbolTokens) { - var marketName = symbol["symbol"].ToStringInvariant(); + var marketName = marketSymbolToken["symbol"].ToStringInvariant(); string[] pieces = marketName.ToStringUpperInvariant().Split('_'); var market = new ExchangeMarket { - MarketName = marketName, - IsActive = symbol["online"].ConvertInvariant(), + MarketSymbol = marketName, + IsActive = marketSymbolToken["online"].ConvertInvariant(), QuoteCurrency = pieces[1], BaseCurrency = pieces[0], - MarginEnabled = symbol["isMarginOpen"].ConvertInvariant(false) + MarginEnabled = marketSymbolToken["isMarginOpen"].ConvertInvariant(false) }; - var quotePrecision = symbol["quotePrecision"].ConvertInvariant(); + var quotePrecision = marketSymbolToken["quotePrecision"].ConvertInvariant(); var quantityStepSize = Math.Pow(10, -quotePrecision); market.QuantityStepSize = quantityStepSize.ConvertInvariant(); - var maxSizeDigit = symbol["maxSizeDigit"].ConvertInvariant(); + var maxSizeDigit = marketSymbolToken["maxSizeDigit"].ConvertInvariant(); var maxTradeSize = Math.Pow(10, maxSizeDigit); market.MaxTradeSize = maxTradeSize.ConvertInvariant() - 1.0m; - market.MinTradeSize = symbol["minTradeSize"].ConvertInvariant(); + market.MinTradeSize = marketSymbolToken["minTradeSize"].ConvertInvariant(); - market.PriceStepSize = symbol["quoteIncrement"].ConvertInvariant(); + market.PriceStepSize = marketSymbolToken["quoteIncrement"].ConvertInvariant(); market.MinPrice = market.PriceStepSize.Value; - var maxPriceDigit = symbol["maxPriceDigit"].ConvertInvariant(); + var maxPriceDigit = marketSymbolToken["maxPriceDigit"].ConvertInvariant(); var maxPrice = Math.Pow(10, maxPriceDigit); market.MaxPrice = maxPrice.ConvertInvariant() - 1.0m; @@ -158,9 +158,9 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - var data = await MakeRequestOkexAsync(symbol, "/ticker.do?symbol=$SYMBOL$"); + var data = await MakeRequestOkexAsync(marketSymbol, "/ticker.do?symbol=$SYMBOL$"); return ParseTicker(data.Item2, data.Item1); } @@ -168,16 +168,16 @@ protected override async Task>> { var data = await MakeRequestOkexAsync(null, "/markets/index-tickers?limit=100000000", BaseUrlV2); List> tickers = new List>(); - string symbol; + string marketSymbol; foreach (JToken token in data.Item1) { - symbol = token["symbol"].ToStringInvariant(); - tickers.Add(new KeyValuePair(symbol, ParseTickerV2(symbol, token))); + marketSymbol = token["symbol"].ToStringInvariant(); + tickers.Add(new KeyValuePair(marketSymbol, ParseTickerV2(marketSymbol, token))); } return tickers; } - protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] symbols) + protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] marketSymbols) { /* {[ @@ -226,7 +226,7 @@ protected override IWebSocket OnGetTradesWebSocket(Action { - symbols = await AddSymbolsToChannel(_socket, "ok_sub_spot_{0}_deals", symbols); + marketSymbols = await AddMarketSymbolsToChannel(_socket, "ok_sub_spot_{0}_deals", marketSymbols); }, (_socket, symbol, sArray, token) => { IEnumerable trades = ParseTradesWebSocket(token); @@ -238,7 +238,7 @@ protected override IWebSocket OnGetTradesWebSocket(Action callback, int maxCount = 20, params string[] symbols) + protected override IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] marketSymbols) { /* {[ @@ -285,26 +285,26 @@ protected override IWebSocket OnGetOrderBookWebSocket(Action return ConnectWebSocketOkex(async (_socket) => { - symbols = await AddSymbolsToChannel(_socket, $"ok_sub_spot_{{0}}_depth_{maxCount}", symbols); + marketSymbols = await AddMarketSymbolsToChannel(_socket, $"ok_sub_spot_{{0}}_depth_{maxCount}", marketSymbols); }, (_socket, symbol, sArray, token) => { ExchangeOrderBook book = ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token, sequence: "timestamp", maxCount: maxCount); - book.Symbol = symbol; + book.MarketSymbol = symbol; callback(book); return Task.CompletedTask; }); } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - var token = await MakeRequestOkexAsync(symbol, "/depth.do?symbol=$SYMBOL$"); + var token = await MakeRequestOkexAsync(marketSymbol, "/depth.do?symbol=$SYMBOL$"); return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token.Item1, maxCount: maxCount); } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { List allTrades = new List(); - var trades = await MakeRequestOkexAsync(symbol, "/trades.do?symbol=$SYMBOL$"); + var trades = await MakeRequestOkexAsync(marketSymbol, "/trades.do?symbol=$SYMBOL$"); foreach (JToken trade in trades.Item1) { // [ { "date": "1367130137", "date_ms": "1367130137000", "price": 787.71, "amount": 0.003, "tid": "230433", "type": "sell" } ] @@ -313,7 +313,7 @@ protected override async Task OnGetHistoricalTradesAsync(Func> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { /* [ @@ -327,7 +327,7 @@ protected override async Task> OnGetCandlesAsync(strin */ List candles = new List(); - string url = "/kline.do?symbol=" + symbol; + string url = "/kline.do?symbol=" + marketSymbol; if (startDate != null) { url += "&since=" + (long)startDate.Value.UnixTimestampFromDateTimeMilliseconds(); @@ -341,7 +341,7 @@ protected override async Task> OnGetCandlesAsync(strin JToken obj = await MakeJsonRequestAsync(url); foreach (JArray token in obj) { - candles.Add(this.ParseCandle(token, symbol, periodSeconds, 1, 2, 3, 4, 0, TimestampType.UnixMilliseconds, 5)); + candles.Add(this.ParseCandle(token, marketSymbol, periodSeconds, 1, 2, 3, 4, 0, TimestampType.UnixMilliseconds, 5)); } return candles; } @@ -407,12 +407,12 @@ protected override async Task> OnGetAmountsAvailable protected override async Task OnPlaceOrderAsync(ExchangeOrderRequest order) { Dictionary payload = await GetNoncePayloadAsync(); - payload["symbol"] = order.Symbol; + payload["symbol"] = order.MarketSymbol; payload["type"] = (order.IsBuy ? "buy" : "sell"); // Okex has strict rules on which prices and quantities are allowed. They have to match the rules defined in the market definition. - decimal outputQuantity = await ClampOrderQuantity(order.Symbol, order.Amount); - decimal outputPrice = await ClampOrderPrice(order.Symbol, order.Price); + decimal outputQuantity = await ClampOrderQuantity(order.MarketSymbol, order.Amount); + decimal outputPrice = await ClampOrderPrice(order.MarketSymbol, order.Price); if (order.OrderType == OrderType.Market) { @@ -447,27 +447,27 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParsePlaceOrder(obj, order); } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { Dictionary payload = await GetNoncePayloadAsync(); - if (symbol.Length == 0) + if (marketSymbol.Length == 0) { throw new InvalidOperationException("Okex cancel order request requires symbol"); } - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; payload["order_id"] = orderId; await MakeJsonRequestAsync("/cancel_order.do", BaseUrl, payload, "POST"); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { List orders = new List(); Dictionary payload = await GetNoncePayloadAsync(); - if (symbol.Length == 0) + if (marketSymbol.Length == 0) { throw new InvalidOperationException("Okex single order details request requires symbol"); } - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; payload["order_id"] = orderId; JToken token = await MakeJsonRequestAsync("/order_info.do", BaseUrl, payload, "POST"); foreach (JToken order in token["orders"]) @@ -479,12 +479,12 @@ protected override async Task OnGetOrderDetailsAsync(string return orders[0]; } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol) { List orders = new List(); Dictionary payload = await GetNoncePayloadAsync(); - payload["symbol"] = symbol; + payload["symbol"] = marketSymbol; // if order_id is -1, then return all unfilled orders, otherwise return the order specified payload["order_id"] = -1; JToken token = await MakeJsonRequestAsync("/order_info.do", BaseUrl, payload, "POST"); @@ -542,7 +542,7 @@ private ExchangeOrderResult ParsePlaceOrder(JToken token, ExchangeOrderRequest o Price = order.Price, IsBuy = order.IsBuy, OrderId = token["order_id"].ToStringInvariant(), - Symbol = order.Symbol + MarketSymbol = order.MarketSymbol }; result.AveragePrice = result.Price; result.Result = ExchangeAPIOrderResult.Pending; @@ -600,7 +600,7 @@ private ExchangeOrderResult ParseOrder(JToken token) IsBuy = token["type"].ToStringInvariant().StartsWith("buy"), OrderDate = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(token["create_date"].ConvertInvariant()), OrderId = token["order_id"].ToStringInvariant(), - Symbol = token["symbol"].ToStringInvariant(), + MarketSymbol = token["symbol"].ToStringInvariant(), Result = ParseOrderStatus(token["status"].ConvertInvariant()), }; @@ -650,8 +650,8 @@ private IWebSocket ConnectWebSocketOkex(Func connected, Func { @@ -677,23 +677,23 @@ private IWebSocket ConnectPrivateWebSocketOkex(Func connected, }, 0); } - private async Task AddSymbolsToChannel(IWebSocket socket, string channelFormat, string[] symbols, bool useJustFirstSymbol = false) + private async Task AddMarketSymbolsToChannel(IWebSocket socket, string channelFormat, string[] marketSymbols, bool useJustFirstSymbol = false) { - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = (await GetSymbolsAsync()).ToArray(); + marketSymbols = (await GetMarketSymbolsAsync()).ToArray(); } - foreach (string symbol in symbols) + foreach (string marketSymbol in marketSymbols) { - string normalizedSymbol = NormalizeSymbol(symbol); + string normalizedSymbol = NormalizeMarketSymbol(marketSymbol); if (useJustFirstSymbol) { - normalizedSymbol = normalizedSymbol.Substring(0, normalizedSymbol.IndexOf(SymbolSeparator[0])); + normalizedSymbol = normalizedSymbol.Substring(0, normalizedSymbol.IndexOf(MarketSymbolSeparator[0])); } string channel = string.Format(channelFormat, normalizedSymbol); await socket.SendMessageAsync(new { @event = "addChannel", channel }); } - return symbols; + return marketSymbols; } #endregion diff --git a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs index 3c871bdb..23fa5b1e 100644 --- a/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs +++ b/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs @@ -54,8 +54,8 @@ static ExchangePoloniexAPI() public ExchangePoloniexAPI() { RequestContentType = "application/x-www-form-urlencoded"; - SymbolSeparator = "_"; - SymbolIsReversed = true; + MarketSymbolSeparator = "_"; + MarketSymbolIsReversed = true; WebSocketOrderBookType = WebSocketOrderBookType.DeltasOnly; } @@ -100,9 +100,9 @@ public ExchangeOrderResult ParsePlacedOrder(JToken result) /// Parses an order which has not been filled. /// /// The JToken to parse. - /// Symbol or null if it's in the result + /// Market symbol or null if it's in the result /// ExchangeOrderResult with the open order and how much is remaining to fill - public ExchangeOrderResult ParseOpenOrder(JToken result, string symbol = null) + public ExchangeOrderResult ParseOpenOrder(JToken result, string marketSymbol = null) { ExchangeOrderResult order = new ExchangeOrderResult { @@ -112,7 +112,7 @@ public ExchangeOrderResult ParseOpenOrder(JToken result, string symbol = null) OrderId = result["orderNumber"].ToStringInvariant(), Price = result["rate"].ConvertInvariant(), Result = ExchangeAPIOrderResult.Pending, - Symbol = (symbol ?? result.Parent.Path) + MarketSymbol = (marketSymbol ?? result.Parent.Path) }; decimal amount = result["amount"].ConvertInvariant(); @@ -137,13 +137,13 @@ public void ParseOrderTrades(IEnumerable trades, ExchangeOrderResult ord { parsedSymbol = trade.Parent.Path; } - if (order.Symbol == "all" || !string.IsNullOrWhiteSpace(parsedSymbol)) + if (order.MarketSymbol == "all" || !string.IsNullOrWhiteSpace(parsedSymbol)) { - order.Symbol = parsedSymbol; + order.MarketSymbol = parsedSymbol; } - if (!string.IsNullOrWhiteSpace(order.Symbol)) + if (!string.IsNullOrWhiteSpace(order.MarketSymbol)) { - order.FeesCurrency = ParseFeesCurrency(order.IsBuy, order.Symbol); + order.FeesCurrency = ParseFeesCurrency(order.IsBuy, order.MarketSymbol); } orderMetadataSet = true; } @@ -178,9 +178,9 @@ public void ParseClosePositionTrades(IEnumerable trades, ExchangeCloseMa { closePosition.IsBuy = trade["type"].ToStringLowerInvariant() != "sell"; - if (!string.IsNullOrWhiteSpace(closePosition.Symbol)) + if (!string.IsNullOrWhiteSpace(closePosition.MarketSymbol)) { - closePosition.FeesCurrency = ParseFeesCurrency(closePosition.IsBuy, closePosition.Symbol); + closePosition.FeesCurrency = ParseFeesCurrency(closePosition.IsBuy, closePosition.MarketSymbol); } closePositionMetadataSet = true; @@ -212,13 +212,13 @@ private static decimal CalculateFees(decimal tradeAmt, decimal tradeRate, bool i return Math.Round(amount, 8, MidpointRounding.AwayFromZero); } - private void ParseCompletedOrderDetails(List orders, JToken trades, string symbol) + private void ParseCompletedOrderDetails(List orders, JToken trades, string marketSymbol) { IEnumerable orderNumsInTrades = trades.Select(x => x["orderNumber"].ToStringInvariant()).Distinct(); foreach (string orderNum in orderNumsInTrades) { IEnumerable tradesForOrder = trades.Where(x => x["orderNumber"].ToStringInvariant() == orderNum); - ExchangeOrderResult order = new ExchangeOrderResult { OrderId = orderNum, Symbol = symbol }; + ExchangeOrderResult order = new ExchangeOrderResult { OrderId = orderNum, MarketSymbol = marketSymbol }; ParseOrderTrades(tradesForOrder, order); order.Price = order.AveragePrice; order.Result = ExchangeAPIOrderResult.Filled; @@ -291,7 +291,7 @@ protected override async Task> OnG return currencies; } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { List symbols = new List(); var tickers = await GetTickersAsync(); @@ -302,7 +302,7 @@ protected override async Task> OnGetSymbolsAsync() return symbols; } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { //https://poloniex.com/public?command=returnOrderBook¤cyPair=all&depth=0 /* @@ -322,7 +322,7 @@ protected override async Task> OnGetSymbolsMetadataA foreach (var kvp in lookup) { - var market = new ExchangeMarket { MarketName = kvp.Key, IsActive = false }; + var market = new ExchangeMarket { MarketSymbol = kvp.Key, IsActive = false }; string isFrozen = kvp.Value["isFrozen"].ToStringInvariant(); if (string.Equals(isFrozen, "0")) @@ -347,12 +347,12 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { IEnumerable> tickers = await GetTickersAsync(); foreach (var kv in tickers) { - if (kv.Key == symbol) + if (kv.Key == marketSymbol) { return kv.Value; } @@ -367,11 +367,11 @@ protected override async Task>> JToken obj = await MakeJsonRequestAsync("/public?command=returnTicker"); foreach (JProperty prop in obj.Children()) { - string symbol = prop.Name; + string marketSymbol = prop.Name; JToken values = prop.Value; //NOTE: Poloniex uses the term "caseVolume" when referring to the QuoteCurrencyVolume - ExchangeTicker ticker = this.ParseTicker(values, symbol, "lowestAsk", "highestBid", "last", "quoteVolume", "baseVolume", idKey: "id"); - tickers.Add(new KeyValuePair(symbol, ticker)); + ExchangeTicker ticker = this.ParseTicker(values, marketSymbol, "lowestAsk", "highestBid", "last", "quoteVolume", "baseVolume", idKey: "id"); + tickers.Add(new KeyValuePair(marketSymbol, ticker)); } return tickers; } @@ -406,7 +406,7 @@ protected override IWebSocket OnGetTickersWebSocket(Action> callback, params string[] symbols) + protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] marketSymbols) { Dictionary> messageIdToSymbol = new Dictionary>(); return ConnectWebSocket(string.Empty, (_socket, msg) => @@ -451,19 +451,19 @@ protected override IWebSocket OnGetTradesWebSocket(Action { - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = (await GetSymbolsAsync()).ToArray(); + marketSymbols = (await GetMarketSymbolsAsync()).ToArray(); } // subscribe to order book and trades channel for each symbol - foreach (var sym in symbols) + foreach (var sym in marketSymbols) { - await _socket.SendMessageAsync(new { command = "subscribe", channel = NormalizeSymbol(sym) }); + await _socket.SendMessageAsync(new { command = "subscribe", channel = NormalizeMarketSymbol(sym) }); } }); } - protected override IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] symbols) + protected override IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] marketSymbols) { Dictionary> messageIdToSymbol = new Dictionary>(); return ConnectWebSocket(string.Empty, (_socket, msg) => @@ -521,9 +521,9 @@ protected override IWebSocket OnGetOrderBookWebSocket(Action var depth = new ExchangeOrderPrice { Price = data[2].ConvertInvariant(), Amount = data[3].ConvertInvariant() }; var list = (type == 1 ? book.Bids : book.Asks); list[depth.Price] = depth; - book.Symbol = symbol.Item1; + book.MarketSymbol = symbol.Item1; book.SequenceId = symbol.Item2 + 1; - messageIdToSymbol[msgId] = new Tuple(book.Symbol, book.SequenceId); + messageIdToSymbol[msgId] = new Tuple(book.MarketSymbol, book.SequenceId); } } else @@ -538,22 +538,22 @@ protected override IWebSocket OnGetOrderBookWebSocket(Action return Task.CompletedTask; }, async (_socket) => { - if (symbols == null || symbols.Length == 0) + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = (await GetSymbolsAsync()).ToArray(); + marketSymbols = (await GetMarketSymbolsAsync()).ToArray(); } // subscribe to order book and trades channel for each symbol - foreach (var sym in symbols) + foreach (var sym in marketSymbols) { - await _socket.SendMessageAsync(new { command = "subscribe", channel = NormalizeSymbol(sym) }); + await _socket.SendMessageAsync(new { command = "subscribe", channel = NormalizeMarketSymbol(sym) }); } }); } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { // {"asks":[["0.01021997",22.83117932],["0.01022000",82.3204],["0.01022480",140],["0.01023054",241.06436945],["0.01023057",140]],"bids":[["0.01020233",164.195],["0.01020232",66.22565096],["0.01020200",5],["0.01020010",66.79296968],["0.01020000",490.19563761]],"isFrozen":"0","seq":147171861} - JToken token = await MakeJsonRequestAsync("/public?command=returnOrderBook¤cyPair=" + symbol + "&depth=" + maxCount); + JToken token = await MakeJsonRequestAsync("/public?command=returnOrderBook¤cyPair=" + marketSymbol + "&depth=" + maxCount); return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token); } @@ -579,7 +579,7 @@ protected override async Task, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { // [{"globalTradeID":245321705,"tradeID":11501281,"date":"2017-10-20 17:39:17","type":"buy","rate":"0.01022188","amount":"0.00954454","total":"0.00009756"},...] ExchangeHistoricalTradeHelper state = new ExchangeHistoricalTradeHelper(this) @@ -589,14 +589,14 @@ protected override async Task OnGetHistoricalTradesAsync(Func token.ParseTrade("amount", "rate", "type", "date", TimestampType.Iso8601, "globalTradeID"), StartDate = startDate, - Symbol = symbol, + MarketSymbol = marketSymbol, TimestampFunction = (DateTime dt) => ((long)CryptoUtility.UnixTimestampFromDateTimeSeconds(dt)).ToStringInvariant(), - Url = "/public?command=returnTradeHistory¤cyPair=[symbol]&start={0}&end={1}" + Url = "/public?command=returnTradeHistory¤cyPair=[marketSymbol]&start={0}&end={1}" }; await state.ProcessHistoricalTrades(); } - protected override async Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override async Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { if (limit != null) { @@ -605,7 +605,7 @@ protected override async Task> OnGetCandlesAsync(strin // https://poloniex.com/public?command=returnChartData¤cyPair=BTC_XMR&start=1405699200&end=9999999999&period=14400 // [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"volume":44.34555992,"quoteVolume":10311.88079097,"weightedAverage":0.00430043}] - string url = "/public?command=returnChartData¤cyPair=" + symbol; + string url = "/public?command=returnChartData¤cyPair=" + marketSymbol; if (startDate != null) { url += "&start=" + (long)startDate.Value.UnixTimestampFromDateTimeSeconds(); @@ -616,7 +616,7 @@ protected override async Task> OnGetCandlesAsync(strin List candles = new List(); foreach (JToken candle in token) { - candles.Add(this.ParseCandle(candle, symbol, periodSeconds, "open", "high", "low", "close", "date", TimestampType.UnixSeconds, "quoteVolume", "volume", "weightedAverage")); + candles.Add(this.ParseCandle(candle, marketSymbol, periodSeconds, "open", "high", "low", "close", "date", TimestampType.UnixSeconds, "quoteVolume", "volume", "weightedAverage")); } return candles; } @@ -668,11 +668,11 @@ protected override async Task> OnGetMarginAmountsAva return amounts; } - protected override async Task OnGetOpenPositionAsync(string symbol) + protected override async Task OnGetOpenPositionAsync(string marketSymbol) { List orderParams = new List { - "currencyPair", symbol + "currencyPair", marketSymbol }; JToken result = await MakePrivateAPIRequestAsync("getMarginPosition", orderParams); @@ -685,16 +685,16 @@ protected override async Task OnGetOpenPositionAsy ProfitLoss = result["pl"].ConvertInvariant(), LendingFees = result["lendingFees"].ConvertInvariant(), Type = result["type"].ToStringInvariant(), - Symbol = symbol + MarketSymbol = marketSymbol }; return marginPositionResult; } - protected override async Task OnCloseMarginPositionAsync(string symbol) + protected override async Task OnCloseMarginPositionAsync(string marketSymbol) { List orderParams = new List { - "currencyPair", symbol + "currencyPair", marketSymbol }; JToken result = await MakePrivateAPIRequestAsync("closeMarginPosition", orderParams); @@ -703,14 +703,14 @@ protected override async Task OnCloseMarginPo { Success = result["success"].ConvertInvariant(), Message = result["message"].ToStringInvariant(), - Symbol = symbol + MarketSymbol = marketSymbol }; JToken symbolTrades = result["resultingTrades"]; if (symbolTrades == null || !symbolTrades.Any()) return closePositionResult; - JToken trades = symbolTrades[symbol]; + JToken trades = symbolTrades[marketSymbol]; if (trades != null && trades.Children().Count() != 0) { ParseClosePositionTrades(trades, closePositionResult); @@ -726,12 +726,12 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd throw new NotSupportedException("Order type " + order.OrderType + " not supported"); } - decimal orderAmount = await ClampOrderQuantity(order.Symbol, order.Amount); - decimal orderPrice = await ClampOrderPrice(order.Symbol, order.Price); + decimal orderAmount = await ClampOrderQuantity(order.MarketSymbol, order.Amount); + decimal orderPrice = await ClampOrderPrice(order.MarketSymbol, order.Price); List orderParams = new List { - "currencyPair", order.Symbol, + "currencyPair", order.MarketSymbol, "rate", orderPrice.ToStringInvariant(), "amount", orderAmount.ToStringInvariant() }; @@ -743,21 +743,21 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd JToken result = await MakePrivateAPIRequestAsync(order.IsBuy ? (order.IsMargin ? "marginBuy" : "buy") : (order.IsMargin ? "marginSell" : "sell"), orderParams); ExchangeOrderResult exchangeOrderResult = ParsePlacedOrder(result); - exchangeOrderResult.Symbol = order.Symbol; - exchangeOrderResult.FeesCurrency = ParseFeesCurrency(order.IsBuy, order.Symbol); + exchangeOrderResult.MarketSymbol = order.MarketSymbol; + exchangeOrderResult.FeesCurrency = ParseFeesCurrency(order.IsBuy, order.MarketSymbol); return exchangeOrderResult; } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { - if (symbol.Length == 0) + if (marketSymbol.Length == 0) { - symbol = "all"; + marketSymbol = "all"; } List orders = new List(); - JToken result = await MakePrivateAPIRequestAsync("returnOpenOrders", new object[] { "currencyPair", symbol }); - if (symbol == "all") + JToken result = await MakePrivateAPIRequestAsync("returnOpenOrders", new object[] { "currencyPair", marketSymbol }); + if (marketSymbol == "all") { foreach (JProperty prop in result) { @@ -774,14 +774,14 @@ protected override async Task> OnGetOpenOrderDe { foreach (JToken token in array) { - orders.Add(ParseOpenOrder(token, symbol)); + orders.Add(ParseOpenOrder(token, marketSymbol)); } } return orders; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { JToken resultArray = await MakePrivateAPIRequestAsync("returnOrderTrades", new object[] { "orderNumber", orderId }); string tickerSymbol = resultArray[0]["currencyPair"].ToStringInvariant(); @@ -797,17 +797,17 @@ protected override async Task OnGetOrderDetailsAsync(string return orders[0]; } - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { - symbol = string.IsNullOrWhiteSpace(symbol) ? "all" : NormalizeSymbol(symbol); + marketSymbol = string.IsNullOrWhiteSpace(marketSymbol) ? "all" : NormalizeMarketSymbol(marketSymbol); List orders = new List(); afterDate = afterDate ?? CryptoUtility.UtcNow.Subtract(TimeSpan.FromDays(365.0)); long afterTimestamp = (long)afterDate.Value.UnixTimestampFromDateTimeSeconds(); - JToken result = await MakePrivateAPIRequestAsync("returnTradeHistory", new object[] { "currencyPair", symbol, "limit", 10000, "start", afterTimestamp }); - if (symbol != "all") + JToken result = await MakePrivateAPIRequestAsync("returnTradeHistory", new object[] { "currencyPair", marketSymbol, "limit", 10000, "start", afterTimestamp }); + if (marketSymbol != "all") { - ParseCompletedOrderDetails(orders, result as JArray, symbol); + ParseCompletedOrderDetails(orders, result as JArray, marketSymbol); } else { @@ -819,7 +819,7 @@ protected override async Task> OnGetCompletedOr return orders; } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { await MakePrivateAPIRequestAsync("cancelOrder", new object[] { "orderNumber", orderId.ConvertInvariant() }); } @@ -843,7 +843,7 @@ protected override async Task OnWithdrawAsync(Exchan } } - var paramsList = new List { "currency", NormalizeSymbol(withdrawalRequest.Currency), "amount", withdrawalRequest.Amount, "address", withdrawalRequest.Address }; + var paramsList = new List { "currency", NormalizeMarketSymbol(withdrawalRequest.Currency), "amount", withdrawalRequest.Amount, "address", withdrawalRequest.Address }; if (!string.IsNullOrWhiteSpace(withdrawalRequest.AddressTag)) { paramsList.Add("paymentId"); @@ -879,7 +879,7 @@ protected override async Task OnGetDepositAddressAsync(s } /// Gets the deposit history for a symbol - /// (ignored) The symbol to check. + /// (ignored) The currency to check. /// Collection of ExchangeCoinTransfers protected override async Task> OnGetDepositHistoryAsync(string currency) { diff --git a/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs b/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs index dd1819e2..449d75d7 100644 --- a/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs +++ b/ExchangeSharp/API/Exchanges/TuxExchange/ExchangeTuxExchangeAPI.cs @@ -33,8 +33,8 @@ public ExchangeTuxExchangeAPI() { RequestContentType = "application/x-www-form-urlencoded"; NonceStyle = NonceStyle.UnixMillisecondsString; - SymbolSeparator = "_"; - SymbolIsReversed = true; + MarketSymbolSeparator = "_"; + MarketSymbolIsReversed = true; } #region ProcessRequest @@ -86,7 +86,7 @@ protected override async Task> OnG /// Uses TuxExchange getticker method to return market names /// /// - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { // {"BTC_LTC":{"id":"2","last":"0.0068","lowestAsk":0,"highestBid":0,"percentChange":"6.249999999999989","quoteVolume":"0.5550265","isFrozen":0,"baseVolume":0,"high24hr":"0.0068","low24hr":"0.0064"}, ... JToken token = await MakeJsonRequestAsync("/api?method=getticker"); @@ -97,7 +97,7 @@ protected override async Task> OnGetSymbolsAsync() /// Uses TuxExchange getticker method to get as much Market info as provided /// /// - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { List markets = new List(); // {"BTC_LTC":{"id":"2","last":"0.0068","lowestAsk":0,"highestBid":0,"percentChange":"6.249999999999989","quoteVolume":"0.5550265","isFrozen":0,"baseVolume":0,"high24hr":"0.0068","low24hr":"0.0064"}, ... @@ -107,7 +107,7 @@ protected override async Task> OnGetSymbolsMetadataA var split = prop.Name.Split('_'); markets.Add(new ExchangeMarket() { - MarketName = prop.Name.ToStringInvariant(), + MarketSymbol = prop.Name.ToStringInvariant(), IsActive = prop.First["isFrozen"].ConvertInvariant() == 0, //NOTE: they list the quote currency first which is unusual QuoteCurrency = split[0], @@ -132,22 +132,22 @@ protected override async Task>> /// /// Uses TuxExchange getticker method and filters by symbol /// - /// + /// /// - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { var tickers = await OnGetTickersAsync(); - return tickers.Where(t => t.Key.Equals(symbol)).Select(t => t.Value).FirstOrDefault(); + return tickers.Where(t => t.Key.Equals(marketSymbol)).Select(t => t.Value).FirstOrDefault(); } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - var split = symbol.Split('_'); + var split = marketSymbol.Split('_'); JToken token = await MakeJsonRequestAsync("/api?method=getorders&coin=" + split[1] + "&market=" + split[0]); return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token); } - protected override async Task> OnGetRecentTradesAsync(string symbol) + protected override async Task> OnGetRecentTradesAsync(string marketSymbol) { List trades = new List(); @@ -157,7 +157,7 @@ protected override async Task> OnGetRecentTradesAsync long end = (long)CryptoUtility.UtcNow.UnixTimestampFromDateTimeSeconds(); // All TuxExchange Market Symbols begin with "BTC_" as a base-currency. They only support getting Trades for the Market Currency Symbol, so we split it for the call - string cur = symbol.Split(SymbolSeparator[0])[1]; + string cur = marketSymbol.Split(MarketSymbolSeparator[0])[1]; // [{"tradeid":"3375","date":"2016-08-26 18:53:38","type":"buy","rate":"0.00000041","amount":"420.00000000","total":"0.00017220"}, ... ] // https://tuxexchange.com/api?method=gettradehistory&coin=DOGE&start=1472237476&end=1472237618 @@ -171,12 +171,12 @@ protected override async Task> OnGetRecentTradesAsync else return trades; } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { List trades = new List(); long start = startDate == null ? (long)CryptoUtility.UtcNow.AddDays(-1).UnixTimestampFromDateTimeSeconds() : new DateTimeOffset((DateTime)startDate).ToUnixTimeSeconds(); long end = (long)CryptoUtility.UtcNow.UnixTimestampFromDateTimeSeconds(); - string coin = symbol.Split(SymbolSeparator[0])[1]; + string coin = marketSymbol.Split(MarketSymbolSeparator[0])[1]; string url = "/api?method=gettradehistory&coin=" + coin + "&start=" + start + "&end=" + end; JToken token = await MakeJsonRequestAsync(url); foreach (JToken trade in token) @@ -190,13 +190,13 @@ protected override async Task OnGetHistoricalTradesAsync(Func - /// + /// /// /// /// /// /// - protected override Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { throw new NotImplementedException(); } @@ -245,10 +245,10 @@ protected override async Task> OnGetAmountsAvailable /// /// TODO: Exchange API Documentation is missing the return values of this call /// - /// + /// /// /// - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { List orders = new List(); @@ -266,9 +266,9 @@ protected override async Task> OnGetCompletedOr /// /// TODO: Exchange API Documentation is missing the return values of this call /// - /// + /// /// - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { List orders = new List(); @@ -280,7 +280,7 @@ protected override async Task> OnGetOpenOrderDe throw new NotImplementedException("API Interface Incomplete"); } - protected override Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { // see OnGetCompletedOrderDetailsAsync throw new NotImplementedException("API Interface Incomplete"); @@ -289,7 +289,7 @@ protected override Task OnGetOrderDetailsAsync(string order protected override async Task OnPlaceOrderAsync(ExchangeOrderRequest order) { - var split = order.Symbol.Split('_'); + var split = order.MarketSymbol.Split('_'); var payload = await GetNoncePayloadAsync(); payload.Add("method", order.IsBuy ? "buy" : "sell"); payload.Add("market", split[0]); @@ -315,7 +315,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd } // This should have a return value for success - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { var payload = await GetNoncePayloadAsync(); payload.Add("method", "cancelorder"); diff --git a/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs b/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs index 18ec07f7..a947e8d0 100644 --- a/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs +++ b/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs @@ -42,8 +42,8 @@ public ExchangeYobitAPI() // to add insult to injury you must always increment by exactly one from the last use of your API key, even when rebooting the computer and restarting your process NonceStyle = NonceStyle.Int32File; - SymbolSeparator = "_"; - SymbolIsUppercase = false; + MarketSymbolSeparator = "_"; + MarketSymbolIsUppercase = false; } #region ProcessRequest @@ -71,7 +71,7 @@ protected override Task> OnGetCurr throw new NotSupportedException("Yobit does not provide data about its currencies via the API"); } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { List symbols = new List(); JToken token = await MakeJsonRequestAsync("/info", BaseUrl, null); @@ -79,7 +79,7 @@ protected override async Task> OnGetSymbolsAsync() return symbols; } - protected override async Task> OnGetSymbolsMetadataAsync() + protected override async Task> OnGetMarketSymbolsMetadataAsync() { List markets = new List(); // "pairs":{"ltc_btc":{"decimal_places":8,"min_price":0.00000001,"max_price":10000,"min_amount":0.0001,"hidden":0,"fee":0.2} ... } @@ -89,7 +89,7 @@ protected override async Task> OnGetSymbolsMetadataA var split = prop.Name.ToUpperInvariant().Split('_'); markets.Add(new ExchangeMarket() { - MarketName = prop.Name.ToStringInvariant(), + MarketSymbol = prop.Name.ToStringInvariant(), BaseCurrency = split[0], QuoteCurrency = split[1], IsActive = prop.First["hidden"].ConvertInvariant().Equals(0), @@ -102,9 +102,9 @@ protected override async Task> OnGetSymbolsMetadataA return markets; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - JToken token = await MakeJsonRequestAsync("/ticker/" + NormalizeSymbol(symbol), null, null, "POST"); + JToken token = await MakeJsonRequestAsync("/ticker/" + NormalizeMarketSymbol(marketSymbol), null, null, "POST"); if (token != null && token.HasValues) return ParseTicker(token.First as JProperty); return null; } @@ -121,25 +121,25 @@ protected override async Task>> return await base.OnGetTickersAsync(); } - protected override async Task OnGetOrderBookAsync(string symbol, int maxCount = 100) + protected override async Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) { - JToken token = await MakeJsonRequestAsync("/depth/" + symbol + "?limit=" + maxCount, BaseUrl, null); - return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token[symbol]); + JToken token = await MakeJsonRequestAsync("/depth/" + marketSymbol + "?limit=" + maxCount, BaseUrl, null); + return ExchangeAPIExtensions.ParseOrderBookFromJTokenArrays(token[marketSymbol]); } - protected override async Task> OnGetRecentTradesAsync(string symbol) + protected override async Task> OnGetRecentTradesAsync(string marketSymbol) { List trades = new List(); - JToken token = await MakeJsonRequestAsync("/trades/" + symbol + "?limit=10", null, null, "POST"); // default is 150, max: 2000, let's do another arbitrary 10 for consistency + JToken token = await MakeJsonRequestAsync("/trades/" + marketSymbol + "?limit=10", null, null, "POST"); // default is 150, max: 2000, let's do another arbitrary 10 for consistency foreach (JToken prop in token.First.First) trades.Add(ParseTrade(prop)); return trades; } - protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + protected override async Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { List trades = new List(); // Not directly supported, but we'll return the max and filter if necessary - JToken token = await MakeJsonRequestAsync("/trades/" + symbol + "?limit=2000", null, null, "POST"); + JToken token = await MakeJsonRequestAsync("/trades/" + marketSymbol + "?limit=2000", null, null, "POST"); token = token.First.First; // bunch of nested foreach (JToken prop in token) { @@ -154,13 +154,13 @@ protected override async Task OnGetHistoricalTradesAsync(Func - /// + /// /// /// /// /// /// - protected override Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + protected override Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { throw new NotImplementedException(); } @@ -205,7 +205,7 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) { var payload = await GetNoncePayloadAsync(); payload.Add("method", "getInfo"); @@ -218,32 +218,32 @@ protected override async Task OnGetOrderDetailsAsync(string /// /// Warning: Yobit will not return transactions over a week old via their api /// - /// + /// /// /// - protected override async Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { - if (symbol == null) { throw new APIException("symbol cannot be null"); } // Seriously, they want you to loop through over 7500 symbol pairs to find your trades! Geez... + if (marketSymbol == null) { throw new APIException("market symbol cannot be null"); } // Seriously, they want you to loop through over 7500 symbol pairs to find your trades! Geez... List orders = new List(); var payload = await GetNoncePayloadAsync(); payload.Add("method", "TradeHistory"); - payload.Add("pair", symbol); + payload.Add("pair", marketSymbol); if (afterDate != null) payload.Add("since", new DateTimeOffset((DateTime)afterDate).ToUnixTimeSeconds()); JToken token = await MakeJsonRequestAsync("/", PrivateURL, payload, "POST"); if (token != null) foreach (JProperty prop in token) orders.Add(ParseOrder(prop)); return orders; } - protected override async Task> OnGetOpenOrderDetailsAsync(string symbol = null) + protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { - if (symbol == null) { throw new APIException("symbol cannot be null"); } // Seriously, they want you to loop through over 7500 symbol pairs to find your trades! Geez... + if (marketSymbol == null) { throw new APIException("market symbol cannot be null"); } // Seriously, they want you to loop through over 7500 symbol pairs to find your trades! Geez... List orders = new List(); var payload = await GetNoncePayloadAsync(); payload.Add("method", "ActiveOrders"); - payload.Add("pair", symbol); + payload.Add("pair", marketSymbol); JToken token = await MakeJsonRequestAsync("/", PrivateURL, payload, "POST"); if (token != null) foreach (JProperty prop in token) orders.Add(ParseOrder(prop)); foreach (JProperty prop in token) orders.Add(ParseOrder(prop)); @@ -254,7 +254,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd { var payload = await GetNoncePayloadAsync(); payload.Add("method", "Trade"); - payload.Add("pair", order.Symbol); + payload.Add("pair", order.MarketSymbol); payload.Add("type", order.IsBuy ? "buy" : "sell"); payload.Add("rate", order.Price); payload.Add("amount", order.Amount); @@ -277,7 +277,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return result; } - protected override async Task OnCancelOrderAsync(string orderId, string symbol = null) + protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { var payload = await GetNoncePayloadAsync(); payload.Add("method", "CancelOrder"); @@ -334,8 +334,8 @@ protected override async Task OnWithdrawAsync(Exchan private ExchangeTicker ParseTicker(JProperty prop) { // "ltc_btc":{ "high":105.41,"low":104.67,"avg":105.04,"vol":43398.22251455,"vol_cur":4546.26962359,"last":105.11,"buy":104.2,"sell":105.11,"updated":1418654531 } - string symbol = prop.Name.ToUpperInvariant(); - return this.ParseTicker(prop.First, symbol, "sell", "buy", "last", "vol", "vol_cur", "updated", TimestampType.UnixSeconds); + string marketSymbol = prop.Name.ToUpperInvariant(); + return this.ParseTicker(prop.First, marketSymbol, "sell", "buy", "last", "vol", "vol_cur", "updated", TimestampType.UnixSeconds); } private ExchangeTrade ParseTrade(JToken prop) @@ -351,7 +351,7 @@ private ExchangeOrderResult ParseOrder(JProperty prop) ExchangeOrderResult result = new ExchangeOrderResult() { OrderId = prop.Name, - Symbol = prop["pair"].ToStringInvariant(), + MarketSymbol = prop["pair"].ToStringInvariant(), Amount = prop["start_amount"].ConvertInvariant(), AmountFilled = prop["amount"].ConvertInvariant(), Price = prop["rate"].ConvertInvariant(), diff --git a/ExchangeSharp/API/Exchanges/ZBcom/ExchangeZBcomAPI.cs b/ExchangeSharp/API/Exchanges/ZBcom/ExchangeZBcomAPI.cs index 844f4698..c5e8eb40 100644 --- a/ExchangeSharp/API/Exchanges/ZBcom/ExchangeZBcomAPI.cs +++ b/ExchangeSharp/API/Exchanges/ZBcom/ExchangeZBcomAPI.cs @@ -26,8 +26,8 @@ public sealed partial class ExchangeZBcomAPI : ExchangeAPI public ExchangeZBcomAPI() { - SymbolSeparator = "_"; - SymbolIsUppercase = false; + MarketSymbolSeparator = "_"; + MarketSymbolIsUppercase = false; } private string NormalizeSymbolWebsocket(string symbol) @@ -39,10 +39,10 @@ private string NormalizeSymbolWebsocket(string symbol) #region publicAPI - private async Task> MakeRequestZBcomAsync(string symbol, string subUrl, string baseUrl = null) + private async Task> MakeRequestZBcomAsync(string marketSymbol, string subUrl, string baseUrl = null) { - JToken obj = await MakeJsonRequestAsync(subUrl.Replace("$SYMBOL$", symbol ?? string.Empty), baseUrl); - return new Tuple(obj, symbol); + JToken obj = await MakeJsonRequestAsync(subUrl.Replace("$SYMBOL$", marketSymbol ?? string.Empty), baseUrl); + return new Tuple(obj, marketSymbol); } private ExchangeTicker ParseTicker(string symbol, JToken data) @@ -57,7 +57,7 @@ private ExchangeTicker ParseTickerV2(string symbol, JToken data) return this.ParseTicker(data.First, symbol, "sell", "buy", "last", "vol"); } - protected override async Task> OnGetSymbolsAsync() + protected override async Task> OnGetMarketSymbolsAsync() { var data = await MakeRequestZBcomAsync(string.Empty, "/markets"); List symbols = new List(); @@ -68,9 +68,9 @@ protected override async Task> OnGetSymbolsAsync() return symbols; } - protected override async Task OnGetTickerAsync(string symbol) + protected override async Task OnGetTickerAsync(string marketSymbol) { - var data = await MakeRequestZBcomAsync(symbol, "/ticker?market=$SYMBOL$"); + var data = await MakeRequestZBcomAsync(marketSymbol, "/ticker?market=$SYMBOL$"); return ParseTicker(data.Item2, data.Item1); } @@ -80,18 +80,18 @@ protected override async Task>> var data = await MakeRequestZBcomAsync(null, "/allTicker", BaseUrl); List> tickers = new List>(); - var symbols = (await GetSymbolsAsync()).ToArray(); - string symbol; + var symbols = (await GetMarketSymbolsAsync()).ToArray(); + string marketSymbol; foreach (JToken token in data.Item1) { //for some reason when returning tickers, the api doesn't include the symbol separator like it does everywhere else so we need to convert it to the correct format - symbol = symbols.First(s => s.Replace(SymbolSeparator, string.Empty).Equals(token.Path)); - tickers.Add(new KeyValuePair(symbol, ParseTickerV2(symbol, token))); + marketSymbol = symbols.First(s => s.Replace(MarketSymbolSeparator, string.Empty).Equals(token.Path)); + tickers.Add(new KeyValuePair(marketSymbol, ParseTickerV2(marketSymbol, token))); } return tickers; } - protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] symbols) + protected override IWebSocket OnGetTradesWebSocket(Action> callback, params string[] marketSymbols) { return ConnectWebSocket(string.Empty, (_socket, msg) => { @@ -100,21 +100,21 @@ protected override IWebSocket OnGetTradesWebSocket(Action(symbol, trade)); + callback(new KeyValuePair(marketSymbol, trade)); } } return Task.CompletedTask; }, async (_socket) => { - foreach (var symbol in symbols) + foreach (var marketSymbol in marketSymbols) { - string normalizedSymbol = NormalizeSymbolWebsocket(symbol); + string normalizedSymbol = NormalizeSymbolWebsocket(marketSymbol); await _socket.SendMessageAsync(new { @event = "addChannel", channel = normalizedSymbol + "_trades" }); } }); diff --git a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs index f8c2bb73..a13c6c95 100644 --- a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs +++ b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs @@ -27,7 +27,7 @@ public abstract partial class ExchangeAPI : BaseAPI, IExchangeAPI /// /// Separator for global symbols /// - public const char GlobalSymbolSeparator = '-'; + public const char GlobalMarketSymbolSeparator = '-'; /// /// Whether to use the default method cache policy, default is true. @@ -47,11 +47,11 @@ public abstract partial class ExchangeAPI : BaseAPI, IExchangeAPI protected virtual async Task>> OnGetTickersAsync() { List> tickers = new List>(); - var symbols = await GetSymbolsAsync(); - foreach (string symbol in symbols) + var marketSymbols = await GetMarketSymbolsAsync(); + foreach (string marketSymbol in marketSymbols) { - var ticker = await GetTickerAsync(symbol); - tickers.Add(new KeyValuePair(symbol, ticker)); + var ticker = await GetTickerAsync(marketSymbol); + tickers.Add(new KeyValuePair(marketSymbol, ticker)); } return tickers; } @@ -59,53 +59,53 @@ protected virtual async Task>> protected virtual async Task>> OnGetOrderBooksAsync(int maxCount = 100) { List> books = new List>(); - var symbols = await GetSymbolsAsync(); - foreach (string symbol in symbols) + var marketSymbols = await GetMarketSymbolsAsync(); + foreach (string marketSymbol in marketSymbols) { - var book = await GetOrderBookAsync(symbol); - books.Add(new KeyValuePair(symbol, book)); + var book = await GetOrderBookAsync(marketSymbol); + books.Add(new KeyValuePair(marketSymbol, book)); } return books; } - protected virtual async Task> OnGetRecentTradesAsync(string symbol) + protected virtual async Task> OnGetRecentTradesAsync(string marketSymbol) { - symbol = NormalizeSymbol(symbol); + marketSymbol = NormalizeMarketSymbol(marketSymbol); List trades = new List(); await GetHistoricalTradesAsync((e) => { trades.AddRange(e); return true; - }, symbol); + }, marketSymbol); return trades; } protected virtual Task> OnGetCurrenciesAsync() => throw new NotImplementedException(); - protected virtual Task> OnGetSymbolsAsync() => throw new NotImplementedException(); - protected virtual Task> OnGetSymbolsMetadataAsync() => throw new NotImplementedException(); - protected virtual Task OnGetTickerAsync(string symbol) => throw new NotImplementedException(); - protected virtual Task OnGetOrderBookAsync(string symbol, int maxCount = 100) => throw new NotImplementedException(); - protected virtual Task OnGetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) => throw new NotImplementedException(); + protected virtual Task> OnGetMarketSymbolsAsync() => throw new NotImplementedException(); + protected virtual Task> OnGetMarketSymbolsMetadataAsync() => throw new NotImplementedException(); + protected virtual Task OnGetTickerAsync(string marketSymbol) => throw new NotImplementedException(); + protected virtual Task OnGetOrderBookAsync(string marketSymbol, int maxCount = 100) => throw new NotImplementedException(); + protected virtual Task OnGetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) => throw new NotImplementedException(); protected virtual Task OnGetDepositAddressAsync(string currency, bool forceRegenerate = false) => throw new NotImplementedException(); protected virtual Task> OnGetDepositHistoryAsync(string currency) => throw new NotImplementedException(); - protected virtual Task> OnGetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) => throw new NotImplementedException(); + protected virtual Task> OnGetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) => throw new NotImplementedException(); protected virtual Task> OnGetAmountsAsync() => throw new NotImplementedException(); protected virtual Task> OnGetFeesAsync() => throw new NotImplementedException(); protected virtual Task> OnGetAmountsAvailableToTradeAsync() => throw new NotImplementedException(); protected virtual Task OnPlaceOrderAsync(ExchangeOrderRequest order) => throw new NotImplementedException(); protected virtual Task OnPlaceOrdersAsync(params ExchangeOrderRequest[] order) => throw new NotImplementedException(); - protected virtual Task OnGetOrderDetailsAsync(string orderId, string symbol = null) => throw new NotImplementedException(); - protected virtual Task> OnGetOpenOrderDetailsAsync(string symbol = null) => throw new NotImplementedException(); - protected virtual Task> OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) => throw new NotImplementedException(); - protected virtual Task OnCancelOrderAsync(string orderId, string symbol = null) => throw new NotImplementedException(); + protected virtual Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) => throw new NotImplementedException(); + protected virtual Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) => throw new NotImplementedException(); + protected virtual Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) => throw new NotImplementedException(); + protected virtual Task OnCancelOrderAsync(string orderId, string marketSymbol = null) => throw new NotImplementedException(); protected virtual Task OnWithdrawAsync(ExchangeWithdrawalRequest withdrawalRequest) => throw new NotImplementedException(); protected virtual Task> OnGetMarginAmountsAvailableToTradeAsync(bool includeZeroBalances) => throw new NotImplementedException(); - protected virtual Task OnGetOpenPositionAsync(string symbol) => throw new NotImplementedException(); - protected virtual Task OnCloseMarginPositionAsync(string symbol) => throw new NotImplementedException(); + protected virtual Task OnGetOpenPositionAsync(string marketSymbol) => throw new NotImplementedException(); + protected virtual Task OnCloseMarginPositionAsync(string marketSymbol) => throw new NotImplementedException(); protected virtual IWebSocket OnGetTickersWebSocket(Action>> tickers) => throw new NotImplementedException(); - protected virtual IWebSocket OnGetTradesWebSocket(Action> callback, params string[] symbols) => throw new NotImplementedException(); - protected virtual IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] symbols) => throw new NotImplementedException(); + protected virtual IWebSocket OnGetTradesWebSocket(Action> callback, params string[] marketSymbols) => throw new NotImplementedException(); + protected virtual IWebSocket OnGetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] marketSymbols) => throw new NotImplementedException(); protected virtual IWebSocket OnGetOrderDetailsWebSocket(Action callback) => throw new NotImplementedException(); protected virtual IWebSocket OnGetCompletedOrderDetailsWebSocket(Action callback) => throw new NotImplementedException(); @@ -116,24 +116,24 @@ await GetHistoricalTradesAsync((e) => /// /// Clamp price using market info. If necessary, a network request will be made to retrieve symbol metadata. /// - /// Symbol + /// Market Symbol /// Price /// Clamped price - protected async Task ClampOrderPrice(string symbol, decimal outputPrice) + protected async Task ClampOrderPrice(string marketSymbol, decimal outputPrice) { - ExchangeMarket market = await GetExchangeMarketFromCacheAsync(symbol); + ExchangeMarket market = await GetExchangeMarketFromCacheAsync(marketSymbol); return market == null ? outputPrice : CryptoUtility.ClampDecimal(market.MinPrice, market.MaxPrice, market.PriceStepSize, outputPrice); } /// /// Clamp quantiy using market info. If necessary, a network request will be made to retrieve symbol metadata. /// - /// Symbol + /// Market Symbol /// Quantity /// Clamped quantity - protected async Task ClampOrderQuantity(string symbol, decimal outputQuantity) + protected async Task ClampOrderQuantity(string marketSymbol, decimal outputQuantity) { - ExchangeMarket market = await GetExchangeMarketFromCacheAsync(symbol); + ExchangeMarket market = await GetExchangeMarketFromCacheAsync(marketSymbol); return market == null ? outputQuantity : CryptoUtility.ClampDecimal(market.MinTradeSize, market.MaxTradeSize, market.QuantityStepSize, outputQuantity); } @@ -144,21 +144,21 @@ protected async Task ClampOrderQuantity(string symbol, decimal outputQu /// second (i.e. ETH). Example BTC-ETH, read as x BTC is worth y ETH. /// BTC is always first, then ETH, etc. Fiat pair is always first in global symbol too. /// - /// Exchange symbol + /// Exchange market symbol /// Separator /// Global symbol - protected string ExchangeSymbolToGlobalSymbolWithSeparator(string symbol, char separator = GlobalSymbolSeparator) + protected string ExchangeMarketSymbolToGlobalMarketSymbolWithSeparator(string marketSymbol, char separator = GlobalMarketSymbolSeparator) { - if (string.IsNullOrEmpty(symbol)) + if (string.IsNullOrEmpty(marketSymbol)) { throw new ArgumentException("Symbol must be non null and non empty"); } - string[] pieces = symbol.Split(separator); - if (SymbolIsReversed) + string[] pieces = marketSymbol.Split(separator); + if (MarketSymbolIsReversed) { - return ExchangeCurrencyToGlobalCurrency(pieces[0]).ToUpperInvariant() + GlobalSymbolSeparator + ExchangeCurrencyToGlobalCurrency(pieces[1]).ToUpperInvariant(); + return ExchangeCurrencyToGlobalCurrency(pieces[0]).ToUpperInvariant() + GlobalMarketSymbolSeparator + ExchangeCurrencyToGlobalCurrency(pieces[1]).ToUpperInvariant(); } - return ExchangeCurrencyToGlobalCurrency(pieces[1]).ToUpperInvariant() + GlobalSymbolSeparator + ExchangeCurrencyToGlobalCurrency(pieces[0]).ToUpperInvariant(); + return ExchangeCurrencyToGlobalCurrency(pieces[1]).ToUpperInvariant() + GlobalMarketSymbolSeparator + ExchangeCurrencyToGlobalCurrency(pieces[0]).ToUpperInvariant(); } /// @@ -197,8 +197,8 @@ public ExchangeAPI() if (UseDefaultMethodCachePolicy) { MethodCachePolicy.Add(nameof(GetCurrenciesAsync), TimeSpan.FromHours(1.0)); - MethodCachePolicy.Add(nameof(GetSymbolsAsync), TimeSpan.FromHours(1.0)); - MethodCachePolicy.Add(nameof(GetSymbolsMetadataAsync), TimeSpan.FromHours(1.0)); + MethodCachePolicy.Add(nameof(GetMarketSymbolsAsync), TimeSpan.FromHours(1.0)); + MethodCachePolicy.Add(nameof(GetMarketSymbolsMetadataAsync), TimeSpan.FromHours(1.0)); MethodCachePolicy.Add(nameof(GetTickerAsync), TimeSpan.FromSeconds(10.0)); MethodCachePolicy.Add(nameof(GetTickersAsync), TimeSpan.FromSeconds(10.0)); MethodCachePolicy.Add(nameof(GetOrderBookAsync), TimeSpan.FromSeconds(10.0)); @@ -337,28 +337,28 @@ public string GlobalCurrencyToExchangeCurrency(string currency) { currency = currency.Replace(kv.Value, kv.Key); } - return (SymbolIsUppercase ? currency.ToUpperInvariant() : currency.ToLowerInvariant()); + return (MarketSymbolIsUppercase ? currency.ToUpperInvariant() : currency.ToLowerInvariant()); } /// /// Normalize an exchange specific symbol. The symbol should already be in the correct order, /// this method just deals with casing and putting in the right separator. /// - /// Symbol + /// Symbol /// Normalized symbol - public virtual string NormalizeSymbol(string symbol) - { - symbol = (symbol ?? string.Empty).Trim(); - symbol = symbol.Replace("-", SymbolSeparator) - .Replace("/", SymbolSeparator) - .Replace("_", SymbolSeparator) - .Replace(" ", SymbolSeparator) - .Replace(":", SymbolSeparator); - if (SymbolIsUppercase) + public virtual string NormalizeMarketSymbol(string marketSymbol) + { + marketSymbol = (marketSymbol ?? string.Empty).Trim(); + marketSymbol = marketSymbol.Replace("-", MarketSymbolSeparator) + .Replace("/", MarketSymbolSeparator) + .Replace("_", MarketSymbolSeparator) + .Replace(" ", MarketSymbolSeparator) + .Replace(":", MarketSymbolSeparator); + if (MarketSymbolIsUppercase) { - return symbol.ToUpperInvariant(); + return marketSymbol.ToUpperInvariant(); } - return symbol.ToLowerInvariant(); + return marketSymbol.ToLowerInvariant(); } /// @@ -368,28 +368,28 @@ public virtual string NormalizeSymbol(string symbol) /// second (i.e. ETH). Example BTC-ETH, read as x BTC is worth y ETH. /// BTC is always first, then ETH, etc. Fiat pair is always first in global symbol too. /// - /// Exchange symbol + /// Exchange symbol /// Global symbol - public virtual string ExchangeSymbolToGlobalSymbol(string symbol) + public virtual string ExchangeMarketSymbolToGlobalMarketSymbol(string marketSymbol) { - if (string.IsNullOrWhiteSpace(SymbolSeparator)) + if (string.IsNullOrWhiteSpace(MarketSymbolSeparator)) { - if (symbol.Length != 6) + if (marketSymbol.Length != 6) { - throw new InvalidOperationException(Name + " symbol must be 6 chars: '" + symbol + "' is not. Override this method to handle symbols that are not 6 chars in length."); + throw new InvalidOperationException(Name + " market symbol must be 6 chars: '" + marketSymbol + "' is not. Override this method to handle symbols that are not 6 chars in length."); } - return ExchangeSymbolToGlobalSymbolWithSeparator(symbol.Substring(0, symbol.Length - 3) + GlobalSymbolSeparator + (symbol.Substring(symbol.Length - 3, 3)), GlobalSymbolSeparator); + return ExchangeMarketSymbolToGlobalMarketSymbolWithSeparator(marketSymbol.Substring(0, marketSymbol.Length - 3) + GlobalMarketSymbolSeparator + (marketSymbol.Substring(marketSymbol.Length - 3, 3)), GlobalMarketSymbolSeparator); } - return ExchangeSymbolToGlobalSymbolWithSeparator(symbol, SymbolSeparator[0]); + return ExchangeMarketSymbolToGlobalMarketSymbolWithSeparator(marketSymbol, MarketSymbolSeparator[0]); } - public virtual string CurrenciesToExchangeSymbol(string baseCurrency, string quoteCurrency) + public virtual string CurrenciesToExchangeMarketSymbol(string baseCurrency, string quoteCurrency) { - var symbol = SymbolIsReversed - ? $"{quoteCurrency}{SymbolSeparator}{baseCurrency}" - : $"{baseCurrency}{SymbolSeparator}{quoteCurrency}"; + var symbol = MarketSymbolIsReversed + ? $"{quoteCurrency}{MarketSymbolSeparator}{baseCurrency}" + : $"{baseCurrency}{MarketSymbolSeparator}{quoteCurrency}"; - return SymbolIsUppercase + return MarketSymbolIsUppercase ? symbol.ToUpperInvariant() : symbol; } @@ -397,26 +397,26 @@ public virtual string CurrenciesToExchangeSymbol(string baseCurrency, string quo /// /// NOTE: This method can potentially make a call to GetSymbolsMetadataAsync /// - /// + /// /// - public virtual (string BaseCurrency, string QuoteCurrency) ExchangeSymbolToCurrencies(string symbol) + public virtual (string BaseCurrency, string QuoteCurrency) ExchangeMarketSymbolToCurrencies(string marketSymbol) { string baseCurrency, quoteCurrency; - if (string.IsNullOrWhiteSpace(SymbolSeparator)) + if (string.IsNullOrWhiteSpace(MarketSymbolSeparator)) { - if (symbol.Length != 6) + if (marketSymbol.Length != 6) { - var errorMessage = Name + " symbol must be 6 chars: '" + symbol + "' is not. Override this method to handle symbols that are not 6 chars in length."; + var errorMessage = Name + " symbol must be 6 chars: '" + marketSymbol + "' is not. Override this method to handle symbols that are not 6 chars in length."; try { //let's try looking this up by the metadata.. - var symbols = GetSymbolsMetadataAsync().Sync().ToArray();//.ToDictionary(market => market.MarketName, market => market); - var symbolMetadata = symbols.First( - market => market.MarketName.Equals(symbol, StringComparison.InvariantCultureIgnoreCase) || CurrenciesToExchangeSymbol(market.BaseCurrency, market.QuoteCurrency) - .Equals(symbol, StringComparison.InvariantCultureIgnoreCase) + var symbols = GetMarketSymbolsMetadataAsync().Sync().ToArray();//.ToDictionary(market => market.MarketName, market => market); + var marketSymbolMetadata = symbols.First( + market => market.MarketSymbol.Equals(marketSymbol, StringComparison.InvariantCultureIgnoreCase) || CurrenciesToExchangeMarketSymbol(market.BaseCurrency, market.QuoteCurrency) + .Equals(marketSymbol, StringComparison.InvariantCultureIgnoreCase) ); - return (symbolMetadata.BaseCurrency, symbolMetadata.QuoteCurrency); + return (marketSymbolMetadata.BaseCurrency, marketSymbolMetadata.QuoteCurrency); } catch (Exception e) { @@ -425,24 +425,24 @@ public virtual (string BaseCurrency, string QuoteCurrency) ExchangeSymbolToCurre throw new InvalidOperationException(errorMessage); } - if (SymbolIsReversed) + if (MarketSymbolIsReversed) { - quoteCurrency = symbol.Substring(0, symbol.Length - 3); - baseCurrency = symbol.Substring(symbol.Length - 3, 3); + quoteCurrency = marketSymbol.Substring(0, marketSymbol.Length - 3); + baseCurrency = marketSymbol.Substring(marketSymbol.Length - 3, 3); } else { - baseCurrency = symbol.Substring(0, symbol.Length - 3); - quoteCurrency = symbol.Substring(symbol.Length - 3, 3); + baseCurrency = marketSymbol.Substring(0, marketSymbol.Length - 3); + quoteCurrency = marketSymbol.Substring(marketSymbol.Length - 3, 3); } } else { - var pieces = symbol.Split(SymbolSeparator[0]); + var pieces = marketSymbol.Split(MarketSymbolSeparator[0]); if (pieces.Length != 2) - throw new InvalidOperationException($"Splitting {Name} symbol '{symbol}' with symbol separator '{SymbolSeparator}' must result in exactly 2 pieces."); - quoteCurrency = SymbolIsReversed ? pieces[0] : pieces[1]; - baseCurrency = SymbolIsReversed ? pieces[1] : pieces[0]; + throw new InvalidOperationException($"Splitting {Name} symbol '{marketSymbol}' with symbol separator '{MarketSymbolSeparator}' must result in exactly 2 pieces."); + quoteCurrency = MarketSymbolIsReversed ? pieces[0] : pieces[1]; + baseCurrency = MarketSymbolIsReversed ? pieces[1] : pieces[0]; } return (baseCurrency, quoteCurrency); @@ -451,24 +451,24 @@ public virtual (string BaseCurrency, string QuoteCurrency) ExchangeSymbolToCurre /// /// Convert a global symbol into an exchange symbol, which will potentially be different from other exchanges. /// - /// Global symbol - /// Exchange symbol - public virtual string GlobalSymbolToExchangeSymbol(string symbol) + /// Global market symbol + /// Exchange market symbol + public virtual string GlobalMarketSymbolToExchangeMarketSymbol(string marketSymbol) { - if (string.IsNullOrWhiteSpace(symbol)) + if (string.IsNullOrWhiteSpace(marketSymbol)) { - throw new ArgumentException("Symbol must be non null and non empty"); + throw new ArgumentException("Market symbol must be non null and non empty"); } - int pos = symbol.IndexOf(GlobalSymbolSeparator); - if (SymbolIsReversed) + int pos = marketSymbol.IndexOf(GlobalMarketSymbolSeparator); + if (MarketSymbolIsReversed) { - symbol = GlobalCurrencyToExchangeCurrency(symbol.Substring(0, pos)) + SymbolSeparator + GlobalCurrencyToExchangeCurrency(symbol.Substring(pos + 1)); + marketSymbol = GlobalCurrencyToExchangeCurrency(marketSymbol.Substring(0, pos)) + MarketSymbolSeparator + GlobalCurrencyToExchangeCurrency(marketSymbol.Substring(pos + 1)); } else { - symbol = GlobalCurrencyToExchangeCurrency(symbol.Substring(pos + 1)) + SymbolSeparator + GlobalCurrencyToExchangeCurrency(symbol.Substring(0, pos)); + marketSymbol = GlobalCurrencyToExchangeCurrency(marketSymbol.Substring(pos + 1)) + MarketSymbolSeparator + GlobalCurrencyToExchangeCurrency(marketSymbol.Substring(0, pos)); } - return (SymbolIsUppercase ? symbol.ToUpperInvariant() : symbol.ToLowerInvariant()); + return (MarketSymbolIsUppercase ? marketSymbol.ToUpperInvariant() : marketSymbol.ToLowerInvariant()); } /// @@ -495,27 +495,27 @@ public virtual async Task> GetCurr /// Get exchange symbols /// /// Array of symbols - public virtual async Task> GetSymbolsAsync() + public virtual async Task> GetMarketSymbolsAsync() { - return await Cache.CacheMethod(MethodCachePolicy, async () => (await OnGetSymbolsAsync()).ToArray(), nameof(GetSymbolsAsync)); + return await Cache.CacheMethod(MethodCachePolicy, async () => (await OnGetMarketSymbolsAsync()).ToArray(), nameof(GetMarketSymbolsAsync)); } /// /// Get exchange symbols including available metadata such as min trade size and whether the market is active /// /// Collection of ExchangeMarkets - public virtual async Task> GetSymbolsMetadataAsync() + public virtual async Task> GetMarketSymbolsMetadataAsync() { - return await Cache.CacheMethod(MethodCachePolicy, async () => (await OnGetSymbolsMetadataAsync()).ToArray(), nameof(GetSymbolsMetadataAsync)); + return await Cache.CacheMethod(MethodCachePolicy, async () => (await OnGetMarketSymbolsMetadataAsync()).ToArray(), nameof(GetMarketSymbolsMetadataAsync)); } /// /// Gets the exchange market from this exchange's SymbolsMetadata cache. This will make a network request if needed to retrieve fresh markets from the exchange using GetSymbolsMetadataAsync(). /// Please note that sending a symbol that is not found over and over will result in many network requests. Only send symbols that you are confident exist on the exchange. /// - /// The symbol. Ex. ADA/BTC. This is assumed to be normalized and already correct for the exchange. + /// The market symbol. Ex. ADA/BTC. This is assumed to be normalized and already correct for the exchange. /// The ExchangeMarket or null if it doesn't exist in the cache or there was an error - public virtual async Task GetExchangeMarketFromCacheAsync(string symbol) + public virtual async Task GetExchangeMarketFromCacheAsync(string marketSymbol) { try { @@ -523,17 +523,17 @@ public virtual async Task GetExchangeMarketFromCacheAsync(string // not sure if this is needed, but adding it just in case await new SynchronizationContextRemover(); - ExchangeMarket[] markets = (await GetSymbolsMetadataAsync()).ToArray(); - ExchangeMarket market = markets.FirstOrDefault(m => m.MarketName == symbol); + ExchangeMarket[] markets = (await GetMarketSymbolsMetadataAsync()).ToArray(); + ExchangeMarket market = markets.FirstOrDefault(m => m.MarketSymbol == marketSymbol); if (market == null) { // try again with a fresh request, every symbol *should* be in the response from PopulateExchangeMarketsAsync - Cache.Remove(nameof(GetSymbolsMetadataAsync)); + Cache.Remove(nameof(GetMarketSymbolsMetadataAsync)); - markets = (await GetSymbolsMetadataAsync()).ToArray(); + markets = (await GetMarketSymbolsMetadataAsync()).ToArray(); // try and find the market again, this time if not found we give up and just return null - market = markets.FirstOrDefault(m => m.MarketName == symbol); + market = markets.FirstOrDefault(m => m.MarketSymbol == marketSymbol); } return market; } @@ -547,12 +547,12 @@ public virtual async Task GetExchangeMarketFromCacheAsync(string /// /// Get exchange ticker /// - /// Symbol to get ticker for + /// Symbol to get ticker for /// Ticker - public virtual async Task GetTickerAsync(string symbol) + public virtual async Task GetTickerAsync(string marketSymbol) { - NormalizeSymbol(symbol); - return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetTickerAsync(symbol), nameof(GetTickerAsync), nameof(symbol), symbol); + NormalizeMarketSymbol(marketSymbol); + return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetTickerAsync(marketSymbol), nameof(GetTickerAsync), nameof(marketSymbol), marketSymbol); } /// @@ -567,13 +567,13 @@ public virtual async Task>> Get /// /// Get exchange order book /// - /// Symbol to get order book for + /// Symbol to get order book for /// Max count, not all exchanges will honor this parameter /// Exchange order book or null if failure - public virtual async Task GetOrderBookAsync(string symbol, int maxCount = 100) + public virtual async Task GetOrderBookAsync(string marketSymbol, int maxCount = 100) { - symbol = NormalizeSymbol(symbol); - return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetOrderBookAsync(symbol, maxCount), nameof(GetOrderBookAsync), nameof(symbol), symbol, nameof(maxCount), maxCount); + marketSymbol = NormalizeMarketSymbol(marketSymbol); + return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetOrderBookAsync(marketSymbol, maxCount), nameof(GetOrderBookAsync), nameof(marketSymbol), marketSymbol, nameof(maxCount), maxCount); } /// @@ -590,25 +590,25 @@ public virtual async Task>> /// Get historical trades for the exchange. TODO: Change to async enumerator when available. /// /// Callback for each set of trades. Return false to stop getting trades immediately. - /// Symbol to get historical data for + /// Symbol to get historical data for /// Optional UTC start date time to start getting the historical data at, null for the most recent data. Not all exchanges support this. /// Optional UTC end date time to start getting the historical data at, null for the most recent data. Not all exchanges support this. - public virtual async Task GetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null) + public virtual async Task GetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null) { // *NOTE*: Do not wrap in CacheMethodCall, uses a callback with custom queries, not easy to cache await new SynchronizationContextRemover(); - await OnGetHistoricalTradesAsync(callback, NormalizeSymbol(symbol), startDate, endDate); + await OnGetHistoricalTradesAsync(callback, NormalizeMarketSymbol(marketSymbol), startDate, endDate); } /// /// Get recent trades on the exchange - the default implementation simply calls GetHistoricalTrades with a null sinceDateTime. /// - /// Symbol to get recent trades for + /// Symbol to get recent trades for /// An enumerator that loops through all recent trades - public virtual async Task> GetRecentTradesAsync(string symbol) + public virtual async Task> GetRecentTradesAsync(string marketSymbol) { - symbol = NormalizeSymbol(symbol); - return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetRecentTradesAsync(symbol), nameof(GetRecentTradesAsync), nameof(symbol), symbol); + marketSymbol = NormalizeMarketSymbol(marketSymbol); + return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetRecentTradesAsync(marketSymbol), nameof(GetRecentTradesAsync), nameof(marketSymbol), marketSymbol); } /// @@ -642,17 +642,17 @@ public virtual async Task> GetDepositHistoryAsy /// /// Get candles (open, high, low, close) /// - /// Symbol to get candles for + /// Symbol to get candles for /// Period in seconds to get candles for. Use 60 for minute, 3600 for hour, 3600*24 for day, 3600*24*30 for month. /// Optional start date to get candles for /// Optional end date to get candles for /// Max results, can be used instead of startDate and endDate if desired /// Candles - public virtual async Task> GetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) + public virtual async Task> GetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null) { - symbol = NormalizeSymbol(symbol); - return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetCandlesAsync(symbol, periodSeconds, startDate, endDate, limit), nameof(GetCandlesAsync), - nameof(symbol), symbol, nameof(periodSeconds), periodSeconds, nameof(startDate), startDate, nameof(endDate), endDate, nameof(limit), limit); + marketSymbol = NormalizeMarketSymbol(marketSymbol); + return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetCandlesAsync(marketSymbol, periodSeconds, startDate, endDate, limit), nameof(GetCandlesAsync), + nameof(marketSymbol), marketSymbol, nameof(periodSeconds), periodSeconds, nameof(startDate), startDate, nameof(endDate), endDate, nameof(limit), limit); } /// @@ -691,7 +691,7 @@ public virtual async Task PlaceOrderAsync(ExchangeOrderRequ { // *NOTE* do not wrap in CacheMethodCall await new SynchronizationContextRemover(); - order.Symbol = NormalizeSymbol(order.Symbol); + order.MarketSymbol = NormalizeMarketSymbol(order.MarketSymbol); return await OnPlaceOrderAsync(order); } @@ -706,7 +706,7 @@ public virtual async Task PlaceOrdersAsync(params Exchang await new SynchronizationContextRemover(); foreach (ExchangeOrderRequest request in orders) { - request.Symbol = NormalizeSymbol(request.Symbol); + request.MarketSymbol = NormalizeMarketSymbol(request.MarketSymbol); } return await OnPlaceOrdersAsync(orders); } @@ -715,48 +715,48 @@ public virtual async Task PlaceOrdersAsync(params Exchang /// Get order details /// /// Order id to get details for - /// Symbol of order (most exchanges do not require this) + /// Symbol of order (most exchanges do not require this) /// Order details - public virtual async Task GetOrderDetailsAsync(string orderId, string symbol = null) + public virtual async Task GetOrderDetailsAsync(string orderId, string marketSymbol = null) { - symbol = NormalizeSymbol(symbol); - return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetOrderDetailsAsync(orderId, symbol), nameof(GetOrderDetailsAsync), nameof(orderId), orderId, nameof(symbol), symbol); + marketSymbol = NormalizeMarketSymbol(marketSymbol); + return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetOrderDetailsAsync(orderId, marketSymbol), nameof(GetOrderDetailsAsync), nameof(orderId), orderId, nameof(marketSymbol), marketSymbol); } /// /// Get the details of all open orders /// - /// Symbol to get open orders for or null for all + /// Symbol to get open orders for or null for all /// All open order details - public virtual async Task> GetOpenOrderDetailsAsync(string symbol = null) + public virtual async Task> GetOpenOrderDetailsAsync(string marketSymbol = null) { - symbol = NormalizeSymbol(symbol); - return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetOpenOrderDetailsAsync(symbol), nameof(GetOpenOrderDetailsAsync), nameof(symbol), symbol); + marketSymbol = NormalizeMarketSymbol(marketSymbol); + return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetOpenOrderDetailsAsync(marketSymbol), nameof(GetOpenOrderDetailsAsync), nameof(marketSymbol), marketSymbol); } /// /// Get the details of all completed orders /// - /// Symbol to get completed orders for or null for all + /// Symbol to get completed orders for or null for all /// Only returns orders on or after the specified date/time /// All completed order details for the specified symbol, or all if null symbol - public virtual async Task> GetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null) + public virtual async Task> GetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) { - symbol = NormalizeSymbol(symbol); - return await Cache.CacheMethod(MethodCachePolicy, async () => (await OnGetCompletedOrderDetailsAsync(symbol, afterDate)).ToArray(), nameof(GetCompletedOrderDetailsAsync), - nameof(symbol), symbol, nameof(afterDate), afterDate); + marketSymbol = NormalizeMarketSymbol(marketSymbol); + return await Cache.CacheMethod(MethodCachePolicy, async () => (await OnGetCompletedOrderDetailsAsync(marketSymbol, afterDate)).ToArray(), nameof(GetCompletedOrderDetailsAsync), + nameof(marketSymbol), marketSymbol, nameof(afterDate), afterDate); } /// /// Cancel an order, an exception is thrown if error /// /// Order id of the order to cancel - /// Symbol of order (most exchanges do not require this) - public virtual async Task CancelOrderAsync(string orderId, string symbol = null) + /// Symbol of order (most exchanges do not require this) + public virtual async Task CancelOrderAsync(string orderId, string marketSymbol = null) { // *NOTE* do not wrap in CacheMethodCall await new SynchronizationContextRemover(); - await OnCancelOrderAsync(orderId, NormalizeSymbol(symbol)); + await OnCancelOrderAsync(orderId, NormalizeMarketSymbol(marketSymbol)); } /// @@ -767,7 +767,7 @@ public virtual async Task WithdrawAsync(ExchangeWith { // *NOTE* do not wrap in CacheMethodCall await new SynchronizationContextRemover(); - withdrawalRequest.Currency = NormalizeSymbol(withdrawalRequest.Currency); + withdrawalRequest.Currency = NormalizeMarketSymbol(withdrawalRequest.Currency); return await OnWithdrawAsync(withdrawalRequest); } @@ -785,24 +785,24 @@ public virtual async Task> GetMarginAmountsAvailable /// /// Get open margin position /// - /// Symbol + /// Symbol /// Open margin position result - public virtual async Task GetOpenPositionAsync(string symbol) + public virtual async Task GetOpenPositionAsync(string marketSymbol) { - symbol = NormalizeSymbol(symbol); - return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetOpenPositionAsync(symbol), nameof(GetOpenPositionAsync), nameof(symbol), symbol); + marketSymbol = NormalizeMarketSymbol(marketSymbol); + return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetOpenPositionAsync(marketSymbol), nameof(GetOpenPositionAsync), nameof(marketSymbol), marketSymbol); } /// /// Close a margin position /// - /// Symbol + /// Symbol /// Close margin position result - public virtual async Task CloseMarginPositionAsync(string symbol) + public virtual async Task CloseMarginPositionAsync(string marketSymbol) { // *NOTE* do not wrap in CacheMethodCall await new SynchronizationContextRemover(); - return await OnCloseMarginPositionAsync(NormalizeSymbol(symbol)); + return await OnCloseMarginPositionAsync(NormalizeMarketSymbol(marketSymbol)); } #endregion REST API @@ -824,12 +824,12 @@ public virtual IWebSocket GetTickersWebSocket(Action /// Callback (symbol and trade) - /// Symbols + /// Market Symbols /// Web socket, call Dispose to close - public virtual IWebSocket GetTradesWebSocket(Action> callback, params string[] symbols) + public virtual IWebSocket GetTradesWebSocket(Action> callback, params string[] marketSymbols) { callback.ThrowIfNull(nameof(callback), "Callback must not be null"); - return OnGetTradesWebSocket(callback, symbols); + return OnGetTradesWebSocket(callback, marketSymbols); } /// @@ -837,12 +837,12 @@ public virtual IWebSocket GetTradesWebSocket(Action /// Callback of symbol, order book /// Max count of bids and asks - not all exchanges will honor this parameter - /// Ticker symbols or null/empty for all of them (if supported) + /// Market symbols or null/empty for all of them (if supported) /// Web socket, call Dispose to close - public virtual IWebSocket GetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] symbols) + public virtual IWebSocket GetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] marketSymbols) { callback.ThrowIfNull(nameof(callback), "Callback must not be null"); - return OnGetOrderBookWebSocket(callback, maxCount, symbols); + return OnGetOrderBookWebSocket(callback, maxCount, marketSymbols); } /// diff --git a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIDefinitions.cs b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIDefinitions.cs index 74453517..0b080542 100644 --- a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIDefinitions.cs +++ b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIDefinitions.cs @@ -81,17 +81,17 @@ public abstract partial class ExchangeAPI /// /// Separator for exchange symbol. If not a hyphen, set in constructor. /// - public string SymbolSeparator { get; protected set; } = "-"; + public string MarketSymbolSeparator { get; protected set; } = "-"; /// /// Whether the symbol is reversed. Most exchanges do ETH-BTC, if your exchange does BTC-ETH, set to true in constructor. /// - public bool SymbolIsReversed { get; protected set; } + public bool MarketSymbolIsReversed { get; protected set; } /// /// Whether the symbol is uppercase. Most exchanges are true, but if your exchange is lowercase, set to false in constructor. /// - public bool SymbolIsUppercase { get; protected set; } = true; + public bool MarketSymbolIsUppercase { get; protected set; } = true; /// /// The type of web socket order book supported diff --git a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs index 3c87c60e..959f2e08 100644 --- a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs +++ b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs @@ -81,7 +81,7 @@ async Task innerCallback(ExchangeOrderBook newOrderBook) // ideally all exchanges would send the full order book on first message, followed by delta order books // but this is not the case - bool foundFullBook = fullBooks.TryGetValue(newOrderBook.Symbol, out ExchangeOrderBook fullOrderBook); + bool foundFullBook = fullBooks.TryGetValue(newOrderBook.MarketSymbol, out ExchangeOrderBook fullOrderBook); switch (api.WebSocketOrderBookType) { case WebSocketOrderBookType.DeltasOnly: @@ -95,10 +95,10 @@ async Task innerCallback(ExchangeOrderBook newOrderBook) // attempt to find the right queue to put the partial order book in to be processed later lock (partialOrderBookQueues) { - if (!partialOrderBookQueues.TryGetValue(newOrderBook.Symbol, out partialOrderBookQueue)) + if (!partialOrderBookQueues.TryGetValue(newOrderBook.MarketSymbol, out partialOrderBookQueue)) { // no queue found, make a new one - partialOrderBookQueues[newOrderBook.Symbol] = partialOrderBookQueue = new Queue(); + partialOrderBookQueues[newOrderBook.MarketSymbol] = partialOrderBookQueue = new Queue(); requestFullOrderBook = !foundFullBook; } @@ -109,9 +109,9 @@ async Task innerCallback(ExchangeOrderBook newOrderBook) // request the entire order book if we need it if (requestFullOrderBook) { - fullOrderBook = await api.GetOrderBookAsync(newOrderBook.Symbol, maxCount); - fullOrderBook.Symbol = newOrderBook.Symbol; - fullBooks[newOrderBook.Symbol] = fullOrderBook; + fullOrderBook = await api.GetOrderBookAsync(newOrderBook.MarketSymbol, maxCount); + fullOrderBook.MarketSymbol = newOrderBook.MarketSymbol; + fullBooks[newOrderBook.MarketSymbol] = fullOrderBook; } else if (!foundFullBook) { @@ -125,7 +125,7 @@ async Task innerCallback(ExchangeOrderBook newOrderBook) // lock dictionary of queues for lookup only lock (partialOrderBookQueues) { - partialOrderBookQueues.TryGetValue(newOrderBook.Symbol, out partialOrderBookQueue); + partialOrderBookQueues.TryGetValue(newOrderBook.MarketSymbol, out partialOrderBookQueue); } if (partialOrderBookQueue != null) @@ -147,7 +147,7 @@ async Task innerCallback(ExchangeOrderBook newOrderBook) // Subsequent updates will be deltas, at least some exchanges have their heads on straight if (!foundFullBook) { - fullBooks[newOrderBook.Symbol] = fullOrderBook = newOrderBook; + fullBooks[newOrderBook.MarketSymbol] = fullOrderBook = newOrderBook; } else { @@ -158,7 +158,7 @@ async Task innerCallback(ExchangeOrderBook newOrderBook) case WebSocketOrderBookType.FullBookAlways: { // Websocket always returns full order book, WTF...? - fullBooks[newOrderBook.Symbol] = fullOrderBook = newOrderBook; + fullBooks[newOrderBook.MarketSymbol] = fullOrderBook = newOrderBook; } break; } @@ -269,7 +269,7 @@ public static async Task PlaceSafeMarketOrderAsync(this Exc OrderType = OrderType.Limit, Price = CryptoUtility.RoundAmount((isBuy ? highPrice : lowPrice) * priceThreshold), ShouldRoundAmount = true, - Symbol = symbol + MarketSymbol = symbol }; ExchangeOrderResult result = await api.PlaceOrderAsync(request); @@ -387,7 +387,7 @@ internal static ExchangeOrderBook ParseOrderBookFromJTokenDictionaries /// /// ExchangeAPI /// Token - /// Symbol + /// Symbol /// Ask key /// Bid key /// Last key @@ -399,7 +399,7 @@ internal static ExchangeOrderBook ParseOrderBookFromJTokenDictionaries /// Quote currency key /// Id key /// ExchangeTicker - internal static ExchangeTicker ParseTicker(this ExchangeAPI api, JToken token, string symbol, + internal static ExchangeTicker ParseTicker(this ExchangeAPI api, JToken token, string marketSymbol, object askKey, object bidKey, object lastKey, object baseVolumeKey, object quoteVolumeKey = null, object timestampKey = null, TimestampType timestampType = TimestampType.None, object baseCurrencyKey = null, object quoteCurrencyKey = null, object idKey = null) @@ -424,13 +424,13 @@ internal static ExchangeTicker ParseTicker(this ExchangeAPI api, JToken token, s baseCurrency = token[baseCurrencyKey].ToStringInvariant(); quoteCurrency = token[quoteCurrencyKey].ToStringInvariant(); } - else if (string.IsNullOrWhiteSpace(symbol)) + else if (string.IsNullOrWhiteSpace(marketSymbol)) { - throw new ArgumentNullException(nameof(symbol)); + throw new ArgumentNullException(nameof(marketSymbol)); } else { - (baseCurrency, quoteCurrency) = api.ExchangeSymbolToCurrencies(symbol); + (baseCurrency, quoteCurrency) = api.ExchangeMarketSymbolToCurrencies(marketSymbol); } // create the ticker and return it @@ -446,7 +446,7 @@ internal static ExchangeTicker ParseTicker(this ExchangeAPI api, JToken token, s } ExchangeTicker ticker = new ExchangeTicker { - Symbol = symbol, + MarketSymbol = marketSymbol, Ask = askValue.ConvertInvariant(), Bid = bidValue.ConvertInvariant(), Id = (idKey == null ? null : token[idKey].ToStringInvariant()), @@ -546,7 +546,7 @@ internal static void ParseVolumes(this JToken token, object baseVolumeKey, objec /// /// Named item /// JToken - /// Symbol + /// Symbol /// Period seconds /// Open key /// High key @@ -558,7 +558,7 @@ internal static void ParseVolumes(this JToken token, object baseVolumeKey, objec /// Quote currency volume key /// Weighted average key /// MarketCandle - internal static MarketCandle ParseCandle(this INamed named, JToken token, string symbol, int periodSeconds, object openKey, object highKey, object lowKey, + internal static MarketCandle ParseCandle(this INamed named, JToken token, string marketSymbol, int periodSeconds, object openKey, object highKey, object lowKey, object closeKey, object timestampKey, TimestampType timestampType, object baseVolumeKey, object quoteVolumeKey = null, object weightedAverageKey = null) { MarketCandle candle = new MarketCandle @@ -567,7 +567,7 @@ internal static MarketCandle ParseCandle(this INamed named, JToken token, string ExchangeName = named.Name, HighPrice = token[highKey].ConvertInvariant(), LowPrice = token[lowKey].ConvertInvariant(), - Name = symbol, + Name = marketSymbol, OpenPrice = token[openKey].ConvertInvariant(), PeriodSeconds = periodSeconds, Timestamp = CryptoUtility.ParseTimestamp(token[timestampKey], timestampType) diff --git a/ExchangeSharp/API/Exchanges/_Base/ExchangeHistoricalTradeHelper.cs b/ExchangeSharp/API/Exchanges/_Base/ExchangeHistoricalTradeHelper.cs index 496005ce..a97ecff3 100644 --- a/ExchangeSharp/API/Exchanges/_Base/ExchangeHistoricalTradeHelper.cs +++ b/ExchangeSharp/API/Exchanges/_Base/ExchangeHistoricalTradeHelper.cs @@ -26,10 +26,10 @@ protected class ExchangeHistoricalTradeHelper private ExchangeAPI api; public Func, bool> Callback { get; set; } - public string Symbol { get; set; } + public string MarketSymbol { get; set; } public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } - public string Url { get; set; } // url with format [symbol], {0} = start timestamp, {1} = end timestamp + public string Url { get; set; } // url with format [marketSymbol], {0} = start timestamp, {1} = end timestamp public int DelayMilliseconds { get; set; } = 1000; public TimeSpan BlockTime { get; set; } = TimeSpan.FromHours(1.0); // how much time to move for each block of data, default 1 hour public bool MillisecondGranularity { get; set; } = true; @@ -62,9 +62,9 @@ public async Task ProcessHistoricalTrades() throw new ArgumentException("Missing required parameter", nameof(Url)); } - Symbol = api.NormalizeSymbol(Symbol); + MarketSymbol = api.NormalizeMarketSymbol(MarketSymbol); string url; - Url = Url.Replace("[symbol]", Symbol); + Url = Url.Replace("[marketSymbol]", MarketSymbol); List trades = new List(); ExchangeTrade trade; EndDate = (EndDate ?? CryptoUtility.UtcNow); diff --git a/ExchangeSharp/API/Exchanges/_Base/ExchangeLogger.cs b/ExchangeSharp/API/Exchanges/_Base/ExchangeLogger.cs index aa9029d4..d7c6a3e5 100644 --- a/ExchangeSharp/API/Exchanges/_Base/ExchangeLogger.cs +++ b/ExchangeSharp/API/Exchanges/_Base/ExchangeLogger.cs @@ -58,15 +58,15 @@ private BinaryWriter CreateLogWriter(string path, bool compress) /// Constructor /// /// API - /// The symbol to log, i.e. btcusd + /// The symbol to log, i.e. btcusd /// Interval in seconds between updates /// The path to write the log files to /// Whether to compress the log files using gzip compression - public ExchangeLogger(IExchangeAPI api, string symbol, float intervalSeconds, string path, bool compress = false) + public ExchangeLogger(IExchangeAPI api, string marketSymbol, float intervalSeconds, string path, bool compress = false) { string compressExtension = (compress ? ".gz" : string.Empty); API = api; - Symbol = symbol; + MarketSymbol = marketSymbol; Interval = TimeSpan.FromSeconds(intervalSeconds); sysTimeWriter = CreateLogWriter(Path.Combine(path, api.Name + "_time.bin" + compressExtension), compress); tickerWriter = CreateLogWriter(Path.Combine(path, api.Name + "_ticker.bin" + compressExtension), compress); @@ -84,7 +84,7 @@ public void Update() try { - if (Symbol == "*") + if (MarketSymbol == "*") { // get all symbols Tickers = API.GetTickersAsync().Sync().ToArray(); @@ -98,9 +98,9 @@ public void Update() else { // make API calls first, if they fail we will try again later - Tickers = new KeyValuePair[1] { new KeyValuePair(Symbol, API.GetTickerAsync(Symbol).Sync()) }; - OrderBook = API.GetOrderBookAsync(Symbol).Sync(); - Trades = API.GetRecentTradesAsync(Symbol).Sync().OrderBy(t => t.Timestamp).ToArray(); + Tickers = new KeyValuePair[1] { new KeyValuePair(MarketSymbol, API.GetTickerAsync(MarketSymbol).Sync()) }; + OrderBook = API.GetOrderBookAsync(MarketSymbol).Sync(); + Trades = API.GetRecentTradesAsync(MarketSymbol).Sync().OrderBy(t => t.Timestamp).ToArray(); // all API calls succeeded, we can write to files @@ -303,7 +303,7 @@ public static IEnumerable> ReadMultiTickers(s /// /// The symbol being logged /// - public string Symbol { get; private set; } + public string MarketSymbol { get; private set; } /// /// The interval in between log calls diff --git a/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs b/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs index a91878df..5076de0d 100644 --- a/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs +++ b/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs @@ -27,9 +27,9 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider /// /// Normalize a symbol for use on this exchange /// - /// Symbol + /// Symbol /// Normalized symbol - string NormalizeSymbol(string symbol); + string NormalizeMarketSymbol(string marketSymbol); /// /// Convert an exchange symbol into a global symbol, which will be the same for all exchanges. @@ -37,16 +37,16 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider /// Global symbols list the base currency first (i.e. BTC) and conversion currency /// second (i.e. USD). Example BTC-USD, read as x BTC is worth y USD. /// - /// Exchange symbol + /// Exchange symbol /// Global symbol - string ExchangeSymbolToGlobalSymbol(string symbol); + string ExchangeMarketSymbolToGlobalMarketSymbol(string marketSymbol); /// /// Convert a global symbol into an exchange symbol, which will potentially be different from other exchanges. /// - /// Global symbol + /// Global symbol /// Exchange symbol - string GlobalSymbolToExchangeSymbol(string symbol); + string GlobalMarketSymbolToExchangeMarketSymbol(string marketSymbol); /// /// Convert seconds to a period string, or throw exception if seconds invalid. Example: 60 seconds becomes 1m. @@ -81,23 +81,23 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider Task> GetDepositHistoryAsync(string currency); /// - /// Get symbols for the exchange + /// Get symbols for the exchange markets /// /// Symbols - Task> GetSymbolsAsync(); + Task> GetMarketSymbolsAsync(); /// - /// Get exchange symbols including available metadata such as min trade size and whether the market is active + /// Get exchange market symbols including available metadata such as min trade size and whether the market is active /// /// Collection of ExchangeMarkets - Task> GetSymbolsMetadataAsync(); + Task> GetMarketSymbolsMetadataAsync(); /// /// Get latest ticker /// - /// Symbol + /// Symbol /// Latest ticker - Task GetTickerAsync(string symbol); + Task GetTickerAsync(string marketSymbol); /// /// Get all tickers, not all exchanges support this @@ -109,28 +109,28 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider /// Get historical trades for the exchange /// /// Callback for each set of trades. Return false to stop getting trades immediately. - /// Symbol to get historical data for + /// Symbol to get historical data for /// Optional start date time to start getting the historical data at, null for the most recent data. Not all exchanges support this. /// Optional UTC end date time to start getting the historical data at, null for the most recent data. Not all exchanges support this. - Task GetHistoricalTradesAsync(Func, bool> callback, string symbol, DateTime? startDate = null, DateTime? endDate = null); + Task GetHistoricalTradesAsync(Func, bool> callback, string marketSymbol, DateTime? startDate = null, DateTime? endDate = null); /// /// Get the latest trades /// - /// Symbol + /// Market Symbol /// Trades - Task> GetRecentTradesAsync(string symbol); + Task> GetRecentTradesAsync(string marketSymbol); /// /// Get candles (open, high, low, close) /// - /// Symbol to get candles for + /// Market symbol to get candles for /// Period in seconds to get candles for. Use 60 for minute, 3600 for hour, 3600*24 for day, 3600*24*30 for month. /// Optional start date to get candles for /// Optional end date to get candles for /// Max results, can be used instead of startDate and endDate if desired /// Candles - Task> GetCandlesAsync(string symbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null); + Task> GetCandlesAsync(string marketSymbol, int periodSeconds, DateTime? startDate = null, DateTime? endDate = null, int? limit = null); /// /// Get total amounts, symbol / amount dictionary @@ -162,30 +162,31 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider /// Get details of an order /// /// order id + /// Market Symbol /// Order details - Task GetOrderDetailsAsync(string orderId, string symbol = null); + Task GetOrderDetailsAsync(string orderId, string marketSymbol = null); /// /// Get the details of all open orders /// - /// Symbol to get open orders for or null for all + /// Market symbol to get open orders for or null for all /// All open order details for the specified symbol - Task> GetOpenOrderDetailsAsync(string symbol = null); + Task> GetOpenOrderDetailsAsync(string marketSymbol = null); /// /// Get the details of all completed orders /// - /// Symbol to get completed orders for or null for all + /// Market symbol to get completed orders for or null for all /// Only returns orders on or after the specified date/time /// All completed order details for the specified symbol, or all if null symbol - Task> GetCompletedOrderDetailsAsync(string symbol = null, DateTime? afterDate = null); + Task> GetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null); /// /// Cancel an order, an exception is thrown if failure /// /// Order id of the order to cancel - /// Order symbol of the order to cancel (not required for most exchanges) - Task CancelOrderAsync(string orderId, string symbol = null); + /// Market symbol of the order to cancel (not required for most exchanges) + Task CancelOrderAsync(string orderId, string marketSymbol = null); /// /// Get margin amounts available to trade, symbol / amount dictionary @@ -197,16 +198,16 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider /// /// Get open margin position /// - /// Symbol + /// Market Symbol /// Open margin position result - Task GetOpenPositionAsync(string symbol); + Task GetOpenPositionAsync(string marketSymbol); /// /// Close a margin position /// - /// Symbol + /// Market Symbol /// Close margin position result - Task CloseMarginPositionAsync(string symbol); + Task CloseMarginPositionAsync(string marketSymbol); /// /// Get fees @@ -229,9 +230,9 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider /// Get information about trades via web socket /// /// Callback (symbol and trade) - /// Symbols + /// Market symbols /// Web socket, call Dispose to close - IWebSocket GetTradesWebSocket(Action> callback, params string[] symbols); + IWebSocket GetTradesWebSocket(Action> callback, params string[] marketSymbols); /// /// Get the details of all changed orders via web socket diff --git a/ExchangeSharp/API/Exchanges/_Base/Interfaces/IOrderBookProvider.cs b/ExchangeSharp/API/Exchanges/_Base/Interfaces/IOrderBookProvider.cs index 23018f7b..2490cfcf 100644 --- a/ExchangeSharp/API/Exchanges/_Base/Interfaces/IOrderBookProvider.cs +++ b/ExchangeSharp/API/Exchanges/_Base/Interfaces/IOrderBookProvider.cs @@ -25,10 +25,10 @@ public interface IOrderBookProvider /// /// Get pending orders. Depending on the exchange, the number of bids and asks will have different counts, typically 50-100. /// - /// Symbol + /// Symbol /// Max count of bids and asks - not all exchanges will honor this parameter /// Orders - Task GetOrderBookAsync(string symbol, int maxCount = 100); + Task GetOrderBookAsync(string marketSymbol, int maxCount = 100); /// /// Get exchange order book for all symbols. Not all exchanges support this. Depending on the exchange, the number of bids and asks will have different counts, typically 50-100. @@ -42,9 +42,9 @@ public interface IOrderBookProvider /// /// Callback with the full ExchangeOrderBook /// Max count of bids and asks - not all exchanges will honor this parameter - /// Order book symbols or null/empty for all of them (if supported) + /// Market symbols or null/empty for all of them (if supported) /// Web socket, call Dispose to close - IWebSocket GetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] symbols); + IWebSocket GetOrderBookWebSocket(Action callback, int maxCount = 20, params string[] marketSymbols); /// /// What type of web socket order book is provided diff --git a/ExchangeSharp/API/Services/CryptowatchAPI.cs b/ExchangeSharp/API/Services/CryptowatchAPI.cs index 3979f635..db56de21 100644 --- a/ExchangeSharp/API/Services/CryptowatchAPI.cs +++ b/ExchangeSharp/API/Services/CryptowatchAPI.cs @@ -102,12 +102,12 @@ public async Task> GetMarketSummaries() return summaries; } - public async Task GetOrderBookAsync(string exchange, string symbol, int maxCount = 100) + public async Task GetOrderBookAsync(string exchange, string marketSymbol, int maxCount = 100) { await new SynchronizationContextRemover(); ExchangeOrderBook book = new ExchangeOrderBook(); - JToken result = await MakeJsonRequestAsync("/markets/" + exchange.ToLowerInvariant() + "/" + symbol + "/orderbook"); + JToken result = await MakeJsonRequestAsync("/markets/" + exchange.ToLowerInvariant() + "/" + marketSymbol + "/orderbook"); int count = 0; foreach (JArray array in result["asks"]) { diff --git a/ExchangeSharp/Model/ExchangeCloseMarginPositionResult.cs b/ExchangeSharp/Model/ExchangeCloseMarginPositionResult.cs index abb882e4..37ba3310 100644 --- a/ExchangeSharp/Model/ExchangeCloseMarginPositionResult.cs +++ b/ExchangeSharp/Model/ExchangeCloseMarginPositionResult.cs @@ -21,7 +21,7 @@ public class ExchangeCloseMarginPositionResult public bool Success { get; set; } public string Message { get; set; } public bool IsBuy { get; set; } - public string Symbol { get; set; } + public string MarketSymbol { get; set; } public string FeesCurrency { get; set; } public decimal AmountFilled { get; set; } public decimal AveragePrice { get; set; } diff --git a/ExchangeSharp/Model/ExchangeInfo.cs b/ExchangeSharp/Model/ExchangeInfo.cs index 41ba6b28..53110e09 100644 --- a/ExchangeSharp/Model/ExchangeInfo.cs +++ b/ExchangeSharp/Model/ExchangeInfo.cs @@ -27,12 +27,12 @@ public sealed class ExchangeInfo /// Constructor /// /// Exchange API - /// The symbol to trade by default, can be null - public ExchangeInfo(IExchangeAPI api, string symbol = null) + /// The market symbol to trade by default, can be null + public ExchangeInfo(IExchangeAPI api, string marketSymbol = null) { API = api; - Symbols = api.GetSymbolsAsync().Sync().ToArray(); - TradeInfo = new ExchangeTradeInfo(this, symbol); + MarketSymbols = api.GetMarketSymbolsAsync().Sync().ToArray(); + TradeInfo = new ExchangeTradeInfo(this, marketSymbol); } /// @@ -54,9 +54,9 @@ public void Update() public int Id { get; set; } /// - /// Symbols of the exchange + /// Market symbols of the exchange /// - public IReadOnlyCollection Symbols { get; private set; } + public IReadOnlyCollection MarketSymbols { get; private set; } /// /// Latest trade info for the exchange diff --git a/ExchangeSharp/Model/ExchangeMarginPositionResult.cs b/ExchangeSharp/Model/ExchangeMarginPositionResult.cs index 2ed9892c..cce2ae00 100644 --- a/ExchangeSharp/Model/ExchangeMarginPositionResult.cs +++ b/ExchangeSharp/Model/ExchangeMarginPositionResult.cs @@ -18,9 +18,9 @@ namespace ExchangeSharp public class ExchangeMarginPositionResult { /// - /// Symbol + /// Market Symbol /// - public string Symbol { get; set; } + public string MarketSymbol { get; set; } /// /// Amount diff --git a/ExchangeSharp/Model/ExchangeMarket.cs b/ExchangeSharp/Model/ExchangeMarket.cs index 916830db..e9d12d73 100644 --- a/ExchangeSharp/Model/ExchangeMarket.cs +++ b/ExchangeSharp/Model/ExchangeMarket.cs @@ -18,8 +18,8 @@ public sealed class ExchangeMarket /// Id of the market (specific to the exchange), null if none public string MarketId { get; set; } - /// Gets or sets the name of the market. - public string MarketName { get; set; } + /// Gets or sets the symbol representing the market's currency pair. + public string MarketSymbol { get; set; } /// A value indicating whether the market is active. public bool IsActive { get; set; } @@ -69,7 +69,7 @@ public sealed class ExchangeMarket public override string ToString() { - return $"{MarketName}, {BaseCurrency}-{QuoteCurrency}"; + return $"{MarketSymbol}, {BaseCurrency}-{QuoteCurrency}"; } } } \ No newline at end of file diff --git a/ExchangeSharp/Model/ExchangeOrderBook.cs b/ExchangeSharp/Model/ExchangeOrderBook.cs index ea79dc2d..004becce 100644 --- a/ExchangeSharp/Model/ExchangeOrderBook.cs +++ b/ExchangeSharp/Model/ExchangeOrderBook.cs @@ -74,10 +74,10 @@ public sealed class ExchangeOrderBook public long SequenceId { get; set; } /// - /// The symbol. + /// The market symbol. /// This property is not serialized using the ToBinary and FromBinary methods. /// - public string Symbol { get; set; } + public string MarketSymbol { get; set; } /// The last updated UTC public DateTime LastUpdatedUtc { get; set; } = DateTime.MinValue; diff --git a/ExchangeSharp/Model/ExchangeOrderRequest.cs b/ExchangeSharp/Model/ExchangeOrderRequest.cs index e0d1f891..fcd953f1 100644 --- a/ExchangeSharp/Model/ExchangeOrderRequest.cs +++ b/ExchangeSharp/Model/ExchangeOrderRequest.cs @@ -22,9 +22,9 @@ namespace ExchangeSharp public class ExchangeOrderRequest { /// - /// Symbol or pair for the order, i.e. btcusd + /// Market symbol or pair for the order, i.e. btcusd /// - public string Symbol { get; set; } + public string MarketSymbol { get; set; } /// /// Amount to buy or sell diff --git a/ExchangeSharp/Model/ExchangeOrderResult.cs b/ExchangeSharp/Model/ExchangeOrderResult.cs index c42bd098..35666e5a 100644 --- a/ExchangeSharp/Model/ExchangeOrderResult.cs +++ b/ExchangeSharp/Model/ExchangeOrderResult.cs @@ -47,8 +47,8 @@ public sealed class ExchangeOrderResult /// Fill datetime in UTC public DateTime FillDate { get; set; } - /// Symbol. E.g. ADA/ETH - public string Symbol { get; set; } + /// Market Symbol. E.g. ADA/ETH + public string MarketSymbol { get; set; } /// Whether the order is a buy or sell public bool IsBuy { get; set; } @@ -65,9 +65,9 @@ public sealed class ExchangeOrderResult /// Order to append public void AppendOrderWithOrder(ExchangeOrderResult other) { - if ((OrderId != null) && (Symbol != null) && ((OrderId != other.OrderId) || (IsBuy != other.IsBuy) || (Symbol != other.Symbol))) + if ((OrderId != null) && (MarketSymbol != null) && ((OrderId != other.OrderId) || (IsBuy != other.IsBuy) || (MarketSymbol != other.MarketSymbol))) { - throw new InvalidOperationException("Appending orders requires order id, symbol and is buy to match"); + throw new InvalidOperationException("Appending orders requires order id, market symbol and is buy to match"); } decimal tradeSum = Amount + other.Amount; @@ -79,7 +79,7 @@ public void AppendOrderWithOrder(ExchangeOrderResult other) AveragePrice = (AveragePrice * (baseAmount / tradeSum)) + (other.AveragePrice * (other.Amount / tradeSum)); OrderId = other.OrderId; OrderDate = OrderDate == default ? other.OrderDate : OrderDate; - Symbol = other.Symbol; + MarketSymbol = other.MarketSymbol; IsBuy = other.IsBuy; } @@ -87,7 +87,7 @@ public void AppendOrderWithOrder(ExchangeOrderResult other) /// A string that represents this instance. public override string ToString() { - return $"[{OrderDate}], {(IsBuy ? "Buy" : "Sell")} {AmountFilled} of {Amount} {Symbol} {Result} at {AveragePrice}, fees paid {Fees} {FeesCurrency}"; + return $"[{OrderDate}], {(IsBuy ? "Buy" : "Sell")} {AmountFilled} of {Amount} {MarketSymbol} {Result} at {AveragePrice}, fees paid {Fees} {FeesCurrency}"; } } } \ No newline at end of file diff --git a/ExchangeSharp/Model/ExchangeTicker.cs b/ExchangeSharp/Model/ExchangeTicker.cs index 3f04b37d..4ec48e8d 100644 --- a/ExchangeSharp/Model/ExchangeTicker.cs +++ b/ExchangeSharp/Model/ExchangeTicker.cs @@ -34,7 +34,7 @@ public sealed class ExchangeTicker /// /// The currency pair symbol that this ticker is in reference to /// - public string Symbol { get; set; } + public string MarketSymbol { get; set; } /// /// The bid is the price to sell at diff --git a/ExchangeSharp/Model/ExchangeTradeInfo.cs b/ExchangeSharp/Model/ExchangeTradeInfo.cs index a6d09dc9..89242cef 100644 --- a/ExchangeSharp/Model/ExchangeTradeInfo.cs +++ b/ExchangeSharp/Model/ExchangeTradeInfo.cs @@ -27,11 +27,11 @@ public sealed class ExchangeTradeInfo /// Constructor /// /// Exchange info - /// The symbol to trade - public ExchangeTradeInfo(ExchangeInfo info, string symbol) + /// The symbol to trade + public ExchangeTradeInfo(ExchangeInfo info, string marketSymbol) { ExchangeInfo = info; - Symbol = symbol; + MarketSymbol = marketSymbol; } /// @@ -39,8 +39,8 @@ public ExchangeTradeInfo(ExchangeInfo info, string symbol) /// public void Update() { - Ticker = ExchangeInfo.API.GetTickerAsync(Symbol).Sync(); - RecentTrades = ExchangeInfo.API.GetRecentTradesAsync(Symbol).Sync().ToArray(); + Ticker = ExchangeInfo.API.GetTickerAsync(MarketSymbol).Sync(); + RecentTrades = ExchangeInfo.API.GetRecentTradesAsync(MarketSymbol).Sync().ToArray(); if (RecentTrades.Length == 0) { Trade = new Trade(); @@ -49,7 +49,7 @@ public void Update() { Trade = new Trade { Amount = (float)RecentTrades[RecentTrades.Length - 1].Amount, Price = (float)RecentTrades[RecentTrades.Length - 1].Price, Ticks = (long)CryptoUtility.UnixTimestampFromDateTimeMilliseconds(RecentTrades[RecentTrades.Length - 1].Timestamp) }; } - Orders = ExchangeInfo.API.GetOrderBookAsync(Symbol).Sync(); + Orders = ExchangeInfo.API.GetOrderBookAsync(MarketSymbol).Sync(); } /// @@ -78,8 +78,8 @@ public void Update() public Trade Trade { get; set; } /// - /// The current symbol being traded + /// The current market symbol being traded /// - public string Symbol { get; set; } + public string MarketSymbol { get; set; } } } diff --git a/ExchangeSharp/Traders/Trader.cs b/ExchangeSharp/Traders/Trader.cs index 14538a01..c625ff25 100644 --- a/ExchangeSharp/Traders/Trader.cs +++ b/ExchangeSharp/Traders/Trader.cs @@ -82,7 +82,7 @@ private void UpdateAmounts() if (ProductionMode) { var dict = TradeInfo.ExchangeInfo.API.GetAmountsAvailableToTradeAsync().Sync(); - string[] tradeSymbols = TradeInfo.Symbol.Split('_'); + string[] tradeSymbols = TradeInfo.MarketSymbol.Split('_'); dict.TryGetValue(tradeSymbols[1], out decimal itemCount); dict.TryGetValue(tradeSymbols[0], out decimal cashFlow); ItemCount = itemCount; @@ -165,7 +165,7 @@ public decimal PerformBuy(decimal count = -1) IsBuy = true, Price = actualBuyPrice, ShouldRoundAmount = false, - Symbol = TradeInfo.Symbol + MarketSymbol = TradeInfo.MarketSymbol }).Sync(); } else @@ -199,7 +199,7 @@ public decimal PerformSell(decimal count = -1) IsBuy = false, Price = actualSellPrice, ShouldRoundAmount = false, - Symbol = TradeInfo.Symbol + MarketSymbol = TradeInfo.MarketSymbol }).Sync(); } else diff --git a/ExchangeSharp/Traders/TraderExchangeExport.cs b/ExchangeSharp/Traders/TraderExchangeExport.cs index 301293dc..d95ca61a 100644 --- a/ExchangeSharp/Traders/TraderExchangeExport.cs +++ b/ExchangeSharp/Traders/TraderExchangeExport.cs @@ -25,13 +25,13 @@ public static class TraderExchangeExport /// Export exchange data to csv and then to optimized bin files /// /// Exchange api, null to just convert existing csv files - /// Symbol to export + /// Market symbol to export /// Base path to export to, should not contain symbol, symbol will be appended /// Start date to begin export at /// Callback if api is not null to notify of progress - public static void ExportExchangeTrades(IExchangeAPI api, string symbol, string basePath, DateTime sinceDateTime, Action callback = null) + public static void ExportExchangeTrades(IExchangeAPI api, string marketSymbol, string basePath, DateTime sinceDateTime, Action callback = null) { - basePath = Path.Combine(basePath, symbol); + basePath = Path.Combine(basePath, marketSymbol); Directory.CreateDirectory(basePath); sinceDateTime = sinceDateTime.ToUniversalTime(); if (api != null) @@ -62,7 +62,7 @@ bool innerCallback(IEnumerable trades) } return true; } - api.GetHistoricalTradesAsync(innerCallback, symbol, sinceDateTime).Sync(); + api.GetHistoricalTradesAsync(innerCallback, marketSymbol, sinceDateTime).Sync(); writer.Close(); callback?.Invoke(count); } diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs index 1fc0654f..0c805868 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs @@ -36,7 +36,7 @@ public static void RunExample(Dictionary dict) Amount = 0.01m, IsBuy = true, Price = ticker.Ask, - Symbol = "XXBTZUSD" + MarketSymbol = "XXBTZUSD" }).Sync(); // Kraken is a bit funny in that they don't return the order details in the initial request, so you have to follow up with an order details request @@ -49,31 +49,31 @@ public static void RunExample(Dictionary dict) Console.WriteLine("Placed an order on Kraken for 0.01 bitcoin at {0} USD. Status is {1}. Order id is {2}.", ticker.Ask, result.Result, result.OrderId); } - private static string[] GetSymbols(Dictionary dict) + private static string[] GetMarketSymbols(Dictionary dict) { - RequireArgs(dict, "symbols"); - if (dict["symbols"] == "*") + RequireArgs(dict, "marketSymbols"); + if (dict["marketSymbols"] == "*") { return null; } - return dict["symbols"].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + return dict["marketSymbols"].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); } - private static string[] ValidateSymbols(IExchangeAPI api, string[] symbols) + private static string[] ValidateMarketSymbols(IExchangeAPI api, string[] marketSymbols) { - string[] apiSymbols = api.GetSymbolsAsync().Sync().ToArray(); - if (symbols == null || symbols.Length == 0) + string[] apiSymbols = api.GetMarketSymbolsAsync().Sync().ToArray(); + if (marketSymbols == null || marketSymbols.Length == 0) { - symbols = apiSymbols; + marketSymbols = apiSymbols; } - foreach (string symbol in symbols) + foreach (string marketSymbol in marketSymbols) { - if (!apiSymbols.Contains(symbol)) + if (!apiSymbols.Contains(marketSymbol)) { - throw new ArgumentException(string.Format("Symbol {0} does not exist in API {1}, valid symbols: {2}", symbol, api.Name, string.Join(",", apiSymbols.OrderBy(s => s)))); + throw new ArgumentException(string.Format("Symbol {0} does not exist in API {1}, valid symbols: {2}", marketSymbol, api.Name, string.Join(",", apiSymbols.OrderBy(s => s)))); } } - return symbols; + return marketSymbols; } private static void SetWebSocketEvents(IWebSocket socket) @@ -128,10 +128,10 @@ private static void RunWebSocketTickers(Dictionary dict) private static void RunTradesWebSocket(Dictionary dict) { - string[] symbols = GetSymbols(dict); + string[] symbols = GetMarketSymbols(dict); RunWebSocket(dict, (api) => { - symbols = ValidateSymbols(api, symbols); + symbols = ValidateMarketSymbols(api, symbols); return api.GetTradesWebSocket(message => { Console.WriteLine($"{message.Key}: {message.Value}"); @@ -141,16 +141,16 @@ private static void RunTradesWebSocket(Dictionary dict) private static void RunOrderBookWebSocket(Dictionary dict) { - string[] symbols = GetSymbols(dict); + string[] symbols = GetMarketSymbols(dict); RunWebSocket(dict, (api) => { - symbols = ValidateSymbols(api, symbols); + symbols = ValidateMarketSymbols(api, symbols); return ExchangeAPIExtensions.GetFullOrderBookWebSocket(api, message => { //print the top bid and ask with amount var topBid = message.Bids.FirstOrDefault(); var topAsk = message.Asks.FirstOrDefault(); - Console.WriteLine($"[{message.Symbol}:{message.SequenceId}] {topBid.Value.Price} ({topBid.Value.Amount}) | {topAsk.Value.Price} ({topAsk.Value.Amount})"); + Console.WriteLine($"[{message.MarketSymbol}:{message.SequenceId}] {topBid.Value.Price} ({topBid.Value.Amount}) | {topAsk.Value.Price} ({topAsk.Value.Amount})"); }, symbols: symbols); }); } @@ -189,11 +189,11 @@ public static void RunGetSymbolsMetadata(Dictionary dict) try { - var symbols = api.GetSymbolsMetadataAsync().Sync(); + var marketSymbols = api.GetMarketSymbolsMetadataAsync().Sync(); - foreach (var symbol in symbols) + foreach (var marketSymbol in marketSymbols) { - Console.WriteLine(symbol); + Console.WriteLine(marketSymbol); } Console.WriteLine("Press any key to quit."); @@ -206,7 +206,7 @@ public static void RunGetSymbolsMetadata(Dictionary dict) } } - public static void RunGetSymbols(Dictionary dict) + public static void RunGetMarketSymbols(Dictionary dict) { RequireArgs(dict, "exchangeName"); using (var api = ExchangeAPI.GetExchangeAPI(dict["exchangeName"])) @@ -218,11 +218,11 @@ public static void RunGetSymbols(Dictionary dict) try { - var symbols = api.GetSymbolsAsync().Sync(); + var marketSymbols = api.GetMarketSymbolsAsync().Sync(); - foreach (var symbol in symbols) + foreach (var marketSymbol in marketSymbols) { - Console.WriteLine(symbol); + Console.WriteLine(marketSymbol); } Console.WriteLine("Press any key to quit."); @@ -248,13 +248,13 @@ public static void RunGetTickers(Dictionary dict) try { IEnumerable> tickers; - if (dict.ContainsKey("symbol")) + if (dict.ContainsKey("marketSymbol")) { - var symbol = dict["symbol"]; - var ticker = api.GetTickerAsync(symbol).Sync(); + var marketSymbol = dict["marketSymbol"]; + var ticker = api.GetTickerAsync(marketSymbol).Sync(); tickers = new List>() { - new KeyValuePair(symbol, ticker) + new KeyValuePair(marketSymbol, ticker) }; } else @@ -279,7 +279,7 @@ public static void RunGetTickers(Dictionary dict) public static void RunGetCandles(Dictionary dict) { - RequireArgs(dict, "exchangeName", "symbol"); + RequireArgs(dict, "exchangeName", "marketSymbol"); using (var api = ExchangeAPI.GetExchangeAPI(dict["exchangeName"])) { if (api == null) @@ -289,8 +289,8 @@ public static void RunGetCandles(Dictionary dict) try { - var symbol = dict["symbol"]; - var candles = api.GetCandlesAsync(symbol, 1800, DateTime.UtcNow.AddDays(-12), DateTime.UtcNow).Sync(); + var marketSymbol = dict["marketSymbol"]; + var candles = api.GetCandlesAsync(marketSymbol, 1800, DateTime.UtcNow.AddDays(-12), DateTime.UtcNow).Sync(); foreach (var candle in candles) { diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs index eb8c5d69..4cd56485 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_ExchangeTests.cs @@ -87,14 +87,14 @@ bool histTradeCallback(IEnumerable tradeEnum) // test all public API for each exchange try { - string symbol = api.NormalizeSymbol(GetSymbol(api)); + string marketSymbol = api.NormalizeMarketSymbol(GetSymbol(api)); if (functionRegex == null || Regex.IsMatch("symbol", functionRegex, RegexOptions.IgnoreCase)) { Console.Write("Test {0} GetSymbolsAsync... ", api.Name); - IReadOnlyCollection symbols = api.GetSymbolsAsync().Sync().ToArray(); - Assert(symbols != null && symbols.Count != 0 && symbols.Contains(symbol, StringComparer.OrdinalIgnoreCase)); - Console.WriteLine($"OK (default: {symbol}; {symbols.Count} symbols)"); + IReadOnlyCollection symbols = api.GetMarketSymbolsAsync().Sync().ToArray(); + Assert(symbols != null && symbols.Count != 0 && symbols.Contains(marketSymbol, StringComparer.OrdinalIgnoreCase)); + Console.WriteLine($"OK (default: {marketSymbol}; {symbols.Count} symbols)"); } if (functionRegex == null || Regex.IsMatch("orderbook", functionRegex, RegexOptions.IgnoreCase)) @@ -102,7 +102,7 @@ bool histTradeCallback(IEnumerable tradeEnum) try { Console.Write("Test {0} GetOrderBookAsync... ", api.Name); - var book = api.GetOrderBookAsync(symbol).Sync(); + var book = api.GetOrderBookAsync(marketSymbol).Sync(); Assert(book.Asks.Count != 0 && book.Bids.Count != 0 && book.Asks.First().Value.Amount > 0m && book.Asks.First().Value.Price > 0m && book.Bids.First().Value.Amount > 0m && book.Bids.First().Value.Price > 0m); Console.WriteLine($"OK ({book.Asks.Count} asks, {book.Bids.Count} bids)"); @@ -118,7 +118,7 @@ bool histTradeCallback(IEnumerable tradeEnum) try { Console.Write("Test {0} GetTickerAsync... ", api.Name); - var ticker = api.GetTickerAsync(symbol).Sync(); + var ticker = api.GetTickerAsync(marketSymbol).Sync(); Assert(ticker != null && ticker.Ask > 0m && ticker.Bid > 0m && ticker.Last > 0m && ticker.Volume != null && ticker.Volume.QuoteCurrencyVolume > 0m && ticker.Volume.BaseCurrencyVolume > 0m); Console.WriteLine($"OK (ask: {ticker.Ask}, bid: {ticker.Bid}, last: {ticker.Last})"); @@ -134,12 +134,12 @@ bool histTradeCallback(IEnumerable tradeEnum) try { Console.Write("Test {0} GetHistoricalTradesAsync... ", api.Name); - api.GetHistoricalTradesAsync(histTradeCallback, symbol).Sync(); + api.GetHistoricalTradesAsync(histTradeCallback, marketSymbol).Sync(); Assert(trades.Length != 0 && trades[0].Price > 0m && trades[0].Amount > 0m); Console.WriteLine($"OK ({trades.Length})"); Console.Write("Test {0} GetRecentTradesAsync... ", api.Name); - trades = api.GetRecentTradesAsync(symbol).Sync().ToArray(); + trades = api.GetRecentTradesAsync(marketSymbol).Sync().ToArray(); Assert(trades.Length != 0 && trades[0].Price > 0m && trades[0].Amount > 0m); Console.WriteLine($"OK ({trades.Length} trades)"); } @@ -154,7 +154,7 @@ bool histTradeCallback(IEnumerable tradeEnum) try { Console.Write("Test {0} GetCandlesAsync... ", api.Name); - var candles = api.GetCandlesAsync(symbol, 86400, CryptoUtility.UtcNow.Subtract(TimeSpan.FromDays(7.0)), null).Sync().ToArray(); + var candles = api.GetCandlesAsync(marketSymbol, 86400, CryptoUtility.UtcNow.Subtract(TimeSpan.FromDays(7.0)), null).Sync().ToArray(); Assert(candles.Length != 0 && candles[0].ClosePrice > 0m && candles[0].HighPrice > 0m && candles[0].LowPrice > 0m && candles[0].OpenPrice > 0m && candles[0].HighPrice >= candles[0].LowPrice && candles[0].HighPrice >= candles[0].ClosePrice && candles[0].HighPrice >= candles[0].OpenPrice && !string.IsNullOrWhiteSpace(candles[0].Name) && candles[0].ExchangeName == api.Name && candles[0].PeriodSeconds == 86400 && candles[0].BaseCurrencyVolume > 0.0 && diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Export.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Export.cs index a269b5d0..905957e0 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Export.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Export.cs @@ -20,11 +20,11 @@ public static partial class ExchangeSharpConsoleMain { public static void RunGetHistoricalTrades(Dictionary dict) { - RequireArgs(dict, "exchangeName", "symbol"); + RequireArgs(dict, "exchangeName", "marketSymbol"); string exchangeName = dict["exchangeName"]; IExchangeAPI api = ExchangeAPI.GetExchangeAPI(exchangeName); - string symbol = dict["symbol"]; + string marketSymbol = dict["marketSymbol"]; Console.WriteLine("Showing historical trades for exchange {0}...", exchangeName); DateTime? startDate = null; DateTime? endDate = null; @@ -43,7 +43,7 @@ public static void RunGetHistoricalTrades(Dictionary dict) Console.WriteLine("Trade at timestamp {0}: {1}/{2}/{3}", trade.Timestamp.ToLocalTime(), trade.Id, trade.Price, trade.Amount); } return true; - }, symbol, startDate, endDate).Sync(); + }, marketSymbol, startDate, endDate).Sync(); } public static void RunExportData(Dictionary dict) diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Orders.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Orders.cs index 02810070..3f1c4945 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Orders.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Orders.cs @@ -12,11 +12,11 @@ public static partial class ExchangeSharpConsoleMain { public static void RunGetOrderHistory(Dictionary dict) { - RequireArgs(dict, "exchangeName", "symbol"); + RequireArgs(dict, "exchangeName", "marketSymbol"); string exchangeName = dict["exchangeName"]; IExchangeAPI api = ExchangeAPI.GetExchangeAPI(exchangeName); - string symbol = dict["symbol"]; + string marketSymbol = dict["marketSymbol"]; Authenticate(api); @@ -26,7 +26,7 @@ public static void RunGetOrderHistory(Dictionary dict) startDate = DateTime.Parse(dict["startDate"]).ToUniversalTime(); } - var completedOrders = api.GetCompletedOrderDetailsAsync(symbol, startDate).Sync(); + var completedOrders = api.GetCompletedOrderDetailsAsync(marketSymbol, startDate).Sync(); foreach (var completedOrder in completedOrders) { Console.WriteLine(completedOrder); @@ -46,13 +46,13 @@ public static void RunGetOrderDetails(Dictionary dict) Authenticate(api); - string symbol = null; - if (dict.ContainsKey("symbol")) + string marketSymbol = null; + if (dict.ContainsKey("marketSymbol")) { - symbol = dict["symbol"]; + marketSymbol = dict["marketSymbol"]; } - var orderDetails = api.GetOrderDetailsAsync(orderId, symbol).Sync(); + var orderDetails = api.GetOrderDetailsAsync(orderId, marketSymbol).Sync(); Console.WriteLine(orderDetails); Console.Write("Press enter to exit.."); diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Stats.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Stats.cs index a9647507..1dd1782e 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Stats.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Stats.cs @@ -22,8 +22,8 @@ public static partial class ExchangeSharpConsoleMain { public static void RunShowExchangeStats(Dictionary dict) { - string symbol = "BTC-USD"; - string symbol2 = "XXBTZUSD"; + string marketSymbol = "BTC-USD"; + string marketSymbol2 = "XXBTZUSD"; IExchangeAPI apiCoinbase = new ExchangeCoinbaseAPI(); IExchangeAPI apiGemini = new ExchangeGeminiAPI(); IExchangeAPI apiKraken = new ExchangeKrakenAPI(); @@ -31,29 +31,29 @@ public static void RunShowExchangeStats(Dictionary dict) while (true) { - ExchangeTicker ticker = apiCoinbase.GetTickerAsync(symbol).Sync(); - ExchangeOrderBook orders = apiCoinbase.GetOrderBookAsync(symbol).Sync(); + ExchangeTicker ticker = apiCoinbase.GetTickerAsync(marketSymbol).Sync(); + ExchangeOrderBook orders = apiCoinbase.GetOrderBookAsync(marketSymbol).Sync(); decimal askAmountSum = orders.Asks.Values.Sum(o => o.Amount); decimal askPriceSum = orders.Asks.Values.Sum(o => o.Price); decimal bidAmountSum = orders.Bids.Values.Sum(o => o.Amount); decimal bidPriceSum = orders.Bids.Values.Sum(o => o.Price); - ExchangeTicker ticker2 = apiGemini.GetTickerAsync(symbol).Sync(); - ExchangeOrderBook orders2 = apiGemini.GetOrderBookAsync(symbol).Sync(); + ExchangeTicker ticker2 = apiGemini.GetTickerAsync(marketSymbol).Sync(); + ExchangeOrderBook orders2 = apiGemini.GetOrderBookAsync(marketSymbol).Sync(); decimal askAmountSum2 = orders2.Asks.Values.Sum(o => o.Amount); decimal askPriceSum2 = orders2.Asks.Values.Sum(o => o.Price); decimal bidAmountSum2 = orders2.Bids.Values.Sum(o => o.Amount); decimal bidPriceSum2 = orders2.Bids.Values.Sum(o => o.Price); - ExchangeTicker ticker3 = apiKraken.GetTickerAsync(symbol2).Sync(); - ExchangeOrderBook orders3 = apiKraken.GetOrderBookAsync(symbol2).Sync(); + ExchangeTicker ticker3 = apiKraken.GetTickerAsync(marketSymbol2).Sync(); + ExchangeOrderBook orders3 = apiKraken.GetOrderBookAsync(marketSymbol2).Sync(); decimal askAmountSum3 = orders3.Asks.Values.Sum(o => o.Amount); decimal askPriceSum3 = orders3.Asks.Values.Sum(o => o.Price); decimal bidAmountSum3 = orders3.Bids.Values.Sum(o => o.Amount); decimal bidPriceSum3 = orders3.Bids.Values.Sum(o => o.Price); - ExchangeTicker ticker4 = apiBitfinex.GetTickerAsync(symbol).Sync(); - ExchangeOrderBook orders4 = apiBitfinex.GetOrderBookAsync(symbol).Sync(); + ExchangeTicker ticker4 = apiBitfinex.GetTickerAsync(marketSymbol).Sync(); + ExchangeOrderBook orders4 = apiBitfinex.GetOrderBookAsync(marketSymbol).Sync(); decimal askAmountSum4 = orders4.Asks.Values.Sum(o => o.Amount); decimal askPriceSum4 = orders4.Asks.Values.Sum(o => o.Price); decimal bidAmountSum4 = orders4.Bids.Values.Sum(o => o.Amount); diff --git a/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs b/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs index b38ecc3c..cb9cab9c 100644 --- a/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs +++ b/ExchangeSharpConsole/ExchangeSharpConsole_Main.cs @@ -138,7 +138,7 @@ public static int ConsoleMain(string[] args) } else if (argsDictionary.ContainsKey("symbols")) { - RunGetSymbols(argsDictionary); + RunGetMarketSymbols(argsDictionary); } else if (argsDictionary.ContainsKey("tickers")) { diff --git a/ExchangeSharpTests/ExchangeBinanceAPITests.cs b/ExchangeSharpTests/ExchangeBinanceAPITests.cs index e4e0f0fa..dc59ccbc 100644 --- a/ExchangeSharpTests/ExchangeBinanceAPITests.cs +++ b/ExchangeSharpTests/ExchangeBinanceAPITests.cs @@ -129,7 +129,7 @@ private static void ValidateDiff(MarketDepthDiffUpdate diff) { diff.EventType.Should().Be("depthUpdate"); diff.EventTime.Should().Be(123456789); - diff.Symbol.Should().Be("BNBBTC"); + diff.MarketSymbol.Should().Be("BNBBTC"); diff.FirstUpdate.Should().Be(157); diff.FinalUpdate.Should().Be(160); diff.Bids[0][0].Should().Be("0.0024"); diff --git a/ExchangeSharpTests/ExchangePoloniexAPITests.cs b/ExchangeSharpTests/ExchangePoloniexAPITests.cs index eb3b8e5b..02fa6c1b 100644 --- a/ExchangeSharpTests/ExchangePoloniexAPITests.cs +++ b/ExchangeSharpTests/ExchangePoloniexAPITests.cs @@ -112,7 +112,7 @@ public void ReturnOrderTrades_Sell_HasCorrectValues() order.OrderId.Should().BeNullOrEmpty(); order.AveragePrice.Should().Be(0.0001716132563851949140701411m); order.Price.Should().Be(order.AveragePrice); - order.Symbol.Should().Be("BTC_VIA"); + order.MarketSymbol.Should().Be("BTC_VIA"); } [TestMethod] @@ -128,7 +128,7 @@ public void ReturnOrderTrades_Buy_HasCorrectValues() order.IsBuy.Should().BeTrue(); order.Fees.Should().Be(28.64470495m); order.FeesCurrency.Should().Be("XEM"); - order.Symbol.Should().Be("BTC_XEM"); + order.MarketSymbol.Should().Be("BTC_XEM"); order.Price.Should().Be(0.00005128m); order.AveragePrice.Should().Be(0.00005128m); } @@ -241,7 +241,7 @@ public void GetOrderDetails_HappyPath() order.IsBuy.Should().BeTrue(); order.Fees.Should().Be(28.64470495m); order.FeesCurrency.Should().Be("XEM"); - order.Symbol.Should().Be("BTC_XEM"); + order.MarketSymbol.Should().Be("BTC_XEM"); order.Price.Should().Be(0.00005128m); order.AveragePrice.Should().Be(0.00005128m); order.Result.Should().Be(ExchangeAPIOrderResult.Filled); @@ -293,7 +293,7 @@ public void GetCompletedOrderDetails_AllSymbols() // {"BTC_MAID": [ { "globalTradeID": 29251512, "tradeID": "1385888", "date": "2016-05-03 01:29:55", "rate": "0.00014243", "amount": "353.74692925", "total": "0.05038417", "fee": "0.00200000", "orderNumber": "12603322113", "type": "buy", "category": "settlement" }, { "globalTradeID": 29251511, "tradeID": "1385887", "date": "2016-05-03 01:29:55", "rate": "0.00014111", "amount": "311.24262497", "total": "0.04391944", "fee": "0.00200000", "orderNumber": "12603319116", "type": "sell", "category": "marginTrade" } var polo = CreatePoloniexAPI(GetCompletedOrderDetails_AllSymbolsOrders); ExchangeOrderResult order = polo.GetCompletedOrderDetailsAsync().Sync().First(); - order.Symbol.Should().Be("BTC_MAID"); + order.MarketSymbol.Should().Be("BTC_MAID"); order.OrderId.Should().Be("12603322113"); order.OrderDate.Should().Be(new DateTime(2016, 5, 3, 1, 29, 55)); order.AveragePrice.Should().Be(0.00014243m); diff --git a/ExchangeSharpTests/ExchangeTests.cs b/ExchangeSharpTests/ExchangeTests.cs index 708d14b8..8e36f3ad 100644 --- a/ExchangeSharpTests/ExchangeTests.cs +++ b/ExchangeSharpTests/ExchangeTests.cs @@ -37,7 +37,7 @@ private string GetAllSymbolsJson() Dictionary allSymbols = new Dictionary(); foreach (IExchangeAPI api in ExchangeAPI.GetExchangeAPIs()) { - allSymbols[api.Name] = api.GetSymbolsAsync().Sync().ToArray(); + allSymbols[api.Name] = api.GetMarketSymbolsAsync().Sync().ToArray(); } return JsonConvert.SerializeObject(allSymbols); } @@ -45,8 +45,8 @@ private string GetAllSymbolsJson() [TestMethod] public void GlobalSymbolTest() { - string globalSymbol = "BTC-ETH"; - string globalSymbolAlt = "KRW-BTC"; // WTF Bitthumb... + string globalMarketSymbol = "BTC-ETH"; + string globalMarketSymbolAlt = "KRW-BTC"; // WTF Bitthumb... Dictionary allSymbols = JsonConvert.DeserializeObject>(Resources.AllSymbolsJson); // sanity test that all exchanges return the same global symbol when converted back and forth @@ -55,11 +55,11 @@ public void GlobalSymbolTest() try { bool isBithumb = (api.Name == ExchangeName.Bithumb); - string exchangeSymbol = api.GlobalSymbolToExchangeSymbol(isBithumb ? globalSymbolAlt : globalSymbol); - string globalSymbol2 = api.ExchangeSymbolToGlobalSymbol(exchangeSymbol); - if ((!isBithumb && globalSymbol2.EndsWith("-BTC")) || - globalSymbol2.EndsWith("-USD") || - globalSymbol2.EndsWith("-USDT")) + string exchangeMarketSymbol = api.GlobalMarketSymbolToExchangeMarketSymbol(isBithumb ? globalMarketSymbolAlt : globalMarketSymbol); + string globalMarketSymbol2 = api.ExchangeMarketSymbolToGlobalMarketSymbol(exchangeMarketSymbol); + if ((!isBithumb && globalMarketSymbol2.EndsWith("-BTC")) || + globalMarketSymbol2.EndsWith("-USD") || + globalMarketSymbol2.EndsWith("-USDT")) { Assert.Fail($"Exchange {api.Name} has wrong SymbolIsReversed parameter"); } @@ -71,13 +71,13 @@ public void GlobalSymbolTest() "then apply this new string to Resources.AllSymbolsJson"); } string[] symbols = allSymbols[api.Name]; - Assert.IsTrue(symbols.Contains(exchangeSymbol), "Symbols does not contain exchange symbol"); + Assert.IsTrue(symbols.Contains(exchangeMarketSymbol), "Symbols does not contain exchange symbol"); } catch { Assert.Fail("Error getting symbols"); } - Assert.IsTrue(globalSymbol == globalSymbol2 || globalSymbolAlt == globalSymbol2); + Assert.IsTrue(globalMarketSymbol == globalMarketSymbol2 || globalMarketSymbolAlt == globalMarketSymbol2); } catch (NotImplementedException) { diff --git a/README.md b/README.md index 18f2cbbf..ee292ecc 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ExchangeSharp is a C# console app and framework for trading and communicating wi ### Features - Many exchanges supported with public, private and web socket API - Easy to use and well documented code and API -- Optional global symbol normalization, since each exchange has their own way of doing symbols +- Optional global market symbol normalization, since each exchange has their own way of doing market symbols - Runs anywhere .NET core will run (Windows 8.1 or newer, MAC, Linux, iOS, Android, Unity 2018+, etc.) ### Exchanges @@ -41,7 +41,7 @@ The following cryptocurrency services are supported: - Cryptowatch (partial) ### Notes -ExchangeSharp uses 'symbol' to refer to markets, or pairs of currencies. +ExchangeSharp uses 'marketSymbol' to refer to markets, or pairs of currencies. Please send pull requests if you have made a change that you feel is worthwhile, want a bug fixed or want a new feature. You can also donate to get new features. @@ -82,7 +82,7 @@ ExchangeOrderResult result = api.PlaceOrderAsync(new ExchangeOrderRequest Amount = 0.01m, IsBuy = true, Price = ticker.Ask, - Symbol = "XXBTZUSD" + MarketSymbol = "XXBTZUSD" }).Sync(); // Kraken is a bit funny in that they don't return the order details in the initial request, so you have to follow up with an order details request From c9047cbdac361bf98ece5ea9ac755274993e1ddb Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 24 Oct 2018 14:30:48 -0500 Subject: [PATCH 8/8] Fix build errors after merge --- .../API/Exchanges/Kucoin/ExchangeKucoinAPI.cs | 14 +++++++------- .../Console/ExchangeSharpConsole_Example.cs | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs b/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs index cf16b504..190a3dad 100644 --- a/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs +++ b/ExchangeSharp/API/Exchanges/Kucoin/ExchangeKucoinAPI.cs @@ -395,7 +395,7 @@ protected override async Task OnWithdrawAsync(Exchan #region Websockets - protected override IWebSocket OnGetTickersWebSocket(Action>> callback, params string[] symbols) + protected override IWebSocket OnGetTickersWebSocket(Action>> callback, params string[] marketSymbols) { var websocketUrlToken = GetWebsocketBulletToken(); return ConnectWebSocket( @@ -405,21 +405,21 @@ protected override IWebSocket OnGetTickersWebSocket(Action() == "message") { var dataToken = token["data"]; - var symbol = dataToken["symbol"].ToStringInvariant(); - ExchangeTicker ticker = this.ParseTicker(dataToken, symbol, "sell", "buy", "lastDealPrice", "vol", "volValue", "datetime", TimestampType.UnixMilliseconds); - callback(new List>() {new KeyValuePair(symbol, ticker)}); + var marketSymbol = dataToken["symbol"].ToStringInvariant(); + ExchangeTicker ticker = this.ParseTicker(dataToken, marketSymbol, "sell", "buy", "lastDealPrice", "vol", "volValue", "datetime", TimestampType.UnixMilliseconds); + callback(new List>() {new KeyValuePair(marketSymbol, ticker)}); } return Task.CompletedTask; }, async (_socket) => { //need to subscribe to tickers one by one - symbols = symbols == null || symbols.Length == 0 ? (await GetSymbolsAsync()).ToArray() : symbols; + marketSymbols = marketSymbols == null || marketSymbols.Length == 0 ? (await GetMarketSymbolsAsync()).ToArray() : marketSymbols; var id = DateTime.UtcNow.Ticks; - foreach (var symbol in symbols) + foreach (var marketSymbol in marketSymbols) { // subscribe to tick topic - await _socket.SendMessageAsync(new {id = id++, type = "subscribe", topic = $"/market/{symbol}_TICK" }); + await _socket.SendMessageAsync(new {id = id++, type = "subscribe", topic = $"/market/{marketSymbol}_TICK" }); } } ); diff --git a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs index dd50b191..b8778c68 100644 --- a/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs +++ b/ExchangeSharpConsole/Console/ExchangeSharpConsole_Example.cs @@ -118,11 +118,11 @@ private static void RunWebSocket(Dictionary dict, Func dict) { - string[] symbols = GetSymbols(dict, false); + string[] symbols = GetMarketSymbols(dict, false); RunWebSocket(dict, (api) => { if(symbols != null) - symbols = ValidateSymbols(api, symbols); + symbols = ValidateMarketSymbols(api, symbols); return api.GetTickersWebSocket( freshTickers => {