public async Task <decimal> GetEstimatedAmount(decimal btcAmount, int currencyId)
        {
            if (currencyId == Constant.BITCOIN_ID)
            {
                return(btcAmount);
            }

            var tradePair = await TradePairReader.GetTradePair(currencyId, Constant.BITCOIN_ID).ConfigureAwait(false);

            if (tradePair == null)
            {
                var ltcTradePair = await TradePairReader.GetTradePair(currencyId, Constant.LITECOIN_ID).ConfigureAwait(false);

                var ltcbtcTradePair = await TradePairReader.GetTradePair(Constant.LITECOIN_ID, Constant.BITCOIN_ID).ConfigureAwait(false);

                if (ltcTradePair == null || ltcbtcTradePair == null)
                {
                    return(0);
                }

                return((btcAmount / Math.Max(0.00000001m, ltcTradePair.LastTrade)) * Math.Max(0.00000001m, ltcbtcTradePair.LastTrade));
            }

            return(btcAmount / Math.Max(0.00000001m, tradePair.LastTrade));
        }
        public async Task <decimal> GetNZDPerCoin(int currencyId)
        {
            var cacheResult = await CacheService.GetOrSetHybridValueAsync(CacheKey.NZDPerCoin(currencyId), TimeSpan.FromHours(2), async() =>
            {
                if (currencyId == Constant.NZDT_ID)
                {
                    return(1);
                }

                var estBtc = await GetEstimatedBTC(1, currencyId);
                if (estBtc == 0)
                {
                    return(0);
                }

                var nzdPrice = await ExternalApiService.ConvertDollarToBTC(1, ConvertDollarToBTCType.NZD);
                if (nzdPrice != 0)
                {
                    return(estBtc / nzdPrice);
                }

                var btc_nzdt = await TradePairReader.GetTradePair(Constant.BITCOIN_ID, Constant.NZDT_ID).ConfigureAwait(false);
                if (btc_nzdt == null || btc_nzdt.LastTrade == 0)
                {
                    return(0);
                }

                return(estBtc *btc_nzdt.LastTrade);
            });

            return(cacheResult);
        }
        public async Task <decimal> GetEstimatedNZD(decimal amount, int currencyId)
        {
            if (amount == 0)
            {
                return(0);
            }

            if (currencyId == Constant.NZDT_ID)
            {
                return(amount);
            }

            var estBtc = await GetEstimatedBTC(amount, currencyId);

            if (estBtc == 0)
            {
                return(0);
            }

            var nzdPrice = await ExternalApiService.ConvertDollarToBTC(1, ConvertDollarToBTCType.NZD);

            if (nzdPrice != 0)
            {
                return(estBtc / nzdPrice);
            }

            var btc_nzdt = await TradePairReader.GetTradePair(Constant.BITCOIN_ID, Constant.NZDT_ID).ConfigureAwait(false);

            if (btc_nzdt == null || btc_nzdt.LastTrade == 0)
            {
                return(0);
            }

            return(estBtc * btc_nzdt.LastTrade);
        }
