Esempio n. 1
0
        private ConversionResult GetMarketAmountInBase(OrderAction orderAction, IEnumerable <ILimitOrder> limitOrders, AssetWithAmount from,
                                                       string assetTo, IDictionary <string, IAsset> assetsDict, IEnumerable <IAssetPair> assetPairs, MarketProfile marketProfile)
        {
            var result    = new ConversionResult();
            var assetPair = assetPairs.PairWithAssets(from.AssetId, assetTo);

            if (!IsInputValid(from, assetTo, assetsDict) || assetPair == null)
            {
                result.SetResult(OperationResult.InvalidInputParameters);
                return(result);
            }

            if (from.AssetId == assetTo)
            {
                result.From  = result.To = from;
                result.Price = result.VolumePrice = 1;
                result.SetResult(OperationResult.Ok);
                return(result);
            }

            limitOrders = limitOrders.Where(x => x.AssetPairId == assetPair.Id).GetAsync(orderAction, assetPair.IsInverted(assetTo));

            double sum      = 0;
            double priceSum = 0;
            int    n        = 0;

            var neededSum = double.MaxValue;

            foreach (var order in limitOrders)
            {
                if (n != 0 && sum >= neededSum)
                {
                    break;
                }

                sum      += Math.Abs(order.Volume);
                priceSum += order.Price;
                n++;
                neededSum = from.Amount * GetRate(assetTo, assetPair, priceSum / n);
            }

            if (n == 0)
            {
                result.SetResult(OperationResult.NoLiquidity);
                return(result);
            }

            var price = priceSum / n;

            result.From = from;
            var rate        = GetRate(assetTo, assetPair, price);
            var displayRate = GetRate(from.AssetId, assetPair, price);

            result.To = new AssetWithAmount
            {
                AssetId = assetTo,
                Amount  = (rate * from.Amount).TruncateDecimalPlaces(assetsDict[assetTo].Accuracy, orderAction == OrderAction.Buy)
            };
            result.SetResult(sum < neededSum ? OperationResult.NoLiquidity : OperationResult.Ok);
            result.Price       = GetRate(from.AssetId, assetPair, marketProfile.GetPrice(assetPair.Id, orderAction).GetValueOrDefault());
            result.VolumePrice = displayRate;

            return(result);
        }