public void calculatePortfolioTotalsTest() { Calculator calculator = new Calculator(); Portfolio portfolio = new Portfolio(); List<Position> positions = new List<Position>(); Position position1 = new Position(); position1.SecLastPrice = 102; position1.SecPrevClosePrice = 100; position1.ExecPrice = 100; position1.Quantity = 10; position1.DailyPnL = 20; position1.TotalPnL = 120; Position position2 = new Position(); position2.SecLastPrice = 102; position2.SecPrevClosePrice = 100; position2.ExecPrice = 100; position2.Quantity = 10; position2.DailyPnL = 10; position2.TotalPnL = 240; positions.Add(position1); positions.Add(position2); portfolio.positions = positions; portfolio = calculator.calculatePortfolioTotals(portfolio); Assert.AreEqual(portfolio.portfolioTotalPnL, 360); Assert.AreEqual(portfolio.portfolioDailyPnL, 30); }
// Calculates the Total PnL of the portfolios since purchase of the positions public Portfolio calculatePortfolioTotals(Portfolio portfolio) { decimal portfolioTotalPnL=0; decimal portfolioDailyPnL = 0; foreach (Position position in portfolio.positions) { portfolioTotalPnL = portfolioTotalPnL + position.TotalPnL; portfolioDailyPnL = portfolioDailyPnL + position.DailyPnL; } portfolio.portfolioTotalPnL = portfolioTotalPnL; portfolio.portfolioDailyPnL = portfolioDailyPnL; return portfolio; }
// Calculates the Total PnL of the portfolios since purchase of the positions in % terms public Portfolio calculatePortfolioTotalPercent(Portfolio portfolio) { decimal costbasis = 0; decimal currentValue = 0; foreach (Position position in portfolio.positions) { costbasis = costbasis + (position.ExecPrice * position.Quantity); currentValue = currentValue + (position.SecLastPrice * position.Quantity); } portfolio.portfolioCostBasis = costbasis; portfolio.portfolioCurrentValue = currentValue; portfolio.portfolioTotalPnLPernt = (currentValue - costbasis) / costbasis; return portfolio; }
public Portfolio ReadPortfolio(string filename) { if (File.Exists(filename)) { Portfolio portfolio = new Portfolio(); foreach (XElement transaction in XDocument.Load(filename).Descendants("portfolio")) { XElement portfolioName = transaction.Element("portfolioName"); portfolio.portfolioName = portfolioName != null ? portfolioName.Value : string.Empty; } var positionList = new List<Position>(); foreach (XElement transaction in XDocument.Load(filename).Descendants("position")) { XElement positionTicker = transaction.Element("positionTicker"); XElement positionOpenDate = transaction.Element("positionOpenDate"); XElement positionSize = transaction.Element("positionSize"); XElement executionPrice = transaction.Element("executionPrice"); positionList.Add(new Position { Ticker = positionTicker != null ? positionTicker.Value : string.Empty, OpenDate = positionOpenDate != null ? Convert.ToDateTime(positionOpenDate.Value) : DateTime.Now, Quantity = positionSize != null ? int.Parse(positionSize.Value) : default(int), ExecPrice = executionPrice != null ? decimal.Parse(executionPrice.Value) : default(decimal) }); } portfolio.positions = positionList; // Console.WriteLine(string.Format(" Number of transactions loaded : {0}",positionList.Count));'' return portfolio; } else { Console.WriteLine("Input portfolio file not found. Please make sure you have the Portfolio.xml file in the correct location"); return null; } }
public Form1(Portfolio portfolio) { InitializeComponent(); this.portfolio = portfolio; }
static void Main() { Console.WriteLine("Portfolio Viewer is launching, please wait..."); Console.WriteLine("Approximate wait time of 8 seconds."); // Load data from the XML datastore Portfolio portfolio = new Portfolio(); Calculator calculator = new Calculator(); String startupPath = Application.StartupPath + "\\Portfolio.xml"; // TODO Make this a relative path instead of an absolute path //C:\\developer\\code\\c#\\PerformanceCalculator\\PerformanceCalculator\\Portfolio.xml portfolio = portfolio.ReadPortfolio(startupPath); // Iterate over the tickers to construct the URL List<Position> positions = portfolio.positions; String concatenatedTicker = ""; if (positions != null) { foreach (Position position in positions) { concatenatedTicker = concatenatedTicker + position.Ticker + yahooConcatenator; } // Removing the last "+" sign concatenatedTicker = concatenatedTicker.Substring(0, concatenatedTicker.LastIndexOf(yahooConcatenator)); } // Construct final URL String yahooURL = baseYahooUrl + concatenatedTicker + baseYahooelements; // Call Yahoo string csvData; using (WebClient web = new WebClient()) { csvData = web.DownloadString(yahooURL); } // Parse prices coming back List<Price> prices = YahooFinance.Parse(csvData); // Map prices to portfolios foreach (Price price in prices) { if (positions != null) { foreach (Position position in positions) { String simpleSymbol = price.Symbol.Replace("\"", ""); if (position.Ticker.Equals(simpleSymbol)) { position.SecName = price.Name.Replace("\"", ""); position.SecLastPrice = price.Last; position.SecOpenPrice = price.Open; position.SecPrevClosePrice = price.PreviousClose; // Also calculate PnLs calculator.calculateDailyPnL(position); calculator.calculateTotalPnL(position); } // Console.WriteLine(string.Format("{0} ({1}) Last:{2} Open: {3} PreviousClose:{4}", price.Name, price.Symbol, price.Last, price.Open, price.PreviousClose)); } } } // Calculate absolute values PnL values at the portfolio level portfolio = calculator.calculatePortfolioTotals(portfolio); portfolio = calculator.calculatePortfolioTotalPercent(portfolio); portfolio.printToConsole(); // Add to the final list for display Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1(portfolio)); }