Commit Latest
This commit is contained in:
@@ -33,12 +33,15 @@ namespace PortfolioManager.Renderers
|
|||||||
|
|
||||||
public class BollingerBandRenderer : ModelBase
|
public class BollingerBandRenderer : ModelBase
|
||||||
{
|
{
|
||||||
|
private String selectedSymbol = default;
|
||||||
|
private int selectedDayCount = int.MinValue;
|
||||||
private Price latestPrice = default;
|
private Price latestPrice = default;
|
||||||
private Price zeroPrice = default;
|
private Price zeroPrice = default;
|
||||||
private bool showLabels = true;
|
private bool showLabels = true;
|
||||||
private bool showMarkers = true;
|
private bool showMarkers = true;
|
||||||
private bool showLegend = false;
|
private bool showLegend = false;
|
||||||
private bool showTradeLabels = true;
|
private bool showTradeLabels = true;
|
||||||
|
private bool showInsiderTransactions = true;
|
||||||
private bool syncTradeToBand = true;
|
private bool syncTradeToBand = true;
|
||||||
private StopLimit stopLimit = default;
|
private StopLimit stopLimit = default;
|
||||||
private StopLimits stopLimits = default;
|
private StopLimits stopLimits = default;
|
||||||
@@ -48,11 +51,14 @@ namespace PortfolioManager.Renderers
|
|||||||
private BollingerBands bollingerBands;
|
private BollingerBands bollingerBands;
|
||||||
private InsiderTransactionSummaries insiderTransactionSummaries = null;
|
private InsiderTransactionSummaries insiderTransactionSummaries = null;
|
||||||
|
|
||||||
double maxBollingerDate = 0.00;
|
// double maxBollingerDate = 0.00;
|
||||||
double minBollingerDate = 0.00;
|
// double minBollingerDate = 0.00;
|
||||||
double spread = 0.00;
|
//double spread = 0.00;
|
||||||
double percentShift3PC = 0.00;
|
double percentShiftHorz3PC = 0.00;
|
||||||
double percentShift1PC = 0.00;
|
double percentShiftHorz1PC = 0.00;
|
||||||
|
double percentShiftVert3PC = 0.00;
|
||||||
|
double percentShiftVert1PC = 0.00;
|
||||||
|
double percentShiftVert5PC = 0.00;
|
||||||
|
|
||||||
public BollingerBandRenderer(AvaPlot plotter)
|
public BollingerBandRenderer(AvaPlot plotter)
|
||||||
{
|
{
|
||||||
@@ -73,6 +79,15 @@ namespace PortfolioManager.Renderers
|
|||||||
if (!ShowLegend) Plotter.Plot.HideLegend();
|
if (!ShowLegend) Plotter.Plot.HideLegend();
|
||||||
else Plotter.Plot.ShowLegend();
|
else Plotter.Plot.ShowLegend();
|
||||||
}
|
}
|
||||||
|
else if (eventArgs.PropertyName.Equals("ShowLegend"))
|
||||||
|
{
|
||||||
|
if (!ShowLegend) Plotter.Plot.HideLegend();
|
||||||
|
else Plotter.Plot.ShowLegend();
|
||||||
|
}
|
||||||
|
else if (eventArgs.PropertyName.Equals("ShowInsiderTransactions"))
|
||||||
|
{
|
||||||
|
SetData(selectedSymbol, selectedDayCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Render()
|
public void Render()
|
||||||
@@ -84,6 +99,8 @@ namespace PortfolioManager.Renderers
|
|||||||
|
|
||||||
public void SetData(String selectedSymbol, int selectedDayCount)
|
public void SetData(String selectedSymbol, int selectedDayCount)
|
||||||
{
|
{
|
||||||
|
this.selectedSymbol = selectedSymbol;
|
||||||
|
this.selectedDayCount = selectedDayCount;
|
||||||
stopLimit = PortfolioDA.GetStopLimit(selectedSymbol);
|
stopLimit = PortfolioDA.GetStopLimit(selectedSymbol);
|
||||||
portfolioTrades = PortfolioDA.GetTradesSymbol(selectedSymbol);
|
portfolioTrades = PortfolioDA.GetTradesSymbol(selectedSymbol);
|
||||||
portfolioTradesLots = LotAggregator.CombineLots(portfolioTrades);
|
portfolioTradesLots = LotAggregator.CombineLots(portfolioTrades);
|
||||||
@@ -129,11 +146,18 @@ namespace PortfolioManager.Renderers
|
|||||||
}
|
}
|
||||||
bollingerBands = BollingerBandGenerator.GenerateBollingerBands(prices);
|
bollingerBands = BollingerBandGenerator.GenerateBollingerBands(prices);
|
||||||
|
|
||||||
maxBollingerDate = bollingerBands.Max(x=>x.Date).ToOADate();
|
double maxBollingerDate = bollingerBands.Max(x=>x.Date).ToOADate();
|
||||||
minBollingerDate = bollingerBands.Min(x=>x.Date).ToOADate();
|
double minBollingerDate = bollingerBands.Min(x=>x.Date).ToOADate();
|
||||||
spread = (maxBollingerDate - minBollingerDate);
|
double maxBollingerValue = bollingerBands.Max(x=>x.K);
|
||||||
percentShift3PC = spread * .03;
|
double minBollingerValue = bollingerBands.Min(x=>x.L);
|
||||||
percentShift1PC = spread * .01;
|
|
||||||
|
double spreadHorz = (maxBollingerDate - minBollingerDate);
|
||||||
|
double spreadVert = (maxBollingerValue - minBollingerValue);
|
||||||
|
percentShiftHorz3PC = spreadHorz * .03;
|
||||||
|
percentShiftHorz1PC = spreadHorz * .01;
|
||||||
|
percentShiftVert3PC = spreadVert * .03;
|
||||||
|
percentShiftVert1PC = spreadVert * .01;
|
||||||
|
percentShiftVert5PC = spreadVert * .05;
|
||||||
|
|
||||||
GenerateBollingerBands();
|
GenerateBollingerBands();
|
||||||
GenerateZeroPoint(zeroPrice);
|
GenerateZeroPoint(zeroPrice);
|
||||||
@@ -233,7 +257,7 @@ namespace PortfolioManager.Renderers
|
|||||||
|
|
||||||
Image image = TextMarkerImageGenerator.GenerateImage(sb.ToString(), 155, 24, FontFactor.FontSize);
|
Image image = TextMarkerImageGenerator.GenerateImage(sb.ToString(), 155, 24, FontFactor.FontSize);
|
||||||
// Coordinates coordinates = new Coordinates(latestPrice.Date.ToOADate()/(1+onePercent), stopLimit.StopPrice - 5.00);
|
// Coordinates coordinates = new Coordinates(latestPrice.Date.ToOADate()/(1+onePercent), stopLimit.StopPrice - 5.00);
|
||||||
Coordinates coordinates = new Coordinates(latestPrice.Date.ToOADate()-percentShift3PC, stopLimit.StopPrice - 5.00);
|
Coordinates coordinates = new Coordinates(latestPrice.Date.ToOADate()-percentShiftHorz3PC, stopLimit.StopPrice - 5.00);
|
||||||
ImageMarker imageMarker = Plotter.Plot.Add.ImageMarker(coordinates, image);
|
ImageMarker imageMarker = Plotter.Plot.Add.ImageMarker(coordinates, image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,7 +269,6 @@ namespace PortfolioManager.Renderers
|
|||||||
{
|
{
|
||||||
if (null == portfolioTradesLots || 0 == portfolioTradesLots.Count || !showTradeLabels) return;
|
if (null == portfolioTradesLots || 0 == portfolioTradesLots.Count || !showTradeLabels) return;
|
||||||
// Here we add the image markers
|
// Here we add the image markers
|
||||||
|
|
||||||
Image tradePointMarker = TextMarkerImageGenerator.ToSPImage(ImageCache.GetInstance().GetImage(ImageCache.ImageType.YellowTriangleUp));
|
Image tradePointMarker = TextMarkerImageGenerator.ToSPImage(ImageCache.GetInstance().GetImage(ImageCache.ImageType.YellowTriangleUp));
|
||||||
for (int index = 0; index < portfolioTradesLots.Count; index++)
|
for (int index = 0; index < portfolioTradesLots.Count; index++)
|
||||||
{
|
{
|
||||||
@@ -265,7 +288,7 @@ namespace PortfolioManager.Renderers
|
|||||||
sb.Append(Utility.FormatCurrency(portfolioTrade.Price));
|
sb.Append(Utility.FormatCurrency(portfolioTrade.Price));
|
||||||
|
|
||||||
Image image = TextMarkerImageGenerator.GenerateImage(sb.ToString(), 150, 24, FontFactor.FontSize);
|
Image image = TextMarkerImageGenerator.GenerateImage(sb.ToString(), 150, 24, FontFactor.FontSize);
|
||||||
Coordinates coordinates = new Coordinates(portfolioTrade.TradeDate.ToOADate(), portfolioTrade.Price - 5.00);
|
Coordinates coordinates = new Coordinates(portfolioTrade.TradeDate.ToOADate(), portfolioTrade.Price - percentShiftVert5PC);
|
||||||
ImageMarker imageMarker = Plotter.Plot.Add.ImageMarker(coordinates, image);
|
ImageMarker imageMarker = Plotter.Plot.Add.ImageMarker(coordinates, image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,7 +298,7 @@ namespace PortfolioManager.Renderers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void GenerateInsiderTransactions()
|
private void GenerateInsiderTransactions()
|
||||||
{
|
{
|
||||||
if (null == prices || 0 == prices.Count || !ShowMarkers) return;
|
if (null == prices || 0 == prices.Count || !ShowInsiderTransactions) return;
|
||||||
ImageMarker imageMarker = default;
|
ImageMarker imageMarker = default;
|
||||||
Coordinates coordinates = default;
|
Coordinates coordinates = default;
|
||||||
|
|
||||||
@@ -512,6 +535,19 @@ namespace PortfolioManager.Renderers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool ShowInsiderTransactions
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return showInsiderTransactions;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
showInsiderTransactions = value;
|
||||||
|
base.OnPropertyChanged("ShowInsiderTransactions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public AvaPlot Plotter { get; private set; }
|
public AvaPlot Plotter { get; private set; }
|
||||||
|
|
||||||
private CompositeDataSource InsiderTransactionPointDisposedSmall { get; set; } = Empty();
|
private CompositeDataSource InsiderTransactionPointDisposedSmall { get; set; } = Empty();
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ namespace PortfolioManager.ViewModels
|
|||||||
|
|
||||||
public abstract class PlotterWorkspaceViewModel : WorkspaceViewModel
|
public abstract class PlotterWorkspaceViewModel : WorkspaceViewModel
|
||||||
{
|
{
|
||||||
|
public AvaPlot Plotter { get; set; }
|
||||||
|
|
||||||
public EventHandler<PlotterLoadedEventArgs> OnPlotterLoadedEventHandler;
|
public EventHandler<PlotterLoadedEventArgs> OnPlotterLoadedEventHandler;
|
||||||
|
|
||||||
public void OnPlotterLoaded(AvaPlot avaPlot)
|
public void OnPlotterLoaded(AvaPlot avaPlot)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.ComponentModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using MarketData;
|
using MarketData;
|
||||||
using MarketData.Cache;
|
using MarketData.Cache;
|
||||||
@@ -17,245 +18,279 @@ using ScottPlot.Avalonia;
|
|||||||
|
|
||||||
namespace PortfolioManager.ViewModels
|
namespace PortfolioManager.ViewModels
|
||||||
{
|
{
|
||||||
public partial class ScottPlotViewModel : PlotterWorkspaceViewModel
|
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()
|
|
||||||
{
|
{
|
||||||
DisplayName = "Bollinger";
|
// private AvaPlot plotter = default;
|
||||||
Plotter = new AvaPlot();
|
private List<String> watchListNames;
|
||||||
base.OnPropertyChanged("Plotter");
|
private String selectedWatchList;
|
||||||
OnPlotterLoadedEventHandler += PlotterLoadedEvent;
|
private ObservableCollection<String> symbols = new ObservableCollection<String>();
|
||||||
PropertyChanged += OnViewModelPropertyChanged;
|
private List<Int32> dayCounts = new int[] { 60, 90, 180, 360, 720, 1440, 3600 }.ToList<int>();
|
||||||
Initialize();
|
private int selectedDayCount = 90;
|
||||||
}
|
private bool isBusy = false;
|
||||||
|
private String selectedSymbol = default;
|
||||||
|
private String companyName = default;
|
||||||
|
BollingerBandRenderer bollingerBandRenderer = default;
|
||||||
|
|
||||||
protected override void OnDispose()
|
public ScottPlotViewModel()
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
base.OnPropertyChanged("Symbols");
|
DisplayName = "Bollinger";
|
||||||
base.OnPropertyChanged("WatchListNames");
|
// Plotter = new AvaPlot();
|
||||||
base.OnPropertyChanged("SelectedWatchList");
|
// base.OnPropertyChanged("Plotter");
|
||||||
|
OnPlotterLoadedEventHandler += PlotterLoadedEvent;
|
||||||
|
PropertyChanged += OnViewModelPropertyChanged;
|
||||||
|
Initialize();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
protected override void OnDispose()
|
||||||
// *******************************************************************************************************************************************
|
|
||||||
/// <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(() =>
|
|
||||||
{
|
{
|
||||||
companyName = PricingDA.GetNameForSymbol(selectedSymbol);
|
MDTrace.WriteLine(LogLevel.DEBUG, $"Dispose BollingerBandViewModel");
|
||||||
bollingerBandRenderer = new BollingerBandRenderer(Plotter);
|
base.OnDispose();
|
||||||
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
|
private void Initialize(bool executePropertyChanged = true)
|
||||||
{
|
|
||||||
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;
|
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
|
// *******************************************************************************************************************************************
|
||||||
{
|
/// <summary>
|
||||||
get
|
/// 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>
|
||||||
if (null == selectedSymbol) return DisplayName;
|
/// <param name="sender"></param>
|
||||||
return "Bollinger " + "(" + selectedSymbol + ")";
|
/// <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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,10 +61,10 @@
|
|||||||
</ComboBox>
|
</ComboBox>
|
||||||
<Label Content="Day Count" HorizontalAlignment="Left" ></Label>
|
<Label Content="Day Count" HorizontalAlignment="Left" ></Label>
|
||||||
<ComboBox ItemsSource="{Binding Path=DayCounts, Mode=OneWay}" SelectedItem="{Binding Path=SelectedDayCount}"/>
|
<ComboBox ItemsSource="{Binding Path=DayCounts, Mode=OneWay}" SelectedItem="{Binding Path=SelectedDayCount}"/>
|
||||||
<!-- <Button Content="Refresh" HorizontalAlignment="Stretch" Command="{Binding Path=Refresh}"></Button>
|
<Button Content="Refresh" HorizontalAlignment="Stretch" Command="{Binding Path=Refresh}"></Button>
|
||||||
<CheckBox Content="Sync Trade To Band" IsChecked="{Binding Mode=TwoWay,Path=SyncTradeToBand}" HorizontalAlignment="Stretch" />
|
<CheckBox Content="Sync Trade To Band" IsChecked="{Binding Mode=TwoWay,Path=SyncTradeToBand}" HorizontalAlignment="Stretch" />
|
||||||
<CheckBox Content="Show Trade Labels" IsChecked="{Binding Mode=TwoWay,Path=ShowTradeLabels}" HorizontalAlignment="Stretch" />
|
<CheckBox Content="Show Trade Labels" IsChecked="{Binding Mode=TwoWay,Path=ShowTradeLabels}" HorizontalAlignment="Stretch" />
|
||||||
<CheckBox Content="Show Insider Transactions" IsChecked="{Binding Mode=TwoWay,Path=CheckBoxShowInsiderTransactions}" HorizontalAlignment="Stretch" /> -->
|
<CheckBox Content="Show Insider Transactions" IsChecked="{Binding Mode=TwoWay,Path=CheckBoxShowInsiderTransactions}" HorizontalAlignment="Stretch" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|||||||
@@ -10,23 +10,23 @@ namespace PortfolioManager.Views;
|
|||||||
|
|
||||||
public partial class ScottPlotView : UserControl
|
public partial class ScottPlotView : UserControl
|
||||||
{
|
{
|
||||||
// private AvaPlot avaPlot = default;
|
public ScottPlotView()
|
||||||
public ScottPlotView()
|
{
|
||||||
{
|
this.DataContextChanged += OnDataContextChanged;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AvaPlot_Loaded(object sender, RoutedEventArgs e)
|
private void OnDataContextChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (default != (sender as ScottPlotView))
|
||||||
{
|
{
|
||||||
// This code will execute when the AvaPlot is loaded
|
ScottPlotView view = (sender as ScottPlotView);
|
||||||
// if (sender is ScottPlot.Avalonia.AvaPlot)
|
PlotterWorkspaceViewModel viewModel = (DataContext as PlotterWorkspaceViewModel);
|
||||||
// {
|
if (default == viewModel.Plotter)
|
||||||
// if (default == avaPlot)
|
{
|
||||||
// {
|
viewModel.Plotter = new AvaPlot();
|
||||||
// PlotterWorkspaceViewModel viewModel = (DataContext as PlotterWorkspaceViewModel);
|
viewModel.OnPlotterLoaded(viewModel.Plotter);
|
||||||
// avaPlot = this.Find<AvaPlot>("AvaPlot");
|
}
|
||||||
// viewModel.OnPlotterLoaded(avaPlot);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user