Commit Latest

This commit is contained in:
2025-06-28 20:08:30 -04:00
parent 961eb11e82
commit 0d8402b234
3 changed files with 64 additions and 11 deletions

View File

@@ -70,6 +70,7 @@ namespace PortfolioManager.Renderers
private bool showLegend = false; private bool showLegend = false;
private bool showTradeLabels = true; private bool showTradeLabels = true;
private bool showInsiderTransactions = true; private bool showInsiderTransactions = true;
private bool showLeastSquares = 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;
@@ -103,7 +104,14 @@ namespace PortfolioManager.Renderers
public void Render() public void Render()
{ {
Plotter.Plot.Axes.Left.TickGenerator = new ScottPlot.TickGenerators.NumericAutomatic()
{
LabelFormatter = (double value) => value.ToString("C") // "C" format specifier formats as currency
};
Plotter.Plot.Axes.DateTimeTicksBottom();
Plotter.Plot.Axes.AutoScale(); Plotter.Plot.Axes.AutoScale();
Plotter.Plot.XLabel("Date");
Plotter.Plot.YLabel("Price");
Plotter.Refresh(); Plotter.Refresh();
base.OnPropertyChanged("ShowLegend"); base.OnPropertyChanged("ShowLegend");
} }
@@ -162,6 +170,7 @@ namespace PortfolioManager.Renderers
GenerateStopLimits(); GenerateStopLimits();
GenerateTradePoints(); GenerateTradePoints();
GenerateZeroPoint(zeroPrice); GenerateZeroPoint(zeroPrice);
GenerateLeastSquares();
} }
/// <summary> /// <summary>
@@ -189,6 +198,23 @@ namespace PortfolioManager.Renderers
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset5PC,spreadVert * .05); offsets.Add(OffsetDictionary.OffsetType.VerticalOffset5PC,spreadVert * .05);
} }
/// <summary>
/// Generate LeastSquares line
/// </summary>
private void GenerateLeastSquares()
{
if (null == bollingerBands || !showLeastSquares) return;
LeastSquares = BollingerBandModel.LeastSquares(bollingerBands);
Scatter scatter = default;
{
(DateTime[] dates, double[] values) = LeastSquares.ToXYData();
scatter = Plotter.Plot.Add.ScatterLine(dates, values, ScottPlot.Color.FromSKColor(SKColors.Orange));
scatter.LegendText = "LeastSquares";
scatter.LineWidth = 3;
}
}
/// <summary> /// <summary>
/// Generate the ZeroPoint marker and text /// Generate the ZeroPoint marker and text
/// </summary> /// </summary>
@@ -202,12 +228,12 @@ namespace PortfolioManager.Renderers
ZeroPoint = GainLossModel.Price(zeroPrice); ZeroPoint = GainLossModel.Price(zeroPrice);
(DateTime[] dates, double[] values) = ZeroPoint.ToXYData(); // There is only a single value in this collection (DateTime[] dates, double[] values) = ZeroPoint.ToXYData(); // There is only a single value in this collection
// Place the triangle marker // Place the triangle marker
image = TextMarkerImageGenerator.ToSPImage(ImageCache.GetInstance().GetImage(ImageCache.ImageType.BlueTriangleUp)); image = TextMarkerImageGenerator.ToSPImage(ImageCache.GetInstance().GetImage(ImageCache.ImageType.BlueTriangleUp));
coordinates = new Coordinates(dates[0].ToOADate(), values[0]); coordinates = new Coordinates(dates[0].ToOADate(), values[0]);
imageMarker = Plotter.Plot.Add.ImageMarker(coordinates, image, SizeFactor.Normal); imageMarker = Plotter.Plot.Add.ImageMarker(coordinates, image, SizeFactor.Normal);
// Place the text marker // Place the text marker
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.Append("Even "); sb.Append("Even ");
sb.Append(Utility.FormatCurrency(zeroPrice.Close)); sb.Append(Utility.FormatCurrency(zeroPrice.Close));
@@ -571,6 +597,19 @@ namespace PortfolioManager.Renderers
} }
} }
public bool ShowLeastSquares
{
get
{
return showLeastSquares;
}
set
{
showLeastSquares = value;
base.OnPropertyChanged("ShowLeastSquares");
}
}
public AvaPlot Plotter { get; private set; } public AvaPlot Plotter { get; private set; }
private CompositeDataSource InsiderTransactionPointDisposedSmall { get; set; } = Empty(); private CompositeDataSource InsiderTransactionPointDisposedSmall { get; set; } = Empty();
@@ -590,9 +629,7 @@ namespace PortfolioManager.Renderers
private CompositeDataSource SMAN { get; set; } = Empty(); private CompositeDataSource SMAN { get; set; } = Empty();
private CompositeDataSource Volume { get; set; } = Empty(); private CompositeDataSource Volume { get; set; } = Empty();
private CompositeDataSource LeastSquares { get; set; } = Empty(); private CompositeDataSource LeastSquares { get; set; } = Empty();
private CompositeDataSource ZeroPoint { get; set; } = Empty(); private CompositeDataSource ZeroPoint { get; set; } = Empty();
private CompositeDataSource StopLimits { get; set; } = Empty(); private CompositeDataSource StopLimits { get; set; } = Empty();
private static CompositeDataSource Empty() private static CompositeDataSource Empty()

