1043 lines
46 KiB
C#
1043 lines
46 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Linq;
|
|
using System.Windows.Input;
|
|
using System.Windows.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Collections.ObjectModel;
|
|
using System.Threading;
|
|
using System.Windows;
|
|
using Microsoft.Research.DynamicDataDisplay.DataSources;
|
|
using MarketData;
|
|
using MarketData.MarketDataModel;
|
|
using MarketData.Generator;
|
|
using MarketData.DataAccess;
|
|
using MarketData.Utils;
|
|
using TradeBlotter.UIUtils;
|
|
using TradeBlotter.Model;
|
|
using TradeBlotter.Command;
|
|
using TradeBlotter.Cache;
|
|
using MarketData.Numerical;
|
|
using MarketData.Generator.GainLoss;
|
|
using MarketData.MarketDataModel.GainLoss;
|
|
using MarketData.Cache;
|
|
using MarketData.Helper;
|
|
using MarketData.Generator.MovingAverage;
|
|
|
|
namespace TradeBlotter.ViewModels
|
|
{
|
|
public class GainLossViewModel : WorkspaceViewModel
|
|
{
|
|
private enum Tasks{Accounts,SelectedSymbol,SelectedAccounts,LeastSquaresFit,UseDividends};
|
|
private Dictionary<Tasks,Semaphore> semaphorePool=new Dictionary<Tasks,Semaphore>();
|
|
private ObservableCollection<GainLossSummaryItem> gainLossSummaryItemCollection=new ObservableCollection<GainLossSummaryItem>();
|
|
private ITotalGainLossGenerator gainLossGenerator=null;
|
|
private IActiveGainLossGenerator activeGainLossGenerator=null;
|
|
private ObservableCollection<GainLossCompoundModel> gainLossCompoundModelCollection=new ObservableCollection<GainLossCompoundModel>();
|
|
private GainLossCompoundModelCollection gainLossModelCollection=null;
|
|
private GainLossCompoundModel selectedGainLossCompoundItem=null;
|
|
private GainLossSummaryItem selectedGainLossSummaryItem=null;
|
|
private String selectedSymbol =Constants.CONST_ALL;
|
|
private TotalGainLossCollection totalGainLoss=null; // total gain/loss
|
|
private PortfolioTrades portfolioTrades = null;
|
|
private String selectedCompanyName;
|
|
private bool suspendUpdate=false;
|
|
private String selectedAccounts;
|
|
private List<String> accounts=null;
|
|
private DateTime latestMarketDate=Utility.Epoch;
|
|
// RelayCommands
|
|
private RelayCommand refreshCommand=null;
|
|
private RelayCommand toggleReturnOrPercentCommand=null;
|
|
private RelayCommand toggleActiveOrTotalCommand=null;
|
|
// RelayCommand for menu
|
|
private RelayCommand saveCommand=null;
|
|
private RelayCommand stochasticsCommand=null;
|
|
private RelayCommand relativeStrengthCommand=null;
|
|
private RelayCommand macdCommand=null;
|
|
private RelayCommand movingAverageCommand;
|
|
private RelayCommand bollingerBandCommand=null;
|
|
private RelayCommand priceHistoryCommand=null;
|
|
private RelayCommand stickerValuationCommand=null;
|
|
private RelayCommand dcfValuationCommand=null;
|
|
private RelayCommand displayAnalystRatingsCommand=null;
|
|
private RelayCommand displayHeadlinesCommand=null;
|
|
private RelayCommand rollPriceForwardCommand=null;
|
|
private RelayCommand dividendHistoryCommand=null;
|
|
private RelayCommand displayHistoricalCommand=null;
|
|
private RelayCommand proformaDividendRiskCommand = null;
|
|
//
|
|
private ObservableCollection<String> symbols = new ObservableCollection<String>();
|
|
private bool busyIndicator = false;
|
|
private bool isLegendVisible = true;
|
|
private bool useLeastSquaresFit=true;
|
|
private bool useCumulativeGainLoss=true;
|
|
private Boolean showAsGainLoss = true;
|
|
private Boolean showActiveGainLoss=false; // show the total gain/loss graph in the view by default
|
|
private Boolean includeDividends=false; // include dividends in the calculation of TOTAL gain/loss, ACTIVE gain/loss never includes dividends
|
|
private String busyContent = "Generating Gain/Loss...";
|
|
|
|
public GainLossViewModel()
|
|
{
|
|
latestMarketDate=PremarketDA.GetLatestMarketDate();
|
|
semaphorePool.Add(Tasks.SelectedSymbol,new Semaphore(1,1));
|
|
semaphorePool.Add(Tasks.SelectedAccounts,new Semaphore(1,1));
|
|
semaphorePool.Add(Tasks.LeastSquaresFit,new Semaphore(1,1));
|
|
semaphorePool.Add(Tasks.Accounts,new Semaphore(1,1));
|
|
semaphorePool.Add(Tasks.UseDividends,new Semaphore(1,1));
|
|
base.DisplayName = "GainLossView";
|
|
PropertyChanged += OnGainLossViewModelPropertyChanged;
|
|
BusyIndicator = true;
|
|
suspendUpdate=true;
|
|
Task workerTask = Task.Factory.StartNew(() =>
|
|
{
|
|
semaphorePool[Tasks.Accounts].WaitOne();
|
|
portfolioTrades = PortfolioDA.GetTrades();
|
|
if(null!=portfolioTrades&&0!=portfolioTrades.Count)
|
|
{
|
|
accounts = portfolioTrades.Accounts;
|
|
}
|
|
});
|
|
workerTask.ContinueWith((continuation) =>
|
|
{
|
|
BusyIndicator = false;
|
|
SelectedAccounts=AccountsToString(accounts);
|
|
suspendUpdate=false;
|
|
SetSymbols();
|
|
semaphorePool[Tasks.Accounts].Release();
|
|
});
|
|
}
|
|
public override SaveParameters GetSaveParameters()
|
|
{
|
|
return null;
|
|
}
|
|
public override void SetSaveParameters(SaveParameters saveParameters)
|
|
{
|
|
}
|
|
public override bool CanPersist()
|
|
{
|
|
return false;
|
|
}
|
|
public bool BusyIndicator
|
|
{
|
|
get { return busyIndicator; }
|
|
set
|
|
{
|
|
busyIndicator = value;
|
|
base.OnPropertyChanged("BusyIndicator");
|
|
}
|
|
}
|
|
public String BusyContent
|
|
{
|
|
get { return busyContent; }
|
|
set
|
|
{
|
|
busyContent = value;
|
|
base.OnPropertyChanged("BusyContent");
|
|
}
|
|
}
|
|
private void OnGainLossViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs)
|
|
{
|
|
if (eventArgs.PropertyName.Equals("SelectedSymbol"))HandleSelectedSymbol();
|
|
else if (eventArgs.PropertyName.Equals("SelectedAccounts"))HandleSelectedAccounts();
|
|
else if (eventArgs.PropertyName.Equals("LeastSquaresFit"))HandleLeastSquaresFit();
|
|
else if (eventArgs.PropertyName.Equals("SelectedGainLossCompoundItem"))HandleSelectedGainLossCompoundItem();
|
|
else if(eventArgs.PropertyName.Equals("CheckBoxUseCumulativeReturns")) HandleCheckBoxUseCumulativeReturns();
|
|
}
|
|
public void HandleCheckBoxUseCumulativeReturns()
|
|
{
|
|
gainLossGenerator=null;
|
|
activeGainLossGenerator=null;
|
|
base.OnPropertyChanged("SelectedSymbol");
|
|
}
|
|
public void HandleSelectedGainLossCompoundItem()
|
|
{
|
|
if(null==selectedGainLossCompoundItem)return;
|
|
BusyIndicator = true;
|
|
Task workerTask = Task.Factory.StartNew(() =>
|
|
{
|
|
DateTime selectedDate=selectedGainLossCompoundItem.Date;
|
|
PortfolioTrades tradesOnOrBefore=portfolioTrades.GetTradesOnOrBefore(selectedDate);
|
|
GainLossSummaryItemCollection gainLossSummaryItems=new GainLossSummaryItemCollection(tradesOnOrBefore,gainLossGenerator,activeGainLossGenerator,selectedDate);
|
|
gainLossSummaryItemCollection=new ObservableCollection<GainLossSummaryItem>(gainLossSummaryItems);
|
|
});
|
|
workerTask.ContinueWith((continuation) =>
|
|
{
|
|
BusyIndicator = false;
|
|
base.OnPropertyChanged("GainLossSummaryItemCollection");
|
|
});
|
|
}
|
|
public void InstantiateGenerators()
|
|
{
|
|
if(null==gainLossGenerator)
|
|
{
|
|
if(useCumulativeGainLoss)gainLossGenerator=new GainLossGeneratorCum();
|
|
else gainLossGenerator=new GainLossGenerator();
|
|
}
|
|
if(null==activeGainLossGenerator) activeGainLossGenerator=new ActiveGainLossGenerator();
|
|
}
|
|
public void HandleLeastSquaresFit()
|
|
{
|
|
try
|
|
{
|
|
semaphorePool[Tasks.LeastSquaresFit].WaitOne();
|
|
base.OnPropertyChanged("LeastSquares");
|
|
}
|
|
finally
|
|
{
|
|
semaphorePool[Tasks.LeastSquaresFit].Release();
|
|
}
|
|
}
|
|
public void HandleSelectedAccounts()
|
|
{
|
|
try
|
|
{
|
|
semaphorePool[Tasks.SelectedAccounts].WaitOne();
|
|
if(suspendUpdate)return;
|
|
MDTrace.WriteLine(String.Format("[GainLossViewModel::OnGainLossViewModelPropertyChanged]SelectedAccounts '{0}'",selectedAccounts));
|
|
portfolioTrades = PortfolioDA.GetTradesForAccounts(ParseAccounts(selectedAccounts));
|
|
SetSymbols();
|
|
}
|
|
finally
|
|
{
|
|
semaphorePool[Tasks.SelectedAccounts].Release();
|
|
}
|
|
}
|
|
public void HandleSelectedSymbol()
|
|
{
|
|
try
|
|
{
|
|
semaphorePool[Tasks.SelectedSymbol].WaitOne();
|
|
gainLossCompoundModelCollection=null;
|
|
gainLossSummaryItemCollection=null;
|
|
if(suspendUpdate)return;
|
|
if (null == selectedSymbol||"".Equals(selectedAccounts))
|
|
{
|
|
UpdateProperties();
|
|
return;
|
|
}
|
|
MDTrace.WriteLine(String.Format("[GainLossViewModel::OnGainLossViewModelPropertyChanged]SelectedSymbol '{0}'",selectedSymbol));
|
|
BusyIndicator = true;
|
|
Task workerTask = Task.Factory.StartNew(() =>
|
|
{
|
|
DividendPayments dividendPayments=null;
|
|
if(Constants.CONST_ALL.Equals(selectedSymbol))
|
|
{
|
|
portfolioTrades = PortfolioDA.GetTrades();
|
|
if(includeDividends)dividendPayments=DividendPaymentDA.GetDividendPayments();
|
|
selectedCompanyName="";
|
|
}
|
|
else
|
|
{
|
|
portfolioTrades = PortfolioDA.GetTrades(selectedSymbol);
|
|
if(includeDividends)dividendPayments=DividendPaymentDA.GetDividendPaymentsForSymbol(selectedSymbol);
|
|
selectedCompanyName=PricingDA.GetNameForSymbol(selectedSymbol);
|
|
}
|
|
if(null!=portfolioTrades&&0!=portfolioTrades.Count)
|
|
{
|
|
accounts = portfolioTrades.Accounts;
|
|
}
|
|
portfolioTrades=portfolioTrades.FilterAccount(ParseAccounts(selectedAccounts));
|
|
if(null!=dividendPayments)dividendPayments=dividendPayments.FilterAccounts(selectedAccounts);
|
|
|
|
// check the TotalGainLoss generator and build appropriately
|
|
InstantiateGenerators();
|
|
LocalPriceCache.GetInstance().Refresh();
|
|
GainLossCollection gainLoss = null;
|
|
gainLoss=activeGainLossGenerator.GenerateGainLoss(portfolioTrades); // gainLoss contains the gain/loss from active positions. Never includes dividends .. just positions
|
|
// Call the appropriate TotalGainLoss method depending on whether we should include dividends or not.
|
|
if(includeDividends)totalGainLoss=gainLossGenerator.GenerateTotalGainLossWithDividends(portfolioTrades,dividendPayments);
|
|
else totalGainLoss=gainLossGenerator.GenerateTotalGainLoss(portfolioTrades);
|
|
|
|
gainLossModelCollection=null;
|
|
gainLossModelCollection=new GainLossCompoundModelCollection(gainLoss,totalGainLoss);
|
|
if(null!=gainLossModelCollection)
|
|
{
|
|
gainLossModelCollection.Sort(new SortGainLossCompoundModelYearDescendingOrder());
|
|
gainLossCompoundModelCollection=new ObservableCollection<GainLossCompoundModel>(gainLossModelCollection);
|
|
}
|
|
GainLossSummaryItemCollection gainLossSummaryItems=new GainLossSummaryItemCollection(portfolioTrades,gainLossGenerator,activeGainLossGenerator);
|
|
gainLossSummaryItemCollection=new ObservableCollection<GainLossSummaryItem>(gainLossSummaryItems);
|
|
});
|
|
workerTask.ContinueWith((continuation) =>
|
|
{
|
|
BusyIndicator = false;
|
|
UpdateProperties();
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
semaphorePool[Tasks.SelectedSymbol].Release();
|
|
}
|
|
}
|
|
public void UpdateProperties()
|
|
{
|
|
base.OnPropertyChanged("Accounts");
|
|
base.OnPropertyChanged("Data");
|
|
base.OnPropertyChanged("MA21");
|
|
base.OnPropertyChanged("MA55");
|
|
base.OnPropertyChanged("MA90");
|
|
base.OnPropertyChanged("Title");
|
|
base.OnPropertyChanged("GainLossCompoundModelCollection");
|
|
base.OnPropertyChanged("GainLossSummaryItemCollection");
|
|
base.OnPropertyChanged("LeastSquares");
|
|
base.OnPropertyChanged("LeastSquaresTitle");
|
|
}
|
|
public void SetSymbols()
|
|
{
|
|
symbols = new ObservableCollection<String>();
|
|
symbols.Add(Constants.CONST_ALL);
|
|
List<String> tradedSymbols = portfolioTrades.Symbols;
|
|
foreach (String symbol in tradedSymbols) symbols.Add(symbol);
|
|
base.OnPropertyChanged("Symbols");
|
|
SelectedSymbol=symbols[0];
|
|
}
|
|
public ObservableCollection<String> Symbols
|
|
{
|
|
get
|
|
{
|
|
return symbols;
|
|
}
|
|
set
|
|
{
|
|
symbols = value;
|
|
base.OnPropertyChanged("Symbols");
|
|
}
|
|
}
|
|
public String SelectedSymbol
|
|
{
|
|
get
|
|
{
|
|
MDTrace.WriteLine(String.Format("[GainLossViewModel::SelectedSymbol] Get {0}",selectedSymbol));
|
|
return selectedSymbol;
|
|
}
|
|
set
|
|
{
|
|
MDTrace.WriteLine(String.Format("[GainLossViewModel::SelectedSymbol] Set {0}",selectedSymbol));
|
|
selectedSymbol = value;
|
|
base.OnPropertyChanged("SelectedSymbol");
|
|
}
|
|
}
|
|
public List<String> Accounts
|
|
{
|
|
get
|
|
{
|
|
semaphorePool[Tasks.Accounts].WaitOne();
|
|
MDTrace.WriteLine(String.Format("[GainLossViewModel::Accounts] {0}",accounts==null?"null":"non-null"));
|
|
semaphorePool[Tasks.Accounts].Release();
|
|
return accounts;
|
|
}
|
|
}
|
|
public String SelectedAccounts
|
|
{
|
|
get
|
|
{
|
|
MDTrace.WriteLine(String.Format("[GainLossViewModel:SelectedAccounts]Get '{0}'",selectedAccounts));
|
|
return selectedAccounts;
|
|
}
|
|
set
|
|
{
|
|
MDTrace.WriteLine(String.Format("[GainLossViewModel:SelectedAccounts]Set '{0}'",value));
|
|
selectedAccounts = value;
|
|
base.OnPropertyChanged("SelectedAccounts");
|
|
portfolioTrades = PortfolioDA.GetTradesForAccounts(ParseAccounts(selectedAccounts));
|
|
if(null==portfolioTrades)return;
|
|
accounts = portfolioTrades.Accounts;
|
|
SetSymbols();
|
|
}
|
|
}
|
|
private static String AccountsToString(List<String> accounts)
|
|
{
|
|
StringBuilder sb=new StringBuilder();
|
|
for(int index=0;index<accounts.Count;index++)
|
|
{
|
|
sb.Append(accounts[index]);
|
|
if(index<accounts.Count-1)sb.Append(",");
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
private List<String> ParseAccounts(String strAccounts)
|
|
{
|
|
String[] accounts=strAccounts.Split(',');
|
|
return accounts.ToList();
|
|
}
|
|
// *************************************************************************************************************************************************************************
|
|
// *************************************************************************** L I N E G R A P H D A T A ***************************************************************
|
|
// *************************************************************************************************************************************************************************
|
|
public CompositeDataSource Data
|
|
{
|
|
get
|
|
{
|
|
if (null == gainLossModelCollection) return null;
|
|
CompositeDataSource compositeDataSource=null;
|
|
if(showActiveGainLoss)compositeDataSource = GainLossModel.GainLoss(gainLossModelCollection,showAsGainLoss);
|
|
else compositeDataSource = GainLossModel.TotalGainLoss(gainLossModelCollection,showAsGainLoss);
|
|
return compositeDataSource;
|
|
}
|
|
}
|
|
public CompositeDataSource LeastSquares
|
|
{
|
|
get
|
|
{
|
|
if(!useLeastSquaresFit||null==gainLossModelCollection)return null;
|
|
if(showActiveGainLoss)return GainLossModel.LeastSquares(gainLossModelCollection,showAsGainLoss);
|
|
else return GainLossModel.TotalLeastSquares(gainLossModelCollection,showAsGainLoss);
|
|
}
|
|
}
|
|
public CompositeDataSource MA21
|
|
{
|
|
get
|
|
{
|
|
if (null == gainLossModelCollection) return null;
|
|
CompositeDataSource compositeDataSource = null;
|
|
DMAValues dmaValues=null;
|
|
if(showActiveGainLoss)
|
|
{
|
|
if(showAsGainLoss)dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesActiveGainLoss,21);
|
|
else dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesActiveGainLossPercent,21);
|
|
compositeDataSource = MovingAverageModel.CreateCompositeDataSource(dmaValues);
|
|
}
|
|
else
|
|
{
|
|
if(showAsGainLoss)dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesTotalGainLoss,21);
|
|
else dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesTotalGainLossPercent,21);
|
|
compositeDataSource = MovingAverageModel.CreateCompositeDataSource(dmaValues);
|
|
}
|
|
return compositeDataSource;
|
|
}
|
|
}
|
|
public CompositeDataSource MA55
|
|
{
|
|
get
|
|
{
|
|
if (null == gainLossModelCollection) return null;
|
|
CompositeDataSource compositeDataSource = null;
|
|
DMAValues dmaValues=null;
|
|
if(showActiveGainLoss)
|
|
{
|
|
if(showAsGainLoss)dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesActiveGainLoss,55);
|
|
else dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesActiveGainLossPercent,55);
|
|
compositeDataSource = MovingAverageModel.CreateCompositeDataSource(dmaValues);
|
|
}
|
|
else
|
|
{
|
|
if(showAsGainLoss)dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesTotalGainLoss,55);
|
|
else dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesTotalGainLossPercent,55);
|
|
compositeDataSource = MovingAverageModel.CreateCompositeDataSource(dmaValues);
|
|
}
|
|
return compositeDataSource;
|
|
}
|
|
}
|
|
public CompositeDataSource MA90
|
|
{
|
|
get
|
|
{
|
|
if (null == gainLossModelCollection) return null;
|
|
CompositeDataSource compositeDataSource = null;
|
|
DMAValues dmaValues=null;
|
|
if(showActiveGainLoss)
|
|
{
|
|
if(showAsGainLoss)dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesActiveGainLoss,90);
|
|
else dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesActiveGainLossPercent,90);
|
|
compositeDataSource = MovingAverageModel.CreateCompositeDataSource(dmaValues);
|
|
}
|
|
else
|
|
{
|
|
if(showAsGainLoss)dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesTotalGainLoss,90);
|
|
else dmaValues=MovingAverageGenerator.GenerateMovingAverage(gainLossModelCollection.DMAValuesTotalGainLossPercent,90);
|
|
compositeDataSource = MovingAverageModel.CreateCompositeDataSource(dmaValues);
|
|
}
|
|
return compositeDataSource;
|
|
}
|
|
}
|
|
// ***********************************************************************************************************************************************************************************
|
|
// ****************************************************************************** C H E C K B O X E S ******************************************************************************
|
|
// ***********************************************************************************************************************************************************************************
|
|
public Boolean CheckBoxLegendVisible
|
|
{
|
|
get
|
|
{
|
|
return isLegendVisible;
|
|
}
|
|
set
|
|
{
|
|
isLegendVisible = value;
|
|
base.OnPropertyChanged("CheckBoxLegendVisible");
|
|
base.OnPropertyChanged("LegendVisible");
|
|
}
|
|
}
|
|
public Boolean CheckBoxIncludeDividends
|
|
{
|
|
get
|
|
{
|
|
return includeDividends;
|
|
}
|
|
set
|
|
{
|
|
includeDividends = value;
|
|
base.OnPropertyChanged("CheckBoxIncludeDividends");
|
|
base.OnPropertyChanged("SelectedSymbol");
|
|
}
|
|
}
|
|
public Boolean CheckBoxUseCumulativeReturns
|
|
{
|
|
get
|
|
{
|
|
return useCumulativeGainLoss;
|
|
}
|
|
set
|
|
{
|
|
useCumulativeGainLoss=value;
|
|
base.OnPropertyChanged("CheckBoxUseCumulativeReturns");
|
|
}
|
|
}
|
|
public Boolean CheckBoxSuspendUpdate
|
|
{
|
|
get
|
|
{
|
|
return suspendUpdate;
|
|
}
|
|
set
|
|
{
|
|
suspendUpdate = value;
|
|
base.OnPropertyChanged("CheckBoxSuspendUpdate");
|
|
if(!suspendUpdate)base.OnPropertyChanged("SelectedSymbol");
|
|
}
|
|
}
|
|
public String LeastSquaresTitle
|
|
{
|
|
get
|
|
{
|
|
if(null==gainLossModelCollection)return "LeastSquares";
|
|
LeastSquaresResult leastSquaresResult=GainLossModel.LeastSquaresFit(gainLossModelCollection,showAsGainLoss);
|
|
return "LeastSquares="+Utility.FormatNumber(leastSquaresResult.Slope,2);
|
|
}
|
|
}
|
|
public Boolean LeastSquaresFit
|
|
{
|
|
get
|
|
{
|
|
return useLeastSquaresFit;
|
|
}
|
|
set
|
|
{
|
|
useLeastSquaresFit = value;
|
|
base.OnPropertyChanged("LeastSquaresFit");
|
|
}
|
|
}
|
|
public String LegendVisible
|
|
{
|
|
get
|
|
{
|
|
if (isLegendVisible) return "true";
|
|
return "false";
|
|
}
|
|
set
|
|
{
|
|
isLegendVisible = Boolean.Parse(value);
|
|
base.OnPropertyChanged("LegendVisible");
|
|
}
|
|
}
|
|
public override String Title
|
|
{
|
|
get
|
|
{
|
|
if(null==gainLossModelCollection||0==gainLossModelCollection.Count)return "";
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Append(showActiveGainLoss?"Active":"Total").Append(" ");
|
|
sb.Append("Gain/Loss ");
|
|
if (showAsGainLoss) sb.Append("($)");
|
|
else sb.Append("(%)");
|
|
if (!Constants.CONST_ALL.Equals(selectedSymbol))sb.Append(" (").Append(selectedAccounts).Append(") ").Append(" - ").Append(selectedCompanyName).Append(" (").Append(selectedSymbol).Append(") ");
|
|
else sb.Append(" (").Append(selectedAccounts).Append(") ").Append(" - ").Append(selectedCompanyName);
|
|
DateTime fromDate=gainLossModelCollection.Select(x => x.Date).Min();
|
|
DateTime toDate = gainLossModelCollection.Select(x => x.Date).Max();
|
|
sb.Append(" from ").Append(Utility.DateTimeToStringMMHDDHYYYY(fromDate));
|
|
sb.Append(" Thru ").Append(Utility.DateTimeToStringMMHDDHYYYY(toDate));
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
private void Refresh()
|
|
{
|
|
latestMarketDate = PremarketDA.GetLatestMarketDate();
|
|
base.OnPropertyChanged("SelectedSymbol");
|
|
}
|
|
public ICommand RefreshCommand
|
|
{
|
|
get
|
|
{
|
|
if (refreshCommand == null)
|
|
{
|
|
refreshCommand = new RelayCommand(param => this.Refresh(), param => { return true;});
|
|
}
|
|
return refreshCommand;
|
|
}
|
|
}
|
|
// This is the button that controls the display in terms of percentages or dollar values
|
|
public String PercentButtonText
|
|
{
|
|
get
|
|
{
|
|
if (!showAsGainLoss) return "Show $";
|
|
else return "Show %";
|
|
}
|
|
}
|
|
public ICommand ToggleReturnOrPercentCommand
|
|
{
|
|
get
|
|
{
|
|
if (toggleReturnOrPercentCommand == null)
|
|
{
|
|
toggleReturnOrPercentCommand = new RelayCommand(action =>
|
|
{
|
|
showAsGainLoss = !showAsGainLoss;
|
|
base.OnPropertyChanged("SelectedSymbol");
|
|
base.OnPropertyChanged("PercentButtonText");
|
|
}, action => { return true; });
|
|
}
|
|
return toggleReturnOrPercentCommand;
|
|
}
|
|
}
|
|
// This is the button that controls the display in terms of active vs total return display on the graph
|
|
public String ActiveTotalButtonText
|
|
{
|
|
get
|
|
{
|
|
if (!showActiveGainLoss) return "Show Active G/L";
|
|
else return "Show Total G/L";
|
|
}
|
|
}
|
|
public ICommand ToggleActiveOrTotalCommand
|
|
{
|
|
get
|
|
{
|
|
if (toggleActiveOrTotalCommand == null)
|
|
{
|
|
toggleActiveOrTotalCommand = new RelayCommand(action =>
|
|
{
|
|
showActiveGainLoss=!showActiveGainLoss;
|
|
base.OnPropertyChanged("SelectedSymbol");
|
|
base.OnPropertyChanged("ActiveTotalButtonText");
|
|
}, action => { return true; });
|
|
}
|
|
return toggleActiveOrTotalCommand;
|
|
}
|
|
}
|
|
|
|
// *************************************************************************************************************************************************************************
|
|
// ***************************************************************************** T A B L E D A T A ***********************************************************************
|
|
// *************************************************************************************************************************************************************************
|
|
// The compound model collection is the data behind the views left-hand grid. This view shows the compound gain/loss since inception
|
|
public ObservableCollection<GainLossCompoundModel> GainLossCompoundModelCollection
|
|
{
|
|
get
|
|
{
|
|
return gainLossCompoundModelCollection;
|
|
}
|
|
}
|
|
// The summary item collection is the data behind the views right-hand grid. This view shows the gain/loss for the date that is selected in the compound model
|
|
public ObservableCollection<GainLossSummaryItem> GainLossSummaryItemCollection
|
|
{
|
|
get
|
|
{
|
|
return gainLossSummaryItemCollection;
|
|
}
|
|
}
|
|
// ****************************************************************************** G R I D S E L E C T I O N S ***********************************************
|
|
// The selected item in the compoint model
|
|
public GainLossCompoundModel SelectedGainLossCompoundItem
|
|
{
|
|
get
|
|
{
|
|
return selectedGainLossCompoundItem;
|
|
}
|
|
set
|
|
{
|
|
selectedGainLossCompoundItem = value;
|
|
base.OnPropertyChanged("SelectedGainLossCompoundItem");
|
|
}
|
|
}
|
|
// The selected item in the summary model
|
|
public GainLossSummaryItem SelectedGainLossSummaryItem
|
|
{
|
|
get
|
|
{
|
|
return selectedGainLossSummaryItem;
|
|
}
|
|
set
|
|
{
|
|
selectedGainLossSummaryItem = value;
|
|
base.OnPropertyChanged("SelectedGainLossSummaryItem");
|
|
}
|
|
}
|
|
// ************************************************************************************************************************************************************************************
|
|
// ************************************************************************************************************************************************************************************
|
|
// ************************************************************************************************************************************************************************************
|
|
public ObservableCollection<MenuItem> MenuItems
|
|
{
|
|
get
|
|
{
|
|
ObservableCollection<MenuItem> collection = new ObservableCollection<MenuItem>();
|
|
collection.Add(new MenuItem() { Text = "Display Bollinger Band", MenuItemClickedCommand = DisplayBollingerBand, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display Dividend History", MenuItemClickedCommand = DisplayDividendHistory, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display Proforma Dividend Risk", MenuItemClickedCommand = DisplayProformaDividendRisk, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display Sticker Valuation", MenuItemClickedCommand = DisplayStickerValuation, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display Historical", MenuItemClickedCommand = DisplayHistorical, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display Stochastics", MenuItemClickedCommand = DisplayStochastic, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display Relative Strength", MenuItemClickedCommand = DisplayRelativeStrength, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display MACD", MenuItemClickedCommand = DisplayMACD, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display Moving Average", MenuItemClickedCommand = DisplayMovingAverage, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display Price History", MenuItemClickedCommand = DisplayPriceHistory, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display DCF Valuation", MenuItemClickedCommand = DisplayDCFValuation, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display Analyst Ratings", MenuItemClickedCommand = DisplayAnalystRatings, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Display Headlines", MenuItemClickedCommand = DisplayHeadlines, StaysOpenOnClick = false });
|
|
collection.Add(new MenuItem() { Text = "Roll Price Forward", MenuItemClickedCommand = RollPriceForward, StaysOpenOnClick = false });
|
|
return collection;
|
|
}
|
|
}
|
|
|
|
public ICommand DisplayBollingerBand
|
|
{
|
|
get
|
|
{
|
|
if (bollingerBandCommand == null)
|
|
{
|
|
bollingerBandCommand = new RelayCommand(param => this.DisplayBollingerBandCommand(),
|
|
param => { return null != selectedGainLossSummaryItem && null!=selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return bollingerBandCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayDividendHistory
|
|
{
|
|
get
|
|
{
|
|
if (dividendHistoryCommand == null)
|
|
{
|
|
dividendHistoryCommand = new RelayCommand(param =>
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.DividendHistoryViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All}");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}, param => { return null != selectedGainLossSummaryItem && null != selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return dividendHistoryCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayProformaDividendRisk
|
|
{
|
|
get
|
|
{
|
|
if (proformaDividendRiskCommand == null)
|
|
{
|
|
proformaDividendRiskCommand = new RelayCommand(param =>
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.DividendRiskParityViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + "");
|
|
saveParams.Referer = this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}, param => { return null != selectedGainLossSummaryItem && null != selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return proformaDividendRiskCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayStickerValuation
|
|
{
|
|
get
|
|
{
|
|
if (null == stickerValuationCommand)
|
|
{
|
|
stickerValuationCommand = new RelayCommand(param =>
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.StickerPriceViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All}");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}, param => { return null != selectedGainLossSummaryItem && null!=selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return stickerValuationCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayHistorical
|
|
{
|
|
get
|
|
{
|
|
if (displayHistoricalCommand == null)
|
|
{
|
|
displayHistoricalCommand = new RelayCommand(param =>
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.HistoricalViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All}");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}, param => { return null != selectedGainLossSummaryItem && null != selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return displayHistoricalCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayStochastic
|
|
{
|
|
get
|
|
{
|
|
if (stochasticsCommand == null)
|
|
{
|
|
stochasticsCommand = new RelayCommand(param => this.DisplayStochasticCommand(),
|
|
param => { return null != selectedGainLossSummaryItem && null!=selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return stochasticsCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayRelativeStrength
|
|
{
|
|
get
|
|
{
|
|
if (relativeStrengthCommand == null)
|
|
{
|
|
relativeStrengthCommand = new RelayCommand(param => this.DisplayRelativeStrengthCommand(),
|
|
param => { return null != selectedGainLossSummaryItem && null!=selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return relativeStrengthCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayMACD
|
|
{
|
|
get
|
|
{
|
|
if (macdCommand == null)
|
|
{
|
|
macdCommand = new RelayCommand(param => this.DisplayMACDCommand(),
|
|
param => { return null != selectedGainLossSummaryItem && null!=selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return macdCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayMovingAverage
|
|
{
|
|
get
|
|
{
|
|
if (movingAverageCommand == null)
|
|
{
|
|
movingAverageCommand = new RelayCommand(param => this.DisplayMovingAverageCommand(), param => { return null != selectedGainLossSummaryItem && null != selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return movingAverageCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayPriceHistory
|
|
{
|
|
get
|
|
{
|
|
if (priceHistoryCommand == null)
|
|
{
|
|
priceHistoryCommand = new RelayCommand(param => this.DisplayPriceHistoryCommand(),
|
|
param => { return null != selectedGainLossSummaryItem && null!=selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return priceHistoryCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayDCFValuation
|
|
{
|
|
get
|
|
{
|
|
if (null == dcfValuationCommand)
|
|
{
|
|
dcfValuationCommand = new RelayCommand(param =>
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.DCFValuationViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All}");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}, param => { return null != selectedGainLossSummaryItem && null!=selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return dcfValuationCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayAnalystRatings
|
|
{
|
|
get
|
|
{
|
|
if (null == displayAnalystRatingsCommand)
|
|
{
|
|
displayAnalystRatingsCommand = new RelayCommand(param =>
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.AnalystRatingsViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All}");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}, param => { return null != selectedGainLossSummaryItem && null!=selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return displayAnalystRatingsCommand;
|
|
}
|
|
}
|
|
public ICommand DisplayHeadlines
|
|
{
|
|
get
|
|
{
|
|
if (null == displayHeadlinesCommand)
|
|
{
|
|
displayHeadlinesCommand = new RelayCommand(param =>
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.HeadlinesViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,Valuations");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}, param => { return null != selectedGainLossSummaryItem && null!=selectedGainLossSummaryItem.Symbol; });
|
|
}
|
|
return displayHeadlinesCommand;
|
|
}
|
|
}
|
|
public ICommand RollPriceForward
|
|
{
|
|
get
|
|
{
|
|
if (null == rollPriceForwardCommand)
|
|
{
|
|
rollPriceForwardCommand = new RelayCommand(param =>
|
|
{
|
|
Price previousPrice=PricingDA.GetPrice(selectedGainLossSummaryItem.Symbol);
|
|
Price latestPrice=PricingMarketDataHelper.RollPriceForward(selectedGainLossSummaryItem.Symbol);
|
|
System.Windows.MessageBox.Show(String.Format("{0} price rolled forward from {1} to {2}",selectedGainLossSummaryItem.Symbol,previousPrice.Date.ToShortDateString(),latestPrice.Date.ToShortDateString()),"Info",MessageBoxButton.OK,MessageBoxImage.Information);
|
|
ClearCache();
|
|
HandleSelectedSymbol();
|
|
}, param =>
|
|
{
|
|
if(null == selectedGainLossSummaryItem || null==selectedGainLossSummaryItem.Symbol)return false;
|
|
Price symbolPrice=GBPriceCache.GetInstance().GetPriceOrLatestAvailable(selectedGainLossSummaryItem.Symbol,latestMarketDate);
|
|
if(null==symbolPrice)return false;
|
|
if(symbolPrice.Date.Equals(latestMarketDate))return false;
|
|
DateGenerator dateGenerator=new DateGenerator();
|
|
DateTime prevBusinessDay=dateGenerator.FindPrevBusinessDay(latestMarketDate);
|
|
if(!symbolPrice.Date.Equals(prevBusinessDay))return false;
|
|
|
|
// This method was slowing things down quite considerably as it was constantly hitting the pricingDA.GetLatestDate()
|
|
// Refactored to the above code and seeing how that works out.
|
|
//DateTime latestDate=PremarketDA.GetLatestMarketDate();
|
|
//DateTime latestDateSymbol=PricingDA.GetLatestDate(selectedGainLossSummaryItem.Symbol);
|
|
//if(latestDate.Equals(latestDateSymbol))return false;
|
|
//DateGenerator dateGenerator=new DateGenerator();
|
|
//DateTime prevBusinessDay=dateGenerator.FindPrevBusinessDay(latestDate);
|
|
//if(!latestDateSymbol.Equals(prevBusinessDay))return false;
|
|
return true;
|
|
});
|
|
}
|
|
return rollPriceForwardCommand;
|
|
}
|
|
}
|
|
private void ClearCache()
|
|
{
|
|
try{LocalPriceCache.GetInstance().Clear();}catch(Exception){;}
|
|
try{GBPriceCache.GetInstance().Clear();}catch(Exception){;}
|
|
}
|
|
// **************************************************************************************************************************************************************************************
|
|
// ******************************************************************************** C O M M A N D S *************************************************************************************
|
|
// **************************************************************************************************************************************************************************************
|
|
public void DisplayBollingerBandCommand()
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.BollingerBandViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180,SyncTradeToBand,FALSE");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}
|
|
public void DisplayRelativeStrengthCommand()
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.RSIViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,60,SelectedRSIDayCount,3");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}
|
|
public void DisplayStochasticCommand()
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.StochasticsViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,90");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}
|
|
public void DisplayMACDCommand()
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.MACDViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,90");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}
|
|
public void DisplayMovingAverageCommand()
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.MovingAverageViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,360");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}
|
|
public void DisplayPriceHistoryCommand()
|
|
{
|
|
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.PricingViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,90");
|
|
saveParams.Referer=this;
|
|
WorkspaceInstantiator.Invoke(saveParams);
|
|
}
|
|
// **************************************************************************************************************************************************
|
|
// ************************************************************* T O O L T I P C A L L O U T*******************************************************
|
|
// **************************************************************************************************************************************************
|
|
public String DollarChangePercent
|
|
{
|
|
get
|
|
{
|
|
return "'$ Change(%)' is calculated as a percentage of dollar change in market value from the previous period to the current period.\nThis number may appear skewed if share count has changed day over day.";
|
|
}
|
|
}
|
|
public String Parity
|
|
{
|
|
get
|
|
{
|
|
if(null== selectedGainLossSummaryItem || null==selectedGainLossSummaryItem.Symbol)return "No row selected.";
|
|
StringBuilder sb=new StringBuilder();
|
|
PortfolioTrades portfolioTrades=PortfolioDA.GetOpenTradesSymbol(selectedGainLossSummaryItem.Symbol);
|
|
double weightAdjustedDividendYield=portfolioTrades.GetWeightAdjustedDividendYield();
|
|
DateTime currentDate=PricingDA.GetLatestDate(selectedGainLossSummaryItem.Symbol);
|
|
|
|
String companyName=PricingDA.GetNameForSymbol(selectedGainLossSummaryItem.Symbol);
|
|
if(null!=companyName)sb.Append(companyName).Append("\n");
|
|
|
|
CompanyProfile companyProfile=CompanyProfileDA.GetCompanyProfile(selectedGainLossSummaryItem.Symbol);
|
|
if(null!=companyProfile)
|
|
{
|
|
sb.Append(companyProfile.Sector??Constants.CONST_QUESTION).Append("/").Append(companyProfile.Industry??Constants.CONST_QUESTION).Append("\n");
|
|
}
|
|
|
|
if(null!=portfolioTrades&&0!=portfolioTrades.Count)
|
|
{
|
|
double shares=(from PortfolioTrade portfolioTrade in portfolioTrades select portfolioTrade.Shares).Sum();
|
|
double exposure=portfolioTrades.Sum(x=>x.Exposure());
|
|
// Calculate the gain loss so that we can show the difference between our all time high percentage and where we are right now
|
|
InstantiateGenerators();
|
|
GainLossCollection gainLoss=activeGainLossGenerator.GenerateGainLoss(portfolioTrades); // gainLoss contains the gain/loss from active positions. Never includes dividends .. just positions
|
|
|
|
GainLossItem maxGainLossItem = gainLoss.OrderByDescending(x => x.GainLossPercent).FirstOrDefault();
|
|
GainLossItem minGainLossItem=gainLoss.OrderBy(x => x.GainLossPercent).FirstOrDefault();
|
|
|
|
String accounts=Utility.ListToString(portfolioTrades.Accounts);
|
|
sb.Append("You own '").Append(selectedGainLossSummaryItem.Symbol).Append("' in ").Append(portfolioTrades.Count).Append(" lot(s) (").Append(Utility.FormatNumber(shares,0,true)).Append(" shares) ").Append("Exposure: ").Append(Utility.FormatCurrency(exposure));
|
|
sb.Append("\n").Append("Accounts: ").Append(accounts);
|
|
if(!double.IsNaN(weightAdjustedDividendYield))
|
|
{
|
|
sb.Append("\n").Append("Dividend Yield: ").Append(Utility.FormatPercent(weightAdjustedDividendYield)).Append(" ");
|
|
sb.Append("(").Append(Utility.FormatCurrency(exposure*weightAdjustedDividendYield)).Append("/Yr.)");
|
|
}
|
|
|
|
ParityElement parityElement=ParityGenerator.GenerateBreakEven(selectedGainLossSummaryItem.Symbol);
|
|
if(null!=parityElement)
|
|
{
|
|
sb.Append("\n").Append(parityElement.ToString());
|
|
sb.Append("\n").Append("All Time Gain/Loss: ").Append(maxGainLossItem.GainLossPercent<0?"":"+").Append(Utility.FormatPercent(maxGainLossItem.GainLossPercent/100));
|
|
sb.Append(" (").Append(minGainLossItem.GainLossPercent<0?"":"+").Append(Utility.FormatPercent(minGainLossItem.GainLossPercent/100)).Append(")");
|
|
}
|
|
}
|
|
else sb.Append("You don't hold any shares of '").Append(selectedGainLossSummaryItem.Symbol).Append("'");
|
|
sb.Append(".");
|
|
DateGenerator dateGenerator=new DateGenerator();
|
|
DateTime priorDate=dateGenerator.FindPrevBusinessDay(currentDate);
|
|
Price p1=PricingDA.GetPrice(selectedGainLossSummaryItem.Symbol,currentDate);
|
|
Price p2=PricingDA.GetPrice(selectedGainLossSummaryItem.Symbol,priorDate);
|
|
if(null==p2&&null!=p1)
|
|
{
|
|
priorDate=dateGenerator.FindPrevBusinessDay(priorDate);
|
|
p2=PricingDA.GetPrice(selectedGainLossSummaryItem.Symbol,priorDate);
|
|
}
|
|
if(null==p1||null==p2)return sb.ToString();
|
|
sb.Append("\n");
|
|
double change=(p1.Close-p2.Close)/p2.Close;
|
|
sb.Append(String.Format("Latest Price {0} {1} ({2}{3})",Utility.DateTimeToStringMMSDDSYYYY(p1.Date),Utility.FormatCurrency(p1.Close),change<0?"-":"+",Utility.FormatPercent(Math.Abs(change))));
|
|
if(companyProfile.FreezePricing)sb.Append(" ").Append("**Frozen**");
|
|
sb.Append("\n").Append(String.Format("Source: {0}",p1.SourceAsString()));
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
}
|
|
}
|