Ejemplo n.º 1
0
        public IAtomexApp UseTerminal(IAtomexClient terminal, bool restart = false)
        {
            if (HasTerminal)
            {
                StopTerminal();
            }

            Terminal = terminal;
            TerminalChanged?.Invoke(this, new TerminalChangedEventArgs(Terminal));

            if (HasTerminal && restart)
            {
                StartTerminal();
            }

            return(this);
        }
Ejemplo n.º 2
0
 public AtomexClientChangedEventArgs(IAtomexClient atomexClient)
 {
     AtomexClient = atomexClient;
 }
Ejemplo n.º 3
0
        public static Task <SwapParams> EstimateSwapParamsAsync(
            IFromSource from,
            decimal fromAmount,
            string redeemFromAddress,
            CurrencyConfig fromCurrency,
            CurrencyConfig toCurrency,
            IAccount account,
            IAtomexClient atomexClient,
            ISymbolsProvider symbolsProvider,
            ICurrencyQuotesProvider quotesProvider,
            CancellationToken cancellationToken = default)
        {
            return(Task.Run(async() =>
            {
                if (fromCurrency == null)
                {
                    return null;
                }

                if (toCurrency == null)
                {
                    return null;
                }

                var redeemFromWalletAddress = redeemFromAddress != null
                    ? await account
                                              .GetAddressAsync(toCurrency.Name, redeemFromAddress, cancellationToken)
                                              .ConfigureAwait(false)
                    : null;

                // estimate redeem fee
                var estimatedRedeemFee = await toCurrency
                                         .GetEstimatedRedeemFeeAsync(redeemFromWalletAddress, withRewardForRedeem: false)
                                         .ConfigureAwait(false);

                // estimate reward for redeem
                var rewardForRedeem = await RewardForRedeemHelper.EstimateAsync(
                    account: account,
                    quotesProvider: quotesProvider,
                    feeCurrencyQuotesProvider: symbol => atomexClient?.GetOrderBook(symbol)?.TopOfBook(),
                    redeemableCurrency: toCurrency,
                    redeemFromAddress: redeemFromWalletAddress,
                    cancellationToken: cancellationToken);

                // get amount reserved for active swaps
                var reservedForSwapsAmount = await GetAmountReservedForSwapsAsync(
                    from: from,
                    account: account,
                    currency: fromCurrency)
                                             .ConfigureAwait(false);

                // estimate maker network fee
                var estimatedMakerNetworkFee = await EstimateMakerNetworkFeeAsync(
                    fromCurrency: fromCurrency,
                    toCurrency: toCurrency,
                    account: account,
                    atomexClient: atomexClient,
                    symbolsProvider: symbolsProvider,
                    cancellationToken: cancellationToken)
                                               .ConfigureAwait(false);

                var fromCurrencyAccount = account
                                          .GetCurrencyAccount(fromCurrency.Name) as IEstimatable;

                // estimate payment fee
                var estimatedPaymentFee = await fromCurrencyAccount
                                          .EstimateSwapPaymentFeeAsync(
                    from: from,
                    amount: fromAmount,
                    cancellationToken: cancellationToken)
                                          .ConfigureAwait(false);

                // estimate max amount and max fee
                var maxAmountEstimation = await fromCurrencyAccount
                                          .EstimateMaxSwapPaymentAmountAsync(
                    from: from,
                    reserve: true,
                    cancellationToken: cancellationToken)
                                          .ConfigureAwait(false);

                if (maxAmountEstimation.Error != null)
                {
                    return new SwapParams
                    {
                        Amount = 0m,
                        PaymentFee = estimatedPaymentFee.Value,
                        RedeemFee = estimatedRedeemFee,
                        RewardForRedeem = rewardForRedeem,
                        MakerNetworkFee = estimatedMakerNetworkFee,
                        ReservedForSwaps = reservedForSwapsAmount,
                        Error = maxAmountEstimation.Error
                    };
                }

                var maxNetAmount = Math.Max(maxAmountEstimation.Amount - reservedForSwapsAmount - estimatedMakerNetworkFee, 0m);

                if (maxNetAmount == 0m) // insufficient funds
                {
                    return new SwapParams
                    {
                        Amount = 0m,
                        PaymentFee = maxAmountEstimation.Fee,
                        RedeemFee = estimatedRedeemFee,
                        RewardForRedeem = rewardForRedeem,
                        MakerNetworkFee = estimatedMakerNetworkFee,
                        ReservedForSwaps = reservedForSwapsAmount,
                        Error = new Error(
                            code: Errors.InsufficientFunds,
                            description: Resources.InsufficientFundsToCoverMakerNetworkFee,
                            details: string.Format(Resources.InsufficientFundsToCoverMakerNetworkFeeDetails,
                                                   estimatedMakerNetworkFee,                             // required
                                                   fromCurrency.Name,                                    // currency code
                                                   maxAmountEstimation.Amount - reservedForSwapsAmount)) // available
                    };
                }

                if (fromAmount > maxNetAmount) // amount greater than max net amount => use max amount params
                {
                    return new SwapParams
                    {
                        Amount = Math.Max(maxNetAmount, 0m),
                        PaymentFee = maxAmountEstimation.Fee,
                        RedeemFee = estimatedRedeemFee,
                        RewardForRedeem = rewardForRedeem,
                        MakerNetworkFee = estimatedMakerNetworkFee,
                        ReservedForSwaps = reservedForSwapsAmount,
                        Error = new Error(
                            code: Errors.InsufficientFunds,
                            description: Resources.InsufficientFunds,
                            details: string.Format(Resources.InsufficientFundsToSendAmountDetails,
                                                   fromAmount,        // required
                                                   fromCurrency.Name, // currency code
                                                   maxNetAmount))     // available
                    };
                }

                return new SwapParams
                {
                    Amount = fromAmount,
                    PaymentFee = estimatedPaymentFee.Value,
                    RedeemFee = estimatedRedeemFee,
                    RewardForRedeem = rewardForRedeem,
                    MakerNetworkFee = estimatedMakerNetworkFee,
                    ReservedForSwaps = reservedForSwapsAmount,
                    Error = null
                };
            }, cancellationToken));
        }