View File

@@ -30,14 +30,15 @@ namespace PortfolioManager.ViewModels
private bool showInsiderTransactions = true; private bool showInsiderTransactions = true;
private bool showTradeLabels = true; private bool showTradeLabels = true;
private bool syncTradeToBand = true; private bool syncTradeToBand = true;
private bool useLeastSquaresFit = true;
public ScottPlotViewModel() public ScottPlotViewModel()
{ {
DisplayName = "Bollinger"; DisplayName = "Bollinger";
OnPlotterLoadedEventHandler += PlotterLoadedEvent; OnPlotterLoadedEventHandler += PlotterLoadedEvent;
PropertyChanged += OnViewModelPropertyChanged; PropertyChanged += OnViewModelPropertyChanged;
Initialize(); Initialize();
} }
protected override void OnDispose() protected override void OnDispose()
{ {
@@ -102,7 +103,7 @@ namespace PortfolioManager.ViewModels
eventArgs.PropertyName.Equals("ShowTradeLabels") || eventArgs.PropertyName.Equals("ShowTradeLabels") ||
eventArgs.PropertyName.Equals("SelectedSymbol") || eventArgs.PropertyName.Equals("SelectedSymbol") ||
eventArgs.PropertyName.Equals("ShowRiskFree") || eventArgs.PropertyName.Equals("ShowRiskFree") ||
eventArgs.PropertyName.Equals("LeastSquaresFit") || eventArgs.PropertyName.Equals("UseLeastSquaresFit") ||
eventArgs.PropertyName.Equals("CheckBoxShowInsiderTransactions") || eventArgs.PropertyName.Equals("CheckBoxShowInsiderTransactions") ||
eventArgs.PropertyName.Equals("SelectedDayCount")) eventArgs.PropertyName.Equals("SelectedDayCount"))
&& !String.IsNullOrEmpty(selectedSymbol) && !String.IsNullOrEmpty(selectedSymbol)
@@ -113,6 +114,7 @@ namespace PortfolioManager.ViewModels
{ {
companyName = PricingDA.GetNameForSymbol(selectedSymbol); companyName = PricingDA.GetNameForSymbol(selectedSymbol);
bollingerBandRenderer = new BollingerBandRenderer(Plotter); bollingerBandRenderer = new BollingerBandRenderer(Plotter);
bollingerBandRenderer.ShowLeastSquares = useLeastSquaresFit;
bollingerBandRenderer.SyncTradeToBand = syncTradeToBand; bollingerBandRenderer.SyncTradeToBand = syncTradeToBand;
bollingerBandRenderer.ShowInsiderTransactions = showInsiderTransactions; bollingerBandRenderer.ShowInsiderTransactions = showInsiderTransactions;
bollingerBandRenderer.ShowTradeLabels = showTradeLabels; bollingerBandRenderer.ShowTradeLabels = showTradeLabels;
@@ -303,6 +305,19 @@ namespace PortfolioManager.ViewModels
} }
} }
public bool UseLeastSquaresFit
{
get
{
return useLeastSquaresFit;
}
set
{
useLeastSquaresFit = value;
base.OnPropertyChanged("UseLeastSquaresFit");
}
}
public Boolean CheckBoxShowInsiderTransactions public Boolean CheckBoxShowInsiderTransactions
{ {
get get

View File

@@ -62,6 +62,7 @@
<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="Show Least Squares" IsChecked="{Binding Mode=TwoWay,Path=UseLeastSquaresFit}" HorizontalAlignment="Stretch" />
<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" />