예제 #1
0
        public void GetFeeTest_TestsIfTheFeeIsasReturnedAsExpectedWhenFinalElementInTheTableIsReached_VerifiesThroughDatabaseQueries()
        {
            IFeeCalculationService      feeCalculationService      = (IFeeCalculationService)ContextRegistry.GetContext()["FeeCalculationService"];
            IFeeRepository              feeRepository              = (IFeeRepository)ContextRegistry.GetContext()["FeeRepository"];
            IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"];


            AccountId  accountId = new AccountId(1);
            List <Fee> allFees   = feeRepository.GetAllFees();

            Assert.IsNotNull(allFees);
            string currencyPair = allFees[0].CurrencyPair;
            Tuple <string, string> splittedCurrencyPair = CurrencySplitterService.SplitCurrencyPair(currencyPair);

            // As amount, the value is so large that it is always greater than any fee in the table
            Ledger ledger = new Ledger("1", DateTime.Now, LedgerType.Trade, new Currency(splittedCurrencyPair.Item2),
                                       2000000, 0, 0, 0, "1", "1", false, accountId);

            fundsPersistenceRepository.SaveOrUpdate(ledger);
            List <Fee> feeByCurrencyPair = feeRepository.GetFeeByCurrencyPair(currencyPair);

            Assert.IsNotNull(feeByCurrencyPair);
            decimal lastElementFee = (feeByCurrencyPair.Last().PercentageFee / 100) * (1000 * 2000);

            decimal feeFromService = feeCalculationService.GetFee(new Currency(splittedCurrencyPair.Item1),
                                                                  new Currency(splittedCurrencyPair.Item2),
                                                                  accountId, 1000, 2000);

            Assert.AreEqual(lastElementFee, feeFromService);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="T:System.Object"/> class.
 /// </summary>
 public FundsValidationService(ITransactionService transactionService, IFundsPersistenceRepository
                               fundsPersistenceRepository, IBalanceRepository balanceRepository,
                               IFeeCalculationService feeCalculationService, IWithdrawFeesRepository withdrawFeesRepository,
                               IWithdrawIdGeneratorService withdrawIdGeneratorService, ILedgerRepository ledgerRepository,
                               IDepositLimitEvaluationService depositLimitEvaluationService, IDepositLimitRepository depositLimitRepository,
                               IWithdrawLimitEvaluationService withdrawLimitEvaluationService, IWithdrawLimitRepository withdrawLimitRepository,
                               ITierLevelRetrievalService tierLevelRetrievalService,
                               IWithdrawRepository withdrawRepository, ITierValidationService tierValidationService,
                               ILimitsConfigurationService limitsConfigurationService)
 {
     _transactionService             = transactionService;
     _fundsPersistenceRepository     = fundsPersistenceRepository;
     _balanceRepository              = balanceRepository;
     _feeCalculationService          = feeCalculationService;
     _withdrawFeesRepository         = withdrawFeesRepository;
     _withdrawIdGeneratorService     = withdrawIdGeneratorService;
     _ledgerRepository               = ledgerRepository;
     _depositLimitEvaluationService  = depositLimitEvaluationService;
     _depositLimitRepository         = depositLimitRepository;
     _withdrawLimitEvaluationService = withdrawLimitEvaluationService;
     _withdrawLimitRepository        = withdrawLimitRepository;
     _tierLevelRetrievalService      = tierLevelRetrievalService;
     _withdrawRepository             = withdrawRepository;
     _tierValidationService          = tierValidationService;
     _limitsConfigurationService     = limitsConfigurationService;
 }
예제 #3
0
        public void GetFeeTest_TestsIfTheFeeIsasReturnedAsExpectedWhenMiddleElementsAreReached_VerifiesThroughDatabaseQueries()
        {
            IFeeCalculationService      feeCalculationService      = (IFeeCalculationService)ContextRegistry.GetContext()["FeeCalculationService"];
            IFeeRepository              feeRepository              = (IFeeRepository)ContextRegistry.GetContext()["FeeRepository"];
            IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"];


            AccountId  accountId = new AccountId(1);
            List <Fee> allFees   = feeRepository.GetAllFees();

            Assert.IsNotNull(allFees);
            string currencyPair = allFees[0].CurrencyPair;
            Tuple <string, string> splittedCurrencyPair = CurrencySplitterService.SplitCurrencyPair(currencyPair);

            List <Fee> feeByCurrencyPair = feeRepository.GetFeeByCurrencyPair(currencyPair);

            Assert.IsNotNull(feeByCurrencyPair);

            if (feeByCurrencyPair.Count > 4)
            {
                decimal amount = feeByCurrencyPair[feeByCurrencyPair.Count - 2].Amount;
                Ledger  ledger = new Ledger("1", DateTime.Now, LedgerType.Trade, new Currency(splittedCurrencyPair.Item2),
                                            amount, 0, 0, 0, "1", "1", false, accountId);
                fundsPersistenceRepository.SaveOrUpdate(ledger);

                decimal lastElementFee = (feeByCurrencyPair[feeByCurrencyPair.Count - 2].PercentageFee / 100) * (10 * 20);

                decimal feeFromService = feeCalculationService.GetFee(new Currency(splittedCurrencyPair.Item1),
                                                                      new Currency(splittedCurrencyPair.Item2),
                                                                      accountId, 10, 20);

                Assert.AreEqual(lastElementFee, feeFromService);
            }
        }
예제 #4
0
 public FeeCalculationCommand(
     ITransactionRepository transactionRepository,
     IFeeCalculationService feeCalculationService,
     IOutputWriter outputWriter)
 {
     _transactionRepository = transactionRepository;
     _feeCalculationService = feeCalculationService;
     _outputWriter          = outputWriter;
 }
예제 #5
0
        public void Setup()
        {
            var mocker = new DiscountServiceMocker();

            _feeCalculationService = new FeeCalculationService(mocker.DiscountService);

            mocker.DiscountService.AddOrUpdateDiscount("TELIA", 10);
            mocker.DiscountService.AddOrUpdateDiscount("CIRCLE_K", 20);
        }
 public OperationsCommandHandler(
     [NotNull] ILogFactory logFactory,
     [NotNull] ITransactionsRepository transactionsRepository,
     [NotNull] ITransactionService transactionService,
     [NotNull] IWalletCredentialsRepository walletCredentialsRepository,
     [NotNull] IFeeCalculationService feeCalculationService,
     [NotNull] IOperationsClient operationsClient)
 {
     _log = logFactory.CreateLog(this) ?? throw new ArgumentNullException(nameof(logFactory));
     _transactionsRepository      = transactionsRepository ?? throw new ArgumentNullException(nameof(transactionsRepository));
     _transactionService          = transactionService ?? throw new ArgumentNullException(nameof(transactionService));
     _walletCredentialsRepository = walletCredentialsRepository ?? throw new ArgumentNullException(nameof(walletCredentialsRepository));
     _feeCalculationService       = feeCalculationService ?? throw new ArgumentNullException(nameof(feeCalculationService));
     _operationsClient            = operationsClient ?? throw new ArgumentNullException(nameof(operationsClient));
 }
예제 #7
0
        private static FeeCalculationCommand BuildFeeCalculationCommand(MpConfig config, params object[] dependencies)
        {
            var defaultFee = new PercentageFee(
                config.Fees.PercentageFee,
                config.Fees.MinAllowedFeeAmount);
            var feeDiscount = new DiscountedFee(
                config.Fees.DiscountedFees,
                config.Fees.MinAllowedFeeAmount);
            var fixedFee = new InvoiceFixedFee(
                config.Fees.InvoiceFixedFee,
                config.Fees.MinAllowedFeeAmount);
            var extraFees = new IExtraFee[] { feeDiscount, fixedFee };

            ITransactionRepository transactionRepository =
                dependencies
                .OfType <ITransactionRepository>()
                .FirstOrDefault() ??
                new TransactionRepository(
                    config.Input.TransactionsFilePath,
                    new FileReader(),
                    new TransactionParser(
                        config.Input.Separator,
                        config.Input.DateFormat));
            IFeeCalculationService feeCalculationService =
                dependencies
                .OfType <IFeeCalculationService>()
                .FirstOrDefault() ??
                new FeeCalculationService(
                    new BaseFeeCalculator(defaultFee, new Dictionary <string, ITransactionFee>()),
                    extraFees,
                    new Mapper());

            IOutputWriter outputWriter =
                dependencies
                .OfType <IOutputWriter>()
                .FirstOrDefault() ??
                new OutputWriter(
                    config.Output.DateFormat,
                    config.Output.AmountFormat,
                    config.Output.MerchantNameMinimalWidth);

            var command = new FeeCalculationCommand(
                transactionRepository,
                feeCalculationService,
                outputWriter);

            return(command);
        }
예제 #8
0
        static void Main(string[] args)
        {
            _discountService       = new DiscountService();
            _feeCalculationService = new FeeCalculationService(_discountService);

            _discountService.AddOrUpdateDiscount("TELIA", 10);
            _discountService.AddOrUpdateDiscount("CIRCLE_K", 20);

            var transactionsInput = File.ReadLines("transactions.txt");
            var transactions      = transactionsInput.Where(x => !string.IsNullOrWhiteSpace(x)).Select(ParseTransaction).ToList();

            var transactionFees = _feeCalculationService.CalculateFees(transactions);

            foreach (var transactionFee in transactionFees)
            {
                Console.WriteLine(transactionFee.ToString());
            }

            Console.ReadKey();
        }
예제 #9
0
        public void SendMultipleOrdersTest_TestsIfSendingMultipleOrdersIsHandledAsExpected_VerifiesThroughTheReturnesValue()
        {
            IFundsValidationService     fundsValidationService     = (IFundsValidationService)ContextRegistry.GetContext()["FundsValidationService"];
            IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"];
            IBalanceRepository          balanceRepository          = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"];
            IFeeCalculationService      feeCalculationService      = (IFeeCalculationService)ContextRegistry.GetContext()["FeeCalculationService"];
            IFeeRepository feeRepository = (IFeeRepository)ContextRegistry.GetContext()["FeeRepository"];

            AccountId              accountId            = new AccountId(123);
            List <Fee>             allFees              = feeRepository.GetAllFees();
            Tuple <string, string> splittedCurrencyPair = CurrencySplitterService.SplitCurrencyPair(allFees.First().CurrencyPair);
            Currency baseCurrency        = new Currency(splittedCurrencyPair.Item1);
            Currency quoteCurrency       = new Currency(splittedCurrencyPair.Item2);
            Balance  baseCurrencyBalance = new Balance(baseCurrency, accountId, 400, 400);

            fundsPersistenceRepository.SaveOrUpdate(baseCurrencyBalance);

            Balance quoteCurrencyBalance = new Balance(quoteCurrency, accountId, 40000, 40000);

            fundsPersistenceRepository.SaveOrUpdate(quoteCurrencyBalance);

            bool validateFundsForOrder = fundsValidationService.ValidateFundsForOrder(accountId, baseCurrency,
                                                                                      quoteCurrency, 40, 100, "buy", "order123");

            Assert.IsTrue(validateFundsForOrder);

            // Get the fee corresponding to the current volume of the quote currency
            decimal usdFee = feeCalculationService.GetFee(baseCurrency, quoteCurrency, accountId, 40, 100);

            Assert.Greater(usdFee, 0);

            baseCurrencyBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, accountId);
            Assert.AreEqual(400, baseCurrencyBalance.CurrentBalance);
            Assert.AreEqual(400, baseCurrencyBalance.AvailableBalance);
            Assert.AreEqual(0, baseCurrencyBalance.PendingBalance);

            quoteCurrencyBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, accountId);
            Assert.AreEqual(40000 - (40 * 100), quoteCurrencyBalance.AvailableBalance);
            Assert.AreEqual(40000, quoteCurrencyBalance.CurrentBalance);
            Assert.AreEqual(40 * 100, quoteCurrencyBalance.PendingBalance);
        }
