/// <inheritdoc /> public override ResponseObject CancelOrder(TradingPair pair, long orderId) { var client = _communications.Client; var query = client.CancelOrder( symbol: pair.ToString(), orderId: orderId, origClientOrderId: null, newClientOrderId: null, receiveWindow: _communications.ReceiveWindow); return(query.Success ? new ResponseObject(ResponseCode.Success) : new ResponseObject(BinanceUtilities.ToInternalError(query.Error.Code), query.Error.Message)); }
// SubmitOrder public async Task <SubmitOrder> SubmitOrder(string currency, TradingPair tradingPair, OrderType orderType, double amount, double price) { string market = String.Format("{0}_{1}", currency, tradingPair.ToString()); using (var client = new HttpClient()) { // create the URL string. string endpoint = "api/private/submitOrder"; // JSON POST parameters JObject jObject = new JObject(); jObject["Market"] = market; jObject["Type"] = orderType.ToString(); jObject["Amount"] = amount; jObject["Price"] = price; string postParams = jObject.ToString(Formatting.None, null); // Http Client params SetHttpClientPropertiesPrivate(client, endpoint, postParams); // make the request var content = new StringContent(postParams, Encoding.UTF8, "application/json"); var response = await client.PostAsync(endpoint, content); // parse the response and return the data. var jsonResponseString = await response.Content.ReadAsStringAsync(); SubmitOrderEntity submitOrderEntity = new SubmitOrderEntity(); try { submitOrderEntity = JsonConvert.DeserializeObject <SubmitOrderEntity>(jsonResponseString); } catch (Exception e) { throw new Exception(_ParseError, e); } // Check success message from server if (submitOrderEntity.Success == false) { throw new Exception(_SuccessError); } return(submitOrderEntity.Result); } }
/// <inheritdoc /> public override ResponseObject <OrderUpdate> ExecuteMarketOrder(TradingPair pair, OrderSide side, decimal quantity, long tradeId) { var client = _communications.Client; var realQuantity = pair.RoundToTradable(quantity); // Attempt to place the order on Binance var query = client.PlaceOrder( symbol: pair.ToString(), side: BinanceUtilities.ToExternal(side), type: OrderType.Market, quantity: realQuantity, newClientOrderId: null, price: null, timeInForce: null, stopPrice: null, icebergQty: null, orderResponseType: null, (int)_communications.ReceiveWindow); // Report failure of placing market order if (!query.Success) { Logger.LogError($"Placing market order {side} {realQuantity} {pair.Left} failed! --> {query.Error.Message}"); return(new ResponseObject <OrderUpdate>(ResponseCode.Error, query.Error.Message)); } var order = query.Data; // Create an order update with known information OrderUpdate result = new OrderUpdate( orderId: order.OrderId, tradeId: tradeId, orderStatus: OrderUpdate.OrderStatus.Filled, orderType: BinanceUtilities.ToInternal(order.Type), createdTimestamp: DateTimeOffset.Now.ToUnixTimeMilliseconds(), setPrice: 0, // This information is unknown for market orders side: side, pair: pair, setQuantity: realQuantity) { FilledQuantity = order.ExecutedQuantity, FilledTimestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(), AverageFilledPrice = HelperMethods.SafeDiv(order.CummulativeQuoteQuantity, order.ExecutedQuantity), }; return(new ResponseObject <OrderUpdate>(ResponseCode.Success, result)); }
// GetTradeHistory public async Task <Order[]> GetTradeHistory(string currency, TradingPair tradingPair, int count, int pageNum) { string market = String.Format("{0}_{1}", currency, tradingPair.ToString()); using (var client = new HttpClient()) { // create the URL string. string endpoint = "api/private/gettradehistory"; // JSON POST parameters JObject jObject = new JObject(); jObject["Market"] = market; jObject["Count"] = count; jObject["PageNumber"] = pageNum; string postParams = jObject.ToString(Formatting.None, null); // Http Client params SetHttpClientPropertiesPrivate(client, endpoint, postParams); // make the request var content = new StringContent(postParams, Encoding.UTF8, "application/json"); var response = await client.PostAsync(endpoint, content); // parse the response and return the data. var jsonResponseString = await response.Content.ReadAsStringAsync(); TradeHistoryEntity tradeHistoryEntity = new TradeHistoryEntity(); try { tradeHistoryEntity = JsonConvert.DeserializeObject <TradeHistoryEntity>(jsonResponseString); } catch (Exception e) { throw new Exception(_ParseError, e); } // Check success message from server if (tradeHistoryEntity.Success == false) { throw new Exception(_SuccessError); } return(tradeHistoryEntity.Result); } }
// GetMarketHistory public async Task <MarketHistory[]> GetMarketHistory(string currency, TradingPair tradingPair, int numRecords) { // Set up parameters string market = String.Format("{0}_{1}", currency, tradingPair.ToString()); string count = numRecords.ToString(); using (var client = new HttpClient()) { SetHttpClientProperties(client); // create the URL string. var url = string.Format("api/public/getmarkethistory?market={0}&count={1}", market, count); // make the request var response = await client.GetAsync(url); // parse the response and return the data. var jsonResponseString = await response.Content.ReadAsStringAsync(); MarketHistoryEntity marketHistoryEntity = new MarketHistoryEntity(); try { marketHistoryEntity = JsonConvert.DeserializeObject <MarketHistoryEntity>(jsonResponseString); } catch (Exception e) { throw new Exception(_ParseError, e); } // Check success message from server if (marketHistoryEntity.Success == false) { throw new Exception(_SuccessError); } return(marketHistoryEntity.Result); } }
// GetTicker public async Task <Ticker> GetTicker(string currency, TradingPair tradingPair) { string market = String.Format("{0}_{1}", currency, tradingPair.ToString()); using (var client = new HttpClient()) { SetHttpClientProperties(client); // create the URL string. var url = string.Format("api/public/getticker?market={0}", market); // make the request var response = await client.GetAsync(url); // parse the response and return the data. var jsonResponseString = await response.Content.ReadAsStringAsync(); TickerEntity tickerEntity = new TickerEntity(); try { tickerEntity = JsonConvert.DeserializeObject <TickerEntity>(jsonResponseString); } catch (Exception e) { throw new Exception(_ParseError, e); } // Check success message from server if (tickerEntity.Success == false) { throw new Exception(_SuccessError); } return(tickerEntity.Result); } }
// GetOrderBook public async Task <OrderBook> GetOrderBook(string currency, TradingPair tradingPair, OrderType orderType, int depth) { string market = String.Format("{0}_{1}", currency, tradingPair.ToString()); using (var client = new HttpClient()) { SetHttpClientProperties(client); // create the URL string. var url = string.Format("api/public/getorderbook?market={0}&type={1}&depth={2}", market, orderType.ToString(), depth); // make the request var response = await client.GetAsync(url); // parse the response and return the data. var jsonResponseString = await response.Content.ReadAsStringAsync(); OrderBookEntity orderBook = new OrderBookEntity(); try { orderBook = JsonConvert.DeserializeObject <OrderBookEntity>(jsonResponseString); } catch (Exception e) { throw new Exception(_ParseError, e); } // Check success message from server if (orderBook.Success == false) { throw new Exception(_SuccessError); } return(orderBook.Result); } }
/// <summary> /// Reconcile ExchangeCommand parameters with supplied and default values, and populate them into the IRestRequest /// </summary> /// <param name="request">Unpopulated IRestRequest</param> /// <param name="command">Reference Command</param> /// <param name="pair">Trading Pair</param> /// <param name="values">Explicitly supplied parameter values</param> private static void PopulateCommandParameters(IRestRequest request, IExchangeCommand command, TradingPair pair, IDictionary <StandardParameter, string> values) { foreach (var param in command.Parameters) { var parameter = param.Value; string value; switch (parameter.StandardParameterIdentifier) { case StandardParameter.Price: case StandardParameter.Amount: case StandardParameter.Id: case StandardParameter.Timestamp: case StandardParameter.Limit: value = values[parameter.StandardParameterIdentifier]; break; case StandardParameter.Base: value = pair.BaseCurrency.ToString(); break; case StandardParameter.Counter: value = pair.CounterCurrency.ToString(); break; case StandardParameter.Currency: value = pair.BaseCurrency.ToString(); break; case StandardParameter.CurrencyFullName: value = pair.BaseCurrency.GetDescription(); break; case StandardParameter.Pair: value = pair.ToString(); break; case StandardParameter.UnixTimestamp: value = DateTime.UtcNow.AddHours(-1).ToUnixTime().ToStringInvariant(); break; case StandardParameter.None: value = parameter.DefaultValue; break; default: value = string.Empty; break; } var parameterType = ParameterType.GetOrPost; if (parameter.ParameterMethod == ParameterMethod.Url) { parameterType = ParameterType.UrlSegment; } else if (parameter.ParameterMethod == ParameterMethod.QueryString) { parameterType = ParameterType.QueryString; } request.AddParameter(parameter.ExchangeParameterName, value, parameterType); } }
/// <inheritdoc /> public override ResponseObject <OrderUpdate> PlaceStoplossOrder(TradingPair pair, OrderSide side, decimal quantity, decimal price, long tradeId) { var client = _communications.Client; decimal limitPrice; if (side == OrderSide.Sell) { // Set the limit price extremely low -> sell immediately for the best price. // 5% is an arbitrary number that is probably more than the spread, but is not // rejected by Binance for deviating too much from the current price. limitPrice = price * 0.95M; } else { // Skew the quantity and the price -> buy immediately for the best price. // Quantity must scale inverse because (quantity * price) is the amount that needs to // be locked. You cannot lock more assets than you have. // 2% is hardcoded on purpose because it is unlikely to change. limitPrice = price * 1.02M; quantity /= 1.02M; } var realQuantity = pair.RoundToTradable(quantity); var realLimitPrice = pair.RoundToPriceable(limitPrice); var realStopPrice = pair.RoundToPriceable(price); lock (_orderCache) { var query = client.PlaceOrder( symbol: pair.ToString(), side: BinanceUtilities.ToExternal(side), type: OrderType.StopLossLimit, quantity: realQuantity, newClientOrderId: null, price: realLimitPrice, timeInForce: TimeInForce.GoodTillCancel, stopPrice: realStopPrice, icebergQty: null, orderResponseType: null, receiveWindow: (int)_communications.ReceiveWindow); if (query.Success) { var order = new OrderUpdate( query.Data.OrderId, tradeId, OrderUpdate.OrderStatus.New, OrderUpdate.OrderTypes.StopLoss, DateTimeOffset.Now.ToUnixTimeMilliseconds(), realLimitPrice, side, pair, realQuantity) { StopPrice = realStopPrice, }; // Enter middleware instance to make sure this order is // also converted to a stoploss order when the exchange reports updates. _transformMiddleWare.Add(order.OrderId, x => x.OrderType = OrderUpdate.OrderTypes.StopLoss); return(new ResponseObject <OrderUpdate>(order)); } return(ResponseObject.OrderPlacementFailed(BinanceUtilities.ToInternalError(query.Error.Code), query.Error.Message)); } }