public bool TradeExecuted(string baseCurrency, string quoteCurrency, decimal tradeVolume, decimal price, DateTime executionDateTime,
                                  string tradeId, int buyAccountId, int sellAccountId, string buyOrderId, string sellOrderId)
        {
            decimal buySideFee = _feeCalculationService.GetFee(new Currency(baseCurrency), new Currency(quoteCurrency),
                                                               new AccountId(buyAccountId), tradeVolume, price);
            decimal sellSideFee = _feeCalculationService.GetFee(new Currency(baseCurrency), new Currency(quoteCurrency),
                                                                new AccountId(sellAccountId), tradeVolume, price);

            // As in case of buy order, the current and available balances differ in the case of quote currency, we
            // evaluate the quote currency first
            if (InitializeBalanceLedgerUpdate(new Currency(quoteCurrency), new AccountId(buyAccountId),
                                              -(tradeVolume * price), 0,
                                              executionDateTime, buyOrderId, tradeId, true, true, buySideFee, false))
            {
                // Then, we update balance for Buy Account's Base Currency
                if (InitializeBalanceLedgerUpdate(new Currency(baseCurrency), new AccountId(buyAccountId), tradeVolume, 0,
                                                  executionDateTime, buyOrderId, tradeId, false, false, 0, true))
                {
                    // In case of a sell order, the available balance is deducted from the base currency, so we validate the
                    // base currency first
                    if (InitializeBalanceLedgerUpdate(new Currency(baseCurrency), new AccountId(sellAccountId),
                                                      -tradeVolume, 0, executionDateTime, sellOrderId, tradeId, false, true,
                                                      0, true))
                    {
                        // Lastly, for the seller account's quote currency
                        return(InitializeBalanceLedgerUpdate(new Currency(quoteCurrency), new AccountId(sellAccountId),
                                                             tradeVolume * price, 0, executionDateTime, sellOrderId, tradeId,
                                                             true, false, sellSideFee, false));
                    }
                }
            }

            return(false);
        }
Esempio n. 2
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);
        }
Esempio n. 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);
            }
        }
Esempio n. 4
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);
        }
Esempio n. 5
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);
        }
Esempio n. 6
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);
        }