/// <summary> /// Logic to construct a sorted list of holdings by stock symbol, pre-subtotaled and pre-formatted for ASPX repeater display. /// </summary> /// <param name="holdingsUI">Holding data to format</param> public int buildPortfolioBySymbol(List<HoldingDataUI> holdingsUI) { if (holdingsUI == null || holdingsUI.Count < 1) return 0; string quoteSymbol = holdingsUI[0].quoteID; decimal quotePrice = holdingsUI[0].quotePriceDecimal; double subtotalquantity = 0; decimal subtotalmktvalue = 0; decimal subtotalbasis = 0; decimal subtotalgain = 0; int uniqueStockCount = 0; int count = holdingsUI.Count; int subtotaledlistcount = 0; for (int i = 0; i <= count; i++) { if (i == count) { subtotaledlistcount--; } if (!quoteSymbol.Equals(holdingsUI[subtotaledlistcount].quoteID)) { uniqueStockCount += 1; HoldingDataUI subtotalline = new HoldingDataUI(subtotalquantity, subtotalgain, subtotalmktvalue, subtotalbasis, quoteSymbol, quotePrice); quoteSymbol = holdingsUI[subtotaledlistcount].quoteID; quotePrice = holdingsUI[subtotaledlistcount].quotePriceDecimal; subtotalgain = holdingsUI[subtotaledlistcount].gainDecimal; subtotalquantity = holdingsUI[subtotaledlistcount].quantityDouble; subtotalmktvalue = holdingsUI[subtotaledlistcount].marketValueDecimal; subtotalbasis = holdingsUI[subtotaledlistcount].basisDecimal; if (i != count) holdingsUI[subtotaledlistcount].convertNumericsForDisplay(true); else subtotaledlistcount++; holdingsUI.Insert(subtotaledlistcount++, subtotalline); subtotaledlistcount++; } else { subtotalgain += holdingsUI[subtotaledlistcount].gainDecimal; subtotalquantity += Convert.ToDouble(holdingsUI[subtotaledlistcount].quantityDouble); subtotalmktvalue += Convert.ToDecimal(holdingsUI[subtotaledlistcount].marketValueDecimal); subtotalbasis += Convert.ToDecimal(holdingsUI[subtotaledlistcount].basisDecimal); holdingsUI[subtotaledlistcount].convertNumericsForDisplay(true); subtotaledlistcount++; } } return uniqueStockCount; }
/// <summary> /// This routine allows us to take an unsorted list (or list sorted by HoldingID) of holdings, /// such as that returned by the WebSphere Trade 6.1 service, and return a sorted list of /// holdings by stock symbol. At the same time, we produce subtotal lines for each unique stock. /// This is used in a new page we added for StockTrader that Trade 6.1 does not have: /// (PortfolioBySymbol.aspx). Yet, it will work with the existing WebSphere backend service, /// since we do the sort here on the UI tier. We do it this way becuase WebSphere Trade 6.1 /// will always return an unsorted list of stock holdings since it does not implement a web service /// method to return a list sorted by quoteID. Without this limiting factor, a better and more /// performant way of doing this would be to implement a business services method and corresponding DAL method /// to execute a query that returned pre-sorted values by stock symbol (as opposed to unsorted, /// as the EJB/Trade 6.1 getHoldings operation does; or sorted by HoldingID as our getHoldings operation /// does. This would avoid the need to do a sort on the UI tier at all. The extra load this /// would place on the database would be negligable, given a typically small number of rows returned. /// At any rate, the sort is implemented here by taking advantage of a custom comparer in our /// HoldingsUI class on the quoteID property (stock symbol), and .NET's ability to sort /// generic typed lists. /// Hence, we can display even WebSphere-returned data that is non sorted in our extra /// PortfolioBySymbol page, adding the subtotal lines for each unique stock as well. /// We resisted adding a second method to the BSL and DAL to return a different sort order (quoteID), simply to /// be consistent across the InProcess and Web Service modes of operation and for true benchmark comparison /// purposes between the InProcess and web service modes. Note this logic is never called in /// published benchmark data, given the fact WebSphere Trade 6.1 does not implement this /// functionality, although even with the extra sort it performs very well. /// </summary> /// <param name="userID">User id to retrieve data for.</param> public Trade.StockTraderWebApplicationModelClasses.TotalHoldingsUI getHoldingsBySymbolSubTotaled(string userID) { try { //get the list of holdings from the BSL List<HoldingDataModel> holdings = BSL.getHoldings(userID); List<HoldingDataUI> holdingsUI = new List<HoldingDataUI>(); decimal marketValue = 0; decimal gain = 0; decimal basis = 0; //create our HoldingsUI class to pass back to the ASPX page. for (int i = 0; i < holdings.Count; i++) { //Now Removed: QuoteDataModel quote = BSL.getQuote(holdings[i].quoteID); HoldingDataUI holdingitem = new HoldingDataUI(holdings[i].holdingID, holdings[i].quantity, holdings[i].purchasePrice, holdings[i].purchaseDate.ToString(), holdings[i].quoteID, holdings[i].price); holdingsUI.Add(holdingitem); decimal _marketValue = (decimal)holdings[i].quantity * holdings[i].price; decimal _basis = (decimal)holdings[i].quantity * holdings[i].purchasePrice; gain += _marketValue - _basis; marketValue += _marketValue; basis += _basis; } //Call our implemented comparer class: see Trade.StockTraderWebApplicationModelClasses.HoldingDataUI.cs for the compararer //class source code. HoldingDataUI.HoldingDataUIComparer comparer = new HoldingDataUI.HoldingDataUIComparer(); comparer.ComparisonMethod = HoldingDataUI.HoldingDataUIComparer.ComparisonType.quoteID; //Do the sort! Sort method is built into the C# Generic List functionality; the comparer //calls our delegate method to compare by quoteID, so just one line of code here! holdingsUI.Sort(comparer); //Our list is now sorted, proceed with building in the subtotal lines. htmlRowBuilder rowBuilder = new htmlRowBuilder(); int uniqueStockCount = rowBuilder.buildPortfolioBySymbol(holdingsUI); TotalHoldingsUI totalHoldings = new TotalHoldingsUI(holdingsUI, marketValue, basis, gain, uniqueStockCount, holdingsUI.Count - uniqueStockCount); return totalHoldings; } catch (Exception e) { ConfigUtility.writeErrorConsoleMessage("StockTraderWebApplicationServiceClient.getHoldingsBySymbolSubTotaled Error: " + e.ToString(), EventLogEntryType.Error, true, new Settings()); throw; } }
/// <summary> /// Gets a holding for a user. Transforms data from DataContract to model UI class for HTML display. /// </summary> /// <param name="userID">User id to retrieve data for.</param> /// <param name="holdingid">Holding id to retrieve data for.</param> public HoldingDataUI getHolding(string userID, int holdingid) { HoldingDataModel holding=null; HoldingDataUI holdingitem=null; try { holding = BSL.getHolding(userID,holdingid); if (holding!=null) { QuoteDataModel quote = BSL.getQuote(holding.quoteID); holdingitem = new HoldingDataUI(holding.holdingID, holding.quantity, holding.purchasePrice, holding.purchaseDate, holding.quoteID, quote.price); } return holdingitem; } catch (Exception e) { ConfigUtility.writeErrorConsoleMessage("StockTraderWebApplicationServiceClient.getHolding Error: " + e.ToString(), EventLogEntryType.Error, true, new Settings()); throw; } }
/// <summary> /// Gets holding data for a user. Transforms data from DataContract to model UI class for HTML display. /// </summary> /// <param name="userID">User id to retrieve data for.</param> public Trade.StockTraderWebApplicationModelClasses.TotalHoldingsUI getHoldings(string userID) { try { List<HoldingDataModel> holdings = BSL.getHoldings(userID); List<HoldingDataUI> holdingsUI = new List<HoldingDataUI>(); decimal marketValue = 0; decimal gain = 0; decimal basis = 0; for (int i = 0; i < holdings.Count; i++) { //Now removed: QuoteDataModel quote = BSL.getQuote(holdings[i].quoteID); HoldingDataUI holdingitem = new HoldingDataUI(holdings[i].holdingID, holdings[i].quantity, holdings[i].purchasePrice, holdings[i].purchaseDate.ToString(), holdings[i].quoteID, holdings[i].price); holdingitem.convertNumericsForDisplay(false); holdingsUI.Add(holdingitem); decimal _marketValue = (decimal)holdings[i].quantity * holdings[i].price; decimal _basis = (decimal)holdings[i].quantity * (decimal)holdings[i].purchasePrice; gain += _marketValue - _basis; marketValue += _marketValue; basis += _basis; } TotalHoldingsUI totalHoldings = new TotalHoldingsUI(holdingsUI, marketValue, basis, gain); return totalHoldings; } catch (Exception e) { ConfigUtility.writeErrorConsoleMessage("StockTraderWebApplicationServiceClient.getHoldings Error: " + e.ToString(), EventLogEntryType.Error, true, new Settings()); throw; } }