예제 #4
0
        public async Task <CreateTradeResponseModel> SubmitUserTrade(ApiSubmitUserTradeRequest request)
        {
            var tradePair = request.TradePairId.HasValue
                                ? await TradePairReader.GetTradePair(request.TradePairId.Value).ConfigureAwait(false)
                                : await TradePairReader.GetTradePair(request.Market.Replace('/', '_')).ConfigureAwait(false);

            if (tradePair == null)
            {
                var marketName = request.TradePairId.HasValue ? request.TradePairId.ToString() : request.Market;
                return(new CreateTradeResponseModel {
                    Error = $"Market '{marketName}' not found."
                });
            }

            var totalTrade = request.Amount * request.Rate;

            if (totalTrade < tradePair.BaseMinTrade)
            {
                return new CreateTradeResponseModel {
                           Error = $"Invalid trade amount, Minimum total trade is {tradePair.BaseMinTrade} {tradePair.BaseSymbol}"
                }
            }
            ;

            var response = await TradeService.CreateTrade(request.UserId.ToString(), new CreateTradeModel
            {
                Amount      = request.Amount,
                Price       = request.Rate,
                TradePairId = tradePair.TradePairId,
                IsBuy       = request.Type == TradeHistoryType.Buy,
            }, true).ConfigureAwait(false);

            return(response);
        }
        public async Task <decimal> GetEstimatedValue(decimal amount, int currencyId, int baseCurrency)
        {
            var tradePair = await TradePairReader.GetTradePair(currencyId, baseCurrency).ConfigureAwait(false);

            if (tradePair != null)
            {
                return(amount * tradePair.LastTrade);
            }
            return(0);
        }
        public async Task <decimal> GetEstimatedBTC(decimal amount, int currencyId)
        {
            if (amount == 0)
            {
                return(0);
            }

            if (currencyId == Constant.BITCOIN_ID)
            {
                return(amount);
            }

            if (currencyId == Constant.USDT_ID)
            {
                var btc_usdt = await TradePairReader.GetTradePair(Constant.BITCOIN_ID, Constant.USDT_ID).ConfigureAwait(false);

                if (btc_usdt == null || btc_usdt.LastTrade == 0)
                {
                    return(0);
                }

                return(amount / btc_usdt.LastTrade);
            }

            if (currencyId == Constant.NZDT_ID)
            {
                var btc_nzdt = await TradePairReader.GetTradePair(Constant.BITCOIN_ID, Constant.NZDT_ID).ConfigureAwait(false);

                if (btc_nzdt == null || btc_nzdt.LastTrade == 0)
                {
                    return(0);
                }

                return(amount / btc_nzdt.LastTrade);
            }

            var tradePair = await TradePairReader.GetTradePair(currencyId, Constant.BITCOIN_ID).ConfigureAwait(false);

            if (tradePair == null)
            {
                var ltcTradePair = await TradePairReader.GetTradePair(currencyId, Constant.LITECOIN_ID).ConfigureAwait(false);

                var ltcbtcTradePair = await TradePairReader.GetTradePair(Constant.LITECOIN_ID, Constant.BITCOIN_ID).ConfigureAwait(false);

                if (ltcTradePair == null || ltcbtcTradePair == null)
                {
                    return(0);
                }

                return((amount * ltcTradePair.LastTrade) * ltcbtcTradePair.LastTrade);
            }

            return(amount * tradePair.LastTrade);
        }
예제 #7
0
        public async Task <ActionResult> SubmitTrade(SubmitTradeModel model)
        {
            if (!ModelState.IsValid)
            {
                return(JsonError(ModelState.FirstError()));
            }

            var tradePair = await TradePairReader.GetTradePair(model.TradePairId);

            if (tradePair == null)
            {
                return(JsonError(Resources.Exchange.tradeNoMarketError));
            }

            if (model.Amount * model.Price < tradePair.BaseMinTrade)
            {
                return(JsonError(string.Format(Resources.Exchange.tradeMinTotalError, $"{tradePair.BaseMinTrade:F8}", tradePair.BaseSymbol)));
            }

            if (model.Amount >= 1000000000 || (model.Amount * model.Price) >= 1000000000)
            {
                return(JsonError(string.Format(Resources.Exchange.tradeMaxAmountError, "1000000000")));
            }

            if (model.Price < 0.00000001m)
            {
                return(JsonError(string.Format(Resources.Exchange.tradeMinPriceError, "0.00000001")));
            }

            if (model.Price > 1000000000)
            {
                return(JsonError(string.Format(Resources.Exchange.tradeMaxPriceError, "1000000000")));
            }

            var response = await TradeService.CreateTrade(User.Identity.GetUserId(), new CreateTradeModel
            {
                Amount      = model.Amount,
                IsBuy       = model.IsBuy,
                Price       = model.Price,
                TradePairId = tradePair.TradePairId
            });

            if (response.IsError)
            {
                return(JsonError(response.Error));
            }

            await response.Notifications.SendNotifications();

            await response.DataUpdates.SendTradeNotifications();

            return(JsonSuccess());
        }
