From 6bf92a14f2140b3e9e62ded7bbe1a36290b2e985 Mon Sep 17 00:00:00 2001 From: "Sean Kessler (Europa)" Date: Sat, 28 Jun 2025 23:49:24 -0400 Subject: [PATCH] Commit Latest --- .../Renderers/BollingerBandRenderer.cs | 15 +- .../ViewModels/BollingerBandViewModel.cs | 988 ++++-------------- .../ViewModels/MainWindowViewModel.cs | 28 +- .../ViewModels/ScottPlotViewModel.cs | 341 ------ .../Views/BollingerBandView.axaml | 143 +-- .../Views/BollingerBandView.axaml.cs | 23 +- PortfolioManager/Views/MainWindow.axaml | 11 +- PortfolioManager/Views/ScottPlotView.axaml | 89 -- PortfolioManager/Views/ScottPlotView.axaml.cs | 32 - PortfolioManager/saveparams.config | 20 +- 10 files changed, 293 insertions(+), 1397 deletions(-) delete mode 100644 PortfolioManager/ViewModels/ScottPlotViewModel.cs delete mode 100644 PortfolioManager/Views/ScottPlotView.axaml delete mode 100644 PortfolioManager/Views/ScottPlotView.axaml.cs diff --git a/PortfolioManager/Renderers/BollingerBandRenderer.cs b/PortfolioManager/Renderers/BollingerBandRenderer.cs index 1ba9475..403418a 100644 --- a/PortfolioManager/Renderers/BollingerBandRenderer.cs +++ b/PortfolioManager/Renderers/BollingerBandRenderer.cs @@ -107,7 +107,7 @@ namespace PortfolioManager.Renderers Plotter.Plot.Axes.Left.TickGenerator = new ScottPlot.TickGenerators.NumericAutomatic() { LabelFormatter = (double value) => value.ToString("C") // "C" format specifier formats as currency - }; + }; Plotter.Plot.Axes.DateTimeTicksBottom(); Plotter.Plot.Axes.AutoScale(); Plotter.Plot.XLabel("Date"); @@ -166,11 +166,11 @@ namespace PortfolioManager.Renderers bollingerBands = BollingerBandGenerator.GenerateBollingerBands(prices); CalculateOffsets(); GenerateBollingerBands(); + GenerateLeastSquares(); GenerateInsiderTransactions(); GenerateStopLimits(); GenerateTradePoints(); GenerateZeroPoint(zeroPrice); - GenerateLeastSquares(); } /// @@ -335,7 +335,7 @@ namespace PortfolioManager.Renderers sb.Append("@"); sb.Append(Utility.FormatCurrency(portfolioTrade.Price)); - Image image = TextMarkerImageGenerator.GenerateImage(sb.ToString(), 150, 24, FontFactor.FontSize); + Image image = TextMarkerImageGenerator.GenerateImage(sb.ToString(), 130, 24, FontFactor.FontSize); Coordinates coordinates = new Coordinates(portfolioTrade.TradeDate.ToOADate(), portfolioTrade.Price - offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset5PC)); ImageMarker imageMarker = Plotter.Plot.Add.ImageMarker(coordinates, image); } @@ -455,7 +455,7 @@ namespace PortfolioManager.Renderers Close = BollingerBandModel.Close(bollingerBands); SMAN = BollingerBandModel.SMAN(bollingerBands); Volume = BollingerBandModel.Volume(bollingerBands); - LeastSquares = BollingerBandModel.LeastSquares(bollingerBands); + // LeastSquares = BollingerBandModel.LeastSquares(bollingerBands); Scatter scatter = default; { @@ -507,13 +507,6 @@ namespace PortfolioManager.Renderers scatter.LineWidth = 2; } - { - (DateTime[] dates, double[] values) = LeastSquares.ToXYData(); - scatter = Plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Orange)); - scatter.LegendText = "LeastSquares"; - scatter.LineWidth = 2; - } - { (DateTime[] dates, double[] values) = SMAN.ToXYData(); scatter = Plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Purple)); diff --git a/PortfolioManager/ViewModels/BollingerBandViewModel.cs b/PortfolioManager/ViewModels/BollingerBandViewModel.cs index f31885c..5fdbf2d 100644 --- a/PortfolioManager/ViewModels/BollingerBandViewModel.cs +++ b/PortfolioManager/ViewModels/BollingerBandViewModel.cs @@ -5,96 +5,74 @@ using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; -using Avalonia.Media; using CommunityToolkit.Mvvm.Input; using DynamicData; -using Eremex.AvaloniaUI.Charts; using MarketData; using MarketData.DataAccess; -using MarketData.Generator; using MarketData.MarketDataModel; -using MarketData.Numerical; using MarketData.Utils; -using PortfolioManager.Cache; -using PortfolioManager.DataSeriesViewModels; using PortfolioManager.Extensions; -using PortfolioManager.Models; +using PortfolioManager.Renderers; using PortfolioManager.UIUtils; namespace PortfolioManager.ViewModels { - - public partial class BollingerBandViewModel : WorkspaceViewModel + public partial class BollingerBandViewModel : PlotterWorkspaceViewModel { - private bool isBusy = false; private List watchListNames; private String selectedWatchList; + private ObservableCollection symbols = new ObservableCollection(); private List dayCounts = new int[] { 60, 90, 180, 360, 720, 1440, 3600 }.ToList(); private int selectedDayCount = 90; - private ObservableCollection symbols = new ObservableCollection(); + private bool isBusy = false; private String selectedSymbol = default; - private bool showMarkers = false; - - private InsiderTransactionSummaries insiderTransactionSummaries = null; - private Price zeroPrice = null; - private PortfolioTrades portfolioTrades; - private PortfolioTrades portfolioTradesLots; - 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 Prices prices = null; - - private bool syncTradeToBand = true; private String companyName = default; - private bool showTradeLabels = true; - - private bool useLeastSquaresFit = true; + private BollingerBandRenderer bollingerBandRenderer = default; private bool showInsiderTransactions = true; + private bool showTradeLabels = true; + private bool syncTradeToBand = true; + private bool useLeastSquaresFit = true; + private StopLimits stopLimits = default; - 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; - - private BollingerBands bollingerBands; - public BollingerBandViewModel() { - InitializeDataSources(); - PropertyChanged += OnViewModelPropertyChanged; DisplayName = "Bollinger"; - Initialize(true); - } - - public BollingerBandViewModel(bool loadedFromParams = false) - { - InitializeDataSources(); + OnPlotterLoadedEventHandler += PlotterLoadedEvent; PropertyChanged += OnViewModelPropertyChanged; - DisplayName = "Bollinger"; - Initialize(false); + Initialize(); } + + // public BollingerBandViewModel(bool loadedFromParams) + // { + // DisplayName = "Bollinger"; + // OnPlotterLoadedEventHandler += PlotterLoadedEvent; + // PropertyChanged += OnViewModelPropertyChanged; + // Initialize(); + // base.OnPropertyChanged("SelectedSymbol"); + // } protected override void OnDispose() + { + MDTrace.WriteLine(LogLevel.DEBUG, $"Dispose BollingerBandViewModel"); + base.OnDispose(); + } + + public override String Title { - MDTrace.WriteLine(LogLevel.DEBUG, $"Dispose BollingerBandViewModel"); - base.OnDispose(); - } + get + { + if (null == selectedSymbol) return DisplayName; + return "Bollinger " + "(" + selectedSymbol + ")"; + } + } + + public override String DisplayName + { + get + { + return "Bollinger Band"; + } + } private void Initialize(bool executePropertyChanged = true) { @@ -117,230 +95,65 @@ namespace PortfolioManager.ViewModels }); } - public bool IsBusy - { - get - { - return isBusy; - } - set - { - isBusy = value; - base.OnPropertyChanged("IsBusy"); - } - } - public override String Title + // ******************************************************************************************************************************************* + /// + /// This event will be called the first time the view is rendered and each time the view comes back into focus (i.e.) Tab activated + /// + /// + /// + public void PlotterLoadedEvent(object sender, PlotterLoadedEventArgs e) { - get + base.OnPropertyChanged("Plotter"); + if (default != selectedSymbol) { - if (null == selectedSymbol) return DisplayName; - return "Bollinger " + "(" + selectedSymbol + ")"; - } - } - - public String GraphTitle - { - 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 override String DisplayName - { - get - { - return "Bollinger Band"; - } - } - - public bool ShowMarkers - { - get - { - return showMarkers; - } - set - { - showMarkers = value; - base.OnPropertyChanged("ShowMarkers"); - } - } - - public ObservableCollection Symbols - { - get - { - return symbols; - } - } - - public String SelectedSymbol - { - get - { - return selectedSymbol; - } - set - { - if (String.IsNullOrEmpty(value)) - { - return; - } - selectedSymbol = value; base.OnPropertyChanged("SelectedSymbol"); } } - public int SelectedDayCount + private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs) { - get - { - return selectedDayCount; - } - set - { - selectedDayCount = value; - base.OnPropertyChanged("SelectedDayCount"); - } + + if ((eventArgs.PropertyName.Equals("SyncTradeToBand") || + eventArgs.PropertyName.Equals("ShowTradeLabels") || + eventArgs.PropertyName.Equals("SelectedSymbol") || + eventArgs.PropertyName.Equals("ShowRiskFree") || + eventArgs.PropertyName.Equals("UseLeastSquaresFit") || + eventArgs.PropertyName.Equals("CheckBoxShowInsiderTransactions") || + eventArgs.PropertyName.Equals("SelectedDayCount")) + && !String.IsNullOrEmpty(selectedSymbol) + && default != Plotter) + { + IsBusy = true; + Task workerTask = Task.Factory.StartNew(() => + { + companyName = PricingDA.GetNameForSymbol(selectedSymbol); + bollingerBandRenderer = new BollingerBandRenderer(Plotter); + bollingerBandRenderer.ShowLeastSquares = useLeastSquaresFit; + bollingerBandRenderer.SyncTradeToBand = syncTradeToBand; + bollingerBandRenderer.ShowInsiderTransactions = showInsiderTransactions; + bollingerBandRenderer.ShowTradeLabels = showTradeLabels; + bollingerBandRenderer.SetData(selectedSymbol, selectedDayCount); + bollingerBandRenderer.Render(); + }); + workerTask.ContinueWith((continuation) => + { + base.OnPropertyChanged("GraphTitle"); + base.OnPropertyChanged("Title"); + IsBusy = false; + }); + } } - public List DayCounts - { - get - { - return dayCounts; - } - } + // ********************************************** P E R S I S T E N C E ************************* - public bool SyncTradeToBand - { - get - { - return syncTradeToBand; - } - set - { - syncTradeToBand = value; - if (syncTradeToBand) showTradeLabels = true; - base.OnPropertyChanged("SyncTradeToBand"); - base.OnPropertyChanged("TradePoints"); - base.OnPropertyChanged("ZeroPoint"); - base.OnPropertyChanged("StopLimits"); - base.OnPropertyChanged("TradePointMarkers"); - base.OnPropertyChanged("ZeroPointMarkers"); - base.OnPropertyChanged("StopLimitMarkers"); -// base.OnPropertyChanged("ZeroPointMarkersTextMarkers"); - } - } + public override bool CanPersist() + { + return true; + } - public bool ShowTradeLabels - { - get - { - return showTradeLabels; - } - set - { - showTradeLabels = value; - base.OnPropertyChanged("ShowTradeLabels"); - } - } - - public Boolean CheckBoxShowInsiderTransactions - { - get - { - return showInsiderTransactions; - } - set - { - showInsiderTransactions = value; - base.OnPropertyChanged("CheckBoxShowInsiderTransactions"); - base.OnPropertyChanged("InsiderTransactionPointDisposedSmall"); - base.OnPropertyChanged("InsiderTransactionPointDisposedMedium"); - base.OnPropertyChanged("InsiderTransactionPointDisposedLarge"); - base.OnPropertyChanged("InsiderTransactionPointAcquiredSmall"); - base.OnPropertyChanged("InsiderTransactionPointAcquiredMedium"); - base.OnPropertyChanged("InsiderTransactionPointAcquiredLarge"); - - base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedSmall"); - base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedMedium"); - base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedLarge"); - base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredSmall"); - base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredMedium"); - base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredLarge"); - } - } - - - // ****************************************************** P R O P E R T I E S ************************************************ - - public List WatchListNames - { - get - { - return watchListNames; - } - } - - public String SelectedWatchList - { - get - { - return selectedWatchList; - } - set - { - selectedWatchList = value; - base.OnPropertyChanged("SelectedWatchList"); - } - } - - /// - /// See the XAML and also OSValueConverter in UIUtils for an explanation. - /// - public int MarkerSize - { - get - { - return 0; - } - } - - // ********************************************************************************************************************************************* - - - // ******************************************************************* P E R S I S T E N C E *************************************************** - - public override bool CanPersist() - { - return true; - } - - public override SaveParameters GetSaveParameters() - { + public override SaveParameters GetSaveParameters() + { SaveParameters saveParams = new SaveParameters(); if (String.IsNullOrEmpty(selectedSymbol)) return null; saveParams.Add(new KeyValuePair("Type", GetType().Namespace + "." + GetType().Name)); @@ -363,17 +176,16 @@ namespace PortfolioManager.ViewModels saveParams.Add(new KeyValuePair(strItemKey, strStopHistoryItem)); } } - return saveParams; - } + return saveParams; + } - public override void SetSaveParameters(SaveParameters saveParameters) - { + public override void SetSaveParameters(SaveParameters saveParameters) + { try { Task workerTask = Task.Factory.StartNew(() => { - Referer = saveParameters.Referer; selectedSymbol = (from KeyValuePair item in saveParameters where item.Key.Equals("SelectedSymbol") select item).FirstOrDefault().Value; selectedWatchList = (from KeyValuePair item in saveParameters where item.Key.Equals("SelectedWatchList") select item).FirstOrDefault().Value; @@ -412,8 +224,6 @@ namespace PortfolioManager.ViewModels { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Exception:{0}", exception.ToString())); } - // base.OnPropertyChanged("SelectedWatchList"); - // base.OnPropertyChanged("SelectedSymbol"); }); workerTask.ContinueWith((continuation) => { @@ -421,527 +231,179 @@ namespace PortfolioManager.ViewModels base.OnPropertyChanged("SelectedSymbol"); }); } - catch (Exception) + catch (Exception exception) { + MDTrace.WriteLine(LogLevel.DEBUG, exception.ToString()); } - } + } - // ****************************************************** R E L A Y S ******************************************************** - [RelayCommand] - public async Task Refresh() - { - base.OnPropertyChanged("SelectedSymbol"); - await Task.FromResult(true); - } + // ****************************************************** P R O P E R T I E S ************************************************ - // ************************************************************************************************************************************* - private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs) - { - if (eventArgs.PropertyName.Equals("SelectedSymbol") && !String.IsNullOrEmpty(selectedSymbol)) + public String GraphTitle + { + get { - InitializeDataSources(); - InitializeData(); - } - - if ((eventArgs.PropertyName.Equals("SyncTradeToBand") || - eventArgs.PropertyName.Equals("ShowTradeLabels") || - eventArgs.PropertyName.Equals("SelectedSymbol") || - eventArgs.PropertyName.Equals("ShowRiskFree") || - eventArgs.PropertyName.Equals("LeastSquaresFit") || - eventArgs.PropertyName.Equals("SelectedDayCount")) - && !String.IsNullOrEmpty(selectedSymbol)) - { - IsBusy = true; - Task workerTask = Task.Factory.StartNew(() => - { - MDTrace.WriteLine(LogLevel.DEBUG, $"OnViewModelPropertyChanged({eventArgs.PropertyName}). Selected symbol '{selectedSymbol}'"); - base.DisplayName = "Bollinger(" + selectedSymbol + ")"; - base.OnPropertyChanged("DisplayName"); - stopLimit = PortfolioDA.GetStopLimit(selectedSymbol); - portfolioTrades = PortfolioDA.GetTradesSymbol(selectedSymbol); - portfolioTradesLots = LotAggregator.CombineLots(portfolioTrades); - if (null != portfolioTrades && 0 != portfolioTrades.Count) + if (null == companyName || null == bollingerBandRenderer || null == bollingerBandRenderer.Prices) 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(bollingerBandRenderer.Prices.Take(2).ToList()); + if (2 == prices2day.Count) change = prices2day.GetReturns()[0]; + sb.Append(displayCompanyName); + sb.Append(" (").Append(selectedSymbol).Append(") "); + sb.Append(Utility.DateTimeToStringMMHDDHYYYY(bollingerBandRenderer.Prices[bollingerBandRenderer.Prices.Count - 1].Date)); + sb.Append(" Thru "); + sb.Append(Utility.DateTimeToStringMMHDDHYYYY(bollingerBandRenderer.Prices[0].Date)); + sb.Append(" (").Append(Utility.FormatCurrency(bollingerBandRenderer.Prices[0].Close)); + sb.Append("/").Append(Utility.FormatCurrency(bollingerBandRenderer.Prices[0].Low)); + if (!float.IsNaN(change)) { - DateGenerator dateGenerator = new DateGenerator(); - DateTime earliestTrade = portfolioTrades[0].TradeDate; - earliestTrade = earliestTrade.AddDays(-30); - int daysBetween = dateGenerator.DaysBetween(earliestTrade, DateTime.Now); - if (daysBetween < selectedDayCount || !syncTradeToBand) prices = PricingDA.GetPrices(selectedSymbol, selectedDayCount); - else prices = PricingDA.GetPrices(selectedSymbol, earliestTrade); - - DateTime earliestInsiderTransactionDate = dateGenerator.GenerateFutureBusinessDate(prices[prices.Count - 1].Date, 30); - insiderTransactionSummaries = InsiderTransactionDA.GetInsiderTransactionSummaries(selectedSymbol, earliestInsiderTransactionDate); - - // calculate the break even price on the open trades for this symbol - PortfolioTrades openTrades = portfolioTrades.GetOpenTrades(); - DateTime latestPricingDate = PricingDA.GetLatestDate(selectedSymbol); - Price latestPrice = PricingDA.GetPrice(selectedSymbol, latestPricingDate); - zeroPrice = ParityGenerator.GenerateGainLossValue(openTrades, latestPrice); - - if (!syncTradeToBand) - { - DateTime earliestPricingDate = prices[prices.Count - 1].Date; - earliestPricingDate = earliestPricingDate.AddDays(30); - IEnumerable tradesInRange = (from portfolioTrade in portfolioTradesLots where portfolioTrade.TradeDate >= earliestPricingDate select portfolioTrade); - portfolioTrades = new PortfolioTrades(); - foreach (PortfolioTrade portfolioTrade in tradesInRange) portfolioTrades.Add(portfolioTrade); - portfolioTradesLots = portfolioTrades; - } + sb.Append(","); + sb.Append(change >= 0.00 ? "+" : "").Append(Utility.FormatPercent((double)change)); } - else - { - prices = PricingDA.GetPrices(selectedSymbol, selectedDayCount); - if (null != prices && 0 != prices.Count) - { - DateGenerator dateGenerator = new DateGenerator(); - DateTime earliestInsiderTransactionDate = dateGenerator.GenerateFutureBusinessDate(prices[prices.Count - 1].Date, 30); - insiderTransactionSummaries = InsiderTransactionDA.GetInsiderTransactionSummaries(selectedSymbol, earliestInsiderTransactionDate); - } - } - companyName = PricingDA.GetNameForSymbol(selectedSymbol); - bollingerBands = BollingerBandGenerator.GenerateBollingerBands(prices); - CreateCompositeDataSources(); - }); - workerTask.ContinueWith((continuation) => - { - 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("GraphTitle"); - base.OnPropertyChanged("Title"); - - base.OnPropertyChanged("TradePoints"); - base.OnPropertyChanged("ZeroPoint"); - base.OnPropertyChanged("StopLimits"); - - base.OnPropertyChanged("TradePointMarkers"); - base.OnPropertyChanged("ZeroPointMarkers"); - base.OnPropertyChanged("StopLimitMarkers"); - -// base.OnPropertyChanged("ZeroPointMarkersTextMarkers"); - - - base.OnPropertyChanged("InsiderTransactionPointDisposedSmall"); - base.OnPropertyChanged("InsiderTransactionPointDisposedMedium"); - base.OnPropertyChanged("InsiderTransactionPointDisposedLarge"); - - base.OnPropertyChanged("InsiderTransactionPointAcquiredSmall"); - base.OnPropertyChanged("InsiderTransactionPointAcquiredMedium"); - base.OnPropertyChanged("InsiderTransactionPointAcquiredLarge"); - - base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedSmall"); - base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedMedium"); - base.OnPropertyChanged("InsiderTransactionPointMarkersDisposedLarge"); - - base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredSmall"); - base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredMedium"); - base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredLarge"); - IsBusy = false; - }); + sb.Append(")"); + return sb.ToString(); } - else if (eventArgs.PropertyName.Equals("SelectedWatchList")) - { - IsBusy = true; - Task workerTask = Task.Factory.StartNew(() => - { - if (selectedWatchList.Equals(Constants.CONST_ALL)) - { - symbols.Clear(); - symbols.AddRange(SymbolCache.GetInstance().GetSymbols()); - } - else - { - symbols.Clear(); - symbols.AddRange(WatchListDA.GetWatchList(selectedWatchList)); - } - }); - workerTask.ContinueWith((continuation) => - { - IsBusy = false; - base.OnPropertyChanged("Symbols"); - }); - } - } + } - // ************************************************* C O M P O S I T E D A T A S O U R C E S ******************************************** - - public CompositeDataSource K - { + public List WatchListNames + { get { - return compositeDataSourceK; + return watchListNames; } - } - public CompositeDataSource KL1 - { - get - { - return compositeDataSourceKL1; - } - } + } - public CompositeDataSource L - { + public String SelectedWatchList + { get { - return compositeDataSourceL; + return selectedWatchList; } - } - public CompositeDataSource LP1 - { - get + set { - return compositeDataSourceLP1; + selectedWatchList = value; + base.OnPropertyChanged("SelectedWatchList"); } - } - 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; - } - } + } - public CompositeDataSource LeastSquares - { + public ObservableCollection Symbols + { get { - if (!useLeastSquaresFit || null == bollingerBands) return Empty(); - return compositeDataSourceLeastSquares; + return symbols; } - } + } - public CompositeDataSource TradePoints - { + public int SelectedDayCount + { get { - if (!showTradeLabels) return Empty(); - return compositeDataSourceTradePoints; + return selectedDayCount; } - } + set + { + selectedDayCount = value; + base.OnPropertyChanged("SelectedDayCount"); + } + } - public CompositeDataSource ZeroPoint - { + public List DayCounts + { get { - if (!showTradeLabels) return Empty(); - return compositeDataSourceZeroPoint; + return dayCounts; } - } + } - public CompositeDataSource StopLimits - { - get - { - if (!showTradeLabels) return Empty(); - return compositeDataSourceStopLimit; - } - } - - public CompositeDataSource InsiderTransactionPointDisposedSmall - { - get - { - if (!showInsiderTransactions) return Empty(); - return compositeDataSourceInsiderTransactionPointDisposedSmall; - } - } - - public CompositeDataSource InsiderTransactionPointDisposedMedium - { - get - { - if (!showInsiderTransactions) return Empty(); - return compositeDataSourceInsiderTransactionPointDisposedMedium; - } - } - - public CompositeDataSource InsiderTransactionPointDisposedLarge - { - get - { - if (!showInsiderTransactions) return Empty(); - return compositeDataSourceInsiderTransactionPointDisposedLarge; - } - } - - public CompositeDataSource InsiderTransactionPointAcquiredSmall - { - get - { - if (!showInsiderTransactions) return Empty(); - return compositeDataSourceInsiderTransactionPointAcquiredSmall; - } - } - - public CompositeDataSource InsiderTransactionPointAcquiredMedium - { - get - { - if (!showInsiderTransactions) return Empty(); - return compositeDataSourceInsiderTransactionPointAcquiredMedium; - } - } - - public CompositeDataSource InsiderTransactionPointAcquiredLarge - { - get - { - if (!showInsiderTransactions) return Empty(); - return compositeDataSourceInsiderTransactionPointAcquiredLarge; - } - } - - // ******************************************************** M A R K E R S ************************************************** - - public IImage StopLimitMarkers - { - get - { - if (!showTradeLabels) return null; - return ImageCache.GetInstance().GetImage(ImageCache.ImageType.RedTriangleUp); - } - } - - /// - /// This is just a single marker - /// - public IImage ZeroPointMarkers - { - get - { - if (!showTradeLabels) return null; - return ImageCache.GetInstance().GetImage(ImageCache.ImageType.BlueTriangleUp); - } - } - - // public IImage ZeroPointMarkersTextMarkers - // { - // get - // { - // return TextMarkerImageGenerator.GenerateImage(64,64,SKColors.Red); - // } - // } - - /// - /// This is just a single marker - /// - // public IImage ZeroPointMarkersTextMarkers - // { - // get - // { - // if (null == zeroPrice || !showTradeLabels) return null; - // 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(")"); - // return TextMarkerImageGenerator.GenerateImage(sb.ToString()); - // } - // } - - public IImage TradePointMarkers + public String SelectedSymbol { get { - if (!showTradeLabels) return null; - return ImageCache.GetInstance().GetImage(ImageCache.ImageType.YellowTriangleUp); + return selectedSymbol; + } + set + { + if (String.IsNullOrEmpty(value)) + { + return; + } + selectedSymbol = value; + base.OnPropertyChanged("SelectedSymbol"); } } - /// - /// This size is controlled in the XAML - /// - public IImage InsiderTransactionPointMarkersDisposedSmall + public bool IsBusy + { + get { - get - { - return ImageCache.GetInstance().GetImage(ImageCache.ImageType.RedTriangleDown); - } + return isBusy; } - - /// - /// This size is controlled in the XAML - /// - public IImage InsiderTransactionPointMarkersDisposedMedium + set { - get - { - return ImageCache.GetInstance().GetImage(ImageCache.ImageType.RedTriangleDown); - } - } - - /// - /// This size is controlled in the XAML - /// - public IImage InsiderTransactionPointMarkersDisposedLarge - { - get - { - return ImageCache.GetInstance().GetImage(ImageCache.ImageType.RedTriangleDown); - } - } - - /// - /// This size is controlled in the XAML - /// - public IImage InsiderTransactionPointMarkersAcquiredSmall - { - get - { - return ImageCache.GetInstance().GetImage(ImageCache.ImageType.GreenTriangleUp); - } - } - - /// - /// This size is controlled in the XAML - /// - public IImage InsiderTransactionPointMarkersAcquiredMedium - { - get - { - return ImageCache.GetInstance().GetImage(ImageCache.ImageType.GreenTriangleUp); - } - } - - /// - /// This size is controlled in the XAML - /// - public IImage InsiderTransactionPointMarkersAcquiredLarge - { - get - { - return ImageCache.GetInstance().GetImage(ImageCache.ImageType.GreenTriangleUp); - } - } - - // ********************************************************************************************************************************************* - 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 disposedSummariesBin = BinHelper.CreateBins(new BinItems(disposedSummaries), 3); - BinCollection acquiredSummariesBin = BinHelper.CreateBins(new BinItems(acquiredSummaries), 3); - - compositeDataSourceZeroPoint = GainLossModel.Price(zeroPrice); - - if (null != stopLimits) - { - compositeDataSourceStopLimit = StopLimitCompositeModel.CreateCompositeDataSource(stopLimits); - } - else if (null != stopLimit && null != zeroPrice) - { - compositeDataSourceStopLimit = GainLossModel.CreateCompositeDataSource(zeroPrice.Date, stopLimit.StopPrice); - } - - 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(portfolioTradesLots); - } - - private void InitializeData() - { - - insiderTransactionSummaries = null; - zeroPrice = null; - prices = null; - portfolioTrades = null; - portfolioTradesLots = null; - stopLimit = null; - } - - private void InitializeDataSources() - { - compositeDataSourceStopLimit = Empty(); - compositeDataSourceZeroPoint = Empty(); - - compositeDataSourceInsiderTransactionPointDisposedSmall = Empty(); - compositeDataSourceInsiderTransactionPointDisposedMedium = Empty(); - compositeDataSourceInsiderTransactionPointDisposedLarge = Empty(); - - compositeDataSourceInsiderTransactionPointAcquiredSmall = Empty(); - compositeDataSourceInsiderTransactionPointAcquiredMedium = Empty(); - compositeDataSourceInsiderTransactionPointAcquiredLarge = Empty(); - - compositeDataSourceK = Empty(); - compositeDataSourceKL1 = Empty(); - compositeDataSourceL = Empty(); - compositeDataSourceLP1 = Empty(); - compositeDataSourceHigh = Empty(); - compositeDataSourceLow = Empty(); - compositeDataSourceClose = Empty(); - compositeDataSourceSMAN = Empty(); - compositeDataSourceVolume = Empty(); - compositeDataSourceLeastSquares = Empty(); - compositeDataSourceTradePoints = Empty(); - } - - private static CompositeDataSource Empty() - { - return new CompositeDataSource() - { - DataAdapter = new SortedDateTimeDataAdapter() - }; + isBusy = value; + base.OnPropertyChanged("IsBusy"); } } -} + + public bool SyncTradeToBand + { + get + { + return syncTradeToBand; + } + set + { + syncTradeToBand = value; + base.OnPropertyChanged("SyncTradeToBand"); + } + } + + public bool ShowTradeLabels + { + get + { + return showTradeLabels; + } + set + { + showTradeLabels = value; + base.OnPropertyChanged("ShowTradeLabels"); + } + } + + public bool UseLeastSquaresFit + { + get + { + return useLeastSquaresFit; + } + set + { + useLeastSquaresFit = value; + base.OnPropertyChanged("UseLeastSquaresFit"); + } + } + + public Boolean CheckBoxShowInsiderTransactions + { + get + { + return showInsiderTransactions; + } + set + { + showInsiderTransactions = value; + base.OnPropertyChanged("CheckBoxShowInsiderTransactions"); + } + } + + [RelayCommand] + public async Task Refresh() + { + base.OnPropertyChanged("SelectedSymbol"); + await Task.FromResult(true); + } + } +} \ No newline at end of file diff --git a/PortfolioManager/ViewModels/MainWindowViewModel.cs b/PortfolioManager/ViewModels/MainWindowViewModel.cs index c834a4f..596b719 100644 --- a/PortfolioManager/ViewModels/MainWindowViewModel.cs +++ b/PortfolioManager/ViewModels/MainWindowViewModel.cs @@ -97,7 +97,7 @@ namespace PortfolioManager.ViewModels { return new List() { - new CommandViewModel("ScottPlot", new MyRelayCommand(ParamArrayAttribute => this.ViewScottPlot())), + // new CommandViewModel("ScottPlot", new MyRelayCommand(ParamArrayAttribute => this.ViewScottPlot())), new CommandViewModel("Bollinger Bands", new MyRelayCommand(ParamArrayAttribute => this.ViewBollingerBands())), new CommandViewModel("Gain/Loss", new MyRelayCommand(ParamArrayAttribute => this.ViewGainLoss())), new CommandViewModel("Momentum Model", new MyRelayCommand(ParamArrayAttribute => this.ViewMomentum())), @@ -107,19 +107,19 @@ namespace PortfolioManager.ViewModels }; } - private void ViewScottPlot() - { - ScottPlotViewModel workspace = null; - if (null == workspace) - { - workspace = new ScottPlotViewModel(); - workspace.WorkspaceInstantiator = InstantiateWorkspace; - workspace.Referer = GetReferal(); - // AddMenuItem(workspace); - this.Workspaces.Add(workspace); - } - this.SetActiveWorkspace(workspace); - } + // private void ViewScottPlot() + // { + // ScottPlotViewModel workspace = null; + // if (null == workspace) + // { + // workspace = new ScottPlotViewModel(); + // workspace.WorkspaceInstantiator = InstantiateWorkspace; + // workspace.Referer = GetReferal(); + // // AddMenuItem(workspace); + // this.Workspaces.Add(workspace); + // } + // this.SetActiveWorkspace(workspace); + // } private void ViewBollingerBands() { diff --git a/PortfolioManager/ViewModels/ScottPlotViewModel.cs b/PortfolioManager/ViewModels/ScottPlotViewModel.cs deleted file mode 100644 index 5d8d97b..0000000 --- a/PortfolioManager/ViewModels/ScottPlotViewModel.cs +++ /dev/null @@ -1,341 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using CommunityToolkit.Mvvm.Input; -using DynamicData; -using MarketData; -using MarketData.DataAccess; -using MarketData.MarketDataModel; -using MarketData.Utils; -using PortfolioManager.Renderers; -using PortfolioManager.UIUtils; - -namespace PortfolioManager.ViewModels -{ - public partial class ScottPlotViewModel : PlotterWorkspaceViewModel - { - private List watchListNames; - private String selectedWatchList; - private ObservableCollection symbols = new ObservableCollection(); - private List dayCounts = new int[] { 60, 90, 180, 360, 720, 1440, 3600 }.ToList(); - private int selectedDayCount = 90; - private bool isBusy = false; - private String selectedSymbol = default; - private String companyName = default; - private BollingerBandRenderer bollingerBandRenderer = default; - private bool showInsiderTransactions = true; - private bool showTradeLabels = true; - private bool syncTradeToBand = true; - private bool useLeastSquaresFit = true; - - public ScottPlotViewModel() - { - DisplayName = "Bollinger"; - OnPlotterLoadedEventHandler += PlotterLoadedEvent; - PropertyChanged += OnViewModelPropertyChanged; - Initialize(); - } - - protected override void OnDispose() - { - MDTrace.WriteLine(LogLevel.DEBUG, $"Dispose BollingerBandViewModel"); - base.OnDispose(); - } - - public override String Title - { - get - { - if (null == selectedSymbol) return DisplayName; - return "Bollinger " + "(" + selectedSymbol + ")"; - } - } - - public override String DisplayName - { - get - { - return "Bollinger Band"; - } - } - - private void Initialize(bool executePropertyChanged = true) - { - Task workerTask = Task.Factory.StartNew(() => - { - MDTrace.WriteLine(LogLevel.DEBUG, $"BollingerBandViewModel::Initialize()"); - watchListNames = WatchListDA.GetWatchLists(); - watchListNames.Insert(0, UIConstants.CONST_ALL); - selectedWatchList = watchListNames.Find(x => x.Equals("Valuations")); - symbols.AddRange(WatchListDA.GetWatchList(selectedWatchList)); - }); - workerTask.ContinueWith((continuation) => - { - if (executePropertyChanged) - { - base.OnPropertyChanged("Symbols"); - base.OnPropertyChanged("WatchListNames"); - base.OnPropertyChanged("SelectedWatchList"); - } - }); - } - - - // ******************************************************************************************************************************************* - /// - /// This event will be called the first time the view is rendered and each time the view comes back into focus (i.e.) Tab activated - /// - /// - /// - public void PlotterLoadedEvent(object sender, PlotterLoadedEventArgs e) - { - base.OnPropertyChanged("Plotter"); - } - - private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs) - { - - if ((eventArgs.PropertyName.Equals("SyncTradeToBand") || - eventArgs.PropertyName.Equals("ShowTradeLabels") || - eventArgs.PropertyName.Equals("SelectedSymbol") || - eventArgs.PropertyName.Equals("ShowRiskFree") || - eventArgs.PropertyName.Equals("UseLeastSquaresFit") || - eventArgs.PropertyName.Equals("CheckBoxShowInsiderTransactions") || - eventArgs.PropertyName.Equals("SelectedDayCount")) - && !String.IsNullOrEmpty(selectedSymbol) - && default != Plotter) - { - IsBusy = true; - Task workerTask = Task.Factory.StartNew(() => - { - companyName = PricingDA.GetNameForSymbol(selectedSymbol); - bollingerBandRenderer = new BollingerBandRenderer(Plotter); - bollingerBandRenderer.ShowLeastSquares = useLeastSquaresFit; - bollingerBandRenderer.SyncTradeToBand = syncTradeToBand; - bollingerBandRenderer.ShowInsiderTransactions = showInsiderTransactions; - bollingerBandRenderer.ShowTradeLabels = showTradeLabels; - bollingerBandRenderer.SetData(selectedSymbol, selectedDayCount); - bollingerBandRenderer.Render(); - }); - workerTask.ContinueWith((continuation) => - { - base.OnPropertyChanged("GraphTitle"); - base.OnPropertyChanged("Title"); - IsBusy = false; - }); - } - } - - // ********************************************** P E R S I S T E N C E ************************* - - public override bool CanPersist() - { - return false; - } - - public override SaveParameters GetSaveParameters() - { - return null; - // SaveParameters saveParams = new SaveParameters(); - // if (String.IsNullOrEmpty(selectedSymbol)) return null; - // saveParams.Add(new KeyValuePair("Type", GetType().Namespace + "." + GetType().Name)); - // saveParams.Add(new KeyValuePair("SelectedSymbol", selectedSymbol)); - // saveParams.Add(new KeyValuePair("SelectedWatchList", selectedWatchList)); - // saveParams.Add(new KeyValuePair("SelectedDayCount", selectedDayCount.ToString())); - // saveParams.Add(new KeyValuePair("SyncTradeToBand", syncTradeToBand.ToString())); - // saveParams.Add(new KeyValuePair("ShowTradeLabels", showTradeLabels.ToString())); - // saveParams.Add(new KeyValuePair("UseLeastSquaresFit", useLeastSquaresFit.ToString())); - // saveParams.Add(new KeyValuePair("ShowInsiderTransactions", showInsiderTransactions.ToString())); - // if (null != stopLimits && 0 != stopLimits.Count) - // { - // saveParams.Add(new KeyValuePair("StopHistoryCount", stopLimits.Count.ToString())); - // for (int index = 0; index < stopLimits.Count; index++) - // { - // String strItemKey = String.Format("StopHistory_{0}", index); - // StopLimit stopLimit = stopLimits[index]; - // NVPCollection nvpCollection = stopLimit.ToNVPCollection(); - // String strStopHistoryItem = nvpCollection.ToString(); - // saveParams.Add(new KeyValuePair(strItemKey, strStopHistoryItem)); - // } - // } - // return saveParams; - } - - public override void SetSaveParameters(SaveParameters saveParameters) - { - } - - // ****************************************************** P R O P E R T I E S ************************************************ - - public String GraphTitle - { - get - { - if (null == companyName || null == bollingerBandRenderer || null == bollingerBandRenderer.Prices) 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(bollingerBandRenderer.Prices.Take(2).ToList()); - if (2 == prices2day.Count) change = prices2day.GetReturns()[0]; - sb.Append(displayCompanyName); - sb.Append(" (").Append(selectedSymbol).Append(") "); - sb.Append(Utility.DateTimeToStringMMHDDHYYYY(bollingerBandRenderer.Prices[bollingerBandRenderer.Prices.Count - 1].Date)); - sb.Append(" Thru "); - sb.Append(Utility.DateTimeToStringMMHDDHYYYY(bollingerBandRenderer.Prices[0].Date)); - sb.Append(" (").Append(Utility.FormatCurrency(bollingerBandRenderer.Prices[0].Close)); - sb.Append("/").Append(Utility.FormatCurrency(bollingerBandRenderer.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 List WatchListNames - { - get - { - return watchListNames; - } - } - - public String SelectedWatchList - { - get - { - return selectedWatchList; - } - set - { - selectedWatchList = value; - base.OnPropertyChanged("SelectedWatchList"); - } - } - - public ObservableCollection Symbols - { - get - { - return symbols; - } - } - - public int SelectedDayCount - { - get - { - return selectedDayCount; - } - set - { - selectedDayCount = value; - base.OnPropertyChanged("SelectedDayCount"); - } - } - - public List DayCounts - { - get - { - return dayCounts; - } - } - - public String SelectedSymbol - { - get - { - return selectedSymbol; - } - set - { - if (String.IsNullOrEmpty(value)) - { - return; - } - selectedSymbol = value; - base.OnPropertyChanged("SelectedSymbol"); - } - } - - public bool IsBusy - { - get - { - return isBusy; - } - set - { - isBusy = value; - base.OnPropertyChanged("IsBusy"); - } - } - - public bool SyncTradeToBand - { - get - { - return syncTradeToBand; - } - set - { - syncTradeToBand = value; - base.OnPropertyChanged("SyncTradeToBand"); - } - } - - public bool ShowTradeLabels - { - get - { - return showTradeLabels; - } - set - { - showTradeLabels = value; - base.OnPropertyChanged("ShowTradeLabels"); - } - } - - public bool UseLeastSquaresFit - { - get - { - return useLeastSquaresFit; - } - set - { - useLeastSquaresFit = value; - base.OnPropertyChanged("UseLeastSquaresFit"); - } - } - - public Boolean CheckBoxShowInsiderTransactions - { - get - { - return showInsiderTransactions; - } - set - { - showInsiderTransactions = value; - base.OnPropertyChanged("CheckBoxShowInsiderTransactions"); - } - } - - [RelayCommand] - public async Task Refresh() - { - base.OnPropertyChanged("SelectedSymbol"); - await Task.FromResult(true); - } - } -} \ No newline at end of file diff --git a/PortfolioManager/Views/BollingerBandView.axaml b/PortfolioManager/Views/BollingerBandView.axaml index 1eb786c..c7e57f1 100644 --- a/PortfolioManager/Views/BollingerBandView.axaml +++ b/PortfolioManager/Views/BollingerBandView.axaml @@ -2,16 +2,15 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:ScottPlot="clr-namespace:ScottPlot.Avalonia;assembly=ScottPlot.Avalonia" xmlns:vm="using:PortfolioManager.ViewModels" xmlns:vw="using:PortfolioManager.Views" xmlns:md="using:PortfolioManager.Models" xmlns:local="using:PortfolioManager.UIUtils" xmlns:li="using:LoadingIndicators.Avalonia" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" - xmlns:mxc="https://schemas.eremexcontrols.net/avalonia/charts" x:DataType="vm:BollingerBandViewModel" - x:Class="PortfolioManager.Views.BollingerBandView" - > + x:Class="PortfolioManager.Views.BollingerBandView"> @@ -63,157 +62,27 @@ + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - diff --git a/PortfolioManager/Views/BollingerBandView.axaml.cs b/PortfolioManager/Views/BollingerBandView.axaml.cs index 1aac1a1..b488565 100644 --- a/PortfolioManager/Views/BollingerBandView.axaml.cs +++ b/PortfolioManager/Views/BollingerBandView.axaml.cs @@ -1,13 +1,32 @@ +using System; using Avalonia; using Avalonia.Controls; +using Avalonia.Interactivity; using Avalonia.Markup.Xaml; +using PortfolioManager.ViewModels; +using ScottPlot.Avalonia; namespace PortfolioManager.Views; public partial class BollingerBandView : UserControl { - public BollingerBandView() + public BollingerBandView() + { + this.DataContextChanged += OnDataContextChanged; + InitializeComponent(); + } + + private void OnDataContextChanged(object sender, EventArgs e) + { + if (default != (sender as BollingerBandView)) { - InitializeComponent(); + BollingerBandView view = (sender as BollingerBandView); + PlotterWorkspaceViewModel viewModel = (DataContext as PlotterWorkspaceViewModel); + if (null!=viewModel && default == viewModel.Plotter) + { + viewModel.Plotter = new AvaPlot(); + viewModel.OnPlotterLoaded(viewModel.Plotter); + } } + } } \ No newline at end of file diff --git a/PortfolioManager/Views/MainWindow.axaml b/PortfolioManager/Views/MainWindow.axaml index d4c7b11..556ff63 100644 --- a/PortfolioManager/Views/MainWindow.axaml +++ b/PortfolioManager/Views/MainWindow.axaml @@ -21,7 +21,7 @@ - + + diff --git a/PortfolioManager/Views/ScottPlotView.axaml b/PortfolioManager/Views/ScottPlotView.axaml deleted file mode 100644 index 1a180cb..0000000 --- a/PortfolioManager/Views/ScottPlotView.axaml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PortfolioManager/Views/ScottPlotView.axaml.cs b/PortfolioManager/Views/ScottPlotView.axaml.cs deleted file mode 100644 index 949f049..0000000 --- a/PortfolioManager/Views/ScottPlotView.axaml.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Interactivity; -using Avalonia.Markup.Xaml; -using PortfolioManager.ViewModels; -using ScottPlot.Avalonia; - -namespace PortfolioManager.Views; - -public partial class ScottPlotView : UserControl -{ - public ScottPlotView() - { - this.DataContextChanged += OnDataContextChanged; - InitializeComponent(); - } - - private void OnDataContextChanged(object sender, EventArgs e) - { - if (default != (sender as ScottPlotView)) - { - ScottPlotView view = (sender as ScottPlotView); - PlotterWorkspaceViewModel viewModel = (DataContext as PlotterWorkspaceViewModel); - if (null!=viewModel && default == viewModel.Plotter) - { - viewModel.Plotter = new AvaPlot(); - viewModel.OnPlotterLoaded(viewModel.Plotter); - } - } - } -} \ No newline at end of file diff --git a/PortfolioManager/saveparams.config b/PortfolioManager/saveparams.config index 6f1cd46..f259450 100644 --- a/PortfolioManager/saveparams.config +++ b/PortfolioManager/saveparams.config @@ -1 +1,19 @@ -Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,KEP,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,CRS,SelectedWatchList,Valuations,SelectedDayCount,90,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,SPY,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,CRK,SelectedWatchList,Valuations,SelectedDayCount,90,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,JFNNX,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,VSTCX,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,PSO,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,PRIM,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,RNMBY,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,DRD,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.MGSHMomentumViewModel,PathFileName,C:\3\MGSH20250331.TXT +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,SXT,SelectedWatchList,Valuations,SelectedDayCount,360,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,RGLD,SelectedWatchList,Valuations,SelectedDayCount,360,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,PSO,SelectedWatchList,Valuations,SelectedDayCount,360,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,TSCDY,SelectedWatchList,Valuations,SelectedDayCount,360,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,DBX,SelectedWatchList,Valuations,SelectedDayCount,360,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,NRG,SelectedWatchList,Valuations,SelectedDayCount,360,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,OPRA,SelectedWatchList,Valuations,SelectedDayCount,360,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,MO,SelectedWatchList,Valuations,SelectedDayCount,360,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True +Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,EXC,SelectedWatchList,Valuations,SelectedDayCount,360,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True