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]