diff --git a/PortfolioManager/PortfolioManager.csproj b/PortfolioManager/PortfolioManager.csproj index 3300a68..34a40fa 100644 --- a/PortfolioManager/PortfolioManager.csproj +++ b/PortfolioManager/PortfolioManager.csproj @@ -44,6 +44,7 @@ + diff --git a/PortfolioManager/Readme.txt b/PortfolioManager/Readme.txt index 7b5b36f..9b60e7e 100644 --- a/PortfolioManager/Readme.txt +++ b/PortfolioManager/Readme.txt @@ -198,4 +198,6 @@ Import the ScottPlot.Avalonia namespace: Add this namespace to your window eleme Add an AvaPlot control: Add an AvaPlot element to your layout in your Avalonia application, giving it a unique name. Plot your data: Use the AvaPlot control to display your data and create various plot types, such as line plots, scatter plots, bar charts, and more. -https://scottplot.net/quickstart/avalonia/ \ No newline at end of file +https://scottplot.net/quickstart/avalonia/ + +1) dotnet add package ScottPlot.Avalonia \ No newline at end of file diff --git a/PortfolioManager/ViewModels/MainWindowViewModel.cs b/PortfolioManager/ViewModels/MainWindowViewModel.cs index 996ec2f..c834a4f 100644 --- a/PortfolioManager/ViewModels/MainWindowViewModel.cs +++ b/PortfolioManager/ViewModels/MainWindowViewModel.cs @@ -97,6 +97,7 @@ namespace PortfolioManager.ViewModels { return new List() { + 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())), @@ -106,19 +107,33 @@ namespace PortfolioManager.ViewModels }; } - private void ViewBollingerBands() + private void ViewScottPlot() { - BollingerBandViewModel workspace = null; + ScottPlotViewModel workspace = null; if (null == workspace) { - workspace = new BollingerBandViewModel(); + workspace = new ScottPlotViewModel(); workspace.WorkspaceInstantiator = InstantiateWorkspace; workspace.Referer = GetReferal(); // AddMenuItem(workspace); this.Workspaces.Add(workspace); } this.SetActiveWorkspace(workspace); - } + } + + private void ViewBollingerBands() + { + BollingerBandViewModel workspace = null; + if (null == workspace) + { + workspace = new BollingerBandViewModel(); + workspace.WorkspaceInstantiator = InstantiateWorkspace; + workspace.Referer = GetReferal(); + // AddMenuItem(workspace); + this.Workspaces.Add(workspace); + } + this.SetActiveWorkspace(workspace); + } private void ViewCMTrend() { diff --git a/PortfolioManager/ViewModels/ScottPlotViewModel.cs b/PortfolioManager/ViewModels/ScottPlotViewModel.cs new file mode 100644 index 0000000..dad88b1 --- /dev/null +++ b/PortfolioManager/ViewModels/ScottPlotViewModel.cs @@ -0,0 +1,44 @@ +using ScottPlot.Avalonia; + +namespace PortfolioManager.ViewModels +{ + public partial class ScottPlotViewModel : WorkspaceViewModel + { + public ScottPlotViewModel() + { + double[] dataX = { 1, 2, 3, 4, 5 }; + double[] dataY = { 1, 4, 9, 16, 25 }; + + // AvaPlot avaPlot = this.Find("AvaPlot"); + // ((ScottPlotViewModel)DataContext).Plotter = avaPlot; + + + if (Plotter != null) + { + Plotter.Plot.Add.Scatter(dataX, dataY); + Plotter.Refresh(); + } + } + + + // ********************************************** P E R S I S T E N C E ************************* + public override bool CanPersist() + { + return false; + } + + public override SaveParameters GetSaveParameters() + { + return null; + } + + public override void SetSaveParameters(SaveParameters saveParameters) + { + } + + // ********************************************************************************************** + + public AvaPlot Plotter { get; set; } = default; + + } +} \ No newline at end of file diff --git a/PortfolioManager/ViewModels/WorkspaceViewModel.cs b/PortfolioManager/ViewModels/WorkspaceViewModel.cs index 35941f2..b626de5 100644 --- a/PortfolioManager/ViewModels/WorkspaceViewModel.cs +++ b/PortfolioManager/ViewModels/WorkspaceViewModel.cs @@ -13,7 +13,7 @@ namespace PortfolioManager.ViewModels private RelayCommand closeCommand; // Events - public event EventHandler RequestClose; + public event EventHandler RequestClose; private InstantiateWorkspace workspaceInstantiator; private bool canClose = true; diff --git a/PortfolioManager/Views/MainWindow.axaml b/PortfolioManager/Views/MainWindow.axaml index bb4263b..d4c7b11 100644 --- a/PortfolioManager/Views/MainWindow.axaml +++ b/PortfolioManager/Views/MainWindow.axaml @@ -39,6 +39,9 @@ + + + diff --git a/PortfolioManager/Views/ScottPlotView.axaml b/PortfolioManager/Views/ScottPlotView.axaml new file mode 100644 index 0000000..f7044fc --- /dev/null +++ b/PortfolioManager/Views/ScottPlotView.axaml @@ -0,0 +1,15 @@ + + + diff --git a/PortfolioManager/Views/ScottPlotView.axaml.cs b/PortfolioManager/Views/ScottPlotView.axaml.cs new file mode 100644 index 0000000..df3ae9a --- /dev/null +++ b/PortfolioManager/Views/ScottPlotView.axaml.cs @@ -0,0 +1,25 @@ +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() + { + InitializeComponent(); + AvaPlot avaPlot = this.Find("AvaPlot"); + avaPlot.Loaded += OnLoadedEvent(this, null); + } + + protected void OnLoadedEvent(object sender, EventArgs args) + { + // if (null == tabControl) return; + // tabControl.SelectedIndex = args.Index; + } +} \ No newline at end of file diff --git a/PortfolioManager/portfolio_manager.log b/PortfolioManager/portfolio_manager.log index 5e29ce4..d413dd1 100644 --- a/PortfolioManager/portfolio_manager.log +++ b/PortfolioManager/portfolio_manager.log @@ -33,3 +33,126 @@ [Thread=1][TRACE.DEBUG][6/15/2025 9:16:44 PM] [PortfolioManager.ViewModels.MainWindowViewModel::OnDispose()][MainWindowViewModel:OnDispose] LEAVE [Thread=1][TRACE.VERBOSE][6/15/2025 9:16:44 PM] [PortfolioManager.Program::Main(args)]There were 62 threads still running at application shutdown. [Thread=1][TRACE.VERBOSE][6/15/2025 9:16:44 PM] [PortfolioManager.Program::Main(args)][MAIN:EXIT] +[Thread=1][TRACE.VERBOSE][6/18/2025 6:59:45 PM] [PortfolioManager.Program::Main(args)][MAIN:STARTING] +[Thread=1][TRACE.VERBOSE][6/18/2025 6:59:45 PM] [PortfolioManager.Program::Main(args)]Using portfolio_data at Adrastea +[Thread=1][TRACE.VERBOSE][6/18/2025 6:59:45 PM] [PortfolioManager.Program::Main(args)]Using market_data at Adrastea +[Thread=1][TRACE.VERBOSE][6/18/2025 6:59:45 PM] [PortfolioManager.Program::Main(args)]Using user_data at Adrastea +[Thread=9][TRACE.VERBOSE][6/18/2025 6:59:45 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass43_0::b__0()]BollingerBandViewModel::Initialize() +[Thread=6][TRACE.VERBOSE][6/18/2025 6:59:45 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass43_0::b__0()]BollingerBandViewModel::Initialize() +[Thread=8][TRACE.VERBOSE][6/18/2025 6:59:45 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass43_0::b__0()]BollingerBandViewModel::Initialize() +[Thread=17][TRACE.VERBOSE][6/18/2025 6:59:46 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass84_0::b__0()]BollingerBandViewModel::SetSaveParameters('NRG','Valuations','360') +[Thread=19][TRACE.VERBOSE][6/18/2025 6:59:46 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass84_0::b__0()]BollingerBandViewModel::SetSaveParameters('CRS','Valuations','90') +[Thread=18][TRACE.VERBOSE][6/18/2025 6:59:46 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass84_0::b__0()]BollingerBandViewModel::SetSaveParameters('DBX','Valuations','180') +[Thread=17][TRACE.VERBOSE][6/18/2025 6:59:46 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass86_0::b__0()]OnViewModelPropertyChanged(SelectedSymbol). Selected symbol 'NRG' +[Thread=18][TRACE.VERBOSE][6/18/2025 6:59:46 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass86_0::b__0()]OnViewModelPropertyChanged(SelectedSymbol). Selected symbol 'DBX' +[Thread=19][TRACE.VERBOSE][6/18/2025 6:59:46 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass86_0::b__0()]OnViewModelPropertyChanged(SelectedSymbol). Selected symbol 'CRS' +[Thread=16][TRACE.VERBOSE][6/18/2025 6:59:46 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]Done, total took 404(ms) +[Thread=16][TRACE.VERBOSE][6/18/2025 6:59:46 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]Done, total took 98(ms) +[Thread=12][TRACE.VERBOSE][6/18/2025 6:59:47 PM] [MarketData.Generator.CMTrend.CMTTrendModel::GetModelPerformance(sessionParams)]Done, total took 1788(ms) +[Thread=15][TRACE.VERBOSE][6/18/2025 6:59:48 PM] [MarketData.Generator.CMMomentum.CMMomentumBacktest::GetModelPerformance(sessionParams)]Done, took 2063(ms) +[Thread=15][TRACE.VERBOSE][6/18/2025 6:59:48 PM] [MarketData.Generator.CMMomentum.CMMomentumBacktest::GetModelPerformance(sessionParams)]Done, took 54(ms) +[Thread=10][TRACE.VERBOSE][6/18/2025 6:59:48 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]Done, total took 2618(ms) +[Thread=10][TRACE.VERBOSE][6/18/2025 6:59:48 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]Done, total took 76(ms) +[Thread=12][TRACE.VERBOSE][6/18/2025 6:59:48 PM] [MarketData.Generator.CMTrend.CMTTrendModel::GetModelPerformance(sessionParams)]Done, total took 64(ms) +[Thread=12][TRACE.VERBOSE][6/18/2025 6:59:51 PM] [PortfolioManager.ViewModels.GainLossViewModel::HandleSelectedSymbol()]HandleSelectedSymbol:{ALL} +[Thread=12][TRACE.VERBOSE][6/18/2025 6:59:51 PM] [PortfolioManager.ViewModels.GainLossViewModel::HandleSelectedSymbol()][GainLossViewModel::OnGainLossViewModelPropertyChanged]SelectedSymbol '{ALL}' +[Thread=12][TRACE.VERBOSE][6/18/2025 6:59:55 PM] [PortfolioManager.ViewModels.GainLossViewModel::b__41_0()]GeneratingActiveGainLoss +[Thread=12][TRACE.VERBOSE][6/18/2025 6:59:56 PM] [PortfolioManager.ViewModels.GainLossViewModel::b__41_0()]GeneratingTotalGainLoss) +[Thread=12][TRACE.VERBOSE][6/18/2025 6:59:56 PM] [PortfolioManager.ViewModels.GainLossViewModel::b__41_0()]Date:6/18/2025 TotalGainLoss:$86,946.25 +[Thread=12][TRACE.VERBOSE][6/18/2025 6:59:56 PM] [MarketData.MarketDataModel.GainLoss.GainLossSummaryItemCollection::.ctor(portfolioTrades,gainLossGenerator,activeGainLossGenerator,maxDateRef)][GainLossSummaryItemCollection] Done, took 381(ms) +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:08 PM] [PortfolioManager.ViewModels.GainLossViewModel::OnDispose()]Dispose GainLossViewModel +[Thread=1][TRACE.DEBUG][6/18/2025 7:00:08 PM] [PortfolioManager.Cache.ImageCache::.ctor()]Reading assets from C:\Avalonia\PortfolioManager/Assets +[Thread=1][TRACE.DEBUG][6/18/2025 7:00:09 PM] [PortfolioManager.App+<>c__DisplayClass1_1::b__1(,)]App: Received ClosingHandler event +[Thread=1][TRACE.DEBUG][6/18/2025 7:00:09 PM] [PortfolioManager.ViewModels.MainWindowViewModel::OnDispose()][MainWindowViewModel:OnDispose] +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:09 PM] [PortfolioManager.ViewModels.MomentumViewModel::OnDispose()]Dispose MomentumViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:09 PM] [PortfolioManager.ViewModels.CMMomentumViewModel::OnDispose()]Dispose CMMomentumViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:09 PM] [PortfolioManager.ViewModels.CMTrendViewModel::OnDispose()]Dispose CMTrendViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:09 PM] [PortfolioManager.ViewModels.MGSHMomentumViewModel::OnDispose()]Dispose MGSHMomentumViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:09 PM] [PortfolioManager.ViewModels.BollingerBandViewModel::OnDispose()]Dispose BollingerBandViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:09 PM] [PortfolioManager.ViewModels.BollingerBandViewModel::OnDispose()]Dispose BollingerBandViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:09 PM] [PortfolioManager.ViewModels.BollingerBandViewModel::OnDispose()]Dispose BollingerBandViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:09 PM] [MarketData.Cache.LocalPriceCache::Dispose()][LocalPriceCache:Dispose]Thread state is 'WaitSleepJoin'. Joining main thread... +[Thread=28][TRACE.VERBOSE][6/18/2025 7:00:10 PM] [MarketData.Cache.LocalPriceCache::ThreadProc()][LocalPriceCache:ThreadProc] Thread ended. Items in cache:0 +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:10 PM] [MarketData.Cache.LocalPriceCache::Dispose()][LocalPriceCache:Dispose] End +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:10 PM] [MarketData.Cache.GBPriceCache::Dispose()][GBPriceCache:Dispose]Thread state is 'WaitSleepJoin'. Joining main thread... +[Thread=31][TRACE.VERBOSE][6/18/2025 7:00:11 PM] [MarketData.Cache.GBPriceCache::ThreadProc()][GBPriceCache:ThreadProc]Thread ended. +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:11 PM] [MarketData.Cache.GBPriceCache::Dispose()][GBPriceCache:Dispose] End. +[Thread=1][TRACE.DEBUG][6/18/2025 7:00:11 PM] [PortfolioManager.ViewModels.MainWindowViewModel::OnDispose()][MainWindowViewModel:OnDispose] LEAVE +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:11 PM] [PortfolioManager.Program::Main(args)]There were 46 threads still running at application shutdown. +[Thread=1][TRACE.VERBOSE][6/18/2025 7:00:11 PM] [PortfolioManager.Program::Main(args)][MAIN:EXIT] +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:34 PM] [PortfolioManager.Program::Main(args)][MAIN:STARTING] +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:34 PM] [PortfolioManager.Program::Main(args)]Using portfolio_data at Adrastea +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:34 PM] [PortfolioManager.Program::Main(args)]Using market_data at Adrastea +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:34 PM] [PortfolioManager.Program::Main(args)]Using user_data at Adrastea +[Thread=6][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass43_0::b__0()]BollingerBandViewModel::Initialize() +[Thread=9][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass43_0::b__0()]BollingerBandViewModel::Initialize() +[Thread=8][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass43_0::b__0()]BollingerBandViewModel::Initialize() +[Thread=17][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass84_0::b__0()]BollingerBandViewModel::SetSaveParameters('NRG','Valuations','360') +[Thread=18][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass84_0::b__0()]BollingerBandViewModel::SetSaveParameters('DBX','Valuations','180') +[Thread=19][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass84_0::b__0()]BollingerBandViewModel::SetSaveParameters('CRS','Valuations','90') +[Thread=18][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass86_0::b__0()]OnViewModelPropertyChanged(SelectedSymbol). Selected symbol 'DBX' +[Thread=19][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass86_0::b__0()]OnViewModelPropertyChanged(SelectedSymbol). Selected symbol 'CRS' +[Thread=17][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [PortfolioManager.ViewModels.BollingerBandViewModel+<>c__DisplayClass86_0::b__0()]OnViewModelPropertyChanged(SelectedSymbol). Selected symbol 'NRG' +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for SXT on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for RGLD on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for PSO on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for TSCDY on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for DBX on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for NRG on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for OPRA on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:35 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]Done, total took 595(ms) +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:36 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for SXT on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:36 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for RGLD on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:36 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for PSO on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:37 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for TSCDY on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:37 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for DBX on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:37 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for NRG on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:37 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]No price for OPRA on 6/18/2025 +[Thread=16][TRACE.VERBOSE][6/18/2025 7:01:37 PM] [MarketData.Generator.MGSHMomentum.MGSHMomentumBacktest::GetModelPerformance(sessionParams)]Done, total took 420(ms) +[Thread=15][TRACE.VERBOSE][6/18/2025 7:01:38 PM] [MarketData.Generator.CMTrend.CMTTrendModel::GetModelPerformance(sessionParams)]******************* No price for SPOT on 6/18/2025 ***************** +[Thread=15][TRACE.VERBOSE][6/18/2025 7:01:38 PM] [MarketData.Generator.CMTrend.CMTTrendModel::GetModelPerformance(sessionParams)]Done, total took 2988(ms) +[Thread=12][TRACE.VERBOSE][6/18/2025 7:01:38 PM] [MarketData.Generator.CMMomentum.CMMomentumBacktest::GetModelPerformance(sessionParams)]No price for IEFA on 6/18/2025 +[Thread=12][TRACE.VERBOSE][6/18/2025 7:01:38 PM] [MarketData.Generator.CMMomentum.CMMomentumBacktest::GetModelPerformance(sessionParams)]Done, took 3266(ms) +[Thread=12][TRACE.VERBOSE][6/18/2025 7:01:38 PM] [MarketData.Generator.CMMomentum.CMMomentumBacktest::GetModelPerformance(sessionParams)]No price for IEFA on 6/18/2025 +[Thread=12][TRACE.VERBOSE][6/18/2025 7:01:38 PM] [MarketData.Generator.CMMomentum.CMMomentumBacktest::GetModelPerformance(sessionParams)]Done, took 38(ms) +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for PSO on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for IDA on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for TSCDY on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for MD on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for DORM on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for PRIM on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for MO on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for HURN on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for DRD on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]Done, total took 3953(ms) +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for PSO on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for IDA on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for TSCDY on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for MD on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for DORM on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for PRIM on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for MO on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for HURN on 6/18/2025 +[Thread=15][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.CMTrend.CMTTrendModel::GetModelPerformance(sessionParams)]******************* No price for SPOT on 6/18/2025 ***************** +[Thread=15][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.CMTrend.CMTTrendModel::GetModelPerformance(sessionParams)]Done, total took 12(ms) +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]No price for DRD on 6/18/2025 +[Thread=10][TRACE.VERBOSE][6/18/2025 7:01:39 PM] [MarketData.Generator.Momentum.MomentumBacktest::GetModelPerformance(sessionParams)]Done, total took 71(ms) +[Thread=1][TRACE.DEBUG][6/18/2025 7:01:47 PM] [PortfolioManager.Cache.ImageCache::.ctor()]Reading assets from C:\Avalonia\PortfolioManager/Assets +[Thread=1][TRACE.DEBUG][6/18/2025 7:01:49 PM] [PortfolioManager.App+<>c__DisplayClass1_1::b__1(,)]App: Received ClosingHandler event +[Thread=1][TRACE.DEBUG][6/18/2025 7:01:49 PM] [PortfolioManager.ViewModels.MainWindowViewModel::OnDispose()][MainWindowViewModel:OnDispose] +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:49 PM] [PortfolioManager.ViewModels.MomentumViewModel::OnDispose()]Dispose MomentumViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:49 PM] [PortfolioManager.ViewModels.CMMomentumViewModel::OnDispose()]Dispose CMMomentumViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:49 PM] [PortfolioManager.ViewModels.CMTrendViewModel::OnDispose()]Dispose CMTrendViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:49 PM] [PortfolioManager.ViewModels.MGSHMomentumViewModel::OnDispose()]Dispose MGSHMomentumViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:49 PM] [PortfolioManager.ViewModels.BollingerBandViewModel::OnDispose()]Dispose BollingerBandViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:49 PM] [PortfolioManager.ViewModels.BollingerBandViewModel::OnDispose()]Dispose BollingerBandViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:49 PM] [PortfolioManager.ViewModels.BollingerBandViewModel::OnDispose()]Dispose BollingerBandViewModel +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:49 PM] [MarketData.Cache.LocalPriceCache::Dispose()][LocalPriceCache:Dispose]Thread state is 'WaitSleepJoin'. Joining main thread... +[Thread=28][TRACE.VERBOSE][6/18/2025 7:01:49 PM] [MarketData.Cache.LocalPriceCache::ThreadProc()][LocalPriceCache:ThreadProc] Thread ended. Items in cache:0 +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:49 PM] [MarketData.Cache.LocalPriceCache::Dispose()][LocalPriceCache:Dispose] End +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:49 PM] [MarketData.Cache.GBPriceCache::Dispose()][GBPriceCache:Dispose]Thread state is 'WaitSleepJoin'. Joining main thread... +[Thread=31][TRACE.VERBOSE][6/18/2025 7:01:50 PM] [MarketData.Cache.GBPriceCache::ThreadProc()][GBPriceCache:ThreadProc]Thread ended. +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:50 PM] [MarketData.Cache.GBPriceCache::Dispose()][GBPriceCache:Dispose] End. +[Thread=1][TRACE.DEBUG][6/18/2025 7:01:50 PM] [PortfolioManager.ViewModels.MainWindowViewModel::OnDispose()][MainWindowViewModel:OnDispose] LEAVE +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:50 PM] [PortfolioManager.Program::Main(args)]There were 65 threads still running at application shutdown. +[Thread=1][TRACE.VERBOSE][6/18/2025 7:01:50 PM] [PortfolioManager.Program::Main(args)][MAIN:EXIT]