예제 #8
0
        public async Task <ActionResult> GetTradePairData(int tradepairId)
        {
            var ticker = await TradePairReader.GetTicker(tradepairId);

            var tradePair = await TradePairReader.GetTradePair(tradepairId);

            var orderbookData = await ExchangeReader.GetOrderBook(User.Identity.GetUserId(), tradepairId);

            var historyData = await ExchangeReader.GetTradeHistory(tradepairId);

            return(Json(new
            {
                Success = true,
                TradePair = tradePair,
                Ticker = ticker,
                Buys = orderbookData.BuyData,
                Sells = orderbookData.SellData,
                History = historyData
            }));
        }
예제 #9
0
        public async Task <ActionResult> Index(int?id, string market, string basemarket = "BTC")
        {
            var viewModel      = new ExchangeModel();
            var baseCurrencies = await CurrencyReader.GetBaseCurrencies();

            var baseMarket = baseCurrencies.FirstOrDefault(x => x.Symbol == basemarket)
                             ?? baseCurrencies.FirstOrDefault(x => x.Symbol == "BTC");
            var tradePair = id.HasValue
                                                        ? await TradePairReader.GetTradePair(id.Value)
                                                        : await TradePairReader.GetTradePair(market);

            viewModel.TradePair      = tradePair;
            viewModel.BaseCurrencies = baseCurrencies;
            viewModel.BaseMarket     = baseMarket?.Symbol ?? "BTC";
            if (viewModel.TradePair == null)
            {
                viewModel.TradePair = new TradePairModel();
                viewModel.Summary   = await ExchangeReader.GetExchangeSummary();

                viewModel.Summary.BaseMarket = baseMarket?.Symbol ?? "BTC";
            }

            return(View("Exchange", viewModel));
        }
예제 #10
0
        public async Task <ApiUserTradeHistoryResponse> GetUserTradeHistory(ApiUserTradeHistoryRequest request)
        {
            var count = Math.Min(request.Count ?? 100, 1000);

            if (request.TradePairId.HasValue || !string.IsNullOrEmpty(request.Market))
            {
                var tradepair = request.TradePairId.HasValue
                                        ? await TradePairReader.GetTradePair(request.TradePairId.Value, true).ConfigureAwait(false)
                                        : await TradePairReader.GetTradePair(request.Market.Replace('/', '_'), true).ConfigureAwait(false);

                if (tradepair == null)
                {
                    return new ApiUserTradeHistoryResponse {
                               Success = false, Error = "Market not found."
                    }
                }
                ;

                var cacheResult = await CacheService.GetOrSetMemoryAsync(CacheKey.ApiUserTradeHistory(request.UserId.ToString(), tradepair.TradePairId), TimeSpan.FromSeconds(1), async() =>
                {
                    using (var context = ExchangeDataContextFactory.CreateReadOnlyContext())
                    {
                        var history = context.TradeHistory
                                      .AsNoTracking()
                                      .Where(x => x.TradePairId == tradepair.TradePairId && (x.UserId == request.UserId || x.ToUserId == request.UserId))
                                      .OrderByDescending(x => x.Id)
                                      .Take(1000)
                                      .Select(x => new ApiTradeHistory
                        {
                            Market  = string.Concat(x.TradePair.Currency1.Symbol, "/", x.TradePair.Currency2.Symbol),
                            TradeId = x.Id,
                            Amount  = x.Amount,
                            Rate    = x.Rate,
                            Type    = x.UserId == request.UserId
                                                                        ? TradeHistoryType.Buy.ToString()
                                                                        : TradeHistoryType.Sell.ToString(),
                            TimeStamp   = x.Timestamp,
                            TradePairId = x.TradePairId,
                            Fee         = x.Fee
                        });
                        return(await history.ToListNoLockAsync().ConfigureAwait(false));
                    }
                }).ConfigureAwait(false);

                return(new ApiUserTradeHistoryResponse
                {
                    Success = true,
                    Data = cacheResult.Take(count).ToList()
                });
            }
            else
            {
                var cacheResult = await CacheService.GetOrSetHybridAsync(CacheKey.ApiUserTradeHistory(request.UserId.ToString()), TimeSpan.FromSeconds(20), async() =>
                {
                    using (var context = ExchangeDataContextFactory.CreateReadOnlyContext())
                    {
                        var history = context.TradeHistory
                                      .AsNoTracking()
                                      .Where(x => x.UserId == request.UserId || x.ToUserId == request.UserId)
                                      .OrderByDescending(x => x.Id)
                                      .Take(1000)
                                      .Select(x => new ApiTradeHistory
                        {
                            Market  = string.Concat(x.TradePair.Currency1.Symbol, "/", x.TradePair.Currency2.Symbol),
                            TradeId = x.Id,
                            Amount  = x.Amount,
                            Rate    = x.Rate,
                            Type    = x.UserId == request.UserId
                                                                        ? TradeHistoryType.Buy.ToString()
                                                                        : TradeHistoryType.Sell.ToString(),
                            TimeStamp   = x.Timestamp,
                            TradePairId = x.TradePairId,
                            Fee         = x.Fee
                        });

                        return(await history.ToListNoLockAsync().ConfigureAwait(false));
                    }
                }).ConfigureAwait(false);

                return(new ApiUserTradeHistoryResponse
                {
                    Success = true,
                    Data = cacheResult.Take(count).ToList()
                });
            }
        }
