From a5b23690340572284d6cb49c2ed0d2f7cd2bf59f Mon Sep 17 00:00:00 2001 From: Sean Date: Thu, 19 Jun 2025 17:03:05 -0400 Subject: [PATCH] Commit Latest --- .../CompositeDataSource.cs | 16 ++ .../ViewModels/ScottPlotViewModel.cs | 154 ++++++++++++++++-- 2 files changed, 157 insertions(+), 13 deletions(-) diff --git a/PortfolioManager/DataSeriesViewModels/CompositeDataSource.cs b/PortfolioManager/DataSeriesViewModels/CompositeDataSource.cs index 4f027e1..bdecc9d 100644 --- a/PortfolioManager/DataSeriesViewModels/CompositeDataSource.cs +++ b/PortfolioManager/DataSeriesViewModels/CompositeDataSource.cs @@ -1,3 +1,4 @@ +using System; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; @@ -6,5 +7,20 @@ namespace PortfolioManager.DataSeriesViewModels public partial class CompositeDataSource : ObservableObject { [ObservableProperty] ISeriesDataAdapter dataAdapter; + public (DateTime[],double[]) ToXYData() + { + double[] values = default; + DateTime[] dates = default; + + if (null == DataAdapter) return (dates, values); + values = new double[DataAdapter.ItemCount]; + dates = new DateTime[DataAdapter.ItemCount]; + for (int index = 0; index < DataAdapter.ItemCount; index++) + { + values[index] = DataAdapter.GetNumericalValue(index, SeriesDataMemberType.Value); + dates[index] = DataAdapter.GetDateTimeValue(index, SeriesDataMemberType.Value1); + } + return (dates, values); + } } } \ No newline at end of file diff --git a/PortfolioManager/ViewModels/ScottPlotViewModel.cs b/PortfolioManager/ViewModels/ScottPlotViewModel.cs index facab7a..7284329 100644 --- a/PortfolioManager/ViewModels/ScottPlotViewModel.cs +++ b/PortfolioManager/ViewModels/ScottPlotViewModel.cs @@ -1,6 +1,10 @@ using System; +using Eremex.AvaloniaUI.Charts; using MarketData.DataAccess; +using MarketData.Generator; using MarketData.MarketDataModel; +using PortfolioManager.DataSeriesViewModels; +using PortfolioManager.Models; using ScottPlot.Avalonia; using ScottPlot.Plottables; using ShimSkiaSharp; @@ -8,6 +12,119 @@ using SkiaSharp; namespace PortfolioManager.ViewModels { + public class BollingerBandCompositeDataSourceGenerater + { + public BollingerBandCompositeDataSourceGenerater() + { + } + + public void GenerateCompositeDataSources(AvaPlot plotter, BollingerBands bollingerBands) + { + K = BollingerBandModel.K(bollingerBands); + KL1 = BollingerBandModel.KL1(bollingerBands); + L = BollingerBandModel.L(bollingerBands); + LP1 = BollingerBandModel.LP1(bollingerBands); + High = BollingerBandModel.High(bollingerBands); + Low = BollingerBandModel.Low(bollingerBands); + Close = BollingerBandModel.Close(bollingerBands); + SMAN = BollingerBandModel.SMAN(bollingerBands); + Volume = BollingerBandModel.Volume(bollingerBands); + LeastSquares = BollingerBandModel.LeastSquares(bollingerBands); + + Scatter scatter = default; + { + (DateTime[] dates, double[] values) = K.ToXYData(); + scatter = plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Green)); + scatter.LegendText = "K"; + scatter.LineWidth = 2; + } + + { + (DateTime[] dates, double[] values) = KL1.ToXYData(); + scatter = plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Green)); + scatter.LegendText = "KL1"; + scatter.LineWidth = 1; + } + + { + (DateTime[] dates, double[] values) = L.ToXYData(); + scatter = plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Green)); + scatter.LegendText = "L"; + scatter.LineWidth = 2; + } + + { + (DateTime[] dates, double[] values) = LP1.ToXYData(); + scatter = plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Green)); + scatter.LegendText = "LP1"; + scatter.LineWidth = 1; + } + + { + (DateTime[] dates, double[] values) = High.ToXYData(); + scatter = plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Blue)); + scatter.LegendText = "High"; + scatter.LineWidth = 1; + } + + { + (DateTime[] dates, double[] values) = Low.ToXYData(); + scatter = plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Red)); + scatter.LegendText = "Low"; + scatter.LineWidth = 1; + } + + { + (DateTime[] dates, double[] values) = Close.ToXYData(); + scatter = plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Black)); + scatter.LegendText = "Close"; + scatter.LineWidth = 1; + } + + { + (DateTime[] dates, double[] values) = LeastSquares.ToXYData(); + scatter = plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Orange)); + scatter.LegendText = "LeastSquares"; + scatter.LineWidth = 1; + } + + { + (DateTime[] dates, double[] values) = SMAN.ToXYData(); + scatter = plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Purple)); + scatter.LegendText = "SMAN"; + scatter.LineWidth = 1; + } + + + + + + + } + + + + public CompositeDataSource K { get; private set; } = Empty(); + public CompositeDataSource KL1 { get; private set; } = Empty(); + public CompositeDataSource L { get; private set; } = Empty(); + public CompositeDataSource LP1 { get; private set; } = Empty(); + public CompositeDataSource High { get; private set; } = Empty(); + public CompositeDataSource Low { get; private set; } = Empty(); + public CompositeDataSource Close { get; private set; } = Empty(); + public CompositeDataSource SMAN { get; private set; } = Empty(); + public CompositeDataSource Volume { get; private set; } = Empty(); + public CompositeDataSource LeastSquares { get; private set; } = Empty(); + + private static CompositeDataSource Empty() + { + return new CompositeDataSource() + { + DataAdapter = new SortedDateTimeDataAdapter() + }; + } + } + + @@ -21,26 +138,37 @@ namespace PortfolioManager.ViewModels public void PlotterLoadedEvent(object sender, PlotterLoadedEventArgs e) { + plotter = e.AvaPlot; // we should store this somewhere Prices prices = PricingDA.GetPrices("SPY", 180); - DateTime[] dates = new DateTime[prices.Count]; - double[] closes = new double[prices.Count]; + BollingerBands bollingerBands = BollingerBandGenerator.GenerateBollingerBands(prices); - for (int index = 0; index < prices.Count; index++) - { - dates[index] = prices[index].Date; - closes[index] = prices[index].Close; - } + BollingerBandCompositeDataSourceGenerater bollingerBandCompositeDataSourceGenerater = new BollingerBandCompositeDataSourceGenerater(); + bollingerBandCompositeDataSourceGenerater.GenerateCompositeDataSources(plotter, bollingerBands); + plotter.Plot.Axes.AutoScale(); + plotter.Refresh(); - plotter = e.AvaPlot; + + // DateTime[] dates = new DateTime[prices.Count]; + // double[] closes = new double[prices.Count]; + + // for (int index = 0; index < prices.Count; index++) + // { + // dates[index] = prices[index].Date; + // closes[index] = prices[index].Close; + // } + + + + // plotter = e.AvaPlot; // double[] dataX = { 1, 2, 3, 4, 5 }; // double[] dataY = { 1, 4, 9, 16, 25 }; // plotter.Plot.Add.Scatter(dataX, dataY); - Scatter closeScatter = plotter.Plot.Add.ScatterLine(dates, closes, ScottPlot.Color.FromSKColor(SKColors.Red)); - closeScatter.LegendText = "Close"; - closeScatter.LineWidth = 3; - plotter.Plot.Axes.AutoScale(); - plotter.Refresh(); + // Scatter closeScatter = plotter.Plot.Add.ScatterLine(dates, closes, ScottPlot.Color.FromSKColor(SKColors.Red)); + // closeScatter.LegendText = "Close"; + // closeScatter.LineWidth = 2; + // plotter.Plot.Axes.AutoScale(); + // plotter.Refresh(); } // ********************************************** P E R S I S T E N C E ************************* public override bool CanPersist()