Ejemplo n.º 4
0
        public static Task <SwapPriceEstimation> EstimateSwapPriceAsync(
            decimal amount,
            AmountType amountType,
            CurrencyConfig fromCurrency,
            CurrencyConfig toCurrency,
            IAccount account,
            IAtomexClient atomexClient,
            ISymbolsProvider symbolsProvider,
            CancellationToken cancellationToken = default)
        {
            return(Task.Run(() =>
            {
                if (fromCurrency == null)
                {
                    return null;
                }

                if (toCurrency == null)
                {
                    return null;
                }

                var symbol = symbolsProvider
                             .GetSymbols(account.Network)
                             .SymbolByCurrencies(fromCurrency, toCurrency);

                if (symbol == null)
                {
                    return null;
                }

                var side = symbol.OrderSideForBuyCurrency(toCurrency);
                var orderBook = atomexClient.GetOrderBook(symbol);

                if (orderBook == null)
                {
                    return null;
                }

                var baseCurrency = account.Currencies.GetByName(symbol.Base);

                var isSoldAmount = amountType == AmountType.Sold;

                var(estimatedOrderPrice, estimatedPrice) = orderBook.EstimateOrderPrices(
                    side: side,
                    amount: amount,
                    amountDigitsMultiplier: isSoldAmount
                        ? fromCurrency.DigitsMultiplier
                        : toCurrency.DigitsMultiplier,
                    qtyDigitsMultiplier: baseCurrency.DigitsMultiplier,
                    amountType: amountType);

                var(estimatedMaxFromAmount, estimatedMaxToAmount) = orderBook.EstimateMaxAmount(side, fromCurrency.DigitsMultiplier);

                var isNoLiquidity = amount != 0 && estimatedOrderPrice == 0;

                var oppositeAmount = isSoldAmount
                    ? symbol.IsBaseCurrency(toCurrency.Name)
                        ? estimatedPrice != 0
                            ? AmountHelper.RoundDown(amount / estimatedPrice, toCurrency.DigitsMultiplier)
                            : 0m
                        : AmountHelper.RoundDown(amount * estimatedPrice, toCurrency.DigitsMultiplier)
                    : symbol.IsBaseCurrency(toCurrency.Name)
                        ? AmountHelper.RoundDown(amount * estimatedPrice, fromCurrency.DigitsMultiplier)
                        : estimatedPrice != 0
                            ? AmountHelper.RoundDown(amount / estimatedPrice, fromCurrency.DigitsMultiplier)
                            : 0m;

                return new SwapPriceEstimation
                {
                    FromAmount = isSoldAmount ? amount : oppositeAmount,
                    ToAmount = isSoldAmount ? oppositeAmount : amount,
                    OrderPrice = estimatedOrderPrice,
                    Price = estimatedPrice,
                    MaxFromAmount = estimatedMaxFromAmount,
                    MaxToAmount = estimatedMaxToAmount,
                    IsNoLiquidity = isNoLiquidity
                };
            }, cancellationToken));
        }
 public TerminalChangedEventArgs(IAtomexClient terminal)
 {
     Terminal = terminal;
 }