Commit Latest
This commit is contained in:
@@ -10,6 +10,8 @@ namespace PortfolioManager.ViewModels
|
||||
|
||||
public abstract class PlotterWorkspaceViewModel : WorkspaceViewModel
|
||||
{
|
||||
public AvaPlot Plotter { get; set; }
|
||||
|
||||
public EventHandler<PlotterLoadedEventArgs> OnPlotterLoadedEventHandler;
|
||||
|
||||
public void OnPlotterLoaded(AvaPlot avaPlot)
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using DynamicData;
|
||||
using MarketData;
|
||||
using MarketData.Cache;
|
||||
@@ -17,245 +18,279 @@ using ScottPlot.Avalonia;
|
||||
|
||||
namespace PortfolioManager.ViewModels
|
||||
{
|
||||
public partial class ScottPlotViewModel : PlotterWorkspaceViewModel
|
||||
{
|
||||
// private AvaPlot plotter = default;
|
||||
private List<String> watchListNames;
|
||||
private String selectedWatchList;
|
||||
private ObservableCollection<String> symbols = new ObservableCollection<String>();
|
||||
private List<Int32> dayCounts = new int[] { 60, 90, 180, 360, 720, 1440, 3600 }.ToList<int>();
|
||||
private int selectedDayCount = 90;
|
||||
private bool isBusy = false;
|
||||
private String selectedSymbol = default;
|
||||
private String companyName = default;
|
||||
BollingerBandRenderer bollingerBandRenderer = default;
|
||||
|
||||
public ScottPlotViewModel()
|
||||
public partial class ScottPlotViewModel : PlotterWorkspaceViewModel
|
||||
{
|
||||
DisplayName = "Bollinger";
|
||||
Plotter = new AvaPlot();
|
||||
base.OnPropertyChanged("Plotter");
|
||||
OnPlotterLoadedEventHandler += PlotterLoadedEvent;
|
||||
PropertyChanged += OnViewModelPropertyChanged;
|
||||
Initialize();
|
||||
}
|
||||
// private AvaPlot plotter = default;
|
||||
private List<String> watchListNames;
|
||||
private String selectedWatchList;
|
||||
private ObservableCollection<String> symbols = new ObservableCollection<String>();
|
||||
private List<Int32> dayCounts = new int[] { 60, 90, 180, 360, 720, 1440, 3600 }.ToList<int>();
|
||||
private int selectedDayCount = 90;
|
||||
private bool isBusy = false;
|
||||
private String selectedSymbol = default;
|
||||
private String companyName = default;
|
||||
BollingerBandRenderer bollingerBandRenderer = default;
|
||||
|
||||
protected override void OnDispose()
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG, $"Dispose BollingerBandViewModel");
|
||||
base.OnDispose();
|
||||
}
|
||||
|
||||
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)
|
||||
public ScottPlotViewModel()
|
||||
{
|
||||
base.OnPropertyChanged("Symbols");
|
||||
base.OnPropertyChanged("WatchListNames");
|
||||
base.OnPropertyChanged("SelectedWatchList");
|
||||
DisplayName = "Bollinger";
|
||||
// Plotter = new AvaPlot();
|
||||
// base.OnPropertyChanged("Plotter");
|
||||
OnPlotterLoadedEventHandler += PlotterLoadedEvent;
|
||||
PropertyChanged += OnViewModelPropertyChanged;
|
||||
Initialize();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// *******************************************************************************************************************************************
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
public void PlotterLoadedEvent(object sender, PlotterLoadedEventArgs e)
|
||||
{
|
||||
// Plotter = e.AvaPlot;
|
||||
// Plotter.Plot.Clear();
|
||||
// Plotter.Refresh();
|
||||
// base.OnPropertyChanged("SelectedSymbol");
|
||||
// MDTrace.WriteLine(LogLevel.DEBUG,$"SelectedSymbol:{selectedSymbol}");
|
||||
// if (default == Plotter)
|
||||
// {
|
||||
// Plotter = e.AvaPlot;
|
||||
// Plotter.Plot.Clear();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Plotter = e.AvaPlot;
|
||||
// Plotter.Plot.Clear();
|
||||
// base.OnPropertyChanged("SelectedSymbol");
|
||||
// }
|
||||
}
|
||||
|
||||
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("LeastSquaresFit") ||
|
||||
eventArgs.PropertyName.Equals("SelectedDayCount"))
|
||||
&& !String.IsNullOrEmpty(selectedSymbol)
|
||||
&& default!=Plotter)
|
||||
{
|
||||
IsBusy = true;
|
||||
Task workerTask = Task.Factory.StartNew(() =>
|
||||
protected override void OnDispose()
|
||||
{
|
||||
companyName = PricingDA.GetNameForSymbol(selectedSymbol);
|
||||
bollingerBandRenderer = new BollingerBandRenderer(Plotter);
|
||||
bollingerBandRenderer.SetData(selectedSymbol, selectedDayCount);
|
||||
bollingerBandRenderer.Render();
|
||||
});
|
||||
workerTask.ContinueWith((continuation) =>
|
||||
{
|
||||
base.OnPropertyChanged("GraphTitle");
|
||||
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;
|
||||
}
|
||||
|
||||
public override void SetSaveParameters(SaveParameters saveParameters)
|
||||
{
|
||||
}
|
||||
|
||||
// ****************************************************** P R O P E R T I E S ************************************************
|
||||
|
||||
public AvaPlot Plotter { get; set; } = default;
|
||||
|
||||
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));
|
||||
MDTrace.WriteLine(LogLevel.DEBUG, $"Dispose BollingerBandViewModel");
|
||||
base.OnDispose();
|
||||
}
|
||||
sb.Append(")");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> WatchListNames
|
||||
{
|
||||
get
|
||||
{
|
||||
return watchListNames;
|
||||
}
|
||||
}
|
||||
|
||||
public String SelectedWatchList
|
||||
{
|
||||
get
|
||||
{
|
||||
return selectedWatchList;
|
||||
}
|
||||
set
|
||||
{
|
||||
selectedWatchList = value;
|
||||
base.OnPropertyChanged("SelectedWatchList");
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<String> Symbols
|
||||
{
|
||||
get
|
||||
{
|
||||
return symbols;
|
||||
}
|
||||
}
|
||||
|
||||
public int SelectedDayCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return selectedDayCount;
|
||||
}
|
||||
set
|
||||
{
|
||||
selectedDayCount = value;
|
||||
base.OnPropertyChanged("SelectedDayCount");
|
||||
}
|
||||
}
|
||||
|
||||
public List<int> DayCounts
|
||||
{
|
||||
get
|
||||
{
|
||||
return dayCounts;
|
||||
}
|
||||
}
|
||||
|
||||
public String SelectedSymbol
|
||||
{
|
||||
get
|
||||
{
|
||||
return selectedSymbol;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (String.IsNullOrEmpty(value))
|
||||
private void Initialize(bool executePropertyChanged = true)
|
||||
{
|
||||
return;
|
||||
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");
|
||||
}
|
||||
});
|
||||
}
|
||||
selectedSymbol = value;
|
||||
base.OnPropertyChanged("SelectedSymbol");
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsBusy
|
||||
{
|
||||
get
|
||||
{
|
||||
return isBusy;
|
||||
}
|
||||
set
|
||||
{
|
||||
isBusy = value;
|
||||
base.OnPropertyChanged("IsBusy");
|
||||
}
|
||||
}
|
||||
|
||||
public override String Title
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == selectedSymbol) return DisplayName;
|
||||
return "Bollinger " + "(" + selectedSymbol + ")";
|
||||
// *******************************************************************************************************************************************
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
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("LeastSquaresFit") ||
|
||||
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.SetData(selectedSymbol, selectedDayCount);
|
||||
bollingerBandRenderer.Render();
|
||||
});
|
||||
workerTask.ContinueWith((continuation) =>
|
||||
{
|
||||
base.OnPropertyChanged("GraphTitle");
|
||||
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;
|
||||
}
|
||||
|
||||
public override void SetSaveParameters(SaveParameters saveParameters)
|
||||
{
|
||||
}
|
||||
|
||||
// ****************************************************** P R O P E R T I E S ************************************************
|
||||
|
||||
// public AvaPlot Plotter { get; set; } = default;
|
||||
|
||||
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<String> WatchListNames
|
||||
{
|
||||
get
|
||||
{
|
||||
return watchListNames;
|
||||
}
|
||||
}
|
||||
|
||||
public String SelectedWatchList
|
||||
{
|
||||
get
|
||||
{
|
||||
return selectedWatchList;
|
||||
}
|
||||
set
|
||||
{
|
||||
selectedWatchList = value;
|
||||
base.OnPropertyChanged("SelectedWatchList");
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<String> Symbols
|
||||
{
|
||||
get
|
||||
{
|
||||
return symbols;
|
||||
}
|
||||
}
|
||||
|
||||
public int SelectedDayCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return selectedDayCount;
|
||||
}
|
||||
set
|
||||
{
|
||||
selectedDayCount = value;
|
||||
base.OnPropertyChanged("SelectedDayCount");
|
||||
}
|
||||
}
|
||||
|
||||
public List<int> 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 override String Title
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == selectedSymbol) return DisplayName;
|
||||
return "Bollinger " + "(" + selectedSymbol + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public bool SyncTradeToBand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == bollingerBandRenderer) return false;
|
||||
return bollingerBandRenderer.SyncTradeToBand;
|
||||
}
|
||||
set
|
||||
{
|
||||
bollingerBandRenderer.SyncTradeToBand = value;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowTradeLabels
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == bollingerBandRenderer) return false;
|
||||
return bollingerBandRenderer.ShowLabels;
|
||||
}
|
||||
set
|
||||
{
|
||||
bollingerBandRenderer.ShowLabels = value;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean CheckBoxShowInsiderTransactions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == bollingerBandRenderer) return false;
|
||||
return bollingerBandRenderer.ShowInsiderTransactions;
|
||||
}
|
||||
set
|
||||
{
|
||||
bollingerBandRenderer.ShowInsiderTransactions = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[RelayCommand]
|
||||
public async Task Refresh()
|
||||
{
|
||||
base.OnPropertyChanged("SelectedSymbol");
|
||||
await Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user