More changes for BollingerBands.

This commit is contained in:
2025-06-16 19:59:04 -04:00
parent a46d507c7a
commit e8d3f68b3d
11 changed files with 117 additions and 77 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -10,7 +10,8 @@ namespace PortfolioManager.Cache
{
public class ImageCache : IDisposable
{
public enum ImageType {BlueTriangleUp,GreenTriangleUp,GreenTriangleDown,RedTriangleUp,RedTriangleDown,YellowTriangleUp }
public enum ImageType {BlueTriangleUp,GreenTriangleUp,GreenTriangleDown,RedTriangleUp,RedTriangleDown,YellowTriangleUp,
OrangeTriangleUp, AmberTriangleUp,MagentaTriangleUp, DarkBlueTriangleUp}
private Dictionary<ImageType,Bitmap> imageCache = new Dictionary<ImageType,Bitmap>();
private Object thisLock=new Object();
private static ImageCache imageCacheInstance=null;
@@ -27,13 +28,17 @@ namespace PortfolioManager.Cache
{
pathToAssets = currentDirectory + "/Assets";
}
MDTrace.WriteLine(LogLevel.DEBUG,$"Reading assets from {pathToAssets}");
imageCache.Add(ImageCache.ImageType.BlueTriangleUp,new Bitmap(pathToAssets+"/BlueTriangleUp.png"));
imageCache.Add(ImageCache.ImageType.GreenTriangleUp,new Bitmap(pathToAssets+"/GreenTriangleUp.png"));
imageCache.Add(ImageCache.ImageType.GreenTriangleDown,new Bitmap(pathToAssets+"/GreenTriangleDown.png"));
imageCache.Add(ImageCache.ImageType.RedTriangleUp,new Bitmap(pathToAssets+"/RedTriangleUp.png"));
imageCache.Add(ImageCache.ImageType.RedTriangleDown,new Bitmap(pathToAssets+"/RedTriangleDown.png"));
imageCache.Add(ImageCache.ImageType.YellowTriangleUp,new Bitmap(pathToAssets+"/YellowTriangleUp.png"));
MDTrace.WriteLine(LogLevel.DEBUG, $"Reading assets from {pathToAssets}");
imageCache.Add(ImageCache.ImageType.BlueTriangleUp, new Bitmap(pathToAssets + "/BlueTriangleUp.png"));
imageCache.Add(ImageCache.ImageType.GreenTriangleUp, new Bitmap(pathToAssets + "/GreenTriangleUp.png"));
imageCache.Add(ImageCache.ImageType.GreenTriangleDown, new Bitmap(pathToAssets + "/GreenTriangleDown.png"));
imageCache.Add(ImageCache.ImageType.RedTriangleUp, new Bitmap(pathToAssets + "/RedTriangleUp.png"));
imageCache.Add(ImageCache.ImageType.RedTriangleDown, new Bitmap(pathToAssets + "/RedTriangleDown.png"));
imageCache.Add(ImageCache.ImageType.YellowTriangleUp, new Bitmap(pathToAssets + "/YellowTriangleUp.png"));
imageCache.Add(ImageCache.ImageType.OrangeTriangleUp, new Bitmap(pathToAssets + "/OrangeTriangleUp.png"));
imageCache.Add(ImageCache.ImageType.AmberTriangleUp, new Bitmap(pathToAssets + "/AmberTriangleUp.png"));
imageCache.Add(ImageCache.ImageType.MagentaTriangleUp,new Bitmap(pathToAssets+"/MagentaTriangleUp.png"));
imageCache.Add(ImageCache.ImageType.DarkBlueTriangleUp,new Bitmap(pathToAssets+"/DarkBlueTriangleUp.png"));
}
public static ImageCache GetInstance()

View File

@@ -73,12 +73,12 @@ namespace PortfolioManager.ViewModels
private BollingerBands bollingerBands;
public BollingerBandViewModel()
public BollingerBandViewModel(bool loadedFromParams = false)
{
InitializeDataSources();
PropertyChanged += OnViewModelPropertyChanged;
DisplayName = "Bollinger";
Initialize();
Initialize(loadedFromParams ? false : true);
}
protected override void OnDispose()
@@ -87,11 +87,11 @@ namespace PortfolioManager.ViewModels
base.OnDispose();
}
private void Initialize()
private void Initialize(bool executePropertyChanged=true)
{
Task workerTask = Task.Factory.StartNew(() =>
{
MDTrace.WriteLine(LogLevel.DEBUG, $"WatchListDA.GetWatchLists()");
MDTrace.WriteLine(LogLevel.DEBUG, $"BollingerBandViewModel::Initialize()");
watchListNames = WatchListDA.GetWatchLists();
watchListNames.Insert(0, UIConstants.CONST_ALL);
selectedWatchList = watchListNames.Find(x => x.Equals("Valuations"));
@@ -99,9 +99,12 @@ namespace PortfolioManager.ViewModels
});
workerTask.ContinueWith((continuation) =>
{
base.OnPropertyChanged("Symbols");
base.OnPropertyChanged("WatchListNames");
base.OnPropertyChanged("SelectedWatchList");
if (executePropertyChanged)
{
base.OnPropertyChanged("Symbols");
base.OnPropertyChanged("WatchListNames");
base.OnPropertyChanged("SelectedWatchList");
}
});
}
@@ -192,6 +195,10 @@ namespace PortfolioManager.ViewModels
}
set
{
if (String.IsNullOrEmpty(selectedSymbol))
{
return;
}
selectedSymbol = value;
base.OnPropertyChanged("SelectedSymbol");
}
@@ -325,7 +332,7 @@ namespace PortfolioManager.ViewModels
public override SaveParameters GetSaveParameters()
{
SaveParameters saveParams = new SaveParameters();
if (null == selectedSymbol) return null;
if (String.IsNullOrEmpty(selectedSymbol)) return null;
saveParams.Add(new KeyValuePair<String, String>("Type",GetType().Namespace+"."+GetType().Name));
saveParams.Add(new KeyValuePair<String, String>("SelectedSymbol", selectedSymbol));
saveParams.Add(new KeyValuePair<String, String>("SelectedWatchList", selectedWatchList));
@@ -353,45 +360,56 @@ namespace PortfolioManager.ViewModels
{
try
{
Referer=saveParameters.Referer;
selectedSymbol = (from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("SelectedSymbol") select item).FirstOrDefault().Value;
selectedWatchList = (from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("SelectedWatchList") select item).FirstOrDefault().Value;
base.OnPropertyChanged("SelectedWatchList");
selectedDayCount = Int32.Parse((from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("SelectedDayCount") select item).FirstOrDefault().Value);
try
Task workerTask = Task.Factory.StartNew(() =>
{
if(saveParameters.ContainsKey("SyncTradeToBand"))syncTradeToBand=Boolean.Parse((from KeyValuePair<String,String> item in saveParameters where item.Key.Equals("SyncTradeToBand") select item).FirstOrDefault().Value);
else syncTradeToBand=true;
}
catch (Exception) { syncTradeToBand = true; }
try
{
if(saveParameters.ContainsKey("ShowTradeLabels"))showTradeLabels = Boolean.Parse((from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("ShowTradeLabels") select item).FirstOrDefault().Value);
else showTradeLabels=true;
}
catch (Exception) { showTradeLabels = true; }
try
{
if(saveParameters.ContainsKey("UseLeastSquaresFit"))useLeastSquaresFit=Boolean.Parse((from KeyValuePair<String,String> item in saveParameters where item.Key.Equals("UseLeastSquaresFit") select item).FirstOrDefault().Value);
}
catch (Exception){;}
try
{
if(saveParameters.ContainsKey("ShowInsiderTransactions"))showInsiderTransactions=Boolean.Parse((from KeyValuePair<String,String> item in saveParameters where item.Key.Equals("ShowInsiderTransactions") select item).FirstOrDefault().Value);
}
catch (Exception){;}
try
{
if(saveParameters.ContainsKey("StopHistoryCount"))
Referer = saveParameters.Referer;
selectedSymbol = (from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("SelectedSymbol") select item).FirstOrDefault().Value;
selectedWatchList = (from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("SelectedWatchList") select item).FirstOrDefault().Value;
selectedDayCount = Int32.Parse((from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("SelectedDayCount") select item).FirstOrDefault().Value);
MDTrace.WriteLine(LogLevel.DEBUG, $"BollingerBandViewModel::SetSaveParameters('{selectedSymbol}','{selectedWatchList}','{selectedDayCount}')");
try
{
stopLimits = StopLimitsExtensions.FromSaveParams(saveParameters);
if (saveParameters.ContainsKey("SyncTradeToBand")) syncTradeToBand = Boolean.Parse((from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("SyncTradeToBand") select item).FirstOrDefault().Value);
else syncTradeToBand = true;
}
}
catch(Exception exception)
catch (Exception) { syncTradeToBand = true; }
try
{
if (saveParameters.ContainsKey("ShowTradeLabels")) showTradeLabels = Boolean.Parse((from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("ShowTradeLabels") select item).FirstOrDefault().Value);
else showTradeLabels = true;
}
catch (Exception) { showTradeLabels = true; }
try
{
if (saveParameters.ContainsKey("UseLeastSquaresFit")) useLeastSquaresFit = Boolean.Parse((from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("UseLeastSquaresFit") select item).FirstOrDefault().Value);
}
catch (Exception) {; }
try
{
if (saveParameters.ContainsKey("ShowInsiderTransactions")) showInsiderTransactions = Boolean.Parse((from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("ShowInsiderTransactions") select item).FirstOrDefault().Value);
}
catch (Exception) {; }
try
{
if (saveParameters.ContainsKey("StopHistoryCount"))
{
stopLimits = StopLimitsExtensions.FromSaveParams(saveParameters);
}
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Exception:{0}", exception.ToString()));
}
// base.OnPropertyChanged("SelectedWatchList");
// base.OnPropertyChanged("SelectedSymbol");
});
workerTask.ContinueWith((continuation) =>
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString()));
}
base.OnPropertyChanged("SelectedSymbol");
base.OnPropertyChanged("SelectedWatchList");
base.OnPropertyChanged("SelectedSymbol");
});
}
catch (Exception)
{
@@ -409,22 +427,24 @@ namespace PortfolioManager.ViewModels
// *************************************************************************************************************************************
private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs)
{
if (eventArgs.PropertyName.Equals("SelectedSymbol"))
if (eventArgs.PropertyName.Equals("SelectedSymbol") && !String.IsNullOrEmpty(selectedSymbol))
{
InitializeDataSources();
InitializeData();
}
if (eventArgs.PropertyName.Equals("SyncTradeToBand") ||
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") && null != selectedSymbol))
eventArgs.PropertyName.Equals("SelectedDayCount"))
&& !String.IsNullOrEmpty(selectedSymbol))
{
IsBusy = true;
Task workerTask = Task.Factory.StartNew(() =>
{
MDTrace.WriteLine(LogLevel.DEBUG,$"OnViewModelPropertyChanged({eventArgs.PropertyName}). Selected symbol '{selectedSymbol}'");
base.DisplayName = "Bollinger(" + selectedSymbol + ")";
base.OnPropertyChanged("DisplayName");
stopLimit = PortfolioDA.GetStopLimit(selectedSymbol);
@@ -474,7 +494,6 @@ namespace PortfolioManager.ViewModels
});
workerTask.ContinueWith((continuation) =>
{
IsBusy = false;
base.OnPropertyChanged("K");
base.OnPropertyChanged("KL1");
base.OnPropertyChanged("L");
@@ -511,6 +530,7 @@ namespace PortfolioManager.ViewModels
base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredSmall");
base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredMedium");
base.OnPropertyChanged("InsiderTransactionPointMarkersAcquiredLarge");
IsBusy = false;
});
}
else if (eventArgs.PropertyName.Equals("SelectedWatchList"))
@@ -719,7 +739,7 @@ namespace PortfolioManager.ViewModels
get
{
if (!showTradeLabels) return null;
return ImageCache.GetInstance().GetImage(ImageCache.ImageType.YellowTriangleUp);
return ImageCache.GetInstance().GetImage(ImageCache.ImageType.DarkBlueTriangleUp);
}
}

