private bool sufficientFundsForTransactions( PortfolioEntry portfolioEntry, SellTransaction[] sellTransactions, out string lackingExchangeName) { bool sufficientFundsForTransactions = true; lackingExchangeName = null; Dictionary <string, double> exchangeNameToExchangeSellAmount = new Dictionary <string, double>(); foreach (SellTransaction sellTransaction in sellTransactions) { if (!exchangeNameToExchangeSellAmount.ContainsKey(sellTransaction.ExchangeName)) { exchangeNameToExchangeSellAmount[sellTransaction.ExchangeName] = 0; } exchangeNameToExchangeSellAmount[sellTransaction.ExchangeName] += sellTransaction.Amount; } foreach (string exchangeName in exchangeNameToExchangeSellAmount.Keys) { double exchangeSellAmount = exchangeNameToExchangeSellAmount[exchangeName]; if (portfolioEntry.GetCoinHoldings(exchangeName) < exchangeSellAmount) { sufficientFundsForTransactions = false; lackingExchangeName = exchangeName; } } return(sufficientFundsForTransactions); }
/// <summary> /// sells coin corresponding to name / symbol specified in <paramref name="commandArguments"/>[0], /// where sell amount is specified in <paramref name="commandArguments"/>[1] /// and sell price per coin is specified in <paramref name="commandArguments"/>[2]. /// returns whether command was executed successfully. /// </summary> /// <seealso cref="CoinListingManager.GetCoinIdByNameOrSymbol(string)"/> /// <seealso cref="PortfolioManager.GetCoinHoldings(int)"/> /// <seealso cref="PortfolioManager.SellCoin(int, double, double, long)"/> /// <param name="commandArguments"></param> protected override bool Execute(string[] commandArguments) { bool commandExecutedSuccessfuly; try { // price coin name or symbol from command argument 0 string coinNameOrSymbol = commandArguments[0]; // get coin id by name or symbol long coinId = CoinListingManager.Instance.GetCoinIdByNameOrSymbol(coinNameOrSymbol); // get coin name & symbol string coinName = CoinListingManager.Instance.GetCoinNameById(coinId); string coinSymbol = CoinListingManager.Instance.GetCoinSymbolById(coinId); // current timestamp long unixTimestamp = DateTimeUtils.GetUnixTimestamp(); // parse buy transactions SellTransaction[] sellTransactions = tryParseTransactionArray( commandArguments, coinId, unixTimestamp, out bool sellTransactionArrayParseSuccess); if (sellTransactionArrayParseSuccess) { // check if there are enough funds for sell transactions PortfolioEntry portfolioEntry = PortfolioManager.Instance.GetPortfolioEntry(coinId); bool sufficientFundsForSellTransactions = sufficientFundsForTransactions( portfolioEntry, sellTransactions, out string lackingExchangeName); if (!sufficientFundsForSellTransactions) // not enough funds to perform sales { double lackingExchangeCoinHoldings = portfolioEntry.GetCoinHoldings( lackingExchangeName); throw new InsufficientFundsForSellTransactionsException( coinId, lackingExchangeName, lackingExchangeCoinHoldings); } // execute sell transactions PortfolioManager.Instance.SellCoin(sellTransactions); // sale(s) performed successfully string successfulSaleNoticeMessage = sellTransactions.Length == 1 ? string.Format( "Successfully sold {0} '{1}' from exchange '{2}' for {3}$ each.", sellTransactions[0].Amount, coinName, sellTransactions[0].ExchangeName, sellTransactions[0].PricePerCoin) : string.Format( "{0} Specified sales made successfully.", sellTransactions.Length); ConsoleIOManager.Instance.LogNotice( successfulSaleNoticeMessage, ConsoleIOManager.eOutputReportType.CommandExecution); commandExecutedSuccessfuly = true; } else // !sellTransactionArrayParseSuccess { commandExecutedSuccessfuly = false; } } catch (CoinNameOrSymbolNotFoundException coinNameOrSymbolNotFoundException) { // coin with specified name / symbol not found in listing repository ConsoleIOManager.Instance.LogError( coinNameOrSymbolNotFoundException.Message, ConsoleIOManager.eOutputReportType.CommandExecution); commandExecutedSuccessfuly = false; } catch (CoinNotInPortfolioException coinNotInPortfolioException) { // portfolio has no entry with specified id string coinName = CoinListingManager.Instance.GetCoinNameById( coinNotInPortfolioException.CoinId); ConsoleIOManager.Instance.LogErrorFormat( false, ConsoleIOManager.eOutputReportType.CommandExecution, "There's no entry in portfolio manager for '{0}'.", coinName); commandExecutedSuccessfuly = false; } catch (InsufficientFundsForSellTransactionsException insufficientFundsForSellTransactionsException) { string coinName = CoinListingManager.Instance.GetCoinNameById( insufficientFundsForSellTransactionsException.CoinId); string coinSymbol = CoinListingManager.Instance.GetCoinSymbolById( insufficientFundsForSellTransactionsException.CoinId); ConsoleIOManager.Instance.LogErrorFormat( false, ConsoleIOManager.eOutputReportType.CommandExecution, "Not enough funds for requested sell operation(s)." + " '{0}' holdings in exchange '{1}': {2} {3}.", coinName, insufficientFundsForSellTransactionsException.ExchangeName, insufficientFundsForSellTransactionsException.ExchangeCoinHoldings, coinSymbol); commandExecutedSuccessfuly = false; } catch (DatabaseCommunicationException databaseCommunicationException) { PortfolioCommand.HandleDatabaseCommunicationException(databaseCommunicationException); commandExecutedSuccessfuly = false; } return(commandExecutedSuccessfuly); }