예제 #11
0
        public async Task <ApiUserOpenOrdersResponse> GetUserOpenOrders(ApiUserOpenOrdersRequest request)
        {
            if (request.TradePairId.HasValue || !string.IsNullOrEmpty(request.Market))
            {
                var tradepair = request.TradePairId.HasValue
                                        ? await TradePairReader.GetTradePair(request.TradePairId.Value, true).ConfigureAwait(false)
                                        : await TradePairReader.GetTradePair(request.Market.Replace('/', '_'), true).ConfigureAwait(false);

                if (tradepair == null)
                {
                    return new ApiUserOpenOrdersResponse {
                               Success = false, Error = "Market not found."
                    }
                }
                ;

                using (var context = ExchangeDataContextFactory.CreateReadOnlyContext())
                {
                    var openOrders = context.Trade
                                     .AsNoTracking()
                                     .Where(x => x.UserId == request.UserId && x.TradePairId == tradepair.TradePairId && (x.Status == TradeStatus.Partial || x.Status == TradeStatus.Pending))
                                     .OrderByDescending(x => x.Id)
                                     .Select(x => new ApiOpenOrder
                    {
                        Amount      = x.Amount,
                        Market      = string.Concat(x.TradePair.Currency1.Symbol, "/", x.TradePair.Currency2.Symbol),
                        OrderId     = x.Id,
                        Rate        = x.Rate,
                        Remaining   = x.Remaining,
                        TimeStamp   = x.Timestamp,
                        TradePairId = x.TradePairId,
                        Type        = x.Type.ToString()
                    });

                    return(new ApiUserOpenOrdersResponse
                    {
                        Success = true,
                        Data = await openOrders.ToListNoLockAsync().ConfigureAwait(false)
                    });
                }
            }
            else
            {
                using (var context = ExchangeDataContextFactory.CreateReadOnlyContext())
                {
                    var openOrders = context.Trade
                                     .AsNoTracking()
                                     .Where(x => x.UserId == request.UserId && (x.Status == TradeStatus.Partial || x.Status == TradeStatus.Pending))
                                     .OrderByDescending(x => x.Id)
                                     .Select(x => new ApiOpenOrder
                    {
                        Amount      = x.Amount,
                        Market      = string.Concat(x.TradePair.Currency1.Symbol, "/", x.TradePair.Currency2.Symbol),
                        OrderId     = x.Id,
                        Rate        = x.Rate,
                        Remaining   = x.Remaining,
                        TimeStamp   = x.Timestamp,
                        TradePairId = x.TradePairId,
                        Type        = x.Type.ToString()
                    });

                    return(new ApiUserOpenOrdersResponse
                    {
                        Success = true,
                        Data = await openOrders.ToListNoLockAsync().ConfigureAwait(false)
                    });
                }
            }
        }