예제 #10
0
 public static Task <decimal> GetAmountNoFeeAsync(this IFeeCalculationService src, TransferQueueMessage message)
 {
     return(src.GetAmountNoFeeAsync(message.Amount.ParseAnyDecimal(), message.AssetId, message.Fees, message.ToClientid));
 }
예제 #11
0
        public void Scenario1Test_TestsFundsValidationServiceOperationsInaRandomOrderToProceedInTheDesiredExpectenacy_VerifiesThroughDatabaseQuery()
        {
            // Deposit --> Order Validations --> Trade --> Withdraw
            IFundsValidationService     fundsValidationService     = (IFundsValidationService)ContextRegistry.GetContext()["FundsValidationService"];
            IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"];
            IBalanceRepository          balanceRepository          = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"];
            IDepositIdGeneratorService  depositIdGeneratorService  = (IDepositIdGeneratorService)ContextRegistry.GetContext()["DepositIdGeneratorService"];
            IWithdrawFeesRepository     withdrawFeesRepository     = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"];
            IFeeCalculationService      feeCalculationService      = (IFeeCalculationService)ContextRegistry.GetContext()["FeeCalculationService"];
            IFeeRepository feeRepository = (IFeeRepository)ContextRegistry.GetContext()["FeeRepository"];

            Tuple <string, string> splittedCurrencyPair = CurrencySplitterService.SplitCurrencyPair(feeRepository.GetAllFees().First().CurrencyPair);
            Currency baseCurrency  = new Currency(splittedCurrencyPair.Item1);
            Currency quoteCurrency = new Currency(splittedCurrencyPair.Item2);

            AccountId user1Account       = new AccountId(1);
            AccountId user2Account       = new AccountId(2);
            decimal   baseDepositAmount  = 1.4m;
            decimal   quoteDepositAmount = 1000;

            Balance user1QuoteInitialBalance = new Balance(quoteCurrency, user1Account, quoteDepositAmount, quoteDepositAmount);
            Balance user2QuoteInitialBalance = new Balance(quoteCurrency, user2Account, quoteDepositAmount, quoteDepositAmount);

            fundsPersistenceRepository.SaveOrUpdate(user1QuoteInitialBalance);
            fundsPersistenceRepository.SaveOrUpdate(user2QuoteInitialBalance);

            // Deposit
            Deposit deposit1 = new Deposit(baseCurrency, depositIdGeneratorService.GenerateId(), DateTime.Now,
                                           DepositType.Default, baseDepositAmount, 0, TransactionStatus.Pending, user1Account,
                                           new TransactionId("1"), new BitcoinAddress("bitcoin1"));

            deposit1.IncrementConfirmations(7);
            fundsPersistenceRepository.SaveOrUpdate(deposit1);

            Deposit deposit2 = new Deposit(baseCurrency, depositIdGeneratorService.GenerateId(), DateTime.Now,
                                           DepositType.Default, baseDepositAmount, 0, TransactionStatus.Pending, user2Account,
                                           new TransactionId("3"), new BitcoinAddress("bitcoin3"));

            deposit2.IncrementConfirmations(7);
            fundsPersistenceRepository.SaveOrUpdate(deposit2);

            // Retrieve Base Currency balance for user 1
            bool depositResponse = fundsValidationService.DepositConfirmed(deposit1);

            Assert.IsTrue(depositResponse);
            Balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account);

            Assert.IsNotNull(balance);
            Assert.AreEqual(deposit1.Amount, balance.CurrentBalance);
            Assert.AreEqual(deposit1.Amount, balance.AvailableBalance);
            Assert.AreEqual(balance.PendingBalance, 0);

            // Retrieve Quote Currency balance for user 1
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user1Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(user1QuoteInitialBalance.CurrentBalance, balance.CurrentBalance);
            Assert.AreEqual(user1QuoteInitialBalance.AvailableBalance, balance.AvailableBalance);
            Assert.AreEqual(0, balance.PendingBalance);

            // Retrieve BTC balance for user 2
            depositResponse = fundsValidationService.DepositConfirmed(deposit2);
            Assert.IsTrue(depositResponse);
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user2Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(deposit2.Amount, balance.CurrentBalance);
            Assert.AreEqual(deposit2.Amount, balance.AvailableBalance);
            Assert.AreEqual(balance.PendingBalance, 0);

            // Retrieve USD balance for user 2
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user2Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(user2QuoteInitialBalance.CurrentBalance, balance.CurrentBalance);
            Assert.AreEqual(user2QuoteInitialBalance.AvailableBalance, balance.AvailableBalance);
            Assert.AreEqual(0, balance.PendingBalance);

            // Order Validation for User 1's Account
            decimal volume             = 1.2m;
            decimal price              = 590;
            string  buy                = "buy";
            string  sell               = "sell";
            string  buyOrderId         = "buy123";
            string  sellOrderId        = "sell123";
            bool    validationResponse = fundsValidationService.ValidateFundsForOrder(user1Account, baseCurrency, quoteCurrency,
                                                                                      volume, price, buy, buyOrderId);

            Assert.IsTrue(validationResponse);

            decimal user1Fee = feeCalculationService.GetFee(baseCurrency, quoteCurrency, user1Account, volume, price);
            decimal user2Fee = feeCalculationService.GetFee(baseCurrency, quoteCurrency, user2Account, volume, price);

            // Base Currency Balance for User Account 1
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(baseDepositAmount, balance.AvailableBalance);
            Assert.AreEqual(baseDepositAmount, balance.CurrentBalance);
            Assert.AreEqual(0, balance.PendingBalance);

            // Quote Currency Balance for User Account 1
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user1Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(quoteDepositAmount - (volume * price), balance.AvailableBalance);
            Assert.AreEqual(quoteDepositAmount, balance.CurrentBalance);
            Assert.AreEqual(volume * price, balance.PendingBalance);

            // Validation of User 2's order
            validationResponse = fundsValidationService.ValidateFundsForOrder(user2Account, baseCurrency, quoteCurrency,
                                                                              volume, price, sell, sellOrderId);
            Assert.IsTrue(validationResponse);

            // Base Currency Balance for User Account 2
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user2Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(baseDepositAmount - volume, balance.AvailableBalance);
            Assert.AreEqual(baseDepositAmount, balance.CurrentBalance);
            Assert.AreEqual(volume, balance.PendingBalance);

            // Quote Currency Balance for User Account 2
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user2Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(quoteDepositAmount, balance.AvailableBalance);
            Assert.AreEqual(quoteDepositAmount, balance.CurrentBalance);
            Assert.AreEqual(0, balance.PendingBalance);

            string tradeId = "tradeid123";
            bool   tradeExecutedResponse = fundsValidationService.TradeExecuted(baseCurrency.Name, quoteCurrency.Name,
                                                                                volume, price, DateTime.Now, tradeId, user1Account.Value, user2Account.Value, buyOrderId, sellOrderId);

            Assert.IsTrue(tradeExecutedResponse);

            // Base Currency Balance for User Account 1
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(baseDepositAmount + volume, balance.AvailableBalance);
            Assert.AreEqual(baseDepositAmount + volume, balance.CurrentBalance);
            Assert.AreEqual(0, balance.PendingBalance);

            // Quote Currency Balance for User Account 1
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user1Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(quoteDepositAmount - (volume * price) - user1Fee, balance.AvailableBalance);
            Assert.AreEqual(quoteDepositAmount - (volume * price) - user1Fee, balance.CurrentBalance);
            Assert.AreEqual(0, balance.PendingBalance);

            // Base Currency Balance for User Account 2
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user2Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(baseDepositAmount - (volume), balance.AvailableBalance);
            Assert.AreEqual(baseDepositAmount - (volume), balance.CurrentBalance);
            Assert.AreEqual(0, balance.PendingBalance);

            // Quote Currency Balance for User Account 2
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user2Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(quoteDepositAmount + (volume * price) - user2Fee, balance.AvailableBalance);
            Assert.AreEqual(quoteDepositAmount + (volume * price) - user2Fee, balance.CurrentBalance);
            Assert.AreEqual(0, balance.PendingBalance);

            decimal withdrawAmount = 0.3M;
            // Withdraw Base Currency
            Withdraw validateFundsForWithdrawal = fundsValidationService.ValidateFundsForWithdrawal(user1Account,
                                                                                                    baseCurrency, withdrawAmount, new TransactionId("transaction123"), new BitcoinAddress("bitcoin123"));

            Assert.IsNotNull(validateFundsForWithdrawal);
            WithdrawFees withdrawFee = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(baseCurrency.Name);

            // Base Currency Balance for User Account 1
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(baseDepositAmount + volume - withdrawAmount, balance.AvailableBalance);
            Assert.AreEqual(baseDepositAmount + volume, balance.CurrentBalance);
            Assert.AreEqual(withdrawAmount, balance.PendingBalance);

            bool withdrawalExecuted = fundsValidationService.WithdrawalExecuted(validateFundsForWithdrawal);

            Assert.IsTrue(withdrawalExecuted);

            // Base Currency Balance for User Account 1
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(baseDepositAmount + volume - withdrawAmount, balance.AvailableBalance);
            Assert.AreEqual(baseDepositAmount + volume - withdrawAmount, balance.CurrentBalance);
            Assert.AreEqual(0, balance.PendingBalance);

            // EXCEPTION OCCURS HERE when the user tries to withdraw more than their remaining limit
            // Withdraw will fail because the amount requested is greater than the maximum limit threshold
            validateFundsForWithdrawal = fundsValidationService.ValidateFundsForWithdrawal(user1Account,
                                                                                           baseCurrency, baseDepositAmount + volume /*Excluding previous withdrawal amount*/,
                                                                                           new TransactionId("transaction123"), new BitcoinAddress("bitcoin123"));
            Assert.IsNull(validateFundsForWithdrawal);

            // Base Currency for User Account 1
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account);
            Assert.IsNotNull(balance);
            Assert.AreEqual(baseDepositAmount + volume - withdrawAmount, balance.AvailableBalance);
            Assert.AreEqual(baseDepositAmount + volume - withdrawAmount, balance.CurrentBalance);
            Assert.AreEqual(0, balance.PendingBalance);
        }
