Files
TradeBlotter/ViewModels/SectorViewModel.cs
2026-02-24 12:20:56 -05:00

330 lines
11 KiB
C#

using System;
using System.Windows.Input;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Threading;
using MarketData.DataAccess;
using MarketData.MarketDataModel;
using MarketData.Utils;
using TradeBlotter.Command;
using TradeBlotter.Cache;
using TradeBlotter.Model;
using Telerik.Charting;
using Telerik.Windows.Controls.Charting;
using MarketData;
namespace TradeBlotter.ViewModels
{
public class SectorViewModel : WorkspaceViewModel
{
private PortfolioTrades portfolioTrades = null;
private List<PieDataPoint> sectorIndustryDataPointsExposure = null;
private List<PieDataPoint> sectorIndustryDataPointsContribution = null;
private List<String> selectedOperations = null;
private String selectedAccount = Constants.CONST_ALL;
private String selectedOperation;
private RelayCommand refreshCommand;
private bool includeCash = false;
private bool busyIndicator = false;
private double cashBalance = double.NaN;
public SectorViewModel()
{
base.DisplayName = "Asset Allocation";
selectedOperations = new List<String>();
selectedOperations.Add("Sector");
selectedOperations.Add("Industry");
selectedOperations.Add("Names");
selectedOperation = selectedOperations[0];
PropertyChanged += OnSectorViewModelPropertyChanged;
base.OnPropertyChanged("SelectedOperation");
}
public override SaveParameters GetSaveParameters()
{
return null;
}
public override void SetSaveParameters(SaveParameters saveParameters)
{
}
public override bool CanPersist()
{
return false;
}
protected override void OnDispose()
{
}
public bool BusyIndicator
{
get
{
return busyIndicator;
}
set
{
busyIndicator = value;
base.OnPropertyChanged("BusyIndicator");
}
}
private void OnSectorViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs)
{
if (eventArgs.PropertyName.Equals("SelectedOperation") || eventArgs.PropertyName.Equals("UseRealPrice") || eventArgs.PropertyName.Equals("IncludeCash") || eventArgs.PropertyName.Equals("SelectedAccount"))
{
BusyIndicator = true;
Task workerTask = Task.Factory.StartNew(() =>
{
if (null == portfolioTrades)portfolioTrades = PortfolioDA.GetOpenTrades();
CreateSectorIndustryExposure(portfolioTrades, selectedOperation);
CreateSectorIndustryContribution(portfolioTrades, selectedOperation);
});
workerTask.ContinueWith((continuation)=>
{
BusyIndicator = false;
base.OnPropertyChanged("PieDataExposure");
base.OnPropertyChanged("PieDataContribution");
base.OnPropertyChanged("TitleExposure");
base.OnPropertyChanged("TitleContribution");
});
}
}
public PortfolioTrades GetAccountTrades()
{
if (Constants.CONST_ALL.Equals(selectedAccount)) return portfolioTrades;
return portfolioTrades.FilterAccount(selectedAccount);
}
private void CreateSectorIndustryExposure(PortfolioTrades portfolioTrades, String sectorIndustry)
{
try
{
double totalExposure = 0.00;
Dictionary<String, double> sectorIndustryExposure = new Dictionary<String, double>();
PortfolioTrades accountTrades = GetAccountTrades();
cashBalance = double.NaN;
if (includeCash)
{
// double cashBalance = CashDA.GetBalance();
cashBalance = CashDA.GetBalance();
if (Constants.CONST_ALL.Equals(selectedAccount)) cashBalance = CashDA.GetBalance();
else cashBalance = CashDA.GetBalance(selectedAccount);
if (!double.IsNaN(cashBalance))
{
totalExposure += cashBalance;
sectorIndustryExposure.Add("Cash", cashBalance);
}
}
foreach (PortfolioTrade portfolioTrade in accountTrades)
{
totalExposure += portfolioTrade.Price * portfolioTrade.Shares;
if (sectorIndustry.Equals("Sector"))
{
String sector = PricingDA.GetSectorForSymbol(portfolioTrade.Symbol);
if(null==sector)sector="Unclassified";
if (sectorIndustryExposure.ContainsKey(sector))
{
sectorIndustryExposure[sector] += (portfolioTrade.Price * portfolioTrade.Shares);
}
else
{
sectorIndustryExposure.Add(sector, portfolioTrade.Price * portfolioTrade.Shares);
}
}
else if (sectorIndustry.Equals("Industry"))
{
String industry = PricingDA.GetIndustryForSymbol(portfolioTrade.Symbol);
if(null==industry)industry="Unclassified";
if (sectorIndustryExposure.ContainsKey(industry))
{
sectorIndustryExposure[industry] += (portfolioTrade.Price * portfolioTrade.Shares);
}
else
{
sectorIndustryExposure.Add(industry, portfolioTrade.Price * portfolioTrade.Shares);
}
}
else
{
if (sectorIndustryExposure.ContainsKey(portfolioTrade.Symbol))
{
sectorIndustryExposure[portfolioTrade.Symbol] += (portfolioTrade.Price * portfolioTrade.Shares);
}
else
{
sectorIndustryExposure.Add(portfolioTrade.Symbol, portfolioTrade.Price * portfolioTrade.Shares);
}
}
}
List<String> keys = new List<String>(sectorIndustryExposure.Keys);
sectorIndustryDataPointsExposure = new List<PieDataPoint>();
foreach (String key in keys)
{
sectorIndustryExposure[key] = (sectorIndustryExposure[key] / totalExposure) * 100.00;
PieDataPoint pieDataPoint = new PieDataPoint();
pieDataPoint.Label = key + " " + String.Format("{0:F}", sectorIndustryExposure[key]) + "%";
pieDataPoint.Value = sectorIndustryExposure[key];
sectorIndustryDataPointsExposure.Add(pieDataPoint);
}
}
catch(Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString()));
}
}
private void CreateSectorIndustryContribution(PortfolioTrades portfolioTrades, String sectorIndustry)
{
double totalExposure = 0.00;
Dictionary<String, double> sectorIndustryContribution = new Dictionary<String, double>();
PortfolioTrades accountTrades = GetAccountTrades();
foreach (PortfolioTrade portfolioTrade in accountTrades)
{
Price price = PricingDA.GetPrice(portfolioTrade.Symbol);
totalExposure += price.Close * portfolioTrade.Shares;
if (sectorIndustry.Equals("Sector"))
{
String sector = PricingDA.GetSectorForSymbol(portfolioTrade.Symbol);
if(null==sector)sector="Unclassified";
if (sectorIndustryContribution.ContainsKey(sector))
{
sectorIndustryContribution[sector] += (price.Close * portfolioTrade.Shares);
}
else
{
sectorIndustryContribution.Add(sector, price.Close * portfolioTrade.Shares);
}
}
else if(sectorIndustry.Equals("Industry"))
{
String industry = PricingDA.GetIndustryForSymbol(portfolioTrade.Symbol);
if(null==industry)industry="Unclassified";
if (sectorIndustryContribution.ContainsKey(industry))
{
sectorIndustryContribution[industry] += (price.Close * portfolioTrade.Shares);
}
else
{
sectorIndustryContribution.Add(industry, price.Close * portfolioTrade.Shares);
}
}
else
{
if (sectorIndustryContribution.ContainsKey(portfolioTrade.Symbol))
{
sectorIndustryContribution[portfolioTrade.Symbol] += (price.Close * portfolioTrade.Shares);
}
else
{
sectorIndustryContribution.Add(portfolioTrade.Symbol, price.Close * portfolioTrade.Shares);
}
}
}
List<String> keys = new List<String>(sectorIndustryContribution.Keys);
sectorIndustryDataPointsContribution = new List<PieDataPoint>();
foreach (String key in keys)
{
sectorIndustryContribution[key] = (sectorIndustryContribution[key] / totalExposure) * 100.00;
PieDataPoint pieDataPoint = new PieDataPoint();
pieDataPoint.Label = key + " " + String.Format("{0:F}", sectorIndustryContribution[key]) + "%";
pieDataPoint.Value = sectorIndustryContribution[key];
sectorIndustryDataPointsContribution.Add(pieDataPoint);
}
}
public List<PieDataPoint> PieDataExposure
{
get
{
return sectorIndustryDataPointsExposure;
}
}
public List<PieDataPoint> PieDataContribution
{
get
{
return sectorIndustryDataPointsContribution;
}
}
public bool IncludeCash
{
get { return includeCash; }
set { includeCash = value; base.OnPropertyChanged("IncludeCash"); }
}
public List<String> Accounts
{
get
{
if (null == portfolioTrades) return null;
List<String> accounts = portfolioTrades.Accounts;
accounts.Insert(0, Constants.CONST_ALL);
return accounts;
}
}
public String SelectedAccount
{
get { return selectedAccount; }
set { selectedAccount = value; base.OnPropertyChanged("SelectedAccount"); }
}
public ICommand RefreshCommand
{
get
{
if (null == refreshCommand)
{
refreshCommand = new RelayCommand(param => this.Refresh(), param => this.CanRefresh);
}
return refreshCommand;
}
}
public bool CanRefresh
{
get { return true; }
}
public void Refresh()
{
base.OnPropertyChanged("SelectedOperation");
}
public List<String> SectorIndustry
{
get { return selectedOperations; }
}
public String SelectedOperation
{
get { return selectedOperation; }
set { selectedOperation = value; base.OnPropertyChanged("SelectedOperation"); }
}
public String TitleExposure
{
get
{
StringBuilder sb = new StringBuilder();
sb.Append(base.DisplayName).Append(" - ");
sb.Append(SelectedOperation);
sb.Append(" Breakdown ");
if (Constants.CONST_ALL.Equals(selectedAccount)) sb.Append("All Accounts ");
else sb.Append("Account ").Append(selectedAccount);
sb.Append(" (Exposure)");
if (includeCash)
{
sb.Append(" (").Append("Available Cash ").Append(Utility.FormatCurrency(cashBalance)).Append(")");
}
return sb.ToString();
}
}
public String TitleContribution
{
get
{
StringBuilder sb = new StringBuilder();
sb.Append(base.DisplayName).Append(" - ");
sb.Append(SelectedOperation);
sb.Append(" Breakdown ");
if (Constants.CONST_ALL.Equals(selectedAccount)) sb.Append("All Accounts ");
else sb.Append("Account ").Append(selectedAccount);
sb.Append(" (Contribution)");
return sb.ToString();
}
}
}
}