Exemplo n.º 1
0
        /// <summary>
        /// Subscribes to updates on a specific market
        /// </summary>
        /// <param name="marketName">The name of the market to subscribe on</param>
        /// <param name="onUpdate">The update event handler</param>
        /// <returns></returns>
        public BittrexApiResult <int> SubscribeToMarketDeltaStream(string marketName, Action <BittrexMarketSummary> onUpdate)
        {
            log.Write(LogVerbosity.Debug, $"Going to subscribe to {marketName}");

            lock (connectionLock)
            {
                if (connection == null || connection.State == ConnectionState.Disconnected)
                {
                    log.Write(LogVerbosity.Debug, "Starting connection to bittrex server");
                    if (!WaitForConnection())
                    {
                        return(ThrowErrorMessage <int>(BittrexErrors.GetError(BittrexErrorKey.CantConnectToServer)));
                    }
                }
            }

            var registration = new BittrexStreamRegistration()
            {
                Callback = onUpdate, MarketName = marketName, StreamId = NextStreamId
            };

            lock (registrationLock)
            {
                registrations.Add(registration);
                localRegistrations.Add(registration);
            }
            return(new BittrexApiResult <int>()
            {
                Result = registration.StreamId, Success = true
            });
        }
Exemplo n.º 2
0
        /// <summary>
        /// Subscribes to updates of all markets
        /// </summary>
        /// <param name="onUpdate">The update event handler</param>
        /// <returns>ApiResult whether subscription was successful. The Result property contains the Stream Id which can be used to unsubscribe the stream again</returns>
        public async Task <BittrexApiResult <int> > SubscribeToAllMarketDeltaStreamAsync(Action <List <BittrexMarketSummary> > onUpdate)
        {
            return(await Task.Run(() =>
            {
                log.Write(LogVerbosity.Debug, $"Going to subscribe to all markets");
                if (!CheckConnection())
                {
                    return ThrowErrorMessage <int>(BittrexErrors.GetError(BittrexErrorKey.CantConnectToServer));
                }

                var registration = new BittrexMarketsAllRegistration()
                {
                    Callback = onUpdate, StreamId = NextStreamId
                };
                lock (registrationLock)
                {
                    registrations.Add(registration);
                    localRegistrations.Add(registration);
                }
                return new BittrexApiResult <int>()
                {
                    Result = registration.StreamId, Success = true
                };
            }).ConfigureAwait(false));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Subscribes to updates on a specific market
        /// </summary>
        /// <param name="marketName">The name of the market to subscribe on</param>
        /// <param name="onUpdate">The update event handler</param>
        /// <returns>ApiResult whether subscription was successful. The Result property contains the Stream Id which can be used to unsubscribe the stream again</returns>
        public async Task <BittrexApiResult <int> > SubscribeToExchangeDeltasAsync(string marketName, Action <BittrexStreamExchangeState> onUpdate)
        {
            return(await Task.Run(() =>
            {
                if (!CheckConnection())
                {
                    return ThrowErrorMessage <int>(BittrexErrors.GetError(BittrexErrorKey.CantConnectToServer));
                }

                // send subscribe to bittrex
                SubscribeToExchangeDeltas(marketName);

                var registration = new BittrexExchangeDeltasRegistration()
                {
                    Callback = onUpdate, MarketName = marketName, StreamId = NextStreamId
                };
                lock (registrationLock)
                {
                    registrations.Add(registration);
                    localRegistrations.Add(registration);
                }
                return new BittrexApiResult <int>()
                {
                    Result = registration.StreamId, Success = true
                };
            }).ConfigureAwait(false));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Gets a list of all balances for the current account
        /// </summary>
        /// <returns>List of balances</returns>
        public async Task <BittrexApiResult <BittrexBalance[]> > GetBalancesAsync()
        {
            if (apiKey == null || encryptor == null)
            {
                return(ThrowErrorMessage <BittrexBalance[]>(BittrexErrors.GetError(BittrexErrorKey.NoApiCredentialsProvided)));
            }

            return(await ExecuteRequest <BittrexBalance[]>(GetUrl(BalancesEndpoint, Api, ApiVersion), true));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Gets the deposit history of the current account
        /// </summary>
        /// <param name="currency">Filter on currency</param>
        /// <returns>List of deposits</returns>
        public async Task <BittrexApiResult <BittrexDeposit[]> > GetDepositHistoryAsync(string currency = null)
        {
            if (apiKey == null || encryptor == null)
            {
                return(ThrowErrorMessage <BittrexDeposit[]>(BittrexErrors.GetError(BittrexErrorKey.NoApiCredentialsProvided)));
            }

            var parameters = new Dictionary <string, string>();

            AddOptionalParameter(parameters, "currency", currency);
            return(await ExecuteRequest <BittrexDeposit[]>(GetUrl(DepositHistoryEndpoint, Api, ApiVersion, parameters), true));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Gets the order history for the current account
        /// </summary>
        /// <param name="market">Filter on market</param>
        /// <returns>List of orders</returns>
        public async Task <BittrexApiResult <BittrexOrderHistoryOrder[]> > GetOrderHistoryAsync(string market = null)
        {
            if (apiKey == null || encryptor == null)
            {
                return(ThrowErrorMessage <BittrexOrderHistoryOrder[]>(BittrexErrors.GetError(BittrexErrorKey.NoApiCredentialsProvided)));
            }

            var parameters = new Dictionary <string, string>();

            AddOptionalParameter(parameters, "market", market);
            return(await ExecuteRequest <BittrexOrderHistoryOrder[]>(GetUrl(OrderHistoryEndpoint, Api, ApiVersion, parameters), true).ConfigureAwait(false));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Gets an order by it's guid
        /// </summary>
        /// <param name="guid">The guid of the order</param>
        /// <returns>The requested order</returns>
        public async Task <BittrexApiResult <BittrexAccountOrder> > GetOrderAsync(Guid guid)
        {
            if (apiKey == null || encryptor == null)
            {
                return(ThrowErrorMessage <BittrexAccountOrder>(BittrexErrors.GetError(BittrexErrorKey.NoApiCredentialsProvided)));
            }

            var parameters = new Dictionary <string, string>()
            {
                { "uuid", guid.ToString() }
            };

            return(await ExecuteRequest <BittrexAccountOrder>(GetUrl(OrderEndpoint, Api, ApiVersion, parameters), true));
        }
Exemplo n.º 8
0
        /// <summary>
        /// Gets the balance of a single currency
        /// </summary>
        /// <param name="currency">Currency to get the balance for</param>
        /// <returns>The balance of the currency</returns>
        public async Task <BittrexApiResult <BittrexBalance> > GetBalanceAsync(string currency)
        {
            if (apiKey == null || encryptor == null)
            {
                return(ThrowErrorMessage <BittrexBalance>(BittrexErrors.GetError(BittrexErrorKey.NoApiCredentialsProvided)));
            }

            var parameters = new Dictionary <string, string>()
            {
                { "currency", currency }
            };

            return(await ExecuteRequest <BittrexBalance>(GetUrl(BalanceEndpoint, Api, ApiVersion, parameters), true));
        }
Exemplo n.º 9
0
        /// <summary>
        /// Places a withdraw request on Bittrex
        /// </summary>
        /// <param name="currency">The currency to withdraw</param>
        /// <param name="quantity">The quantity to withdraw</param>
        /// <param name="address">The address to withdraw to</param>
        /// <param name="paymentId">Optional string identifier to add to the withdraw</param>
        /// <returns>Guid of the withdrawal</returns>
        public async Task <BittrexApiResult <BittrexGuid> > WithdrawAsync(string currency, decimal quantity, string address, string paymentId = null)
        {
            if (apiKey == null || encryptor == null)
            {
                return(ThrowErrorMessage <BittrexGuid>(BittrexErrors.GetError(BittrexErrorKey.NoApiCredentialsProvided)));
            }

            var parameters = new Dictionary <string, string>()
            {
                { "currency", currency },
                { "quantity", quantity.ToString(CultureInfo.InvariantCulture) },
                { "address", address },
            };

            AddOptionalParameter(parameters, "paymentid", paymentId);

            return(await ExecuteRequest <BittrexGuid>(GetUrl(WithdrawEndpoint, Api, ApiVersion, parameters), true));
        }
Exemplo n.º 10
0
        /// <summary>
        /// Places an order
        /// </summary>
        /// <param name="type">Type of the order</param>
        /// <param name="market">Market to place the order on</param>
        /// <param name="quantity">The quantity of the order</param>
        /// <param name="rate">The rate per unit of the order</param>
        /// <returns></returns>
        public async Task <BittrexApiResult <BittrexGuid> > PlaceOrderAsync(OrderType type, string market, decimal quantity, decimal rate)
        {
            if (apiKey == null || encryptor == null)
            {
                return(ThrowErrorMessage <BittrexGuid>(BittrexErrors.GetError(BittrexErrorKey.NoApiCredentialsProvided)));
            }

            var parameters = new Dictionary <string, string>()
            {
                { "market", market },
                { "quantity", quantity.ToString(CultureInfo.InvariantCulture) },
                { "rate", rate.ToString(CultureInfo.InvariantCulture) }
            };

            var uri = GetUrl(type == OrderType.Buy ? BuyLimitEndpoint : SellLimitEndpoint, Api, ApiVersion, parameters);

            return(await ExecuteRequest <BittrexGuid>(uri, true));
        }
Exemplo n.º 11
0
        /// <summary>
        /// get basic/initial info of a specific market
        /// 500 Buys
        /// 100 Fills
        /// 500 Sells
        /// </summary>
        /// <param name="marketName">The name of the market to subscribe on</param>
        /// <param name="onUpdate">The update event handler</param>
        /// <returns>ApiResult whether subscription was successful. The Result property contains the Stream Id which can be used to unsubscribe the stream again</returns>
        public async Task <BittrexApiResult <int> > QueryExchangeStateAsync(string marketName, Action <BittrexExchangeState> onUpdate)
        {
            return(await Task.Run(() =>
            {
                log.Write(LogVerbosity.Debug, $"Going to call QueryExchangeState for market: {marketName}");
                if (!CheckConnection())
                {
                    return ThrowErrorMessage <int>(BittrexErrors.GetError(BittrexErrorKey.CantConnectToServer));
                }


                // gives direkt return -> no subscription
                // https://stackoverflow.com/questions/11140164/signalr-console-app-example
                proxy.Invoke <JObject>("QueryExchangeState", marketName).ContinueWith(task => {
                    if (task.IsFaulted)
                    {
                        log.Write(LogVerbosity.Error, String.Format("There was an error calling send: {0}", task.Exception.GetBaseException()));
                    }
                    else
                    {
                        string json = "";

                        try
                        {
                            json = task.Result.ToString();

                            BittrexExchangeState StreamData = JsonConvert.DeserializeObject <BittrexExchangeState>(json);

                            onUpdate(StreamData);
                        }
                        catch (Exception e)
                        {
                            log.Write(LogVerbosity.Warning, $"Received an event but an unknown error occured. Message: {e.Message}, Received data: {json}");
                        }
                    }
                });

                return new BittrexApiResult <int>()
                {
                    Success = true
                };
            }).ConfigureAwait(false));
        }
Exemplo n.º 12
0
        private async Task <BittrexApiResult <T> > ExecuteRequest <T>(Uri uri, bool signed = false, int currentTry = 0)
        {
            string returnedData = "";

            try
            {
                var uriString = uri.ToString();
                if (signed)
                {
                    if (!uriString.EndsWith("?"))
                    {
                        uriString += "&";
                    }

                    uriString += $"apiKey={apiKey}&nonce={nonce}";
                }

                var request = RequestFactory.Create(uriString);
                if (signed)
                {
                    request.Headers.Add("apisign",
                                        ByteToString(encryptor.ComputeHash(Encoding.UTF8.GetBytes(uriString))));
                }

                foreach (var limiter in rateLimiters)
                {
                    double limitedBy = limiter.LimitRequest(uri.AbsolutePath);
                    if (limitedBy > 0)
                    {
                        log.Write(LogVerbosity.Debug, $"Request {uri.AbsolutePath} was limited by {limitedBy}ms by {limiter.GetType().Name}");
                    }
                }

                log.Write(LogVerbosity.Debug, $"Sending request to {uriString}");
                var response = request.GetResponse();
                using (var reader = new StreamReader(response.GetResponseStream()))
                {
                    returnedData = await reader.ReadToEndAsync();

                    var result = JsonConvert.DeserializeObject <BittrexApiResult <T> >(returnedData);
                    if (!result.Success)
                    {
                        log.Write(LogVerbosity.Debug, $"Call failed to {uri}, Error message: {result.Message}");
                        result.Error   = new BittrexError(6000, result.Message);
                        result.Message = null;
                    }
                    return(result);
                }
            }
            catch (WebException we)
            {
                var response = (HttpWebResponse)we.Response;
                if (currentTry < MaxRetries)
                {
                    return(await ExecuteRequest <T>(uri, signed, ++currentTry));
                }

                return(ThrowErrorMessage <T>(BittrexErrors.GetError(BittrexErrorKey.ErrorWeb), $"Status: {response.StatusCode}-{response.StatusDescription}, Message: {we.Message}"));
            }
            catch (JsonReaderException jre)
            {
                return(ThrowErrorMessage <T>(BittrexErrors.GetError(BittrexErrorKey.ParseErrorReader), $"Error occured at Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}. Received data: {returnedData}"));
            }
            catch (JsonSerializationException jse)
            {
                return(ThrowErrorMessage <T>(BittrexErrors.GetError(BittrexErrorKey.ParseErrorSerialization), $"Message: {jse.Message}. Received data: {returnedData}"));
            }
            catch (Exception e)
            {
                return(ThrowErrorMessage <T>(BittrexErrors.GetError(BittrexErrorKey.UnknownError), $"Message: {e.Message}"));
            }
        }