예제 #12
0
        public void ValidateOrderAndHandleTradeTest_CheksIfEnoughBalanceIsAvailableForAnOrderToBeSentAndHandlesTradeWhenItExectues_VerifiesThroughDatabaseQueryAndValueReturned()
        {
            IFundsValidationService     fundsValidationService     = (IFundsValidationService)ContextRegistry.GetContext()["FundsValidationService"];
            IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"];
            IBalanceRepository          balanceRepository          = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"];
            IDepositIdGeneratorService  depositIdGeneratorService  = (IDepositIdGeneratorService)ContextRegistry.GetContext()["DepositIdGeneratorService"];
            IWithdrawFeesRepository     withdrawFeesRepository     = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"];
            IFeeCalculationService      feeCalculationService      = (IFeeCalculationService)ContextRegistry.GetContext()["FeeCalculationService"];

            Currency baseCurrency  = new Currency("BTC");
            Currency quoteCurrency = new Currency("USD");
            decimal  volume        = 1.4m;
            decimal  price         = 590m;

            string    buyOrderId       = "buy123";
            string    sellOrderId      = "sell123";
            string    buy              = "buy";
            string    sell             = "sell";
            AccountId buyAccountId     = new AccountId(1);
            AccountId sellAccountId    = new AccountId(2);
            Balance   buyBaseBalance   = new Balance(baseCurrency, buyAccountId, 20, 20);
            Balance   buyQuoteBalance  = new Balance(quoteCurrency, buyAccountId, 15000, 15000);
            Balance   sellBaseBalance  = new Balance(baseCurrency, sellAccountId, 20, 20);
            Balance   sellQuoteBalance = new Balance(quoteCurrency, sellAccountId, 15000, 15000);

            fundsPersistenceRepository.SaveOrUpdate(buyBaseBalance);
            fundsPersistenceRepository.SaveOrUpdate(buyQuoteBalance);
            fundsPersistenceRepository.SaveOrUpdate(sellBaseBalance);
            fundsPersistenceRepository.SaveOrUpdate(sellQuoteBalance);

            bool validationResponse = fundsValidationService.ValidateFundsForOrder(buyAccountId, baseCurrency, quoteCurrency,
                                                                                   volume, price, buy, buyOrderId);

            Assert.IsTrue(validationResponse);

            validationResponse = fundsValidationService.ValidateFundsForOrder(sellAccountId, baseCurrency, quoteCurrency,
                                                                              volume, price, sell, sellOrderId);
            Assert.IsTrue(validationResponse);

            buyBaseBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, buyAccountId);
            Assert.AreEqual(20, buyBaseBalance.AvailableBalance);
            Assert.AreEqual(20, buyBaseBalance.CurrentBalance);
            Assert.AreEqual(0, buyBaseBalance.PendingBalance);

            buyQuoteBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, buyAccountId);
            Assert.AreEqual(15000 - (price * volume), buyQuoteBalance.AvailableBalance);
            Assert.AreEqual(15000, buyQuoteBalance.CurrentBalance);
            Assert.AreEqual(price * volume, buyQuoteBalance.PendingBalance);

            sellBaseBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, sellAccountId);
            Assert.AreEqual(20 - volume, sellBaseBalance.AvailableBalance);
            Assert.AreEqual(20, sellBaseBalance.CurrentBalance);
            Assert.AreEqual(volume, sellBaseBalance.PendingBalance);

            sellQuoteBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, sellAccountId);
            Assert.AreEqual(15000, sellQuoteBalance.AvailableBalance);
            Assert.AreEqual(15000, sellQuoteBalance.CurrentBalance);
            Assert.AreEqual(0, sellQuoteBalance.PendingBalance);

            string tradeId = "tradeid123";
            bool   tradeExecutedResponse = fundsValidationService.TradeExecuted(baseCurrency.Name, quoteCurrency.Name,
                                                                                volume, price, DateTime.Now, tradeId, buyAccountId.Value, sellAccountId.Value, buyOrderId, sellOrderId);

            Assert.IsTrue(tradeExecutedResponse);

            decimal buySideFee  = feeCalculationService.GetFee(baseCurrency, quoteCurrency, buyAccountId, volume, price);
            decimal sellSidefee = feeCalculationService.GetFee(baseCurrency, quoteCurrency, sellAccountId, volume, price);

            buyBaseBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, buyAccountId);
            Assert.AreEqual(20 + volume, buyBaseBalance.AvailableBalance);
            Assert.AreEqual(20 + volume, buyBaseBalance.CurrentBalance);
            Assert.AreEqual(0, buyBaseBalance.PendingBalance);

            buyQuoteBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, buyAccountId);
            Assert.AreEqual(15000 - (price * volume) - buySideFee, buyQuoteBalance.AvailableBalance);
            Assert.AreEqual(15000 - (price * volume) - buySideFee, buyQuoteBalance.CurrentBalance);
            Assert.AreEqual(0, buyQuoteBalance.PendingBalance);

            sellBaseBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, sellAccountId);
            Assert.AreEqual(20 - volume, sellBaseBalance.AvailableBalance);
            Assert.AreEqual(20 - volume, sellBaseBalance.CurrentBalance);
            Assert.AreEqual(0, sellBaseBalance.PendingBalance);

            sellQuoteBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, sellAccountId);
            Assert.AreEqual(15000 + (price * volume) - sellSidefee, sellQuoteBalance.AvailableBalance);
            Assert.AreEqual(15000 + (price * volume) - sellSidefee, sellQuoteBalance.CurrentBalance);
            Assert.AreEqual(0, sellQuoteBalance.PendingBalance);
        }