using System; using System.Collections.Generic; using System.Linq; using System.Text; using MarketData.Utils; namespace MarketData.MarketDataModel { public class Position { public String Symbol { get; set; } public double Shares{get;set;} public double Exposure { get; set; } public double MarketValue { get; set; } } public class PortfolioTrades : List { public PortfolioTrades() { } public PortfolioTrades(List trades) { if(null==trades)return; for (int index = 0; index < trades.Count; index++) Add(trades[index]); } public List Symbols { get { Dictionary uniqueSymbols = new Dictionary(); List symbols = new List(); foreach (PortfolioTrade portfolioTrade in this) { if (!uniqueSymbols.ContainsKey(portfolioTrade.Symbol)) uniqueSymbols.Add(portfolioTrade.Symbol, portfolioTrade.Symbol); } symbols = new List(uniqueSymbols.Values); symbols.Sort(); return symbols; } } public List GetPositions(DateTime asOf) { List positions = new List(); List symbols = Symbols; foreach (String symbol in symbols) positions.Add(GetPosition(symbol, asOf)); return positions; } public Position GetPosition(String symbol,DateTime asof) { List portfolioTrades = new List(); for (int index = 0; index < Count; index++) { PortfolioTrade portfolioTrade = this[index]; if (!portfolioTrade.Symbol.Equals(symbol)) continue; if (portfolioTrade.IsOpen && portfolioTrade.TradeDate<=asof) { portfolioTrades.Add(portfolioTrade); continue; } if (portfolioTrade.IsClosed && portfolioTrade.SellDate > asof) { portfolioTrades.Add(portfolioTrade); continue; } } if (0 == portfolioTrades.Count) return null; Position position = new Position(); position.Symbol = symbol; position.Shares = portfolioTrades.Sum(x => x.Shares); position.Exposure = portfolioTrades.Sum(x=>x.Shares*x.Price); return position; } public double Exposure(){return this.Sum(x=>x.Exposure());} public List Accounts { get { Dictionary uniqueAccounts = new Dictionary(); List accounts = new List(); foreach (PortfolioTrade portfolioTrade in this) { if (!uniqueAccounts.ContainsKey(portfolioTrade.Account)) uniqueAccounts.Add(portfolioTrade.Account, portfolioTrade.Account); } accounts = new List(uniqueAccounts.Values); accounts.Sort(); return accounts; } } public DateTime GetMinTradeDate() { DateTime minDate = Utility.Epoch; minDate = (from portfolioTrade in this select portfolioTrade.TradeDate).Min(); return minDate; } public DateTime GetMinTradeDate(String symbol) { DateTime minDate=Utility.Epoch; symbol=symbol.ToUpper(); minDate = (from portfolioTrade in this where portfolioTrade.Symbol.Equals(symbol) select portfolioTrade.TradeDate).Min(); return minDate; } // We just want the trades (open or closed) on or before the specified date. This will be used to run a cumulative gain/loss and return public PortfolioTrades GetTradesOnOrBefore(DateTime date) { PortfolioTrades tradesOnOrBefore = new PortfolioTrades(); foreach (PortfolioTrade portfolioTrade in this) { if (date >= portfolioTrade.TradeDate) tradesOnOrBefore.Add(portfolioTrade); } return tradesOnOrBefore; } // This will remove trades that are status='CLOSED' and SELL_DATE=closingDate // The user of this fucntion would be making the inference that a trade that closed on closingDate should not be seen as part of the holdings. // For example. The assumption would be that trades that closed on closingDate would not be a part of the portfolio on closingDate public PortfolioTrades RemoveClosedTradesWhereClosedOn(DateTime closingDate) { PortfolioTrades portfolioTrades; List removeTrades = (from PortfolioTrade portfolioTrade in this where portfolioTrade.Status.Equals("CLOSED") && portfolioTrade.SellDate.Date.Equals(closingDate.Date) select portfolioTrade).ToList(); if (null != removeTrades && 0 != removeTrades.Count) portfolioTrades = new PortfolioTrades(this.Except(removeTrades).ToList()); else portfolioTrades = this; return portfolioTrades; } public PortfolioTrades GetOpenTradesOn(DateTime date) { PortfolioTrades openTrades = new PortfolioTrades(); foreach (PortfolioTrade portfolioTrade in this) { if (Utility.Epoch.Equals(portfolioTrade.SellDate)) // No sell date so trade is open { if (date >= portfolioTrade.TradeDate) openTrades.Add(portfolioTrade); } else // sell date is not epoch so see if date is in between tradedate and selldate { if (date >= portfolioTrade.TradeDate && date < portfolioTrade.SellDate) openTrades.Add(portfolioTrade); // assume that if the sell date is equal to date then the position is closed } } return openTrades; } public bool HasOpenPositions(String symbol) { int openTrades=(from PortfolioTrade portfolioTrade in this where portfolioTrade.Symbol.Equals(symbol) && portfolioTrade.IsOpen select portfolioTrade).Count(); return openTrades>0?true:false; } public bool HasOpenPositionsOn(String symbol,DateTime dateTime) { PortfolioTrades portfolioTrades=GetOpenTradesOn(dateTime); int numTrades=(from PortfolioTrade portfolioTrade in portfolioTrades where portfolioTrade.Symbol.Equals(symbol) select portfolioTrade).Count(); return numTrades>0?true:false; } // This method relies on the fact that BreakoutTrades method in PortfolioDA.GetTradesSymbol() creates pairs of BUY and SELL legs with paired legs sharing the same TradeId. // The open trades will show up with count==1 when we group them by TradeId public PortfolioTrades GetOpenTrades() { if(0==Count)return new PortfolioTrades(); PortfolioTrades openTrades=new PortfolioTrades((from PortfolioTrade trade in this select trade).GroupBy(x=>x.TradeId).Where(grouping=>grouping.Count()==1).Select(grouping=>grouping.FirstOrDefault()).ToList()); return openTrades; } public PortfolioTrades FilterAccount(String account) { PortfolioTrades portfolioTrades = new PortfolioTrades(); foreach (PortfolioTrade portfolioTrade in this) { if (portfolioTrade.Account.Equals(account)) portfolioTrades.Add(portfolioTrade); } return portfolioTrades; } public PortfolioTrades FilterAccount(List accounts) { PortfolioTrades portfolioTrades = new PortfolioTrades(); foreach (PortfolioTrade portfolioTrade in this) { if(accounts.Any(x=>x.Equals(portfolioTrade.Account)))portfolioTrades.Add(portfolioTrade); } return portfolioTrades; } public PortfolioTrades FilterSymbol(String symbol) { PortfolioTrades portfolioTrades = new PortfolioTrades(); foreach (PortfolioTrade portfolioTrade in this) { if (portfolioTrade.Symbol.Equals(symbol)) portfolioTrades.Add(portfolioTrade); } return portfolioTrades; } } }