Files
Navigator/MarketDataLib/MarketDataModel/PortfolioTrades.cs
2024-02-23 06:53:16 -05:00

179 lines
7.4 KiB
C#

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<PortfolioTrade>
{
public PortfolioTrades()
{
}
public PortfolioTrades(List<PortfolioTrade> trades)
{
if(null==trades)return;
for (int index = 0; index < trades.Count; index++) Add(trades[index]);
}
public List<String> Symbols
{
get
{
Dictionary<String, String> uniqueSymbols = new Dictionary<String, String>();
List<String> symbols = new List<String>();
foreach (PortfolioTrade portfolioTrade in this)
{
if (!uniqueSymbols.ContainsKey(portfolioTrade.Symbol)) uniqueSymbols.Add(portfolioTrade.Symbol, portfolioTrade.Symbol);
}
symbols = new List<String>(uniqueSymbols.Values);
symbols.Sort();
return symbols;
}
}
public List<Position> GetPositions(DateTime asOf)
{
List<Position> positions = new List<Position>();
List<String> symbols = Symbols;
foreach (String symbol in symbols) positions.Add(GetPosition(symbol, asOf));
return positions;
}
public Position GetPosition(String symbol,DateTime asof)
{
List<PortfolioTrade> portfolioTrades = new List<PortfolioTrade>();
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<String> Accounts
{
get
{
Dictionary<String, String> uniqueAccounts = new Dictionary<String, String>();
List<String> accounts = new List<String>();
foreach (PortfolioTrade portfolioTrade in this)
{
if (!uniqueAccounts.ContainsKey(portfolioTrade.Account)) uniqueAccounts.Add(portfolioTrade.Account, portfolioTrade.Account);
}
accounts = new List<String>(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<PortfolioTrade> 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<String> 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;
}
}
}