Fix views and view models.

This commit is contained in:
2025-02-14 19:02:17 -05:00
parent 786f5f67df
commit 9f836a09f5
5 changed files with 1171 additions and 57 deletions

View File

@@ -0,0 +1,951 @@
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.Threading.Tasks;
using System.Windows.Input;
using MarketData;
using MarketData.Numerical;
using MarketData.Utils;
using MarketData.MarketDataModel;
using MarketData.Generator;
using MarketData.Generator.GainLoss;
using MarketData.DataAccess;
using TradeBlotter.DataAccess;
using TradeBlotter.Command;
using TradeBlotter.Model;
using TradeBlotter.Cache;
using Microsoft.Research.DynamicDataDisplay.DataSources;
using Microsoft.Research.DynamicDataDisplay.PointMarkers;
using System.Windows.Media;
using System.Windows.Threading;
using System.Windows.Forms;
using TradeBlotter.UIUtils;
using TradeBlotter.Extensions;
using System.Runtime.InteropServices.WindowsRuntime;
// Author:Sean Kessler
// This view model is intended to be called by trading models as it will only displayed the data that is provided via the SaveParams and is not editable.
// Although this view accepts PortfolioTrades (a collection of PortfolioTrade) THAT collection should only contain a single position
namespace TradeBlotter.ViewModels
{
public class BollingerBandPositionViewModel : WorkspaceViewModel
{
private static readonly String BAND_MESSAGE="Generating Bollinger Band...";
private static readonly String DATA_MESSAGE="Loading Pricing Data...";
private static readonly int MIN_DAYS = 40; // This is the minimum nunber of pricing days for bollinger bands to work
private BollingerBands bollingerBands;
private StopLimit stopLimit; // This is the stop limit that is looked up in the database and displayed (if there is one)
private StopLimits stopLimits; // These stop limits might be passed in with the SaveParams. (i.e.) MMTRend model passes in StopLimits. If these are passsed in then they are displayed instead of stopLimit.
private String symbol;
private String companyName;
private Prices prices = null;
private RelayCommand refreshCommand;
private List<Int32> dayCounts;
private PortfolioTrades portfolioTrades;
private InsiderTransactionSummaries insiderTransactionSummaries=null;
private bool showTradeLabels = true;
private bool showInsiderTransactions=true;
private bool busyIndicator = false;
private Price zeroPrice = null;
private bool isLegendVisible = false;
private bool useLeastSquaresFit=true;
private String busyContent = BAND_MESSAGE;
private CompositeDataSource compositeDataSourceZeroPoint=null;
private CompositeDataSource compositeDataSourceStopLimit=null;
private CompositeDataSource compositeDataSourceInsiderTransactionPointDisposedSmall=null;
private CompositeDataSource compositeDataSourceInsiderTransactionPointDisposedMedium=null;
private CompositeDataSource compositeDataSourceInsiderTransactionPointDisposedLarge=null;
private CompositeDataSource compositeDataSourceInsiderTransactionPointAcquiredSmall=null;
private CompositeDataSource compositeDataSourceInsiderTransactionPointAcquiredMedium=null;
private CompositeDataSource compositeDataSourceInsiderTransactionPointAcquiredLarge=null;
private CompositeDataSource compositeDataSourceK=null;
private CompositeDataSource compositeDataSourceKL1=null;
private CompositeDataSource compositeDataSourceL=null;
private CompositeDataSource compositeDataSourceLP1=null;
private CompositeDataSource compositeDataSourceHigh=null;
private CompositeDataSource compositeDataSourceLow=null;
private CompositeDataSource compositeDataSourceClose=null;
private CompositeDataSource compositeDataSourceSMAN=null;
private CompositeDataSource compositeDataSourceVolume=null;
private CompositeDataSource compositeDataSourceLeastSquares=null;
private CompositeDataSource compositeDataSourceTradePoints=null;
public BollingerBandPositionViewModel()
{
base.DisplayName = "Bollinger Band Position";
dayCounts = new List<Int32>();
dayCounts.Add(60);
dayCounts.Add(90);
dayCounts.Add(180);
dayCounts.Add(360);
dayCounts.Add(720);
dayCounts.Add(1440);
dayCounts.Add(3600);
PropertyChanged += OnBollingerBandPositionViewModelPropertyChanged;
}
private PortfolioTrade PortfolioTrade
{
get
{
return portfolioTrades.Take(1).FirstOrDefault();
}
}
private int GetNearestDayCount(int desiredDayCount)
{
for(int index=0;index<dayCounts.Count;index++)
{
if(dayCounts[index]>=desiredDayCount)
{
return dayCounts[index];
}
}
return dayCounts[dayCounts.Count-1];
}
private Price GetZeroPrice()
{
if(null==PortfolioTrade)return null;
PortfolioTrades lots = CreateBuySellLots(PortfolioTrade);
DateTime latestPricingDate=Utility.Epoch;
Price zeroPrice = default;
if(PortfolioTrade.IsOpen)
{
PortfolioTrades openLots = new PortfolioTrades();
openLots.Add(lots.Where(x => x.IsOpen==true).First());
latestPricingDate=PricingDA.GetLatestDate(SelectedSymbol);
Price latestPrice = PricingDA.GetPrice(SelectedSymbol, latestPricingDate);
zeroPrice=ParityGenerator.GenerateGainLossValue(openLots, latestPrice);
}
return zeroPrice;
}
// SERIALIZE TO PARAMETERS
public override SaveParameters GetSaveParameters()
{
SaveParameters saveParams = new SaveParameters();
if (null == SelectedSymbol) return null;
saveParams.Add(new KeyValuePair<String, String>("Type",GetType().Namespace+"."+GetType().Name));
saveParams.Add(new KeyValuePair<String, String>("SelectedSymbol", SelectedSymbol));
saveParams.Add(new KeyValuePair<String, String>("ShowTradeLabels", showTradeLabels.ToString()));
saveParams.Add(new KeyValuePair<String, String>("IsLegendVisible", isLegendVisible.ToString()));
saveParams.Add(new KeyValuePair<String, String>("UseLeastSquaresFit", useLeastSquaresFit.ToString()));
saveParams.Add(new KeyValuePair<String, String>("ShowInsiderTransactions", showInsiderTransactions.ToString()));
if(null!=stopLimits && 0!=stopLimits.Count)
{
SaveParameters stopLimitSaveParams = StopLimitsExtensions.FromStopLimits(stopLimits);
saveParams.AddRange(stopLimitSaveParams);
}
if(null!=portfolioTrades && 0!=portfolioTrades.Count)
{
SaveParameters portfolioTradesSaveParams = PortfolioTradesExtensions.FromPortfolioTrades(portfolioTrades);
saveParams.AddRange(portfolioTradesSaveParams);
}
return saveParams;
}
// DESERIALZIE FROM PARAMETERS
public override void SetSaveParameters(SaveParameters saveParameters)
{
try
{
Referer=saveParameters.Referer;
symbol = (from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("SelectedSymbol") select item).FirstOrDefault().Value;
try
{
if(saveParameters.ContainsKey("ShowTradeLabels"))
{
showTradeLabels = Boolean.Parse((from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("ShowTradeLabels") select item).FirstOrDefault().Value);
}
else showTradeLabels=true;
}
catch (Exception)
{
showTradeLabels = true;
}
try
{
if(saveParameters.ContainsKey("IsLegendVisible"))
{
isLegendVisible=Boolean.Parse((from KeyValuePair<String,String> item in saveParameters where item.Key.Equals("IsLegendVisible") select item).FirstOrDefault().Value);
}
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString()));
}
try
{
if(saveParameters.ContainsKey("UseLeastSquaresFit"))
{
useLeastSquaresFit=Boolean.Parse((from KeyValuePair<String,String> item in saveParameters where item.Key.Equals("UseLeastSquaresFit") select item).FirstOrDefault().Value);
}
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString()));
}
try
{
if(saveParameters.ContainsKey("ShowInsiderTransactions"))
{
showInsiderTransactions=Boolean.Parse((from KeyValuePair<String,String> item in saveParameters where item.Key.Equals("ShowInsiderTransactions") select item).FirstOrDefault().Value);
}
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString()));
}
try
{
if(saveParameters.ContainsKey("StopHistoryCount"))
{
stopLimits = StopLimitsExtensions.FromSaveParams(saveParameters);
if(stopLimits.Count>0)
{
stopLimit = stopLimits[stopLimits.Count-1]; // This is the latest stop.
}
}
}
catch(Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString()));
}
try
{
if(saveParameters.ContainsKey("PortfolioTradesCount"))
{
portfolioTrades = PortfolioTradesExtensions.FromSaveParams(saveParameters);
portfolioTrades = new PortfolioTrades(portfolioTrades.Take(1).ToList()); // This view works on a single position provided by a model
}
}
catch(Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString()));
}
base.OnPropertyChanged("SelectedSymbol");
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString()));
}
}
public override bool CanPersist()
{
return true;
}
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 OnBollingerBandPositionViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs)
{
if (eventArgs.PropertyName.Equals("SelectedSymbol")||
eventArgs.PropertyName.Equals("ShowTradeLabels")||
eventArgs.PropertyName.Equals("SelectedSymbol")||
eventArgs.PropertyName.Equals("LeastSquaresFit")&&
null!=SelectedSymbol)
{
BusyIndicator=true;
InitializeDataSources();
Task workerTask=Task.Factory.StartNew(()=>
{
base.DisplayName="Position("+SelectedSymbol+")";
base.OnPropertyChanged("DisplayName");
BusyContent=DATA_MESSAGE;
// DEBUG
// if (null != portfolioTrades && 0 != portfolioTrades.Count)
if(null!=PortfolioTrade)
{
DateGenerator dateGenerator = new DateGenerator();
DateTime latestMarketDate = PricingDA.GetLatestDate(SelectedSymbol);
DateTime earliestDate = PortfolioTrade.TradeDate;
earliestDate = dateGenerator.FindPastBusinessDay(earliestDate, 30); // expand to the left a little bit
DateTime latestDate = PortfolioTrade.SellDate;
if(Utility.IsEpoch(latestDate))latestDate=latestMarketDate;
DateTime expandDate = dateGenerator.FindForwardBusinessDay(latestDate, 10); // try to expand to the right a little bit
if(expandDate < latestMarketDate)
{
latestDate=expandDate;
}
int marketDaysBetween = dateGenerator.TradingDaysBetween(earliestDate, latestDate);
int daysRequired = MIN_DAYS - marketDaysBetween;
if(marketDaysBetween < MIN_DAYS)
{
if(latestDate < latestMarketDate) // expand to the right
{
int daysBetween = dateGenerator.TradingDaysBetween(latestDate, latestMarketDate);
if(daysBetween>daysRequired) // we can expand to the right
{
latestDate = dateGenerator.FindForwardBusinessDay(latestDate, daysRequired);
}
else // we can't expand further to the right we need to expznd to the left
{
earliestDate = dateGenerator.FindPastBusinessDay(earliestDate, daysRequired);
}
}
else // expand to the left
{
earliestDate = dateGenerator.FindPastBusinessDay(earliestDate, daysRequired);
}
}
int nearestDayCount = GetNearestDayCount(marketDaysBetween);
prices = PricingDA.GetPrices(SelectedSymbol, latestDate, earliestDate);
DateTime earliestInsiderTransactionDate=dateGenerator.GenerateFutureBusinessDate(prices[prices.Count-1].Date,30);
insiderTransactionSummaries=InsiderTransactionDA.GetInsiderTransactionSummaries(SelectedSymbol,earliestInsiderTransactionDate);
if(PortfolioTrade.IsClosed)
{
insiderTransactionSummaries=new InsiderTransactionSummaries(insiderTransactionSummaries.Where(x => x.TransactionDate<=PortfolioTrade.SellDate).ToList());
}
zeroPrice=GetZeroPrice();
}
companyName = PricingDA.GetNameForSymbol(SelectedSymbol);
BusyContent=BAND_MESSAGE;
bollingerBands = BollingerBandGenerator.GenerateBollingerBands(prices);
CreateCompositeDataSources();
});
workerTask.ContinueWith((continuation)=>
{
BusyIndicator = false;
base.OnPropertyChanged("K");
base.OnPropertyChanged("KL1");
base.OnPropertyChanged("L");
base.OnPropertyChanged("LP1");
base.OnPropertyChanged("High");
base.OnPropertyChanged("Low");
base.OnPropertyChanged("Close");
base.OnPropertyChanged("SMAN");
base.OnPropertyChanged("Volume");
base.OnPropertyChanged("LeastSquares");
base.OnPropertyChanged("Title");
base.OnPropertyChanged("TradePoints");
base.OnPropertyChanged("Markers");
base.OnPropertyChanged("ZeroPoint");
base.OnPropertyChanged("ZeroPointMarkers");
base.OnPropertyChanged("StopLimit");
base.OnPropertyChanged("StopLimitMarkers");
base.OnPropertyChanged("InsiderTransactionPointDisposedSmall");
base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedSmall");
base.OnPropertyChanged("InsiderTransactionPointDisposedMedium");
base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedMedium");
base.OnPropertyChanged("InsiderTransactionPointDisposedLarge");
base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedLarge");
base.OnPropertyChanged("InsiderTransactionPointAcquiredSmall");
base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredSmall");
base.OnPropertyChanged("InsiderTransactionPointAcquiredMedium");
base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredMedium");
base.OnPropertyChanged("InsiderTransactionPointAcquiredLarge");
base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredLarge");
});
}
}
// *************************************************************************** C U S T O M B E H A V I O R **************************************************
public Boolean LeastSquaresFit
{
get
{
return useLeastSquaresFit;
}
set
{
useLeastSquaresFit = value;
base.OnPropertyChanged("LeastSquaresFit");
}
}
public Boolean CheckBoxLegendVisible
{
get
{
return isLegendVisible;
}
set
{
isLegendVisible = value;
base.OnPropertyChanged("CheckBoxLegendVisible");
base.OnPropertyChanged("LegendVisible");
}
}
public String LegendVisible
{
get
{
if (isLegendVisible) return "true";
return "false";
}
set
{
isLegendVisible = Boolean.Parse(value);
base.OnPropertyChanged("LegendVisible");
}
}
public bool ShowTradeLabels
{
get
{
return showTradeLabels;
}
set
{
showTradeLabels = value;
base.OnPropertyChanged("ShowTradeLabels");
}
}
// ************************************************************ C o m p o s i t e D a t a S o u r c e s *************************************************
public void CreateCompositeDataSources()
{
if(null==prices||0==prices.Count)return;
double minClose=(from Price price in prices select price.Close).Min();
// get the maximum date in the bollinger band series
DateTime maxBollingerDate=(from BollingerBandElement bollingerBandElement in bollingerBands select bollingerBandElement.Date).Max();
// ensure that the insider transactions are clipped to the bollingerband max date. There are some items in insider transaction summaries (options dated in the future) that will throw the graphic out of proportion
InsiderTransactionSummaries disposedSummaries=new InsiderTransactionSummaries((from InsiderTransactionSummary insiderTransactionSummary in insiderTransactionSummaries where insiderTransactionSummary.NumberOfSharesAcquiredDisposed<0 && insiderTransactionSummary.TransactionDate.Date<=maxBollingerDate select insiderTransactionSummary).ToList());
InsiderTransactionSummaries acquiredSummaries=new InsiderTransactionSummaries((from InsiderTransactionSummary insiderTransactionSummary in insiderTransactionSummaries where insiderTransactionSummary.NumberOfSharesAcquiredDisposed>0 && insiderTransactionSummary.TransactionDate.Date<=maxBollingerDate select insiderTransactionSummary).ToList());
BinCollection<InsiderTransactionSummary> disposedSummariesBin=BinHelper<InsiderTransactionSummary>.CreateBins(new BinItems<InsiderTransactionSummary>(disposedSummaries),3);
BinCollection<InsiderTransactionSummary> acquiredSummariesBin=BinHelper<InsiderTransactionSummary>.CreateBins(new BinItems<InsiderTransactionSummary>(acquiredSummaries),3);
if(null!=zeroPrice)
{
compositeDataSourceZeroPoint= GainLossModel.Price(zeroPrice);
}
// if(null!=PortfolioTrade && PortfolioTrade.IsOpen && null!=zeroPrice)
// {
// compositeDataSourceGainLoss=GainLossModel.CreateCompositeDataSource(zeroPrice.Date,stopLimit.StopPrice);
// compositeDataSourceGainLoss=GainLossModel.CreateCompositeDataSource(zeroPrice.Date,zeroPrice.Close);
// }
// else
// {
compositeDataSourceStopLimit=StopLimitCompositeModel.CreateCompositeDataSource(stopLimits);
// }
compositeDataSourceInsiderTransactionPointDisposedSmall=InsiderTransactionModel.InsiderTransactionSummaries(new InsiderTransactionSummaries(disposedSummariesBin[2]),minClose);
compositeDataSourceInsiderTransactionPointDisposedMedium=InsiderTransactionModel.InsiderTransactionSummaries(new InsiderTransactionSummaries(disposedSummariesBin[1]),minClose);
compositeDataSourceInsiderTransactionPointDisposedLarge=InsiderTransactionModel.InsiderTransactionSummaries(new InsiderTransactionSummaries(disposedSummariesBin[0]),minClose);
compositeDataSourceInsiderTransactionPointAcquiredSmall=InsiderTransactionModel.InsiderTransactionSummaries(new InsiderTransactionSummaries(acquiredSummariesBin[0]),minClose);
compositeDataSourceInsiderTransactionPointAcquiredMedium=InsiderTransactionModel.InsiderTransactionSummaries(new InsiderTransactionSummaries(acquiredSummariesBin[1]),minClose);
compositeDataSourceInsiderTransactionPointAcquiredLarge=InsiderTransactionModel.InsiderTransactionSummaries(new InsiderTransactionSummaries(acquiredSummariesBin[2]),minClose);
compositeDataSourceK =BollingerBandModel.K(bollingerBands);
compositeDataSourceKL1 =BollingerBandModel.KL1(bollingerBands);
compositeDataSourceL =BollingerBandModel.L(bollingerBands);
compositeDataSourceLP1 =BollingerBandModel.LP1(bollingerBands);
compositeDataSourceHigh =BollingerBandModel.High(bollingerBands);
compositeDataSourceLow =BollingerBandModel.Low(bollingerBands);
compositeDataSourceClose =BollingerBandModel.Close(bollingerBands);
compositeDataSourceSMAN =BollingerBandModel.SMAN(bollingerBands);
compositeDataSourceVolume =BollingerBandModel.Volume(bollingerBands);
compositeDataSourceLeastSquares = BollingerBandModel.LeastSquares(bollingerBands);
compositeDataSourceTradePoints = PortfolioTradeModel.PortfolioTrades(CreateBuySellLots(PortfolioTrade));
}
public void InitializeDataSources()
{
if(compositeDataSourceStopLimit!=null)compositeDataSourceStopLimit.Clear();
if(compositeDataSourceZeroPoint!=null)compositeDataSourceZeroPoint.Clear();
if(compositeDataSourceInsiderTransactionPointDisposedSmall!=null)compositeDataSourceInsiderTransactionPointDisposedSmall.Clear();
if(compositeDataSourceInsiderTransactionPointDisposedMedium!=null)compositeDataSourceInsiderTransactionPointDisposedMedium.Clear();
if(compositeDataSourceInsiderTransactionPointDisposedLarge!=null)compositeDataSourceInsiderTransactionPointDisposedLarge.Clear();
if(compositeDataSourceInsiderTransactionPointAcquiredSmall!=null)compositeDataSourceInsiderTransactionPointAcquiredSmall.Clear();
if(compositeDataSourceInsiderTransactionPointAcquiredMedium!=null)compositeDataSourceInsiderTransactionPointAcquiredMedium.Clear();
if(compositeDataSourceInsiderTransactionPointAcquiredLarge!=null)compositeDataSourceInsiderTransactionPointAcquiredLarge.Clear();
if(compositeDataSourceK!=null)compositeDataSourceK.Clear();
if(compositeDataSourceKL1!=null)compositeDataSourceKL1.Clear();
if(compositeDataSourceL!=null)compositeDataSourceL.Clear();
if(compositeDataSourceLP1!=null)compositeDataSourceLP1.Clear();
if(compositeDataSourceHigh!=null)compositeDataSourceHigh.Clear();
if(compositeDataSourceLow!=null)compositeDataSourceLow.Clear();
if(compositeDataSourceClose!=null)compositeDataSourceClose.Clear();
if(compositeDataSourceSMAN!=null)compositeDataSourceSMAN.Clear();
if(compositeDataSourceVolume!=null)compositeDataSourceVolume.Clear();
if(compositeDataSourceLeastSquares!=null)compositeDataSourceLeastSquares.Clear();
if (compositeDataSourceTradePoints != null) compositeDataSourceTradePoints.Clear();
}
public CompositeDataSource ZeroPoint
{
get
{
return compositeDataSourceZeroPoint;
}
}
public CompositeDataSource StopLimit
{
get
{
return compositeDataSourceStopLimit;
}
}
// **************************************************************** I N S I D E R T R A N S A C T I O N S *************************************************
public CompositeDataSource InsiderTransactionPointDisposedSmall
{
get
{
if (!showInsiderTransactions || null == insiderTransactionSummaries || null==prices) return null;
return compositeDataSourceInsiderTransactionPointDisposedSmall;
}
}
public CenteredTextMarker[] InsiderTransactionPointMarkersDisposedSmall
{
get
{
return null; // not displaying any text markers for disposed shares yet
}
}
public CompositeDataSource InsiderTransactionPointDisposedMedium
{
get
{
if (!showInsiderTransactions || null == insiderTransactionSummaries || null==prices) return null;
return compositeDataSourceInsiderTransactionPointDisposedMedium;
}
}
public CenteredTextMarker[] InsiderTransactionPointMarkersDisposedMedium
{
get
{
return null; // not displaying any text markers for disposed shares yet
}
}
public CompositeDataSource InsiderTransactionPointDisposedLarge
{
get
{
if (!showInsiderTransactions || null == insiderTransactionSummaries || null==prices) return null;
return compositeDataSourceInsiderTransactionPointDisposedLarge;
}
}
public CenteredTextMarker[] InsiderTransactionPointMarkersDisposedLarge
{
get
{
return null; // not displaying any text markers for disposed shares yet
}
}
// *****************************************************************************************************************************************************
public CompositeDataSource InsiderTransactionPointAcquiredSmall
{
get
{
if (!showInsiderTransactions || null == insiderTransactionSummaries || null==prices) return null;
return compositeDataSourceInsiderTransactionPointAcquiredSmall;
}
}
public CenteredTextMarker[] InsiderTransactionPointMarkersAcquiredSmall
{
get
{
return null; // not displaying any text markers for acquired shares yet.
}
}
public CompositeDataSource InsiderTransactionPointAcquiredMedium
{
get
{
if (!showInsiderTransactions || null == insiderTransactionSummaries || null==prices) return null;
return compositeDataSourceInsiderTransactionPointAcquiredMedium;
}
}
public CenteredTextMarker[] InsiderTransactionPointMarkersAcquiredMedium
{
get
{
return null; // not displaying any text markers for acquired shares yet.
}
}
public CompositeDataSource InsiderTransactionPointAcquiredLarge
{
get
{
if (!showInsiderTransactions || null == insiderTransactionSummaries || null==prices) return null;
return compositeDataSourceInsiderTransactionPointAcquiredLarge;
}
}
public CenteredTextMarker[] InsiderTransactionPointMarkersAcquiredLarge
{
get
{
return null; // not displaying any text markers for acquired shares yet.
}
}
// *********************************************************************************************************************************************************************
public CompositeDataSource K
{
get
{
return compositeDataSourceK;
}
}
public CompositeDataSource KL1
{
get
{
return compositeDataSourceKL1;
}
}
public CompositeDataSource L
{
get
{
return compositeDataSourceL;
}
}
public CompositeDataSource LP1
{
get
{
return compositeDataSourceLP1;
}
}
public CompositeDataSource High
{
get
{
return compositeDataSourceHigh;
}
}
public CompositeDataSource Low
{
get
{
return compositeDataSourceLow;
}
}
public CompositeDataSource Close
{
get
{
return compositeDataSourceClose;
}
}
public CompositeDataSource SMAN
{
get
{
return compositeDataSourceSMAN;
}
}
public CompositeDataSource Volume
{
get
{
return compositeDataSourceVolume;
}
}
// ********************************************************************* L E A S T S Q U A R E S *************************************************************
public CompositeDataSource LeastSquares
{
get
{
if(!useLeastSquaresFit||null==bollingerBands)return null;
return compositeDataSourceLeastSquares;
}
}
// ***************************************************************************************************************************************************************
public CompositeDataSource TradePoints
{
get
{
return compositeDataSourceTradePoints;
}
}
// ***************************************************************************** M A R K E R S *************************************************************
// BUY/SELL MARKERS
public CenteredTextMarker[] Markers
{
get
{
if(null == PortfolioTrade || !showTradeLabels)return null;
PortfolioTrades lots = CreateBuySellLots(PortfolioTrade);
TextMarkerOffsets textMarkerOffsets = new TextMarkerOffsets(35, 18);
List<CenteredTextMarker> centeredTextMarkers = new List<CenteredTextMarker>();
for (int index = 0; index < lots.Count; index++)
{
CenteredTextMarker centerTextMarker = new CenteredTextMarker();
PortfolioTrade portfolioTrade = lots[index];
StringBuilder sb = new StringBuilder();
sb.Append(portfolioTrade.BuySell.Equals("B") ? "Buy " : "Sell ");
sb.Append(Utility.FormatNumber(portfolioTrade.Shares));
sb.Append("@");
sb.Append(Utility.FormatCurrency(portfolioTrade.Price));
centerTextMarker.Text = sb.ToString();
centerTextMarker.HorizontalShift = "0";
centerTextMarker.VerticalShift = textMarkerOffsets.GetOffset(portfolioTrade).ToString();
centeredTextMarkers.Add(centerTextMarker);
}
return centeredTextMarkers.ToArray();
}
}
// ZERO POINT MARKERS
public CenteredTextMarker[] ZeroPointMarkers
{
get
{
if (null == zeroPrice || !showTradeLabels) return null;
List<CenteredTextMarker> centeredTextMarkers = new List<CenteredTextMarker>();
CenteredTextMarker centerTextMarker = new CenteredTextMarker();
StringBuilder sb = new StringBuilder();
sb.Append("Even ");
sb.Append(Utility.FormatCurrency(zeroPrice.Close));
Price latestPrice=prices[0];
double parityOffsetPercent=(latestPrice.Close-zeroPrice.Close)/zeroPrice.Close;
sb.Append("(").Append(parityOffsetPercent<0?"":"+").Append(Utility.FormatPercent(parityOffsetPercent)).Append(")");
centerTextMarker.Text = sb.ToString();
centeredTextMarkers.Add(centerTextMarker);
centerTextMarker.VerticalShift="40";
centerTextMarker.HorizontalShift="32";
return centeredTextMarkers.ToArray();
}
}
// STOP LIMIT MARKERS
public CenteredTextMarker[] StopLimitMarkers
{
get
{
List<CenteredTextMarker> centeredTextMarkers=new List<CenteredTextMarker>();
if(!showTradeLabels) return null;
if(null!=stopLimits)
{
for(int index=0;index<stopLimits.Count;index++)
{
StopLimit limit=stopLimits[index];
CenteredTextMarker centerTextMarker=new CenteredTextMarker();
StringBuilder sb=new StringBuilder();
sb.Append(limit.StopType).Append(" ");
sb.Append(Utility.FormatCurrency(limit.StopPrice));
if(index==stopLimits.Count-1)
{
Price latestPrice=prices[0]; // always use the most recent price when calculating the spread (in percent) from the active stop limit.
double percentOffsetFromLow=((latestPrice.Low-limit.StopPrice)/limit.StopPrice);
sb.Append(" (").Append(percentOffsetFromLow>0?"+":"").Append(Utility.FormatPercent(percentOffsetFromLow)).Append(")");
}
centerTextMarker.Text=sb.ToString();
if(0==index&&stopLimits.Count>1) centerTextMarker.VerticalShift="25";
else centerTextMarker.VerticalShift="40";
centerTextMarker.HorizontalShift="32";
centeredTextMarkers.Add(centerTextMarker);
}
}
else
{
if(null==zeroPrice)return null;
if(null==stopLimit||null==zeroPrice||!showTradeLabels) return null;
CenteredTextMarker centerTextMarker=new CenteredTextMarker();
Price latestPrice=prices[0];
double percentOffsetFromLow=((latestPrice.Low-stopLimit.StopPrice)/stopLimit.StopPrice);
StringBuilder sb=new StringBuilder();
sb.Append(stopLimit.StopType).Append(" ");
sb.Append(Utility.FormatCurrency(stopLimit.StopPrice));
sb.Append(" (").Append(percentOffsetFromLow>0?"+":"").Append(Utility.FormatPercent(percentOffsetFromLow)).Append(")");
centerTextMarker.Text=sb.ToString();
centeredTextMarkers.Add(centerTextMarker);
centerTextMarker.VerticalShift="40";
centerTextMarker.HorizontalShift="32";
}
return centeredTextMarkers.ToArray();
}
}
// ************************************************************************************************************************************************************************
// ************************************************************************************************************************************************************************
// ************************************************************************************************************************************************************************
// The approach here is to trick the marker and trade composites to line up a BUY and SELL position.
// The markers and trades are looking at TradeDate and Price so for the SELL logic we need to put the SellDate into TradeDate and the SellPrice into Price
private PortfolioTrades CreateBuySellLots(PortfolioTrade portfolioTrade)
{
PortfolioTrades portfolioTrades = new PortfolioTrades();
if(null == portfolioTrade)return portfolioTrades;
NVPCollection clonedTrade = portfolioTrade.ToNVPCollection();
PortfolioTrade buyTrade = PortfolioTrade.FromNVPCollection(clonedTrade);
PortfolioTrade sellTrade = PortfolioTrade.FromNVPCollection(clonedTrade);
// BUY position
buyTrade.SellDate=Utility.Epoch;
buyTrade.BuySell="B";
buyTrade.Status="OPEN";
portfolioTrades.Add(buyTrade);
// SELL position
if(Utility.IsEpoch(portfolioTrade.SellDate))return portfolioTrades;
sellTrade.BuySell="S";
sellTrade.Status="CLOSE";
sellTrade.TradeDate=portfolioTrade.SellDate;
sellTrade.Price=sellTrade.SellPrice;
portfolioTrades.Add(sellTrade);
return portfolioTrades;
}
// ************************************************************************************************************************************************************************
// ************************************************************************************************************************************************************************
// ************************************************************************************************************************************************************************
public override String Title
{
get
{
if (null == companyName || null == prices || 0 == prices.Count) return "";
String displayCompanyName=companyName;
if(displayCompanyName.Length>40)displayCompanyName=displayCompanyName.Substring(0,40)+"...";
StringBuilder sb=new StringBuilder();
float change=float.NaN;
Prices prices2day=new Prices(prices.Take(2).ToList());
if(2==prices2day.Count)change=prices2day.GetReturns()[0];
sb.Append(displayCompanyName);
sb.Append(" (").Append(SelectedSymbol).Append(") ");
sb.Append(Utility.DateTimeToStringMMHDDHYYYY(prices[prices.Count-1].Date));
sb.Append(" Thru ");
sb.Append(Utility.DateTimeToStringMMHDDHYYYY(prices[0].Date));
sb.Append(" (").Append(Utility.FormatCurrency(prices[0].Close));
sb.Append("/").Append(Utility.FormatCurrency(prices[0].Low));
if(!float.IsNaN(change))
{
sb.Append(",");
sb.Append(change>=0.00?"+":"").Append(Utility.FormatPercent((double)change));
}
sb.Append(")");
return sb.ToString();
}
}
public Boolean Visibility
{
get { return false; }
}
public List<Int32> DayCounts
{
get{return dayCounts;}
}
public String SelectedSymbol
{
get
{
return symbol;
}
set
{
if (value == symbol || String.IsNullOrEmpty(value)) return;
symbol = value;
base.OnPropertyChanged("SelectedSymbol");
}
}
private void Refresh()
{
base.OnPropertyChanged("SelectedSymbol");
}
private bool CanRefresh
{
get
{
return true;
}
}
public ICommand RefreshCommand
{
get
{
if (refreshCommand == null)
{
refreshCommand = new RelayCommand(param => this.Refresh(),param=>this.CanRefresh);
}
return refreshCommand;
}
}
public Boolean CheckBoxShowInsiderTransactions
{
get
{
return showInsiderTransactions;
}
set
{
showInsiderTransactions = value;
base.OnPropertyChanged("CheckBoxShowInsiderTransactions");
base.OnPropertyChanged("InsiderTransactionPointDisposedSmall");
base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedSmall");
base.OnPropertyChanged("InsiderTransactionPointDisposedMedium");
base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedMedium");
base.OnPropertyChanged("InsiderTransactionPointDisposedLarge");
base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedLarge");
base.OnPropertyChanged("InsiderTransactionPointAcquiredSmall");
base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredSmall");
base.OnPropertyChanged("InsiderTransactionPointAcquiredMedium");
base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredMedium");
base.OnPropertyChanged("InsiderTransactionPointAcquiredLarge");
base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredLarge");
base.OnPropertyChanged("LeastSquares");
}
}
}
}

