using System; using System.Windows.Input; using System.ComponentModel; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Threading.Tasks; using System.Windows; using System.Linq; using System.Text; using MarketData; using MarketData.Utils; using MarketData.DataAccess; using MarketData.MarketDataModel; using MarketData.Generator; using TradeBlotter.DataAccess; using TradeBlotter.Command; using TradeBlotter.Cache; using TradeBlotter.Model; namespace TradeBlotter.ViewModels { public class TradeModelViewModel : WorkspaceViewModel { private RelayCommand runModelCommand; private List watchLists; private String selectedWatchList; private List symbols; private String selectedSymbol; private DateTime? selectedStartDate; private Items models = new Items(); private int selectedModelIndex = 0; private int selectedSymbolIndex = 0; private double stopLossThreshold; private int stopLossDays; private double investment = 10000; private TradeResultList tradeResults = null; private ObservableCollection tradeResultSummary = null; private bool busyIndicator = false; public TradeModelViewModel() { DateGenerator dateGenerator=new DateGenerator(); base.DisplayName = "TradeModel"; PropertyChanged += OnTradeModelViewModelPropertyChanged; watchLists = WatchListDA.GetWatchLists(); watchLists.Insert(0, Constants.CONST_ALL); selectedWatchList = watchLists.Find(x => x.Equals("Valuations")); models.Add(new Item("MACD(8,17,9)")); models.Add(new Item("MACD(12,26,9)")); models.Add(new Item("Swing Trade")); models.Add(new Item("Band Break")); selectedModelIndex = 0; selectedStartDate = new DateTime(DateTime.Now.Year, 1, 1); base.OnPropertyChanged("SelectedModelIndex"); base.OnPropertyChanged("SelectedWatchList"); base.OnPropertyChanged("SelectedSymbolIndex"); } public override SaveParameters GetSaveParameters() { return null; } public override void SetSaveParameters(SaveParameters saveParameters) { } public override bool CanPersist() { return false; } protected override void OnDispose() { } public bool BusyIndicator { get {return busyIndicator; } set { busyIndicator = false; } } private void OnTradeModelViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs) { if (eventArgs.PropertyName.Equals("SelectedModelIndex") || (eventArgs.PropertyName.Equals("SelectedModel") && null != selectedSymbol)) { } else if (eventArgs.PropertyName.Equals("SelectedSymbol") || (eventArgs.PropertyName.Equals("SelectedDayCount") && null != selectedSymbol)) { } else if (eventArgs.PropertyName.Equals("SelectedWatchList")) { if (selectedWatchList.Equals(Constants.CONST_ALL)) symbols = PricingDA.GetSymbols(); else symbols = WatchListDA.GetWatchList(selectedWatchList); base.OnPropertyChanged("Symbols"); selectedSymbolIndex = 0; base.OnPropertyChanged("SelectedSymbolIndex"); } } public IList Models { get { return models; } } public int SelectedModelIndex { get { return selectedModelIndex; } set { selectedModelIndex = value; base.OnPropertyChanged("SelectedModelIndex"); } } public int SelectedSymbolIndex { get { return selectedSymbolIndex; } set { selectedSymbolIndex = value; base.OnPropertyChanged("SelectedSymbolIndex"); } } public List Symbols { get { return symbols; } } public String SelectedSymbol { get { return selectedSymbol; } set { if (value == selectedSymbol || String.IsNullOrEmpty(value)) return; selectedSymbol = value; selectedSymbol = selectedSymbol.ToUpper(); base.OnPropertyChanged("SelectedSymbol"); } } public List WatchListNames { get { return watchLists; } set { ;} } public String SelectedWatchList { get { return selectedWatchList; } set { selectedWatchList = value; base.OnPropertyChanged("SelectedWatchList"); } } public DateTime? SelectedStartDate { get { return selectedStartDate; } set { DateTime today = DateTime.Now; selectedStartDate = value; if (selectedStartDate.Value.Date >= today.Date) { MessageBox.Show("start date must be less than today", "Error"); DateGenerator dateGenerator = new DateGenerator(); selectedStartDate = dateGenerator.GenerateHistoricalDate(DateTime.Now, 2); base.OnPropertyChanged("SelectedStartDate"); return; } base.OnPropertyChanged("SelectedStartDate"); } } public double StopLossThreshold { get { return stopLossThreshold; } set { stopLossThreshold = value; base.OnPropertyChanged("StopLossThreshold"); } } public int StopLossDays { get { return stopLossDays; } set { stopLossDays = value; base.OnPropertyChanged("StopLossDays"); } } public double Investment { get { return investment; } set { investment = value; base.OnPropertyChanged("Investment"); } } //************************************************************************************************************************** //******************************************************** R U N M O D E L *************************************************** //************************************************************************************************************************** public ObservableCollection TradeResults { get { return null==tradeResults?null:new ObservableCollection(tradeResults); } } public ObservableCollection TradeResultsSummary { get { return tradeResultSummary; } } private void RunModel() { String selectedModel=models[selectedModelIndex].Value; if (selectedModel.Equals("MACD(8,17,9)") || selectedModel.Equals("MACD(12,26,9)")) RunMACDModel(selectedModel); else MessageBox.Show(selectedModel+" is not supported."); } private void RunMACDModel(String selctedModel) { DateGenerator dateGenerator = new DateGenerator(); MACDSetup macdSetup = null; DateRange tradeDates = new DateRange(selectedStartDate.Value, DateTime.Now); if (double.IsNaN(stopLossThreshold)) stopLossThreshold = 0; try { BusyIndicator = true; Task workerTask = Task.Factory.StartNew(() => { DateTime latestPricingDate = PricingDA.GetLatestDate(selectedSymbol); String companyName = PricingDA.GetNameForSymbol(selectedSymbol); if (models[selectedModelIndex].Value.Equals("MACD(8,17,9)")) macdSetup = new MACDSetup(8, 17, 9); else if (models[selectedModelIndex].Value.Equals("MACD(12,26,9)")) macdSetup = new MACDSetup(12, 26, 9); DateTime historicalDate = dateGenerator.GenerateHistoricalDate(selectedStartDate.Value, macdSetup.Slow); if (latestPricingDate < historicalDate) { MessageBox.Show("The historical date you are trying to run is later than the latest date for which prices are available."); return; } if (selectedStartDate.Value > DateTime.Now) { MessageBox.Show("The start date must be in the past."); return; } Dictionary pricesByDate = new Dictionary(); Prices prices = PricingDA.GetPrices(selectedSymbol, DateTime.Now, historicalDate); Price latestPrice = prices[0]; DateTime startDate = prices[0].Date; DateTime endDate = prices[prices.Count - 1].Date; for (int index = 0; index < prices.Count; index++) pricesByDate.Add(prices[index].Date, prices[index]); MACDSignals macdSignals = MACDGenerator.GenerateMACD(prices, macdSetup); Signals signals = SignalGenerator.GenerateSignals(macdSignals); Portfolio portfolio = SignalTrader.TradeSignals(tradeDates, signals, prices, investment, stopLossThreshold, stopLossDays); tradeResults = new TradeResultList(); for (int index = 0; index < portfolio.Trades.Count; index++) { ModelTrade modelTrade = portfolio.Trades[index]; TradeBlotter.Model.TradeResult tradeResult = new TradeBlotter.Model.TradeResult(modelTrade.TradeDate, modelTrade.Type.Equals(ModelTrade.TradeType.Buy) ? "Buy" : "Sell", modelTrade.Symbol, modelTrade.Shares, modelTrade.Price, modelTrade.GainLoss, modelTrade.Return,modelTrade.Exposure,modelTrade.DaysHeld, modelTrade.Comment); tradeResults.Add(tradeResult); } tradeResults.Sort(); tradeResultSummary = new ObservableCollection(); TradeResultSummary summary = new TradeResultSummary(); summary.AverageGainLoss = portfolio.GetAverageGainLoss(); summary.AverageHoldingDays = portfolio.GetAverageHoldingDays(); summary.MaximumHoldingDays = portfolio.GetMaxHoldingDays(); summary.MinimumHoldingDays = portfolio.GetMinHoldingDays(); summary.PortfolioValue = portfolio.GetPortfolioValue(prices[0]); summary.PortfolioReturn = portfolio.GetPortfolioReturn(prices[0]); tradeResultSummary.Add(summary); }); workerTask.ContinueWith((continuation) => { BusyIndicator = false; base.OnPropertyChanged("TradeResults"); base.OnPropertyChanged("TradeResultsSummary"); }); } catch (Exception exception) { BusyIndicator = false; MessageBox.Show(exception.ToString()); } } private bool CanRunModel { get { if (null == selectedSymbol) return false; if (null == selectedStartDate || Utility.IsEpoch(selectedStartDate.Value)) return false; return true; } } public ICommand RunModelCommand { get { if (runModelCommand == null) { runModelCommand = new RelayCommand(param => this.RunModel(), param => this.CanRunModel); } return runModelCommand; } } } }