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; }
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); } }
public FeeCalculationCommand( ITransactionRepository transactionRepository, IFeeCalculationService feeCalculationService, IOutputWriter outputWriter) { _transactionRepository = transactionRepository; _feeCalculationService = feeCalculationService; _outputWriter = outputWriter; }
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)); }
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); }
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(); }
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); }
public static Task <decimal> GetAmountNoFeeAsync(this IFeeCalculationService src, TransferQueueMessage message) { return(src.GetAmountNoFeeAsync(message.Amount.ParseAnyDecimal(), message.AssetId, message.Fees, message.ToClientid)); }
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); }
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); }