View File

@@ -70,13 +70,15 @@ namespace TradeBlotter.ViewModels
private String selectedParameter=null; private String selectedParameter=null;
private MGSHPositionModelCollection positions=null; private MGSHPositionModelCollection positions=null;
private MGSHPositionModel selectedPosition=null; private MGSHPositionModel selectedPosition=null;
private RelayCommand loadFileCommand;
private RelayCommand reloadCommand;
private RelayCommand monitorCommand;
private ObservableCollection<String> monitorIntervals; private ObservableCollection<String> monitorIntervals;
private String selectedMonitorInterval; private String selectedMonitorInterval;
private bool monitorRunning=false; private bool monitorRunning=false;
private DispatcherTimer dispatcherTimer = new DispatcherTimer(); private DispatcherTimer dispatcherTimer = new DispatcherTimer();
private RelayCommand loadFileCommand;
private RelayCommand reloadCommand;
private RelayCommand monitorCommand;
private RelayCommand stochasticsCommandPosition; private RelayCommand stochasticsCommandPosition;
private RelayCommand relativeStrengthCommandPosition; private RelayCommand relativeStrengthCommandPosition;
private RelayCommand macdCommandPosition; private RelayCommand macdCommandPosition;
@@ -130,6 +132,7 @@ namespace TradeBlotter.ViewModels
base.OnPropertyChanged("SelectedParameter"); base.OnPropertyChanged("SelectedParameter");
base.OnPropertyChanged("ParameterValue"); base.OnPropertyChanged("ParameterValue");
} }
protected override void OnDispose() protected override void OnDispose()
{ {
StopMonitor(); StopMonitor();
@@ -140,6 +143,7 @@ namespace TradeBlotter.ViewModels
{ {
return true; return true;
} }
public override SaveParameters GetSaveParameters() public override SaveParameters GetSaveParameters()
{ {
SaveParameters saveParams = new SaveParameters(); SaveParameters saveParams = new SaveParameters();
@@ -148,6 +152,7 @@ namespace TradeBlotter.ViewModels
saveParams.Add(new KeyValuePair<String, String>("PathFileName", pathFileName)); saveParams.Add(new KeyValuePair<String, String>("PathFileName", pathFileName));
return saveParams; return saveParams;
} }
public override void SetSaveParameters(SaveParameters saveParameters) public override void SetSaveParameters(SaveParameters saveParameters)
{ {
try try
@@ -173,6 +178,7 @@ namespace TradeBlotter.ViewModels
base.OnPropertyChanged("BusyIndicator"); base.OnPropertyChanged("BusyIndicator");
} }
} }
public String BusyContent public String BusyContent
{ {
get get
@@ -207,6 +213,7 @@ namespace TradeBlotter.ViewModels
return collection; return collection;
} }
} }
public ObservableCollection<MenuItem> PositionsMenuItems public ObservableCollection<MenuItem> PositionsMenuItems
{ {
get get
@@ -226,11 +233,12 @@ namespace TradeBlotter.ViewModels
collection.Add(new MenuItem() { Text = "Display DCF Valuation", MenuItemClickedCommand = DisplayDCFValuationPosition, 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 = "Add to Watchlist", MenuItemClickedCommand = AddToWatchListPosition, StaysOpenOnClick = false });
collection.Add(new MenuItem() { Text = "Remove from Watchlist", MenuItemClickedCommand = RemoveFromWatchListPosition, 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 = "Close Position...",MenuItemClickedCommand=ClosePosition,StaysOpenOnClick=false });
collection.Add(new MenuItem() { Text="Edit Position...",MenuItemClickedCommand=EditPosition,StaysOpenOnClick=false }); collection.Add(new MenuItem() { Text = "Edit Position...",MenuItemClickedCommand=EditPosition,StaysOpenOnClick=false });
return collection; return collection;
} }
} }
private void OnMomentumViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs) private void OnMomentumViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs)
{ {
} }
@@ -248,6 +256,7 @@ namespace TradeBlotter.ViewModels
return "MGSHMomentum Model ("+pureFileName+")"; return "MGSHMomentum Model ("+pureFileName+")";
} }
} }
public override String Title public override String Title
{ {
get get
@@ -255,11 +264,13 @@ namespace TradeBlotter.ViewModels
return DisplayName; return DisplayName;
} }
} }
public DateTime SelectableDateStart public DateTime SelectableDateStart
{ {
get{return selectableDateStart;} get{return selectableDateStart;}
set{selectableDateStart=value;} set{selectableDateStart=value;}
} }
public DateTime SelectableDateEnd public DateTime SelectableDateEnd
{ {
get{return selectableDateEnd;} get{return selectableDateEnd;}
@@ -309,6 +320,7 @@ namespace TradeBlotter.ViewModels
return sb.ToString(); return sb.ToString();
} }
} }
public String VelocityDescription public String VelocityDescription
{ {
get get
@@ -317,6 +329,7 @@ namespace TradeBlotter.ViewModels
return "Velocity is the percentage range of the current price within the price history."; return "Velocity is the percentage range of the current price within the price history.";
} }
} }
public String BetaDescription public String BetaDescription
{ {
get get
@@ -325,6 +338,7 @@ namespace TradeBlotter.ViewModels
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."; 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 // Position
public String CompanyDescriptionSelectedPosition public String CompanyDescriptionSelectedPosition
{ {
@@ -355,11 +369,13 @@ namespace TradeBlotter.ViewModels
base.OnPropertyChanged("SelectedItem"); base.OnPropertyChanged("SelectedItem");
} }
} }
public MGSHPositionModel SelectedPosition public MGSHPositionModel SelectedPosition
{ {
get{return selectedPosition;} get{return selectedPosition;}
set{selectedPosition=value;base.OnPropertyChanged("SelectedPosition");} set{selectedPosition=value;base.OnPropertyChanged("SelectedPosition");}
} }
public String SelectedDate public String SelectedDate
{ {
get { return selectedDate; } get { return selectedDate; }
@@ -369,40 +385,49 @@ namespace TradeBlotter.ViewModels
base.OnPropertyChanged("SelectedDate"); base.OnPropertyChanged("SelectedDate");
} }
} }
public ObservableCollection<MGSHMomentumCandidate> AllItems public ObservableCollection<MGSHMomentumCandidate> AllItems
{ {
get{return momentumCandidates;} get{return momentumCandidates;}
} }
public MGSHPositionModelCollection AllPositions public MGSHPositionModelCollection AllPositions
{ {
get{return positions;} get{return positions;}
} }
public ObservableCollection<String> Parameters public ObservableCollection<String> Parameters
{ {
get{return nvpDictionaryKeys;} get{return nvpDictionaryKeys;}
} }
public ObservableCollection<String> MonitorIntervals public ObservableCollection<String> MonitorIntervals
{ {
get{return monitorIntervals;} get{return monitorIntervals;}
} }
public bool CanMonitor public bool CanMonitor
{ {
get{return IsTradeFileLoaded;} get{return IsTradeFileLoaded;}
} }
public String MonitorStatus public String MonitorStatus
{ {
get{return monitorRunning?"Stop Monitor":"Start Monitor";} get{return monitorRunning?"Stop Monitor":"Start Monitor";}
} }
public String SelectedMonitorInterval public String SelectedMonitorInterval
{ {
get{return selectedMonitorInterval;} get{return selectedMonitorInterval;}
set{selectedMonitorInterval=value;base.OnPropertyChanged("SelectedMonitorInterval");} set{selectedMonitorInterval=value;base.OnPropertyChanged("SelectedMonitorInterval");}
} }
public String SelectedParameter public String SelectedParameter
{ {
get{return selectedParameter;} get{return selectedParameter;}
set{selectedParameter=value;base.OnPropertyChanged("SelectedParameter");base.OnPropertyChanged("ParameterValue");} set{selectedParameter=value;base.OnPropertyChanged("SelectedParameter");base.OnPropertyChanged("ParameterValue");}
} }
public String ParameterValue public String ParameterValue
{ {
get get
@@ -411,6 +436,7 @@ namespace TradeBlotter.ViewModels
return nvpDictionary[selectedParameter].Value; return nvpDictionary[selectedParameter].Value;
} }
} }
public String CashBalance public String CashBalance
{ {
get get
@@ -419,6 +445,7 @@ namespace TradeBlotter.ViewModels
return Utility.FormatCurrency(sessionParams.CashBalance); return Utility.FormatCurrency(sessionParams.CashBalance);
} }
} }
public String NonTradeableCash public String NonTradeableCash
{ {
get get
@@ -427,6 +454,16 @@ namespace TradeBlotter.ViewModels
return Utility.FormatCurrency(sessionParams.NonTradeableCash); return Utility.FormatCurrency(sessionParams.NonTradeableCash);
} }
} }
public String HedgeCash
{
get
{
if(null==sessionParams) return "";
return Utility.FormatCurrency(sessionParams.HedgeCashBalance);
}
}
public String ModelExpectation public String ModelExpectation
{ {
get get
@@ -435,6 +472,7 @@ namespace TradeBlotter.ViewModels
return Utility.FormatNumber(modelStatistics.Expectancy,2); return Utility.FormatNumber(modelStatistics.Expectancy,2);
} }
} }
public Brush ExpectationColor public Brush ExpectationColor
{ {
get get
@@ -444,6 +482,7 @@ namespace TradeBlotter.ViewModels
return UIUtils.BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red); return UIUtils.BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
} }
} }
public String ExpectationDescription public String ExpectationDescription
{ {
get get
@@ -465,10 +504,11 @@ namespace TradeBlotter.ViewModels
sb.Append("The calculations are based on closed positions."); sb.Append("The calculations are based on closed positions.");
return sb.ToString(); return sb.ToString();
} }
} }
// *************************************************************************************************************************************************************
// *********************************************************************** I C O M M A N D ******************************************************************** // *************************************************************************************************************************************************************
// ************************************************************************************************************************************************************* // *********************************************************************** I C O M M A N D ********************************************************************
// *************************************************************************************************************************************************************
public ICommand DisplayHistorical public ICommand DisplayHistorical
{ {
get get
@@ -485,6 +525,7 @@ namespace TradeBlotter.ViewModels
return displayHistoricalCommand; return displayHistoricalCommand;
} }
} }
public ICommand RunCommand public ICommand RunCommand
{ {
get get
@@ -496,6 +537,7 @@ namespace TradeBlotter.ViewModels
return runCommand; return runCommand;
} }
} }
public ICommand DisplayMovingAverage public ICommand DisplayMovingAverage
{ {
get get
@@ -507,6 +549,7 @@ namespace TradeBlotter.ViewModels
return movingAverageCommand; return movingAverageCommand;
} }
} }
public ICommand DisplayAnalystRatings public ICommand DisplayAnalystRatings
{ {
get get
@@ -518,6 +561,7 @@ namespace TradeBlotter.ViewModels
return analystRatingsCommand; return analystRatingsCommand;
} }
} }
public ICommand DisplayMACD public ICommand DisplayMACD
{ {
get get
@@ -529,6 +573,7 @@ namespace TradeBlotter.ViewModels
return macdCommand; return macdCommand;
} }
} }
public ICommand DisplayStochastics public ICommand DisplayStochastics
{ {
get get
@@ -540,6 +585,7 @@ namespace TradeBlotter.ViewModels
return stochasticsCommand; return stochasticsCommand;
} }
} }
public ICommand DisplayRelativeStrength public ICommand DisplayRelativeStrength
{ {
get get
@@ -551,6 +597,7 @@ namespace TradeBlotter.ViewModels
return relativeStrengthCommand; return relativeStrengthCommand;
} }
} }
public ICommand DisplayStickerValuation public ICommand DisplayStickerValuation
{ {
get get
@@ -567,6 +614,7 @@ namespace TradeBlotter.ViewModels
return stickerValuationCommand; return stickerValuationCommand;
} }
} }
public ICommand DisplayDCFValuation public ICommand DisplayDCFValuation
{ {
get get
@@ -583,6 +631,7 @@ namespace TradeBlotter.ViewModels
return dcfValuationCommand; return dcfValuationCommand;
} }
} }
public ICommand DisplayPriceHistory public ICommand DisplayPriceHistory
{ {
get get
@@ -594,6 +643,7 @@ namespace TradeBlotter.ViewModels
return priceHistoryCommand; return priceHistoryCommand;
} }
} }
public ICommand DisplayDividendHistory public ICommand DisplayDividendHistory
{ {
get get
@@ -610,12 +660,14 @@ namespace TradeBlotter.ViewModels
return dividendHistoryCommand; return dividendHistoryCommand;
} }
} }
public void DisplayPriceHistoryCommand() public void DisplayPriceHistoryCommand()
{ {
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.PricingViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180"); SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.PricingViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180");
saveParams.Referer=this; saveParams.Referer=this;
WorkspaceInstantiator.Invoke(saveParams); WorkspaceInstantiator.Invoke(saveParams);
} }
public ICommand DisplayBollingerBand public ICommand DisplayBollingerBand
{ {
get get
@@ -627,6 +679,7 @@ namespace TradeBlotter.ViewModels
return bollingerBandCommand; return bollingerBandCommand;
} }
} }
public ICommand AddToWatchList public ICommand AddToWatchList
{ {
get get
@@ -644,6 +697,7 @@ namespace TradeBlotter.ViewModels
return addToWatchListCommand; return addToWatchListCommand;
} }
} }
public ICommand RemoveFromWatchList public ICommand RemoveFromWatchList
{ {
get get
@@ -680,6 +734,7 @@ namespace TradeBlotter.ViewModels
return displayHeadlinesCommandPosition; return displayHeadlinesCommandPosition;
} }
} }
public ICommand DisplayHistoricalPosition public ICommand DisplayHistoricalPosition
{ {
get get
@@ -696,6 +751,7 @@ namespace TradeBlotter.ViewModels
return displayHistoricalCommandPosition; return displayHistoricalCommandPosition;
} }
} }
public ICommand DisplayAnalystRatingsPosition public ICommand DisplayAnalystRatingsPosition
{ {
get get
@@ -707,6 +763,7 @@ namespace TradeBlotter.ViewModels
return analystRatingsCommandPosition; return analystRatingsCommandPosition;
} }
} }
public ICommand DisplayMovingAveragePosition public ICommand DisplayMovingAveragePosition
{ {
get get
@@ -718,6 +775,7 @@ namespace TradeBlotter.ViewModels
return movingAverageCommandPosition; return movingAverageCommandPosition;
} }
} }
public ICommand DisplayMACDPosition public ICommand DisplayMACDPosition
{ {
get get
@@ -729,6 +787,7 @@ namespace TradeBlotter.ViewModels
return macdCommandPosition; return macdCommandPosition;
} }
} }
public ICommand DisplayStochasticsPosition public ICommand DisplayStochasticsPosition
{ {
get get
@@ -740,6 +799,7 @@ namespace TradeBlotter.ViewModels
return stochasticsCommandPosition; return stochasticsCommandPosition;
} }
} }
public ICommand DisplayRelativeStrengthPosition public ICommand DisplayRelativeStrengthPosition
{ {
get get
@@ -751,6 +811,7 @@ namespace TradeBlotter.ViewModels
return relativeStrengthCommandPosition; return relativeStrengthCommandPosition;
} }
} }
public ICommand DisplayStickerValuationPosition public ICommand DisplayStickerValuationPosition
{ {
get get
@@ -767,6 +828,7 @@ namespace TradeBlotter.ViewModels
return stickerValuationCommandPosition; return stickerValuationCommandPosition;
} }
} }
public ICommand DisplayDCFValuationPosition public ICommand DisplayDCFValuationPosition
{ {
get get
@@ -783,6 +845,7 @@ namespace TradeBlotter.ViewModels
return dcfValuationCommandPosition; return dcfValuationCommandPosition;
} }
} }
public ICommand DisplayPriceHistoryPosition public ICommand DisplayPriceHistoryPosition
{ {
get get
@@ -794,6 +857,7 @@ namespace TradeBlotter.ViewModels
return priceHistoryCommandPosition; return priceHistoryCommandPosition;
} }
} }
public ICommand DisplayDividendHistoryPosition public ICommand DisplayDividendHistoryPosition
{ {
get get
@@ -810,6 +874,7 @@ namespace TradeBlotter.ViewModels
return dividendHistoryCommandPosition; return dividendHistoryCommandPosition;
} }
} }
public ICommand DisplayBollingerBandPosition public ICommand DisplayBollingerBandPosition
{ {
get get
@@ -821,6 +886,7 @@ namespace TradeBlotter.ViewModels
return bollingerBandCommandPosition; return bollingerBandCommandPosition;
} }
} }
public ICommand AddToWatchListPosition public ICommand AddToWatchListPosition
{ {
get get
@@ -839,6 +905,7 @@ namespace TradeBlotter.ViewModels
return addToWatchListCommandPosition; return addToWatchListCommandPosition;
} }
} }
public ICommand RemoveFromWatchListPosition public ICommand RemoveFromWatchListPosition
{ {
get get
@@ -904,6 +971,7 @@ namespace TradeBlotter.ViewModels
return reloadCommand; return reloadCommand;
} }
} }
public bool ReloadEnabled public bool ReloadEnabled
{ {
get get
@@ -911,6 +979,7 @@ namespace TradeBlotter.ViewModels
return !String.IsNullOrEmpty(pathFileName); return !String.IsNullOrEmpty(pathFileName);
} }
} }
public ICommand LoadFile public ICommand LoadFile
{ {
get get
@@ -922,6 +991,7 @@ namespace TradeBlotter.ViewModels
return loadFileCommand; return loadFileCommand;
} }
} }
public ICommand Monitor public ICommand Monitor
{ {
get get
@@ -946,24 +1016,28 @@ namespace TradeBlotter.ViewModels
saveParams.Referer=this; saveParams.Referer=this;
WorkspaceInstantiator.Invoke(saveParams); WorkspaceInstantiator.Invoke(saveParams);
} }
public void DisplayAnalystRatingsCommand() public void DisplayAnalystRatingsCommand()
{ {
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.AnalystRatingsViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All}"); SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.AnalystRatingsViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All}");
saveParams.Referer=this; saveParams.Referer=this;
WorkspaceInstantiator.Invoke(saveParams); WorkspaceInstantiator.Invoke(saveParams);
} }
public void DisplayStochasticsCommand() public void DisplayStochasticsCommand()
{ {
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.StochasticsViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180"); SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.StochasticsViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180");
saveParams.Referer=this; saveParams.Referer=this;
WorkspaceInstantiator.Invoke(saveParams); WorkspaceInstantiator.Invoke(saveParams);
} }
public void DisplayRelativeStrengthCommand() public void DisplayRelativeStrengthCommand()
{ {
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.RSIViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,60,SelectedRSIDayCount,3"); SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.RSIViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,60,SelectedRSIDayCount,3");
saveParams.Referer=this; saveParams.Referer=this;
WorkspaceInstantiator.Invoke(saveParams); WorkspaceInstantiator.Invoke(saveParams);
} }
public void DisplayMACDCommand() public void DisplayMACDCommand()
{ {
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.MACDViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180"); SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.MACDViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180");
@@ -1072,24 +1146,28 @@ namespace TradeBlotter.ViewModels
saveParams.Referer=this; saveParams.Referer=this;
WorkspaceInstantiator.Invoke(saveParams); WorkspaceInstantiator.Invoke(saveParams);
} }
public void DisplayStochasticsCommandPosition() public void DisplayStochasticsCommandPosition()
{ {
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.StochasticsViewModel,SelectedSymbol," + selectedPosition.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180"); SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.StochasticsViewModel,SelectedSymbol," + selectedPosition.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180");
saveParams.Referer=this; saveParams.Referer=this;
WorkspaceInstantiator.Invoke(saveParams); WorkspaceInstantiator.Invoke(saveParams);
} }
public void DisplayRelativeStrengthCommandPosition() public void DisplayRelativeStrengthCommandPosition()
{ {
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.RSIViewModel,SelectedSymbol," + selectedPosition.Symbol + ",SelectedWatchList,{All},SelectedDayCount,60,SelectedRSIDayCount,3"); SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.RSIViewModel,SelectedSymbol," + selectedPosition.Symbol + ",SelectedWatchList,{All},SelectedDayCount,60,SelectedRSIDayCount,3");
saveParams.Referer=this; saveParams.Referer=this;
WorkspaceInstantiator.Invoke(saveParams); WorkspaceInstantiator.Invoke(saveParams);
} }
public void DisplayMACDCommandPosition() public void DisplayMACDCommandPosition()
{ {
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.MACDViewModel,SelectedSymbol," + selectedPosition.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180"); SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.MACDViewModel,SelectedSymbol," + selectedPosition.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180");
saveParams.Referer=this; saveParams.Referer=this;
WorkspaceInstantiator.Invoke(saveParams); WorkspaceInstantiator.Invoke(saveParams);
} }
public void DisplayPriceHistoryCommandPosition() public void DisplayPriceHistoryCommandPosition()
{ {
SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.PricingViewModel,SelectedSymbol," + selectedPosition.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180"); SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.PricingViewModel,SelectedSymbol," + selectedPosition.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180");
@@ -1110,6 +1188,7 @@ namespace TradeBlotter.ViewModels
saveParams.Referer=this; saveParams.Referer=this;
WorkspaceInstantiator.Invoke(saveParams); WorkspaceInstantiator.Invoke(saveParams);
} }
public void AddToWatchListCommand(String symbol) public void AddToWatchListCommand(String symbol)
{ {
if (WatchListDA.IsInWatchList(symbol)) if (WatchListDA.IsInWatchList(symbol))
@@ -1126,6 +1205,7 @@ namespace TradeBlotter.ViewModels
System.Windows.MessageBox.Show("Added '"+symbol+"'","Success", MessageBoxButton.OK, MessageBoxImage.Information); System.Windows.MessageBox.Show("Added '"+symbol+"'","Success", MessageBoxButton.OK, MessageBoxImage.Information);
} }
} }
public void RemoveFromWatchListCommand(String symbol) public void RemoveFromWatchListCommand(String symbol)
{ {
if (!WatchListDA.IsInWatchList(symbol)) if (!WatchListDA.IsInWatchList(symbol))
@@ -1158,6 +1238,7 @@ namespace TradeBlotter.ViewModels
monitorRunning=false; monitorRunning=false;
base.OnPropertyChanged("MonitorStatus"); base.OnPropertyChanged("MonitorStatus");
} }
private void StartMonitor() private void StartMonitor()
{ {
if(monitorRunning)return; if(monitorRunning)return;
@@ -1167,12 +1248,14 @@ namespace TradeBlotter.ViewModels
DispatcherTimerTick(null,null); DispatcherTimerTick(null,null);
base.OnPropertyChanged("MonitorStatus"); base.OnPropertyChanged("MonitorStatus");
} }
private void DispatcherTimerTick(object sender, EventArgs e) private void DispatcherTimerTick(object sender, EventArgs e)
{ {
UpdatePositionPrices(false); UpdatePositionPrices(false);
UpdatePositionRSI3(true); UpdatePositionRSI3(true);
RunPerformance(); RunPerformance();
} }
private void UpdatePositionPrices(bool change=true) private void UpdatePositionPrices(bool change=true)
{ {
try try
@@ -1199,6 +1282,7 @@ namespace TradeBlotter.ViewModels
MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString()); MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString());
} }
} }
private void UpdatePositionRSI3(bool change=true) private void UpdatePositionRSI3(bool change=true)
{ {
try try
@@ -1222,10 +1306,12 @@ namespace TradeBlotter.ViewModels
MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString()); MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString());
} }
} }
public void ReloadCommand() public void ReloadCommand()
{ {
LoadSessionFile(); LoadSessionFile();
} }
public void LoadFileCommand() public void LoadFileCommand()
{ {
Forms.OpenFileDialog openFileDialog=new Forms.OpenFileDialog(); Forms.OpenFileDialog openFileDialog=new Forms.OpenFileDialog();
@@ -1297,6 +1383,7 @@ namespace TradeBlotter.ViewModels
base.OnPropertyChanged("CanMonitor"); base.OnPropertyChanged("CanMonitor");
base.OnPropertyChanged("CashBalance"); base.OnPropertyChanged("CashBalance");
base.OnPropertyChanged("NonTradeableCash"); base.OnPropertyChanged("NonTradeableCash");
base.OnPropertyChanged("HedgeCash");
base.OnPropertyChanged("ModelExpectation"); base.OnPropertyChanged("ModelExpectation");
base.OnPropertyChanged("ExpectationColor"); base.OnPropertyChanged("ExpectationColor");
base.OnPropertyChanged("ExpectationDescription"); base.OnPropertyChanged("ExpectationDescription");
@@ -1326,6 +1413,7 @@ namespace TradeBlotter.ViewModels
base.OnPropertyChanged("LegendVisible"); base.OnPropertyChanged("LegendVisible");
} }
} }
public String PercentButtonText public String PercentButtonText
{ {
get get
@@ -1334,6 +1422,7 @@ namespace TradeBlotter.ViewModels
else return "Show %"; else return "Show %";
} }
} }
public ICommand ToggleReturnOrPercentCommand public ICommand ToggleReturnOrPercentCommand
{ {
get get
@@ -1351,6 +1440,7 @@ namespace TradeBlotter.ViewModels
return toggleReturnOrPercentCommand; return toggleReturnOrPercentCommand;
} }
} }
public CompositeDataSource Data public CompositeDataSource Data
{ {
get get
@@ -1361,6 +1451,7 @@ namespace TradeBlotter.ViewModels
return compositeDataSource; return compositeDataSource;
} }
} }
public String GraphTitle public String GraphTitle
{ {
get get
@@ -1480,6 +1571,7 @@ namespace TradeBlotter.ViewModels
return sb.ToString(); return sb.ToString();
} }
} }
public String ToolTipInitialStop public String ToolTipInitialStop
{ {
get get
@@ -1531,6 +1623,7 @@ namespace TradeBlotter.ViewModels
{ {
get get
{ {
if(null==selectedPosition)return "Please select a position by clicking on a row.";
StringBuilder sb=new StringBuilder(); StringBuilder sb=new StringBuilder();
sb.Append("RMultiple is based on original position setup.").Append("\n"); 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 Exposure=").Append(Utility.FormatCurrency(selectedPosition.PurchasePrice*selectedPosition.Shares)).Append("\n");
@@ -1545,6 +1638,46 @@ namespace TradeBlotter.ViewModels
} }
} }
public String ToolTipSold
{
get
{
if(null==selectedPosition)return "Please select a position by clicking on a row.";
StringBuilder sb=new StringBuilder();
if(selectedPosition.IsActivePosition)
{
sb.Append($"{selectedPosition.Symbol} is currently active.");
}
else
{
sb.Append($"{selectedPosition.Symbol} {selectedPosition.Comment}.");
}
return sb.ToString();
}
}
public String ToolTipExposure
{
get
{
if(null==selectedPosition)return "Please select a position by clicking on a row.";
StringBuilder sb=new StringBuilder();
if(selectedPosition.IsActivePosition)
{
sb.Append("Exposure = PurchasePrice * Shares\n");
sb.Append($"{Utility.FormatCurrency(selectedPosition.Exposure)} = {Utility.FormatCurrency(selectedPosition.PurchasePrice)} * {Utility.FormatNumber(selectedPosition.Shares,3)}");
}
else
{
sb.Append("Original Exposure = PurchasePrice * Shares\n");
sb.Append($"{Utility.FormatCurrency(selectedPosition.PurchasePrice * selectedPosition.Shares)} = {Utility.FormatCurrency(selectedPosition.PurchasePrice)} * {Utility.FormatNumber(selectedPosition.Shares,3)}");
}
return sb.ToString();
}
}
// ************************************************************** T O O L T I P H E L P E R S ************************************************************** // ************************************************************** T O O L T I P H E L P E R S **************************************************************
public MarketData.Generator.Model.StopLimits GetHistoricalStopLimits() public MarketData.Generator.Model.StopLimits GetHistoricalStopLimits()
{ {

View File

@@ -53,10 +53,13 @@ namespace TradeBlotter.ViewModels
{ {
this.OnDispose(); this.OnDispose();
} }
public virtual String DisplayName { get; protected set; } public virtual String DisplayName { get; protected set; }
protected virtual void OnDispose() protected virtual void OnDispose()
{ {
} }
#if DEBUG #if DEBUG
~ViewModelBase() ~ViewModelBase()
{ {

View File

@@ -132,7 +132,7 @@
<d3:VerticalAxis Name="countAxis"/> <d3:VerticalAxis Name="countAxis"/>
</d3:ChartPlotter.MainVerticalAxis> </d3:ChartPlotter.MainVerticalAxis>
<d3:LineGraph d3:NewLegend.Description="Gain/Loss" d3:Viewport2D.UsesApproximateContentBoundsComparison="False" x:Name="Data" DataSource="{Binding Path=Data}" Stroke="MidnightBlue" StrokeThickness="2"/> <d3:LineGraph d3:NewLegend.Description="Gain/Loss" d3:Viewport2D.UsesApproximateContentBoundsComparison="False" x:Name="Data" DataSource="{Binding Path=Data}" Stroke="MidnightBlue" StrokeThickness="2"/>
<d3:LineGraph x:Name="LeastSquares" d3:NewLegend.Description="{Binding Path=LeastSquaresTitle}" DataSource="{Binding LeastSquares}" Stroke="Orange" StrokeThickness="2"/> <!--<d3:LineGraph x:Name="LeastSquares" d3:NewLegend.Description="{Binding Path=LeastSquaresTitle}" DataSource="{Binding LeastSquares}" Stroke="Orange" StrokeThickness="2"/>-->
<d3:CursorCoordinateGraph Name="cursorGraph" dc:CoordinateGraphBehavior.XTextMappingProperty="MM/dd/yyyy" LineStrokeThickness="1"/> <d3:CursorCoordinateGraph Name="cursorGraph" dc:CoordinateGraphBehavior.XTextMappingProperty="MM/dd/yyyy" LineStrokeThickness="1"/>
<d3:Header FontFamily="Arial" Content="{Binding Path=GraphTitle}"/> <d3:Header FontFamily="Arial" Content="{Binding Path=GraphTitle}"/>
<d3:VerticalAxisTitle FontFamily="Arial" Content="Gain/Loss"/> <d3:VerticalAxisTitle FontFamily="Arial" Content="Gain/Loss"/>

View File

@@ -40,6 +40,7 @@
<StackPanel Orientation="Vertical" Grid.Row="2" Grid.RowSpan="3" Grid.Column="0" Margin="0,4.962,0.396,-5"> <StackPanel Orientation="Vertical" Grid.Row="2" Grid.RowSpan="3" Grid.Column="0" Margin="0,4.962,0.396,-5">
<Label Content="Date" HorizontalAlignment="Left" ></Label> <Label Content="Date" HorizontalAlignment="Left" ></Label>
<telerik:RadDatePicker SelectableDateStart="{Binding Path=SelectableDateStart}" SelectableDateEnd="{Binding Path=SelectableDateEnd}" VerticalAlignment="Top" HorizontalAlignment="Left" SelectedDate="{Binding Path=SelectedDate,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> <telerik:RadDatePicker SelectableDateStart="{Binding Path=SelectableDateStart}" SelectableDateEnd="{Binding Path=SelectableDateEnd}" VerticalAlignment="Top" HorizontalAlignment="Left" SelectedDate="{Binding Path=SelectedDate,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<Label Content="Parameters" HorizontalAlignment="Left" ></Label> <Label Content="Parameters" HorizontalAlignment="Left" ></Label>
<ComboBox ItemsSource="{Binding Path=Parameters, Mode=OneWay}" SelectedItem="{Binding Path=SelectedParameter, ValidatesOnDataErrors=True}" Validation.ErrorTemplate="{x:Null}" > <ComboBox ItemsSource="{Binding Path=Parameters, Mode=OneWay}" SelectedItem="{Binding Path=SelectedParameter, ValidatesOnDataErrors=True}" Validation.ErrorTemplate="{x:Null}" >
<ComboBox.ItemsPanel> <ComboBox.ItemsPanel>
@@ -49,11 +50,19 @@
</ComboBox.ItemsPanel> </ComboBox.ItemsPanel>
</ComboBox> </ComboBox>
<TextBox Height="24" MinWidth="80" HorizontalAlignment="Stretch" IsReadOnly="true" Text="{Binding Path=ParameterValue, Mode=OneWay,ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" Validation.ErrorTemplate="{x:Null}"/> <TextBox Height="24" MinWidth="80" HorizontalAlignment="Stretch" IsReadOnly="true" Text="{Binding Path=ParameterValue, Mode=OneWay,ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" Validation.ErrorTemplate="{x:Null}"/>
<Label Content="Tradeable Cash" HorizontalAlignment="Left" ></Label> <Label Content="Tradeable Cash" HorizontalAlignment="Left" ></Label>
<TextBox Height="24" MinWidth="80" HorizontalAlignment="Stretch" IsReadOnly="true" Text="{Binding Path=CashBalance, Mode=OneWay,ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" Validation.ErrorTemplate="{x:Null}"/> <TextBox Height="24" MinWidth="80" HorizontalAlignment="Stretch" IsReadOnly="true" Text="{Binding Path=CashBalance, Mode=OneWay,ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" Validation.ErrorTemplate="{x:Null}"/>
<Label Content="Non-Tradeable Cash" HorizontalAlignment="Left" ></Label> <Label Content="Non-Tradeable Cash" HorizontalAlignment="Left" ></Label>
<TextBox Height="24" MinWidth="80" HorizontalAlignment="Stretch" IsReadOnly="true" Text="{Binding Path=NonTradeableCash, Mode=OneWay,ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" Validation.ErrorTemplate="{x:Null}"/> <TextBox Height="24" MinWidth="80" HorizontalAlignment="Stretch" IsReadOnly="true" Text="{Binding Path=NonTradeableCash, Mode=OneWay,ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" Validation.ErrorTemplate="{x:Null}"/>
<Button Margin="0,2" Content="Find Candidates" HorizontalAlignment="Stretch" Command="{Binding Path=RunCommand}"></Button>
<Label Content="Hedge Cash" HorizontalAlignment="Left" ></Label>
<TextBox Height="24" MinWidth="80" HorizontalAlignment="Stretch" IsReadOnly="true" Text="{Binding Path=HedgeCash, Mode=OneWay,ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" Validation.ErrorTemplate="{x:Null}"/>
<Button Margin="0,2" Content="Find Candidates" HorizontalAlignment="Stretch" Command="{Binding Path=RunCommand}"></Button>
<Label Content="Monitor Interval (sec)" HorizontalAlignment="Left" ></Label> <Label Content="Monitor Interval (sec)" HorizontalAlignment="Left" ></Label>
<ComboBox ItemsSource="{Binding Path=MonitorIntervals, Mode=OneWay}" SelectedItem="{Binding Path=SelectedMonitorInterval, ValidatesOnDataErrors=True}" Validation.ErrorTemplate="{x:Null}" > <ComboBox ItemsSource="{Binding Path=MonitorIntervals, Mode=OneWay}" SelectedItem="{Binding Path=SelectedMonitorInterval, ValidatesOnDataErrors=True}" Validation.ErrorTemplate="{x:Null}" >
<ComboBox.ItemsPanel> <ComboBox.ItemsPanel>
@@ -77,7 +86,8 @@
</StackPanel> </StackPanel>
<DockPanel x:Name="DockPanelA" Grid.Row="2" Grid.Column="2" Width="Auto" Height="Auto" > <DockPanel x:Name="DockPanelA" Grid.Row="2" Grid.Column="2" Width="Auto" Height="Auto" >
<telerik:RadGridView SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}" ItemContainerStyle="{StaticResource MomentumItemStyle}" AlternationCount="2" AlternateRowBackground="Bisque" ShowGroupFooters="True" ShowColumnFooters="True" ItemsSource="{Binding Path=AllItems, ValidatesOnDataErrors=True}" AutoGenerateColumns="False" >
<telerik:RadGridView SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}" ItemContainerStyle="{StaticResource MomentumItemStyle}" AlternationCount="2" AlternateRowBackground="Bisque" ShowGroupFooters="True" ShowColumnFooters="True" ItemsSource="{Binding Path=AllItems, ValidatesOnDataErrors=True}" AutoGenerateColumns="False" >
<telerik:RadContextMenu.ContextMenu> <telerik:RadContextMenu.ContextMenu>
<telerik:RadContextMenu x:Name="GridContextMenu" StaysOpen="False" ItemsSource="{Binding CandidateMenuItems}"> <telerik:RadContextMenu x:Name="GridContextMenu" StaysOpen="False" ItemsSource="{Binding CandidateMenuItems}">
<telerik:RadContextMenu.ItemContainerStyle> <telerik:RadContextMenu.ItemContainerStyle>
@@ -104,8 +114,6 @@
<telerik:GridViewDataColumn IsReadOnly="True" Header="DayCount" DataMemberBinding="{Binding Path=DayCount,StringFormat='{}{0:N0}'}" /> <telerik:GridViewDataColumn IsReadOnly="True" Header="DayCount" DataMemberBinding="{Binding Path=DayCount,StringFormat='{}{0:N0}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="IDIndicator" DataMemberBinding="{Binding Path=IDIndicator,StringFormat='{}{0:N2}'}" /> <telerik:GridViewDataColumn IsReadOnly="True" Header="IDIndicator" DataMemberBinding="{Binding Path=IDIndicator,StringFormat='{}{0:N2}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="Score" DataMemberBinding="{Binding Path=Score,Converter={StaticResource DoubleFormat},ConverterParameter=2}" /> <telerik:GridViewDataColumn IsReadOnly="True" Header="Score" DataMemberBinding="{Binding Path=Score,Converter={StaticResource DoubleFormat},ConverterParameter=2}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="MaxDrawdown" DataMemberBinding="{Binding Path=MaxDrawdown,StringFormat='{}{0:P2}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="MaxUpside" DataMemberBinding="{Binding Path=MaxUpside,StringFormat='{}{0:P2}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="PE" DataMemberBinding="{Binding Path=PE,StringFormat='{}{0:N2}'}" /> <telerik:GridViewDataColumn IsReadOnly="True" Header="PE" DataMemberBinding="{Binding Path=PE,StringFormat='{}{0:N2}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="Beta" DataMemberBinding="{Binding Path=Beta,StringFormat='{}{0:N2}'}" > <telerik:GridViewDataColumn IsReadOnly="True" Header="Beta" DataMemberBinding="{Binding Path=Beta,StringFormat='{}{0:N2}'}" >
@@ -128,8 +136,6 @@
</telerik:GridViewColumn.ToolTipTemplate> </telerik:GridViewColumn.ToolTipTemplate>
</telerik:GridViewDataColumn> </telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="ZacksRank" DataMemberBinding="{Binding Path=ZacksRank}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="Volume" DataMemberBinding="{Binding Path=Volume,StringFormat='{}{0:N2}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="Return1D" DataMemberBinding="{Binding Path=Return1D,StringFormat='{}{0:N3}'}" /> <telerik:GridViewDataColumn IsReadOnly="True" Header="Return1D" DataMemberBinding="{Binding Path=Return1D,StringFormat='{}{0:N3}'}" />
</telerik:RadGridView.Columns> </telerik:RadGridView.Columns>
</telerik:RadGridView> </telerik:RadGridView>
@@ -145,7 +151,7 @@
<d3:VerticalAxis Name="countAxis"/> <d3:VerticalAxis Name="countAxis"/>
</d3:ChartPlotter.MainVerticalAxis> </d3:ChartPlotter.MainVerticalAxis>
<d3:LineGraph d3:NewLegend.Description="Gain/Loss" d3:Viewport2D.UsesApproximateContentBoundsComparison="False" x:Name="Data" DataSource="{Binding Path=Data}" Stroke="MidnightBlue" StrokeThickness="2"/> <d3:LineGraph d3:NewLegend.Description="Gain/Loss" d3:Viewport2D.UsesApproximateContentBoundsComparison="False" x:Name="Data" DataSource="{Binding Path=Data}" Stroke="MidnightBlue" StrokeThickness="2"/>
<d3:LineGraph x:Name="LeastSquares" d3:NewLegend.Description="{Binding Path=LeastSquaresTitle}" DataSource="{Binding LeastSquares}" Stroke="Orange" StrokeThickness="2"/> <!--<d3:LineGraph x:Name="LeastSquares" d3:NewLegend.Description="{Binding Path=LeastSquaresTitle}" DataSource="{Binding LeastSquares}" Stroke="Orange" StrokeThickness="2"/>-->
<d3:CursorCoordinateGraph Name="cursorGraph" dc:CoordinateGraphBehavior.XTextMappingProperty="MM/dd/yyyy" LineStrokeThickness="1"/> <d3:CursorCoordinateGraph Name="cursorGraph" dc:CoordinateGraphBehavior.XTextMappingProperty="MM/dd/yyyy" LineStrokeThickness="1"/>
<d3:Header FontFamily="Arial" Content="{Binding Path=GraphTitle}"/> <d3:Header FontFamily="Arial" Content="{Binding Path=GraphTitle}"/>
<d3:VerticalAxisTitle FontFamily="Arial" Content="Gain/Loss"/> <d3:VerticalAxisTitle FontFamily="Arial" Content="Gain/Loss"/>
@@ -195,6 +201,13 @@
</telerik:GridViewDataColumn> </telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="Sold" DataMemberBinding="{Binding Path=SellDate,StringFormat='{}{0:MM/dd/yyyy}'}" > <telerik:GridViewDataColumn IsReadOnly="True" Header="Sold" DataMemberBinding="{Binding Path=SellDate,StringFormat='{}{0:MM/dd/yyyy}'}" >
<telerik:GridViewColumn.ToolTipTemplate>
<DataTemplate >
<StackPanel Orientation="Horizontal" >
<TextBlock Background="LemonChiffon" MaxWidth="1000" TextWrapping="Wrap" Text="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type vw:MGSHMomentumView}},Path=DataContext.ToolTipSold}"/>
</StackPanel>
</DataTemplate>
</telerik:GridViewColumn.ToolTipTemplate>
<telerik:GridViewDataColumn.CellTemplate> <telerik:GridViewDataColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding Path=SellDate,StringFormat='{}{0:MM/dd/yyyy}'}" Foreground="{Binding Path=SellDateColor}"/> <TextBlock Text="{Binding Path=SellDate,StringFormat='{}{0:MM/dd/yyyy}'}" Foreground="{Binding Path=SellDateColor}"/>
@@ -219,6 +232,26 @@
</telerik:GridViewDataColumn.CellTemplate> </telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn> </telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="RSI3" >
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<TextBlock >
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Text" Value="{Binding Path=RSI3,StringFormat='{}{0:N2}'}"/>
<Setter Property="Foreground" Value="{Binding Path=RSI3Color}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=RSI3}" Value="NaN" >
<Setter Property="Text" Value="---"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="Initial Stop" DataMemberBinding="{Binding Path=InitialStopLimit,StringFormat='{}{0:C}'}" > <telerik:GridViewDataColumn IsReadOnly="True" Header="Initial Stop" DataMemberBinding="{Binding Path=InitialStopLimit,StringFormat='{}{0:C}'}" >
<telerik:GridViewColumn.ToolTipTemplate> <telerik:GridViewColumn.ToolTipTemplate>
<DataTemplate > <DataTemplate >
@@ -282,7 +315,6 @@
</telerik:GridViewDataColumn.CellTemplate> </telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn> </telerik:GridViewDataColumn>
<!--<telerik:GridViewDataColumn IsReadOnly="True" Header="RMultiple" DataMemberBinding="{Binding Path=RMultipleAsString,StringFormat='{}{0:S}'}" >-->
<telerik:GridViewDataColumn IsReadOnly="True" Header="RMultiple" DataMemberBinding="{Binding Path=RMultiple,Converter={StaticResource RMultipleFormat}}" > <telerik:GridViewDataColumn IsReadOnly="True" Header="RMultiple" DataMemberBinding="{Binding Path=RMultiple,Converter={StaticResource RMultipleFormat}}" >
<telerik:GridViewColumn.ToolTipTemplate> <telerik:GridViewColumn.ToolTipTemplate>
<DataTemplate > <DataTemplate >
@@ -293,34 +325,19 @@
</telerik:GridViewColumn.ToolTipTemplate> </telerik:GridViewColumn.ToolTipTemplate>
<telerik:GridViewDataColumn.CellTemplate> <telerik:GridViewDataColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding Path=RMultipleAsString,StringFormat='{}{0:S}'}" Foreground="{Binding Path=RMultipleAsStringColor}"/> <TextBlock Text="{Binding Path=RMultipleAsString,StringFormat='{}{0:S}'}" Foreground="{Binding Path=RMultipleColor}"/>
</DataTemplate> </DataTemplate>
</telerik:GridViewDataColumn.CellTemplate> </telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn> </telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="RSI3" >
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<TextBlock >
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Text" Value="{Binding Path=RSI3,StringFormat='{}{0:N2}'}"/>
<Setter Property="Foreground" Value="{Binding Path=RSI3Color}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=RSI3}" Value="NaN" >
<Setter Property="Text" Value="---"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="Updated" DataMemberBinding="{Binding Path=LastUpdated,StringFormat='{}{0:MM/dd/yyyy HH:mm:ss}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="Exposure"> <telerik:GridViewDataColumn IsReadOnly="True" Header="Exposure">
<telerik:GridViewColumn.ToolTipTemplate>
<DataTemplate >
<StackPanel Orientation="Horizontal" >
<TextBlock Background="LemonChiffon" MaxWidth="1000" TextWrapping="Wrap" Text="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type vw:MGSHMomentumView}},Path=DataContext.ToolTipExposure}"/>
</StackPanel>
</DataTemplate>
</telerik:GridViewColumn.ToolTipTemplate>
<telerik:GridViewDataColumn.AggregateFunctions> <telerik:GridViewDataColumn.AggregateFunctions>
<local:MGSHMomentumPositionSumFunctionExposure /> <local:MGSHMomentumPositionSumFunctionExposure />
</telerik:GridViewDataColumn.AggregateFunctions> </telerik:GridViewDataColumn.AggregateFunctions>
@@ -331,17 +348,6 @@
</telerik:GridViewDataColumn.CellTemplate> </telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn> </telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="Mkt.Value">
<telerik:GridViewDataColumn.AggregateFunctions>
<local:MGSHMomentumPositionSumFunctionMarketValue />
</telerik:GridViewDataColumn.AggregateFunctions>
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=ActiveMarketValue,StringFormat='{}{0:C}'}" Foreground="{Binding Path=ActiveMarketValueColor}"/>
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="GainLoss" > <telerik:GridViewDataColumn IsReadOnly="True" Header="GainLoss" >
<telerik:GridViewDataColumn.AggregateFunctions> <telerik:GridViewDataColumn.AggregateFunctions>
<local:MGSHMomentumPositionSumFunctionGainLoss /> <local:MGSHMomentumPositionSumFunctionGainLoss />
@@ -364,6 +370,17 @@
</telerik:GridViewDataColumn.CellTemplate> </telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn> </telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="Mkt.Value">
<telerik:GridViewDataColumn.AggregateFunctions>
<local:MGSHMomentumPositionSumFunctionMarketValue />
</telerik:GridViewDataColumn.AggregateFunctions>
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=ActiveMarketValue,StringFormat='{}{0:C}'}" Foreground="{Binding Path=ActiveMarketValueColor}"/>
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="Last Stop Adj." DataMemberBinding="{Binding Path=LastStopAdjustment,Converter={StaticResource DateFormat}}" > <telerik:GridViewDataColumn IsReadOnly="True" Header="Last Stop Adj." DataMemberBinding="{Binding Path=LastStopAdjustment,Converter={StaticResource DateFormat}}" >
<telerik:GridViewDataColumn.CellTemplate> <telerik:GridViewDataColumn.CellTemplate>
<DataTemplate> <DataTemplate>
@@ -372,15 +389,25 @@
</telerik:GridViewDataColumn.CellTemplate> </telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn> </telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="Days" DataMemberBinding="{Binding Path=DaysSinceLastStopAdjustment,Converter={StaticResource IntFormat},ConverterParameter=0}" >
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=DaysSinceLastStopAdjustment,Converter={StaticResource IntFormat},ConverterParameter=0}" Foreground="{Binding Path=DaysSinceLastStopAdjustmentColor}"/>
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>
<telerik:GridViewDataColumn IsReadOnly="True" Header="PE" DataMemberBinding="{Binding Path=PE,StringFormat='{}{0:N2}'}" /> <telerik:GridViewDataColumn IsReadOnly="True" Header="PE" DataMemberBinding="{Binding Path=PE,StringFormat='{}{0:N2}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="Beta" DataMemberBinding="{Binding Path=Beta,StringFormat='{}{0:N2}'}" /> <telerik:GridViewDataColumn IsReadOnly="True" Header="Beta" DataMemberBinding="{Binding Path=Beta,StringFormat='{}{0:N2}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="IDIndicator" DataMemberBinding="{Binding Path=IDIndicator,StringFormat='{}{0:N2}'}" /> <telerik:GridViewDataColumn IsReadOnly="True" Header="IDIndicator" DataMemberBinding="{Binding Path=IDIndicator,StringFormat='{}{0:N2}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="Score" DataMemberBinding="{Binding Path=Score,Converter={StaticResource DoubleFormat},ConverterParameter=2}" /> <telerik:GridViewDataColumn IsReadOnly="True" Header="Score" DataMemberBinding="{Binding Path=Score,Converter={StaticResource DoubleFormat},ConverterParameter=2}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="MaxDrawdown" DataMemberBinding="{Binding Path=MaxDrawdown,StringFormat='{}{0:P2}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="MaxUpside" DataMemberBinding="{Binding Path=MaxUpside,StringFormat='{}{0:P2}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="ZacksRank" DataMemberBinding="{Binding Path=ZacksRank}" /> <telerik:GridViewDataColumn IsReadOnly="True" Header="Updated" DataMemberBinding="{Binding Path=LastUpdated,StringFormat='{}{0:MM/dd/yyyy HH:mm:ss}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="Volume" DataMemberBinding="{Binding Path=Volume,StringFormat='{}{0:N0}'}" />
<telerik:GridViewDataColumn IsReadOnly="True" Header="Comment" DataMemberBinding="{Binding Path=Comment}" />
</telerik:RadGridView.Columns> </telerik:RadGridView.Columns>
</telerik:RadGridView> </telerik:RadGridView>
</Grid> </Grid>