using System; using System.ComponentModel; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Linq; using System.Text; using System.Windows.Input; using System.Threading.Tasks; using System.Windows.Media; using Forms=System.Windows.Forms; using System.Threading; using System.Windows; using System.IO; using MarketData; using MarketData.Utils; using MarketData.MarketDataModel; using MarketData.Generator; using MarketData.DataAccess; using TradeBlotter.DataAccess; using TradeBlotter.Command; using TradeBlotter.Model; using Microsoft.Research.DynamicDataDisplay.DataSources; using System.Windows.Threading; using MarketData.Generator.CMTrend; using Position=MarketData.Generator.CMTrend.Position; using StopLimit=MarketData.MarketDataModel.StopLimit; using TradeBlotter.UIUtils; using MarketData.Generator.Model; using MarketData.Generator.ModelGenerators; using MarketData.Generator.Interface; using TradeBlotter.Extensions; namespace TradeBlotter.ViewModels { public class CMTTrendViewModel:WorkspaceViewModel { // generic section private const String DISPLAY_NAME="CMTrend Model"; private bool busyIndicator=false; private String busyContent=null; private String initialPath=null; private String pathFileName=null; // momentum candidate section private String selectedDate=null; private DateTime selectableDateStart=Utility.Epoch; private DateTime selectableDateEnd=Utility.Epoch; private ObservableCollection trendCandidates=new ObservableCollection(); private CMTCandidate selectedItem=null; // private RelayCommand runCommand; private RelayCommand stochasticsCommand; private RelayCommand relativeStrengthCommand; private RelayCommand macdCommand; private RelayCommand bollingerBandCommand; private RelayCommand priceHistoryCommand; private RelayCommand stickerValuationCommand; private RelayCommand dcfValuationCommand; private RelayCommand dividendHistoryCommand; private RelayCommand analystRatingsCommand; private RelayCommand addToWatchListCommand; private RelayCommand removeFromWatchListCommand; private RelayCommand movingAverageCommand; private RelayCommand displayHistoricalCommand; // session section private ModelStatistics modelStatistics=null; private NVPDictionary nvpDictionary=null; private ObservableCollection nvpDictionaryKeys=null; private CMTParams configuration=null; private CMTSessionParams sessionParams; private String selectedParameter=null; private CMTPositionModelCollection positions=null; private CMTPositionModel selectedPosition=null; private RelayCommand loadFileCommand; private RelayCommand reloadCommand; private RelayCommand monitorCommand; private ObservableCollection monitorIntervals; private String selectedMonitorInterval; private bool monitorRunning=false; private DispatcherTimer dispatcherTimer=new DispatcherTimer(); private RelayCommand stochasticsCommandPosition; private RelayCommand relativeStrengthCommandPosition; private RelayCommand macdCommandPosition; private RelayCommand bollingerBandCommandPosition; private RelayCommand bollingerBandCommandPositionAll; private RelayCommand priceHistoryCommandPosition; private RelayCommand stickerValuationCommandPosition; private RelayCommand dcfValuationCommandPosition; private RelayCommand dividendHistoryCommandPosition; private RelayCommand analystRatingsCommandPosition; private RelayCommand addToWatchListCommandPosition; private RelayCommand removeFromWatchListCommandPosition; private RelayCommand movingAverageCommandPosition; private RelayCommand displayHistoricalCommandPosition; private RelayCommand displayHeadlinesCommandPosition; private RelayCommand closePositionCommandPosition; private RelayCommand editPositionCommandPosition; // chart plotter private bool showAsGainLoss=true; private bool isLegendVisible=false; private RelayCommand toggleReturnOrPercentCommand=null; private ModelPerformanceSeries modelPerformanceSeries=null; public CMTTrendViewModel(bool loadedFromParams=false) { PropertyChanged+=OnMomentumViewModelPropertyChanged; base.DisplayName=DISPLAY_NAME; monitorIntervals=new ObservableCollection(); monitorIntervals.Add("30"); monitorIntervals.Add("60"); monitorIntervals.Add("90"); monitorIntervals.Add("120"); selectedMonitorInterval=monitorIntervals[0]; DateTime earliestPricingDate=PricingDA.GetEarliestDate(); earliestPricingDate+=new TimeSpan(252,0,0,0); selectableDateStart=earliestPricingDate; selectableDateEnd=PricingDA.GetLatestDate(); selectedDate=selectableDateEnd.ToShortDateString(); configuration=new CMTParams(); NVPCollection nvpCollection=configuration.ToNVPCollection(); nvpDictionary=nvpCollection.ToDictionary(); List dictionaryKeys=new List(nvpDictionary.Keys); dictionaryKeys.Sort(); nvpDictionaryKeys=new ObservableCollection(dictionaryKeys); selectedParameter=nvpDictionaryKeys[0]; dispatcherTimer.Tick+=DispatcherTimerTick; dispatcherTimer.Interval=new TimeSpan(0,0,int.Parse(selectedMonitorInterval)); base.OnPropertyChanged("MonitorIntervals"); base.OnPropertyChanged("SelectedMonitorInterval"); base.OnPropertyChanged("Parameters"); base.OnPropertyChanged("SelectedParameter"); base.OnPropertyChanged("ParameterValue"); } protected override void OnDispose() { StopMonitor(); base.OnDispose(); } // ******************************************************************************************** P E R S I S T E N C E ******************************************************************************************** public override bool CanPersist() { return true; } public override SaveParameters GetSaveParameters() { SaveParameters saveParams=new SaveParameters(); if(null==pathFileName) return null; saveParams.Add(new KeyValuePair("Type",GetType().Namespace+"."+GetType().Name)); saveParams.Add(new KeyValuePair("PathFileName",pathFileName)); return saveParams; } public override void SetSaveParameters(SaveParameters saveParameters) { try { pathFileName=(from KeyValuePair item in saveParameters where item.Key.Equals("PathFileName") select item).FirstOrDefault().Value; if(!LoadSessionFile()) pathFileName=null; } catch(Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString())); } } // ************************************************************************************************************************************************************************** public bool BusyIndicator { get { return busyIndicator; } set { busyIndicator=value; base.OnPropertyChanged("BusyIndicator"); } } public String BusyContent { get { return busyContent; } set { busyContent=value; base.OnPropertyChanged("BusyContent"); } } // ************************************************************************************************************************************************************************** public ObservableCollection CandidateMenuItems { get { ObservableCollection collection=new ObservableCollection(); 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 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=DisplayStochastics,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 Price History",MenuItemClickedCommand=DisplayPriceHistory,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Moving Average",MenuItemClickedCommand=DisplayMovingAverage,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Analyst Ratings",MenuItemClickedCommand=DisplayAnalystRatings,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display DCF Valuation",MenuItemClickedCommand=DisplayDCFValuation,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Add to Watchlist",MenuItemClickedCommand=AddToWatchList,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Remove from Watchlist",MenuItemClickedCommand=RemoveFromWatchList,StaysOpenOnClick=false }); return collection; } } public ObservableCollection PositionsMenuItems { get { ObservableCollection collection=new ObservableCollection(); collection.Add(new MenuItem() { Text="Display Bollinger Band Model Position",MenuItemClickedCommand=DisplayBollingerBandPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Bollinger Band All",MenuItemClickedCommand=DisplayBollingerBandPositionAll,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Headlines",MenuItemClickedCommand=DisplayHeadlinesPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Dividend History",MenuItemClickedCommand=DisplayDividendHistoryPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Sticker Valuation",MenuItemClickedCommand=DisplayStickerValuationPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Historical",MenuItemClickedCommand=DisplayHistoricalPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Stochastics",MenuItemClickedCommand=DisplayStochasticsPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Relative Strength",MenuItemClickedCommand=DisplayRelativeStrengthPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display MACD",MenuItemClickedCommand=DisplayMACDPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Price History",MenuItemClickedCommand=DisplayPriceHistoryPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Moving Average",MenuItemClickedCommand=DisplayMovingAveragePosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display Analyst Ratings",MenuItemClickedCommand=DisplayAnalystRatingsPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Display DCF Valuation",MenuItemClickedCommand=DisplayDCFValuationPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Add to Watchlist",MenuItemClickedCommand=AddToWatchListPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Remove from Watchlist",MenuItemClickedCommand=RemoveFromWatchListPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Close Position...",MenuItemClickedCommand=ClosePosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text="Edit Position...",MenuItemClickedCommand=EditPosition,StaysOpenOnClick=false }); return collection; } } private void OnMomentumViewModelPropertyChanged(object sender,PropertyChangedEventArgs eventArgs) { } // ************************************************************************************************************************************************ // ************************************************************************************************************************************************ // ************************************************************************************************************************************************ public override String DisplayName { get { if(null==pathFileName) return DISPLAY_NAME; String fileName=Path.GetFileName(pathFileName); fileName=Utility.BetweenString(fileName,null,"."); return DISPLAY_NAME+" ("+fileName+")"; } } public override String Title { get { return DisplayName; } } public DateTime SelectableDateStart { get { return selectableDateStart; } set { selectableDateStart=value; } } public DateTime SelectableDateEnd { get { return selectableDateEnd; } set { selectableDateEnd=value; } } // ****************************************************************************************************************************************************** // *************************************************************** T O O L T I P C A L L O U T S ****************************************************** // ******************************************************************************************************************************************************* // Candidate public String CompanyDescription { get { if(null==selectedItem||null==selectedItem.Symbol) return "No row selected."; CompanyProfile companyProfile=CompanyProfileDA.GetCompanyProfile(selectedItem.Symbol); if(null==companyProfile||null==companyProfile.Description||"".Equals(companyProfile.Description)) return "No description found."; StringBuilder sb=new StringBuilder(); sb.Append(companyProfile.Sector).Append("/").Append(companyProfile.Industry).Append("\n").Append(companyProfile.Description); return sb.ToString(); } } public String VelocityDescription { get { if(null==selectedItem||null==selectedItem.Symbol) return "No row selected."; return "Velocity is the percentage range of the current price within the price history."; } } public String BetaDescription { get { if(null==selectedItem||null==selectedItem.Symbol) return "No row selected."; return "A beta of less than 1 means that the security is theoretically less volatile than the market. A beta of greater than 1 indicates that the security's price is theoretically more volatile than the market. For example, if a stock's beta is 1.2, it's theoretically 20% more volatile than the market."; } } // Position public String CompanyDescriptionSelectedPosition { get { if(null==selectedPosition||null==selectedPosition.Symbol) return "No row selected."; StringBuilder sb=new StringBuilder(); String companyName=PricingDA.GetNameForSymbol(selectedPosition.Symbol); if(null!=companyName)sb.Append(companyName).Append("\n"); CompanyProfile companyProfile=CompanyProfileDA.GetCompanyProfile(selectedPosition.Symbol); if(null==companyProfile||null==companyProfile.Description||"".Equals(companyProfile.Description))sb.Append("No description found."); else sb.Append(companyProfile.Sector).Append("/").Append(companyProfile.Industry).Append("\n").Append(companyProfile.Description); return sb.ToString(); } } // **************************************************************************************************************************************************************** // **************************************************************************************************************************************************************** // **************************************************************************************************************************************************************** public CMTCandidate SelectedItem { get { return selectedItem; } set { if(value==selectedItem) return; selectedItem=value; base.OnPropertyChanged("SelectedItem"); } } public CMTPositionModel SelectedPosition { get { return selectedPosition; } set { selectedPosition=value; base.OnPropertyChanged("SelectedPosition"); } } public String SelectedDate { get { return selectedDate; } set { selectedDate=value; base.OnPropertyChanged("SelectedDate"); } } public ObservableCollection AllItems { get { return trendCandidates; } } public CMTPositionModelCollection AllPositions { get { return positions; } } public ObservableCollection Parameters { get { return nvpDictionaryKeys; } } public ObservableCollection MonitorIntervals { get { return monitorIntervals; } } public bool CanMonitor { get { return IsTradeFileLoaded; } } public String MonitorStatus { get { return monitorRunning?"Stop Monitor":"Start Monitor"; } } public String SelectedMonitorInterval { get { return selectedMonitorInterval; } set { selectedMonitorInterval=value; base.OnPropertyChanged("SelectedMonitorInterval"); } } public String SelectedParameter { get { return selectedParameter; } set { selectedParameter=value; base.OnPropertyChanged("SelectedParameter"); base.OnPropertyChanged("ParameterValue"); } } public String ParameterValue { get { if(null==nvpDictionary||null==nvpDictionaryKeys||null==selectedParameter) return null; return nvpDictionary[selectedParameter].Value; } } public String CashBalance { get { if(null==sessionParams) return ""; return Utility.FormatCurrency(sessionParams.CashBalance); } } public String NonTradeableCash { get { if(null==sessionParams) return ""; return Utility.FormatCurrency(sessionParams.NonTradeableCash); } } public String ModelExpectation { get { if(null==modelStatistics) return ""; return Utility.FormatNumber(modelStatistics.Expectancy,2); } } public Brush ExpectationColor { get { if(null==modelStatistics) return UIUtils.BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black); if(modelStatistics.Expectancy>0.00)return UIUtils.BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black); return UIUtils.BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red); } } public String ExpectationDescription { get { if(null==modelStatistics)return ""; StringBuilder sb=new StringBuilder(); sb.Append("Expectancy is (percentage of winning trades * average gain) / (percentage of losing trades * average loss).").Append("\n"); sb.Append("Total Trades : ").Append(modelStatistics.TotalTrades).Append("\n"); sb.Append("Winning Trades : ").Append(modelStatistics.WinningTrades).Append("\n"); sb.Append("Losing Trades : ").Append(modelStatistics.LosingTrades).Append("\n"); sb.Append("Winning Trades : ").Append(Utility.FormatNumber(modelStatistics.WinningTradesPercent,2)).Append("%").Append("\n"); sb.Append("Losing Trades : ").Append(Utility.FormatNumber(modelStatistics.LosingTradesPercent,2)).Append("%").Append("\n"); sb.Append("Average Winning Trade Gain : ").Append(Utility.FormatNumber(modelStatistics.AverageWinningTradePercentGain,2)).Append("%").Append("\n"); sb.Append("Average Losing Trade Loss : ").Append(Utility.FormatNumber(modelStatistics.AverageLosingTradePercentLoss,2)).Append("%").Append("\n"); sb.Append("Expectancy : ").Append(Utility.FormatNumber(modelStatistics.Expectancy,2)).Append("\n"); sb.Append("\n"); sb.Append("Maintain a positive Expectancy and you're a winner."); sb.Append("\n"); sb.Append("The calculations are based on closed positions."); return sb.ToString(); } } public String TradeableCashDescription { get { if(null==sessionParams) return ""; StringBuilder sb=new StringBuilder(); sb.Append("Risk parameters for next purchase.").Append("\n"); sb.Append("Risk=C=(TotalRiskPercentDecimal * AvailableCash)").Append("\n"); sb.Append(Utility.FormatCurrency(sessionParams.CMTParams.TotalRiskPercentDecimal*sessionParams.CashBalance)).Append("=("); sb.Append(Utility.FormatNumber(sessionParams.CMTParams.TotalRiskPercentDecimal,2)); sb.Append(" * "); sb.Append(Utility.FormatCurrency(sessionParams.CashBalance)).Append(")").Append("\n\n"); sb.Append("Approximate Exposure=C/PositionRiskPercentDecimal").Append("\n"); sb.Append("Approximate Exposure=").Append(Utility.FormatCurrency(sessionParams.CMTParams.TotalRiskPercentDecimal*sessionParams.CashBalance)).Append("/").Append(Utility.FormatNumber(sessionParams.CMTParams.PositionRiskPercentDecimal,2)).Append("\n"); sb.Append("Approximate Exposure=").Append(Utility.FormatCurrency((sessionParams.CMTParams.TotalRiskPercentDecimal*sessionParams.CashBalance)/sessionParams.CMTParams.PositionRiskPercentDecimal)).Append("\n"); sb.Append("*based on $1.00/share purchase price."); return sb.ToString(); } } public String NonTradeableCashDescription { get { if(null==sessionParams) return ""; StringBuilder sb=new StringBuilder(); sb.Append("Cash that is set aside and will not be used for purchases."); return sb.ToString(); } } // ************************************************************************************************************************************************************* // *********************************************************************** I C O M M A N D ******************************************************************** // ************************************************************************************************************************************************************* public ICommand DisplayHistorical { get { if(displayHistoricalCommand==null) { displayHistoricalCommand=new RelayCommand(param => { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.HistoricalViewModel,SelectedSymbol,"+selectedItem.Symbol+",SelectedWatchList,{All}"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); },param => { return null!=selectedItem&&null!=selectedItem.Symbol; }); } return displayHistoricalCommand; } } public ICommand DisplayMovingAverage { get { if(movingAverageCommand==null) { movingAverageCommand=new RelayCommand(param => this.DisplayMovingAverageCommand(selectedItem.Symbol),param => { return null!=selectedItem&&null!=selectedItem.Symbol; }); } return movingAverageCommand; } } public ICommand DisplayAnalystRatings { get { if(analystRatingsCommand==null) { analystRatingsCommand=new RelayCommand(param => this.DisplayAnalystRatingsCommand(),param => { return null!=selectedItem&&null!=selectedItem.Symbol; }); } return analystRatingsCommand; } } public ICommand DisplayMACD { get { if(macdCommand==null) { macdCommand=new RelayCommand(param => this.DisplayMACDCommand(),param => { return null!=selectedItem&&null!=selectedItem.Symbol; }); } return macdCommand; } } public ICommand DisplayStochastics { get { if(stochasticsCommand==null) { stochasticsCommand=new RelayCommand(param => this.DisplayStochasticsCommand(),param => { return null!=selectedItem&&null!=selectedItem.Symbol; }); } return stochasticsCommand; } } public ICommand DisplayRelativeStrength { get { if(relativeStrengthCommand==null) { relativeStrengthCommand=new RelayCommand(param => this.DisplayRelativeStrengthCommand(),param => { return null!=selectedItem&&null!=selectedItem.Symbol; }); } return relativeStrengthCommand; } } public ICommand DisplayStickerValuation { get { if(null==stickerValuationCommand) { stickerValuationCommand=new RelayCommand(param => { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.StickerPriceViewModel,SelectedSymbol,"+selectedItem.Symbol+",SelectedWatchList,{All}"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); },param => { return null!=selectedItem&&null!=selectedItem.Symbol; }); } return stickerValuationCommand; } } public ICommand DisplayDCFValuation { get { if(null==dcfValuationCommand) { dcfValuationCommand=new RelayCommand(param => { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.DCFValuationViewModel,SelectedSymbol,"+selectedItem.Symbol+",SelectedWatchList,{All}"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); },param => { return null!=selectedItem&&null!=selectedItem.Symbol; }); } return dcfValuationCommand; } } public ICommand DisplayPriceHistory { get { if(priceHistoryCommand==null) { priceHistoryCommand=new RelayCommand(param => this.DisplayPriceHistoryCommand(),param => { return null!=selectedItem&&null!=selectedItem.Symbol; }); } return priceHistoryCommand; } } public ICommand DisplayDividendHistory { get { if(dividendHistoryCommand==null) { dividendHistoryCommand=new RelayCommand(param => { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.DividendHistoryViewModel,SelectedSymbol,"+selectedItem.Symbol+",SelectedWatchList,{All}"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); },param => { return null!=selectedItem&&null!=selectedItem.Symbol; }); } return dividendHistoryCommand; } } public void DisplayPriceHistoryCommand() { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.PricingViewModel,SelectedSymbol,"+selectedItem.Symbol+",SelectedWatchList,{All},SelectedDayCount,180"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } public ICommand DisplayBollingerBand { get { if(bollingerBandCommand==null) { bollingerBandCommand=new RelayCommand(param => this.DisplayBollingerBandCommand(),param => { return null!=selectedItem&&null!=selectedItem.Symbol; }); } return bollingerBandCommand; } } public ICommand AddToWatchList { get { if(addToWatchListCommand==null) { addToWatchListCommand=new RelayCommand(param => this.AddToWatchListCommand(selectedItem.Symbol), param => { if(null==selectedItem||null==selectedItem.Symbol) return false; if(WatchListDA.IsInWatchList(selectedItem.Symbol)) return false; return true; }); } return addToWatchListCommand; } } public ICommand RemoveFromWatchList { get { if(removeFromWatchListCommand==null) { removeFromWatchListCommand=new RelayCommand(param => this.RemoveFromWatchListCommand(selectedItem.Symbol), param => { if(null==selectedItem||null==selectedItem.Symbol) return false; if(!WatchListDA.IsInWatchList(selectedItem.Symbol)) return false; return true; }); } return removeFromWatchListCommand; } } // ************************************************************************************************************************************************************* // **************************************************************** I C O M M A N D P O S I T I O N *********************************************************** // ************************************************************************************************************************************************************* public ICommand DisplayHeadlinesPosition { get { if(null==displayHeadlinesCommandPosition) { displayHeadlinesCommandPosition=new RelayCommand(param => { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.HeadlinesViewModel,SelectedSymbol,"+selectedPosition.Symbol+",SelectedWatchList,Valuations"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); },param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return displayHeadlinesCommandPosition; } } public ICommand DisplayHistoricalPosition { get { if(displayHistoricalCommandPosition==null) { displayHistoricalCommandPosition=new RelayCommand(param => { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.HistoricalViewModel,SelectedSymbol,"+selectedPosition.Symbol+",SelectedWatchList,{All}"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); },param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return displayHistoricalCommandPosition; } } public ICommand DisplayAnalystRatingsPosition { get { if(analystRatingsCommandPosition==null) { analystRatingsCommandPosition=new RelayCommand(param => this.DisplayAnalystRatingsCommandPosition(),param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return analystRatingsCommandPosition; } } public ICommand DisplayMovingAveragePosition { get { if(movingAverageCommandPosition==null) { movingAverageCommandPosition=new RelayCommand(param => this.DisplayMovingAverageCommand(selectedPosition.Symbol),param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return movingAverageCommandPosition; } } public ICommand DisplayMACDPosition { get { if(macdCommandPosition==null) { macdCommandPosition=new RelayCommand(param => this.DisplayMACDCommandPosition(),param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return macdCommandPosition; } } public ICommand DisplayStochasticsPosition { get { if(stochasticsCommandPosition==null) { stochasticsCommandPosition=new RelayCommand(param => this.DisplayStochasticsCommandPosition(),param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return stochasticsCommandPosition; } } public ICommand DisplayRelativeStrengthPosition { get { if(relativeStrengthCommandPosition==null) { relativeStrengthCommandPosition=new RelayCommand(param => this.DisplayRelativeStrengthCommandPosition(),param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return relativeStrengthCommandPosition; } } public ICommand DisplayStickerValuationPosition { get { if(null==stickerValuationCommandPosition) { stickerValuationCommandPosition=new RelayCommand(param => { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.StickerPriceViewModel,SelectedSymbol,"+selectedPosition.Symbol+",SelectedWatchList,{All}"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); },param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return stickerValuationCommandPosition; } } public ICommand DisplayDCFValuationPosition { get { if(null==dcfValuationCommandPosition) { dcfValuationCommandPosition=new RelayCommand(param => { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.DCFValuationViewModel,SelectedSymbol,"+selectedPosition.Symbol+",SelectedWatchList,{All}"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); },param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return dcfValuationCommandPosition; } } public ICommand DisplayPriceHistoryPosition { get { if(priceHistoryCommandPosition==null) { priceHistoryCommandPosition=new RelayCommand(param => this.DisplayPriceHistoryCommandPosition(),param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return priceHistoryCommandPosition; } } public ICommand DisplayDividendHistoryPosition { get { if(dividendHistoryCommandPosition==null) { dividendHistoryCommandPosition=new RelayCommand(param => { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.DividendHistoryViewModel,SelectedSymbol,"+selectedPosition.Symbol+",SelectedWatchList,{All}"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); },param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return dividendHistoryCommandPosition; } } public ICommand DisplayBollingerBandPosition { get { if(bollingerBandCommandPosition==null) { bollingerBandCommandPosition=new RelayCommand(param => this.DisplayBollingerBandCommandPosition(),param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return bollingerBandCommandPosition; } } public ICommand DisplayBollingerBandPositionAll { get { if(bollingerBandCommandPositionAll==null) { bollingerBandCommandPositionAll=new RelayCommand(param => this.DisplayBollingerBandCommandPositionAll(),param => { return null!=selectedPosition&&null!=selectedPosition.Symbol; }); } return bollingerBandCommandPositionAll; } } public ICommand AddToWatchListPosition { get { if(addToWatchListCommandPosition==null) { addToWatchListCommandPosition=new RelayCommand(param => this.AddToWatchListCommand(selectedPosition.Symbol), param => { if(null==selectedPosition||null==selectedPosition.Symbol) return false; if(WatchListDA.IsInWatchList(selectedPosition.Symbol)) return false; return true; }); } return addToWatchListCommandPosition; } } public ICommand RemoveFromWatchListPosition { get { if(removeFromWatchListCommandPosition==null) { removeFromWatchListCommandPosition=new RelayCommand(param => this.RemoveFromWatchListCommand(selectedPosition.Symbol),param => { if(null==selectedPosition||null==selectedPosition.Symbol) return false; if(!WatchListDA.IsInWatchList(selectedPosition.Symbol)) return false; return true; }); } return removeFromWatchListCommandPosition; } } public ICommand ClosePosition { get { if(closePositionCommandPosition==null) { closePositionCommandPosition=new RelayCommand(param => this.ClosePositionCommand(selectedPosition),param => { if(null==selectedPosition||null==selectedPosition.Symbol) return false; return true; }); } return closePositionCommandPosition; } } public ICommand EditPosition { get { if(editPositionCommandPosition==null) { editPositionCommandPosition=new RelayCommand(param => this.EditPositionCommand(selectedPosition),param => { if(null==selectedPosition||null==selectedPosition.Symbol||!Utility.IsEpoch(selectedPosition.SellDate)) return false; return true; }); } return editPositionCommandPosition; } } // ************************************************************************************************************************************************************* // ******************************************************************* I C O M M A N D S E S S I O N ********************************************************* // ************************************************************************************************************************************************************* public ICommand Reload { get { if(reloadCommand==null) { reloadCommand=new RelayCommand(param => this.ReloadCommand(),param => { return ReloadEnabled; }); } return reloadCommand; } } public bool ReloadEnabled { get { return !String.IsNullOrEmpty(pathFileName); } } public ICommand LoadFile { get { if(loadFileCommand==null) { loadFileCommand=new RelayCommand(param => this.LoadFileCommand(),param => { return true; }); } return loadFileCommand; } } public ICommand Monitor { get { if(monitorCommand==null) { monitorCommand=new RelayCommand(param => this.MonitorCommand(),param => { return IsTradeFileLoaded; }); } return monitorCommand; } } private bool IsTradeFileLoaded { get { return null==pathFileName?false:true; } } // ************************************************************************************************************************************************************* // ********************************************************************** C O M M A N D W O R K E R S ******************************************************** // ************************************************************************************************************************************************************* public void DisplayBollingerBandCommand() { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.BollingerBandViewModel,SelectedSymbol,"+selectedItem.Symbol+",SelectedWatchList,{All},SelectedDayCount,360"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } public void DisplayAnalystRatingsCommand() { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.AnalystRatingsViewModel,SelectedSymbol,"+selectedItem.Symbol+",SelectedWatchList,{All}"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } public void DisplayStochasticsCommand() { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.StochasticsViewModel,SelectedSymbol,"+selectedItem.Symbol+",SelectedWatchList,{All},SelectedDayCount,180"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } public void DisplayRelativeStrengthCommand() { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.RSIViewModel,SelectedSymbol,"+selectedItem.Symbol+",SelectedWatchList,{All},SelectedDayCount,60,SelectedRSIDayCount,3"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } public void DisplayMACDCommand() { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.MACDViewModel,SelectedSymbol,"+selectedItem.Symbol+",SelectedWatchList,{All},SelectedDayCount,180"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } // ************************************************************************************************************************************************************* // ********************************************************************** C O M M A N D W O R K E R S P O S I T I O N **************************************** // ************************************************************************************************************************************************************* // Legacy bollinger band public void DisplayBollingerBandCommandPositionAll() { MarketData.MarketDataModel.StopLimits stopLimits = GetHistoricalStopLimitsMarketDataModel(); StringBuilder sb = new StringBuilder(); SaveParameters saveParams = null; sb = new StringBuilder(); sb.Append("Type,TradeBlotter.ViewModels.BollingerBandViewModel,SelectedSymbol,"); sb.Append(selectedPosition.Symbol).Append(","); sb.Append("SelectedWatchList,{All},SelectedDayCount,"); sb.Append(GetDayCountSelectionForBollingerBands(selectedPosition)); saveParams = SaveParameters.Parse(sb.ToString()); SaveParameters stopLimitParams = StopLimitsExtensions.FromStopLimits(stopLimits); saveParams.AddRange(stopLimitParams); saveParams.Referer = this; WorkspaceInstantiator.Invoke(saveParams); } // Bollinger band for this position public void DisplayBollingerBandCommandPosition() { MarketData.MarketDataModel.StopLimits stopLimits = GetHistoricalStopLimitsMarketDataModel(); StringBuilder sb = new StringBuilder(); SaveParameters saveParams = null; sb = new StringBuilder(); sb.Append("Type,TradeBlotter.ViewModels.BollingerBandPositionViewModel,SelectedSymbol,"); sb.Append(selectedPosition.Symbol).Append(","); sb.Append("SelectedWatchList,{All},SelectedDayCount,"); sb.Append(GetDayCountSelectionForBollingerBands(selectedPosition)); saveParams = SaveParameters.Parse(sb.ToString()); SaveParameters stopLimitParams = StopLimitsExtensions.FromStopLimits(stopLimits); saveParams.AddRange(stopLimitParams); SaveParameters portfolioTradesParams = PortfolioTradesExtensions.FromPosition(selectedPosition); saveParams.AddRange(portfolioTradesParams); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } private int GetDayCountSelectionForBollingerBands(CMTPositionModel selectedPosition) { DateGenerator dateGenerator=new DateGenerator(); int daysBetween=dateGenerator.DaysBetween(selectedPosition.PurchaseDate,DateTime.Today); if(daysBetween<90)return 90; if(daysBetween<180)return 180; if(daysBetween<360)return 360; if(daysBetween<720)return 720; if(daysBetween<1440)return 1440; return 3600; } public void DisplayAnalystRatingsCommandPosition() { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.AnalystRatingsViewModel,SelectedSymbol,"+selectedPosition.Symbol+",SelectedWatchList,{All}"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } public void DisplayStochasticsCommandPosition() { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.StochasticsViewModel,SelectedSymbol,"+selectedPosition.Symbol+",SelectedWatchList,{All},SelectedDayCount,180"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } public void DisplayRelativeStrengthCommandPosition() { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.RSIViewModel,SelectedSymbol,"+selectedPosition.Symbol+",SelectedWatchList,{All},SelectedDayCount,60,SelectedRSIDayCount,3"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } public void DisplayMACDCommandPosition() { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.MACDViewModel,SelectedSymbol,"+selectedPosition.Symbol+",SelectedWatchList,{All},SelectedDayCount,180"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } public void DisplayPriceHistoryCommandPosition() { SaveParameters saveParams=SaveParameters.Parse("Type,TradeBlotter.ViewModels.PricingViewModel,SelectedSymbol,"+selectedPosition.Symbol+",SelectedWatchList,{All},SelectedDayCount,180"); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } // *************************************************************************************************************************************************************************** // ********************************************************************* G E N E R A L W O R K E R S *********************************************************************** // *************************************************************************************************************************************************************************** public void DisplayMovingAverageCommand(String symbol) { SaveParameters saveParams=new SaveParameters(); saveParams.Add(new KeyValuePair("Type","TradeBlotter.ViewModels.MovingAverageViewModel")); saveParams.Add(new KeyValuePair("SelectedSymbol",symbol)); saveParams.Add(new KeyValuePair("SelectedWatchList",Constants.CONST_ALL)); saveParams.Add(new KeyValuePair("SelectedDayCount","360")); saveParams.Add(new KeyValuePair("IsLegendVisible","true")); saveParams.Referer=this; WorkspaceInstantiator.Invoke(saveParams); } public void ClosePositionCommand(CMTPositionModel selectedPosition) { bool deleteStop=false; Position clonedPosition=Position.Clone(selectedPosition.Position); bool hasStopLimit=StopLimitDA.HasStopLimit(clonedPosition.Symbol,clonedPosition.Shares); IPosition changedPosition=ClosePositionDialog.Prompt("Close Position",clonedPosition,hasStopLimit,ref deleteStop); if(null==changedPosition) return; CMTTrendModel mmTrendModel=new CMTTrendModel(); if(!mmTrendModel.ClosePosition(changedPosition.Symbol,changedPosition.PurchaseDate,changedPosition.SellDate,changedPosition.CurrentPrice,pathFileName)) { MessageBox.Show("Failed to close the position, check log for details.","Close Position"); return; } if(deleteStop) StopLimitDA.DeleteStopLimit(changedPosition.Symbol,changedPosition.Shares); String strMessage=String.Format("Closed position for {0}, Purchase Date:{1}, Sell Date{2}, Current Price:{3}, Delete Stop:{4} to {5}. A backup was created.", changedPosition.Symbol,changedPosition.PurchaseDate.ToShortDateString(),changedPosition.SellDate.ToShortDateString(),Utility.FormatCurrency(changedPosition.CurrentPrice),deleteStop,pathFileName); MessageBox.Show(strMessage,"Close Position"); LoadSessionFile(); } public void EditPositionCommand(CMTPositionModel selectedPosition) { Position clonedPosition=Position.Clone(selectedPosition.Position); IPosition changedPosition=EditPositionDialog.Prompt("Edit Position",clonedPosition); if(null==changedPosition) return; CMTTrendModel mmTrendModel=new CMTTrendModel(); if(!mmTrendModel.EditPosition(changedPosition.Symbol,changedPosition.PurchaseDate,changedPosition.PurchasePrice,changedPosition.InitialStopLimit,changedPosition.TrailingStopLimit,pathFileName)) { MessageBox.Show("Failed to edit the position, check log for details.","Edit Position"); return; } if(!selectedPosition.TrailingStopLimit.Equals(changedPosition.TrailingStopLimit)) { selectedPosition.TrailingStopLimit=changedPosition.TrailingStopLimit; selectedPosition.LastStopAdjustment=DateTime.Now.Date; StopLimit stopLimit=StopLimitDA.GetStopLimit(changedPosition.Symbol,changedPosition.Shares); if(null==stopLimit) { stopLimit=new StopLimit(); stopLimit.Symbol=changedPosition.Symbol; stopLimit.StopType=StopLimitConstants.STOP_QUOTE; stopLimit.Shares=changedPosition.Shares; } stopLimit.StopPrice=changedPosition.TrailingStopLimit; StopLimitDA.InsertUpdateStopLimit(stopLimit); } selectedPosition.PurchaseDate=changedPosition.PurchaseDate; selectedPosition.PurchasePrice=changedPosition.PurchasePrice; selectedPosition.TrailingStopLimit=changedPosition.TrailingStopLimit; selectedPosition.InitialStopLimit=changedPosition.InitialStopLimit; String strMessage=String.Format("Edited Position for {0} Purchase Date:{1} Purchase Price:{2}, Trailing Stop:{3}. A backup was created.", selectedPosition.Symbol,selectedPosition.PurchaseDate.ToShortDateString(),Utility.FormatCurrency(selectedPosition.PurchasePrice),Utility.FormatCurrency(selectedPosition.TrailingStopLimit)); MessageBox.Show(strMessage,"Edit Position"); LoadSessionFile(); } public void AddToWatchListCommand(String symbol) { if(WatchListDA.IsInWatchList(symbol)) { System.Windows.MessageBox.Show("'"+symbol+"' is already in watchlist","Info",MessageBoxButton.OK,MessageBoxImage.Information); return; } if(!WatchListDA.AddToWatchList(symbol)) { System.Windows.MessageBox.Show("Error adding '"+symbol+"' to watchlist","Warning",MessageBoxButton.OK,MessageBoxImage.Warning); } else { System.Windows.MessageBox.Show("Added '"+symbol+"'","Success",MessageBoxButton.OK,MessageBoxImage.Information); } } public void RemoveFromWatchListCommand(String symbol) { if(!WatchListDA.IsInWatchList(symbol)) { System.Windows.MessageBox.Show("'"+symbol+"' is not in watchlist","Info",MessageBoxButton.OK,MessageBoxImage.Information); return; } if(!WatchListDA.RemoveFromWatchList(symbol)) { System.Windows.MessageBox.Show("Error removing '"+symbol+"' from watchlist","Warning",MessageBoxButton.OK,MessageBoxImage.Warning); } else { System.Windows.MessageBox.Show("Removed '"+symbol+"'","Success",MessageBoxButton.OK,MessageBoxImage.Information); } } // ************************************************************************************************************************************************************************** // ********************************************************************** C O M M A N D W O R K E R S S E S S I O N ******************************************************** // *************************************************************************************************************************************************************************** public void MonitorCommand() { if(monitorRunning) StopMonitor(); else StartMonitor(); } private void StopMonitor() { if(!monitorRunning) return; dispatcherTimer.Stop(); monitorRunning=false; base.OnPropertyChanged("MonitorStatus"); } private void StartMonitor() { if(monitorRunning) return; dispatcherTimer.Start(); monitorRunning=true; Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => { DispatcherTimerTick(null,null); }),DispatcherPriority.Normal); DispatcherTimerTick(null,null); base.OnPropertyChanged("MonitorStatus"); } private void DispatcherTimerTick(object sender,EventArgs e) { UpdatePositionPrices(true); RunPerformance(); } private void UpdatePositionPrices(bool signalChangeEvent=true) { try { DateTime today=DateTime.Now; if(null==positions||0==positions.Count) return; List symbols=(from CMTPositionModel position in positions where position.IsActivePosition select position.Symbol).Distinct().ToList(); foreach(String symbol in symbols) { var selectedPositions=(from CMTPositionModel position in positions where position.IsActivePosition&&position.Symbol.Equals(symbol) select position); foreach(CMTPositionModel selectedPosition in selectedPositions) { Price price=PricingDA.GetPrice(symbol); if(null==price) continue; selectedPosition.CurrentPrice=price.Close; selectedPosition.CurrentPriceLow=price.Low; selectedPosition.LastUpdated=price.Date.Date { try { if(!CMTSessionManager.IsValidSessionFile(pathFileName)) return false; initialPath=Path.GetDirectoryName(pathFileName); sessionParams=CMTSessionManager.RestoreSession(pathFileName); if(null==sessionParams) { MessageBox.Show(String.Format("Unable to open {0}",pathFileName)); pathFileName=null; return false; } modelStatistics=CMTTrendModel.GetModelStatistics(sessionParams); configuration=sessionParams.CMTParams; NVPCollection nvpCollection=sessionParams.CMTParams.ToNVPCollection(); nvpDictionary=nvpCollection.ToDictionary(); List dictionaryKeys=new List(nvpDictionary.Keys); dictionaryKeys.Sort(); nvpDictionaryKeys=new ObservableCollection(dictionaryKeys); selectedParameter=nvpDictionaryKeys[0]; positions=new CMTPositionModelCollection(); positions.Add(sessionParams.ActivePositions); positions.Add(sessionParams.AllPositions); trendCandidates=new ObservableCollection(); foreach(CMTCandidate candidate in sessionParams.Candidates)trendCandidates.Add(candidate); UpdatePositionPrices(true); RunPerformance(); return true; } catch(Exception exception) { System.Windows.MessageBox.Show(String.Format("Exception {0}",exception.ToString()),"Error",MessageBoxButton.OK,MessageBoxImage.Exclamation); return false; } }); workerTask.ContinueWith(continuation => { BusyIndicator = false; base.OnPropertyChanged("Parameters"); base.OnPropertyChanged("SelectedParameter"); base.OnPropertyChanged("ParameterValue"); base.OnPropertyChanged("Title"); base.OnPropertyChanged("DisplayName"); base.OnPropertyChanged("AllPositions"); base.OnPropertyChanged("CanMonitor"); base.OnPropertyChanged("AllItems"); base.OnPropertyChanged("CashBalance"); base.OnPropertyChanged("NonTradeableCash"); base.OnPropertyChanged("ModelExpectation"); base.OnPropertyChanged("ExpectationColor"); base.OnPropertyChanged("ExpectationDescription"); base.OnPropertyChanged("TradeableCashDescription"); base.OnPropertyChanged("NonTradeableCashDescription"); }); return true; } private void RunPerformance() { if(null==sessionParams)return; modelPerformanceSeries=CMTTrendModel.GetModelPerformance(sessionParams); base.OnPropertyChanged("Data"); base.OnPropertyChanged("GraphTitle"); } // **************************************************************************** C H A R T P L O T T E R ********************************************************* public String LegendVisible { get { if(isLegendVisible) return "true"; return "false"; } set { isLegendVisible=Boolean.Parse(value); base.OnPropertyChanged("LegendVisible"); } } 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("Data"); base.OnPropertyChanged("PercentButtonText"); base.OnPropertyChanged("GraphTitle"); },action => { return true; }); } return toggleReturnOrPercentCommand; } } public CompositeDataSource Data { get { if(null==modelPerformanceSeries) return null; CompositeDataSource compositeDataSource=null; compositeDataSource=GainLossModel.GainLoss(modelPerformanceSeries,showAsGainLoss); return compositeDataSource; } } public String GraphTitle { get { if(null==sessionParams||null==modelPerformanceSeries) return ""; StringBuilder sb=new StringBuilder(); Positions allPositions=sessionParams.GetCombinedPositions(); DateTime minDate=allPositions.Min(x => x.PurchaseDate); DateTime maxDate=PricingDA.GetLatestDate(); if(modelPerformanceSeries.Count<2) { sb.Append(showAsGainLoss?"$ GainLoss":"% Return"); sb.Append(" "); sb.Append("(").Append(minDate.ToShortDateString()).Append("-").Append(maxDate.ToShortDateString()).Append(")"); sb.Append(" "); sb.Append(showAsGainLoss?Utility.FormatCurrency(modelPerformanceSeries[modelPerformanceSeries.Count-1].CumulativeGainLoss):Utility.FormatPercent(modelPerformanceSeries[modelPerformanceSeries.Count-1].CumProdMinusOne)); return sb.ToString(); } if(showAsGainLoss) { double latestGainLoss=modelPerformanceSeries[modelPerformanceSeries.Count-1].CumulativeGainLoss; double change=modelPerformanceSeries[modelPerformanceSeries.Count-1].GainLossDOD; sb.Append("$ GainLoss"); sb.Append(" "); sb.Append("(").Append(minDate.ToShortDateString()).Append("-").Append(maxDate.ToShortDateString()).Append(")"); sb.Append(" "); sb.Append(Utility.FormatCurrency(latestGainLoss)); sb.Append(","); sb.Append(" "); sb.Append(change>0.00?"+":"").Append(Utility.FormatCurrency(change)); } else { double latestCumGainLoss=modelPerformanceSeries[modelPerformanceSeries.Count-1].CumProdMinusOne; double prevCumGainLoss=modelPerformanceSeries[modelPerformanceSeries.Count-2].CumProdMinusOne; double change=latestCumGainLoss-prevCumGainLoss; sb.Append("% Return"); sb.Append(" "); sb.Append("(").Append(minDate.ToShortDateString()).Append("-").Append(maxDate.ToShortDateString()).Append(")"); sb.Append(" "); sb.Append(Utility.FormatPercent(latestCumGainLoss)); sb.Append(","); sb.Append(" "); sb.Append(change>0.00?"+":"").Append(Utility.FormatPercent(change)); } return sb.ToString(); } } // **************************************************************************************************************************************************************** // *************************************************************************** T O O L T I P C A L L O U T S ***************************************************** // **************************************************************************************************************************************************************** public String ToolTipRMultiple { get { if(null==selectedPosition)return "Please select a position by clicking on a row."; StringBuilder sb=new StringBuilder(); sb.Append("RMultiple is based on original position setup.").Append("\n"); sb.Append("Original Exposure=").Append(Utility.FormatCurrency(selectedPosition.PurchasePrice*selectedPosition.Shares)).Append("\n"); sb.Append("Original R/Share=PurchasePrice-InitialStop").Append("\n"); sb.Append(Utility.FormatCurrency(selectedPosition.PurchasePrice-selectedPosition.InitialStopLimit)).Append("=").Append(Utility.FormatCurrency(selectedPosition.PurchasePrice)).Append("-").Append(Utility.FormatCurrency(selectedPosition.InitialStopLimit)).Append("\n"); sb.Append("Original Risk=Original R/Share*Shares").Append("\n"); sb.Append(Utility.FormatCurrency((selectedPosition.PurchasePrice-selectedPosition.InitialStopLimit)*selectedPosition.Shares)).Append("=").Append(Utility.FormatCurrency(selectedPosition.PurchasePrice-selectedPosition.InitialStopLimit)).Append("*").Append(selectedPosition.Shares).Append("\n"); sb.Append("RMultiple=(CurrentPrice-PurchasePrice)/(PurchasePrice-InitialStop)").Append("\n"); sb.Append(selectedPosition.RMultipleAsString).Append("=").Append("(").Append(Utility.FormatCurrency(selectedPosition.CurrentPrice)).Append("-").Append(Utility.FormatCurrency(selectedPosition.PurchasePrice)).Append(")"); sb.Append("/").Append("(").Append(Utility.FormatCurrency(selectedPosition.PurchasePrice)).Append("-").Append(Utility.FormatCurrency(selectedPosition.InitialStopLimit)).Append(")"); return sb.ToString(); } } public String ToolTipTotalRiskExposure { get { if(null==selectedPosition)return "Please select a position by clicking on a row."; StringBuilder sb=new StringBuilder(); sb.Append("Current Risk. See RMultiple for initial risk assumptions.").Append("\n"); sb.Append("[TotalRiskExposure]=([R/Share]*[Shares])").Append("\n"); if(null==selectedPosition) return sb.ToString(); sb.Append(Utility.FormatCurrency(selectedPosition.TotalRiskExposure)).Append("=(").Append(Utility.FormatCurrency(selectedPosition.R)).Append("*").Append(Utility.FormatNumber(selectedPosition.Shares,0)).Append(")"); return sb.ToString(); } } public String ToolTipR { get { if(null==selectedPosition)return "Please select a position by clicking on a row."; StringBuilder sb=new StringBuilder(); sb.Append("Current R/Share. See RMultiple for initial risk assumptions.").Append("\n"); sb.Append("R/Share=TrailingStop>PurchasePrice?0.00:PurchasePrice-TrailingStop").Append("\n"); if(selectedPosition.TrailingStopLimit>selectedPosition.PurchasePrice) { sb.Append(Utility.FormatCurrency(0)).Append("=").Append(Utility.FormatCurrency(0)); } else { sb.Append(Utility.FormatCurrency(selectedPosition.TrailingStopLimit>selectedPosition.PurchasePrice?0.00:selectedPosition.PurchasePrice-selectedPosition.TrailingStopLimit)); sb.Append("=").Append(Utility.FormatCurrency(selectedPosition.PurchasePrice)).Append("-").Append(Utility.FormatCurrency(selectedPosition.TrailingStopLimit)); } return sb.ToString(); } } public String ToolTipPriceLow { get { if(null==selectedPosition) return "Please select a position by clicking on a row."; StringBuilder sb=new StringBuilder(); sb.Append("[Low]=([CurrentLowPrice])").Append("\n"); sb.Append(Utility.FormatCurrency(selectedPosition.CurrentPriceLow)).Append("=").Append(Utility.FormatCurrency(selectedPosition.CurrentPriceLow)); return sb.ToString(); } } public String ToolTipPrice { get { if(null==selectedPosition) return "Please select a position by clicking on a row."; StringBuilder sb=new StringBuilder(); sb.Append("[Price]=([CurrentPrice])").Append("\n"); sb.Append(Utility.FormatCurrency(selectedPosition.CurrentPrice)).Append("=").Append(Utility.FormatCurrency(selectedPosition.CurrentPrice)); return sb.ToString(); } } public String ToolTipTrailingStop { get { if(null==selectedPosition) return "Please select a position by clicking on a row."; StringBuilder sb=new StringBuilder(); sb.Append("[TrailingStop]=([TrailingStopLimit])").Append("\n"); sb.Append(Utility.FormatCurrency(selectedPosition.TrailingStopLimit)).Append("=").Append(Utility.FormatCurrency(selectedPosition.TrailingStopLimit)).Append("\n"); List stopLimits=GetHistoricalStopLimits(); if(selectedPosition.TrailingStopLimit > selectedPosition.PurchasePrice) { sb.Append("Riskless Gain").Append(" = "); sb.Append(String.Format("(Trailing Stop - Purchase Price) * Shares")); sb.Append("\n"); sb.Append(String.Format("{0}",Utility.FormatCurrency((selectedPosition.TrailingStopLimit-selectedPosition.PurchasePrice)*selectedPosition.Shares))); sb.Append(String.Format("=({0}-{1})*{2}",Utility.FormatCurrency(selectedPosition.TrailingStopLimit),Utility.FormatCurrency(selectedPosition.PurchasePrice),Utility.FormatNumber(selectedPosition.Shares,3))); sb.Append("\n"); } if(null!=stopLimits && 0!=stopLimits.Count) { sb.Append("Stop History").Append("\n"); foreach(MarketData.Generator.Model.StopLimit stopLimit in stopLimits) { sb.Append(String.Format("Analysis Date:{0} New Stop:{1} Previous Stop:{2}",Utility.DateTimeToStringMMSDDSYYYY(stopLimit.AnalysisDate),Utility.FormatCurrency(stopLimit.NewStop),Utility.FormatCurrency(stopLimit.PreviousStop))); sb.Append("\n"); } } return sb.ToString(); } } public String ToolTipInitialStop { get { if(null==selectedPosition) return "Please select a position by clicking on a row."; StringBuilder sb=new StringBuilder(); sb.Append("[InitialStop]=([InitialStopLimit])").Append("\n"); sb.Append(Utility.FormatCurrency(selectedPosition.InitialStopLimit)).Append("=").Append(Utility.FormatCurrency(selectedPosition.InitialStopLimit)); return sb.ToString(); } } public String ToolTipPurchasePrice { get { if(null==selectedPosition) return "Please select a position by clicking on a row."; StringBuilder sb=new StringBuilder(); sb.Append("[PurchasePrice]=([PurchasePrice])").Append("\n"); sb.Append(Utility.FormatCurrency(selectedPosition.PurchasePrice)).Append("=").Append(Utility.FormatCurrency(selectedPosition.PurchasePrice)); return sb.ToString(); } } public String ToolTipEdgeRatio { get { if(null==selectedPosition) return "Please select a position by clicking on a row."; StringBuilder sb=new StringBuilder(); sb.Append("[EdgeRatio]=AVG(SUM(MFE/ATR(14)))/AVG(SUM(MAE/ATR(14)))").Append("\n"); sb.Append("MFE=Maximum Favorable Excursion").Append("\n"); sb.Append("MAE=Maximum Adverse Excursion").Append("\n"); sb.Append("ATR=Average True Range. 14 days").Append("\n"); if(selectedPosition.EdgeRatio<1.00) { sb.Append(String.Format("You can expect a further {0} units more of adverse volatility.",Utility.FormatNumber(1.00-selectedPosition.EdgeRatio,2))); } else { sb.Append(String.Format("You can expect a further {0} units more of favorable volatility.",Utility.FormatNumber(selectedPosition.EdgeRatio-1.00,2))); } return sb.ToString(); } } // ************************************************************************************************************************************************************************************************************ // This getter returns MMTrend specific stop limits to show in the tooltips public MarketData.Generator.Model.StopLimits GetHistoricalStopLimits() { if(null==sessionParams||null==selectedPosition) return null; MarketData.Generator.Model.StopLimits stopLimits=new MarketData.Generator.Model.StopLimits((from MarketData.Generator.Model.StopLimit stopLimit in sessionParams.StopLimits where stopLimit.Symbol.Equals(selectedPosition.Symbol) select stopLimit).OrderByDescending(x => x.AnalysisDate).ToList()); return stopLimits; } // This getter returns non-model (MarketData.MarketDataModel) specific stop limits to pass along to the bollinger bands public MarketData.MarketDataModel.StopLimits GetHistoricalStopLimitsMarketDataModel() { if(null==sessionParams||null==selectedPosition) return null; DateGenerator dateGenerator=new DateGenerator(); MarketData.MarketDataModel.StopLimits marketDataModelStopLimits=new MarketData.MarketDataModel.StopLimits(); MarketData.Generator.Model.StopLimits stopLimits = default; if(selectedPosition.IsActivePosition) { stopLimits = new MarketData.Generator.Model.StopLimits( (from MarketData.Generator.Model.StopLimit stopLimit in sessionParams.StopLimits where stopLimit.Symbol.Equals(selectedPosition.Symbol) && stopLimit.AnalysisDate > selectedPosition.PurchaseDate select stopLimit).OrderByDescending(x => x.AnalysisDate).ToList()); } else { stopLimits = new MarketData.Generator.Model.StopLimits( (from MarketData.Generator.Model.StopLimit stopLimit in sessionParams.StopLimits where stopLimit.Symbol.Equals(selectedPosition.Symbol) && stopLimit.AnalysisDate > selectedPosition.PurchaseDate && stopLimit.AnalysisDate <= selectedPosition.SellDate select stopLimit). OrderByDescending(x => x.AnalysisDate).ToList()); } MarketData.MarketDataModel.StopLimit initialStopLimit=new MarketData.MarketDataModel.StopLimit(); initialStopLimit.Symbol=selectedPosition.Symbol; initialStopLimit.Shares=0; initialStopLimit.StopPrice=selectedPosition.InitialStopLimit; initialStopLimit.StopType=StopLimitConstants.STOP_QUOTE; initialStopLimit.EffectiveDate=selectedPosition.PurchaseDate; // initialStopLimit.Active=1; marketDataModelStopLimits.Add(initialStopLimit); foreach(MarketData.Generator.Model.StopLimit stopLimit in stopLimits) { MarketData.MarketDataModel.StopLimit marketDataModelStopLimit=new MarketData.MarketDataModel.StopLimit(); marketDataModelStopLimit.Symbol=stopLimit.Symbol; marketDataModelStopLimit.Shares=0; marketDataModelStopLimit.StopPrice=stopLimit.NewStop; marketDataModelStopLimit.StopType=StopLimitConstants.STOP_QUOTE; marketDataModelStopLimit.EffectiveDate=stopLimit.AnalysisDate; // marketDataModelStopLimit.Active=1; marketDataModelStopLimits.Add(marketDataModelStopLimit); } return marketDataModelStopLimits; } } }