View File

@@ -750,21 +750,20 @@ namespace PortfolioManager.ViewModels
}
}
[RelayCommand]
[RelayCommand(CanExecute = nameof(CanExecuteBollingerBand))]
public async Task BollingerBands()
{
if (null == selectedGainLossSummaryItem) return;
SaveParameters saveParams = SaveParameters.Parse("Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180,SyncTradeToBand,FALSE");
saveParams.Referer = this;
WorkspaceInstantiator.Invoke(saveParams);
await Task.FromResult(true);
}
// await Task.FromResult(() =>
// {
// SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.BollingerBandViewModel,SelectedSymbol," + selectedGainLossSummaryItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180,SyncTradeToBand,FALSE");
// saveParams.Referer = this;
// WorkspaceInstantiator.Invoke(saveParams);
// });
}
public bool CanExecuteBollingerBand()
{
return selectedGainLossSummaryItem == default ? false : true;
}
// ****************************************************** T O O L T I P S *********************************************************
public String DollarChangePercent

View File

@@ -112,6 +112,7 @@ namespace PortfolioManager.ViewModels
get
{
ObservableCollection<MenuItem> collection = new ObservableCollection<MenuItem>();
collection.Add(new MenuItem() { Header = "Bollinger Bands...", Command = BollingerBandsCommand, StaysOpenOnClick = false });
collection.Add(new MenuItem() { Header = "Close Position...", Command = CloseCommand, StaysOpenOnClick = false });
collection.Add(new MenuItem() { Header = "Edit Position...", Command = EditCommand, StaysOpenOnClick = false });
collection.Add(new MenuItem() { Header = "Add To WatchList", Command = AddToWatchListCommand, StaysOpenOnClick = false });
@@ -122,6 +123,12 @@ namespace PortfolioManager.ViewModels
// ********************************************************************* R E L A Y S *****************************************************************
[RelayCommand(CanExecute = nameof(CanExecuteBollingerBands))]
public async Task BollingerBands()
{
await ExecuteBollingerBands();
}
[RelayCommand(CanExecute = nameof(CanClosePosition))]
public async Task Close()
{
@@ -140,6 +147,12 @@ namespace PortfolioManager.ViewModels
await OpenEditDialog();
}
public bool CanExecuteBollingerBands()
{
if (null == selectedPosition || null == selectedPosition.Symbol) return false;
return true;
}
public bool CanEdit()
{
if (null == selectedPosition || null == selectedPosition.Symbol || !Utility.IsEpoch(selectedPosition.SellDate)) return false;
@@ -164,6 +177,14 @@ namespace PortfolioManager.ViewModels
await ReloadTradeFile();
}
public async Task ExecuteBollingerBands()
{
SaveParameters saveParams = SaveParameters.Parse("Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol," + selectedPosition.Symbol + ",SelectedWatchList,{All},SelectedDayCount,360");
saveParams.Referer=this;
WorkspaceInstantiator.Invoke(saveParams);
await Task.FromResult(true);
}
public async Task ReloadTradeFile()
{
LoadSessionFile();

View File

@@ -82,7 +82,7 @@
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize="16" Text="{Binding Path=GraphTitle}" HorizontalAlignment="Center"></TextBlock>
<mxc:CartesianChart Grid.Row="1">
<mxc:CartesianChart Grid.Row="1" >
<mxc:CartesianChart.AxesY>
<mxc:AxisY Title="Price" >
@@ -91,7 +91,7 @@
</mxc:CartesianChart.AxesY>
<mxc:CartesianChart.AxesX>
<mxc:AxisX />
<mxc:AxisX Title="Date"/>
</mxc:CartesianChart.AxesX>
<mxc:CartesianChart.Series>

View File

@@ -1,7 +1,7 @@
{
"market_data" : "Database=market_data;Datasource=10.0.0.199;Username=guest;Password=guest",
"portfolio_data" : "Database=portfolio_data;Datasource=10.0.0.199;Username=guest;Password=guest",
"user_data" : "Database=user_data;Datasource=10.0.0.199;Username=guest;Password=guest",
"market_data" : "Database=market_data;Datasource=Adrastea;Username=guest;Password=guest",
"portfolio_data" : "Database=portfolio_data;Datasource=Adrastea;Username=guest;Password=guest",
"user_data" : "Database=user_data;Datasource=Adrastea;Username=guest;Password=guest",
"sms_smtpaddress" : "smtp.gmail.com",
"sms_smsusername" : "skessler1964@gmail.com",
"sms_smspassword" : "xjfo isnf gmyi zovr",

View File

@@ -1,11 +1,6 @@
Type,PortfolioManager.ViewModels.MGSHMomentumViewModel,PathFileName,C:\boneyard\marketdata\Sessions\MGSH20250331.TXT
Type,PortfolioManager.ViewModels.MomentumViewModel,PathFileName,C:\boneyard\marketdata\Sessions\MG20180131.TXT
Type,PortfolioManager.ViewModels.CMMomentumViewModel,PathFileName,C:\boneyard\marketdata\Sessions\CM20191031.TXT
Type,PortfolioManager.ViewModels.CMTrendViewModel,PathFileName,C:\boneyard\marketdata\Sessions\CMT20200817.TXT
Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,RNMBY,SelectedWatchList,Valuations,SelectedDayCount,90,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True
Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,JFNNX,SelectedWatchList,Valuations,SelectedDayCount,1440,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True
Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,CRS,SelectedWatchList,Valuations,SelectedDayCount,90,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True
Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,TSCDY,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True
Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,GWRE,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True
Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,SPOT,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True
Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,RGLD,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True
Type,PortfolioManager.ViewModels.MGSHMomentumViewModel,PathFileName,C:\boneyard\marketdata\Sessions\MGSH20250331.TXT
Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,NRG,SelectedWatchList,Valuations,SelectedDayCount,360,SyncTradeToBand,True,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True
Type,PortfolioManager.ViewModels.BollingerBandViewModel,SelectedSymbol,DBX,SelectedWatchList,Valuations,SelectedDayCount,180,SyncTradeToBand,False,ShowTradeLabels,True,UseLeastSquaresFit,True,ShowInsiderTransactions,True