Removed Active from StopLimits. The real solution is to have an additional key on the stop limits table in addition to Symbol..like Shares.

This commit is contained in:
2025-12-12 17:25:40 -05:00
parent 247eb8141b
commit 015b6c4dab
6 changed files with 45 additions and 25 deletions

View File

@@ -268,7 +268,7 @@ namespace TradeBlotter.Model
{
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
if(!Utility.IsEpoch(position.LastStopAdjustment)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black); // if we have a trailing stop then we are no longer using the initial stop
StopLimit stopLimit=PortfolioDA.GetStopLimit(position.Symbol);
StopLimit stopLimit=StopLimitDA.GetStopLimit(position.Symbol);
if(null==stopLimit||!stopLimit.StopPrice.Equals(Math.Round(position.InitialStopLimit,2))) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Purple);
if(currentPriceLow<=position.InitialStopLimit) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
@@ -293,7 +293,7 @@ namespace TradeBlotter.Model
{
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
}
StopLimit stopLimit=PortfolioDA.GetStopLimit(position.Symbol);
StopLimit stopLimit=StopLimitDA.GetStopLimit(position.Symbol);
if(null==stopLimit || !stopLimit.StopPrice.Equals(Math.Round(position.TrailingStopLimit,2)))
{
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Purple);

View File

@@ -550,7 +550,7 @@ namespace TradeBlotter.Model
{
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
if(!Utility.IsEpoch(position.LastStopAdjustment)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black); // if we have a trailing stop then we are no longer using the initial stop
StopLimit stopLimit=PortfolioDA.GetStopLimit(position.Symbol);
StopLimit stopLimit=StopLimitDA.GetStopLimit(position.Symbol);
if(null==stopLimit||!stopLimit.StopPrice.Equals(Math.Round(position.InitialStopLimit,2))) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Purple);
if(currentPriceLow<=position.InitialStopLimit) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
@@ -577,7 +577,7 @@ namespace TradeBlotter.Model
{
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
}
StopLimit stopLimit=PortfolioDA.GetStopLimit(position.Symbol);
StopLimit stopLimit=StopLimitDA.GetStopLimit(position.Symbol);
if(null==stopLimit || !stopLimit.StopPrice.Equals(Math.Round(position.TrailingStopLimit,2))) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Purple);
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
}

View File

@@ -238,7 +238,7 @@ namespace TradeBlotter.ViewModels
BusyContent=DATA_MESSAGE;
// DEBUG
stopLimit=PortfolioDA.GetStopLimit(symbol);
stopLimit=StopLimitDA.GetStopLimit(symbol);
portfolioTrades = PortfolioDA.GetTradesSymbol(symbol);
portfolioTradesLots=LotAggregator.CombineLots(portfolioTrades);
if (null != portfolioTrades && 0 != portfolioTrades.Count)

View File

@@ -1069,7 +1069,7 @@ namespace TradeBlotter.ViewModels
{
bool deleteStop=false;
Position clonedPosition=Position.Clone(selectedPosition.Position);
bool hasStopLimit=PortfolioDA.HasStopLimit(clonedPosition.Symbol);
bool hasStopLimit=StopLimitDA.HasStopLimit(clonedPosition.Symbol);
IPosition changedPosition=ClosePositionDialog.Prompt("Close Position",clonedPosition,hasStopLimit,ref deleteStop);
if(null==changedPosition) return;
CMTTrendModel mmTrendModel=new CMTTrendModel();
@@ -1078,7 +1078,7 @@ namespace TradeBlotter.ViewModels
MessageBox.Show("Failed to close the position, check log for details.","Close Position");
return;
}
if(deleteStop) PortfolioDA.DeleteStopLimit(changedPosition.Symbol);
if(deleteStop) StopLimitDA.DeleteStopLimit(changedPosition.Symbol);
String strMessage=String.Format("Closed position for {0}, Purchase Date:{1}, Sell Date{2}, Current Price:{3}, Delete Stop:{4} to {5}. A backup was created.",
changedPosition.Symbol,changedPosition.PurchaseDate.ToShortDateString(),changedPosition.SellDate.ToShortDateString(),Utility.FormatCurrency(changedPosition.CurrentPrice),deleteStop,pathFileName);
MessageBox.Show(strMessage,"Close Position");
@@ -1100,7 +1100,7 @@ namespace TradeBlotter.ViewModels
{
selectedPosition.TrailingStopLimit=changedPosition.TrailingStopLimit;
selectedPosition.LastStopAdjustment=DateTime.Now.Date;
StopLimit stopLimit=PortfolioDA.GetStopLimit(changedPosition.Symbol);
StopLimit stopLimit=StopLimitDA.GetStopLimit(changedPosition.Symbol);
if(null==stopLimit)
{
stopLimit=new StopLimit();
@@ -1109,7 +1109,7 @@ namespace TradeBlotter.ViewModels
stopLimit.Shares=changedPosition.Shares;
}
stopLimit.StopPrice=changedPosition.TrailingStopLimit;
PortfolioDA.InsertUpdateStopLimit(stopLimit);
StopLimitDA.InsertUpdateStopLimit(stopLimit);
}
selectedPosition.PurchaseDate=changedPosition.PurchaseDate;
selectedPosition.PurchasePrice=changedPosition.PurchasePrice;
@@ -1588,7 +1588,7 @@ namespace TradeBlotter.ViewModels
initialStopLimit.StopPrice=selectedPosition.InitialStopLimit;
initialStopLimit.StopType=StopLimitConstants.STOP_QUOTE;
initialStopLimit.EffectiveDate=selectedPosition.PurchaseDate;
initialStopLimit.Active=1;
// initialStopLimit.Active=1;
marketDataModelStopLimits.Add(initialStopLimit);
foreach(MarketData.Generator.Model.StopLimit stopLimit in stopLimits)
@@ -1599,7 +1599,7 @@ namespace TradeBlotter.ViewModels
marketDataModelStopLimit.StopPrice=stopLimit.NewStop;
marketDataModelStopLimit.StopType=StopLimitConstants.STOP_QUOTE;
marketDataModelStopLimit.EffectiveDate=stopLimit.AnalysisDate;
marketDataModelStopLimit.Active=1;
// marketDataModelStopLimit.Active=1;
marketDataModelStopLimits.Add(marketDataModelStopLimit);
}
return marketDataModelStopLimits;

View File

@@ -1057,7 +1057,7 @@ namespace TradeBlotter.ViewModels
{
bool deleteStop=false;
MGSHPosition clonedPosition=MGSHPosition.Clone(selectedPosition.Position);
bool hasStopLimit=PortfolioDA.HasStopLimit(clonedPosition.Symbol);
bool hasStopLimit=StopLimitDA.HasStopLimit(clonedPosition.Symbol);
IPosition changedPosition=ClosePositionDialog.Prompt("Close Position",clonedPosition,hasStopLimit,ref deleteStop);
if(null==changedPosition) return;
MGSHMomentumBacktest mgshMomentumBacktest = new MGSHMomentumBacktest();
@@ -1066,7 +1066,7 @@ namespace TradeBlotter.ViewModels
MessageBox.Show("Failed to close the position, check log for details.","Close Position");
return;
}
if(deleteStop) PortfolioDA.DeleteStopLimit(changedPosition.Symbol);
if(deleteStop) StopLimitDA.DeleteStopLimit(changedPosition.Symbol);
String strMessage=String.Format("Closed position for {0}, Purchase Date:{1}, Sell Date{2}, Current Price:{3}, Delete Stop:{4} to {5}. A backup was created.",
changedPosition.Symbol,changedPosition.PurchaseDate.ToShortDateString(),changedPosition.SellDate.ToShortDateString(),Utility.FormatCurrency(changedPosition.CurrentPrice),deleteStop,pathFileName);
MessageBox.Show(strMessage,"Close Position");
@@ -1088,7 +1088,7 @@ namespace TradeBlotter.ViewModels
{
selectedPosition.TrailingStopLimit = changedPosition.TrailingStopLimit;
selectedPosition.LastStopAdjustment = DateTime.Now.Date;
StopLimit stopLimit = PortfolioDA.GetStopLimit(changedPosition.Symbol);
StopLimit stopLimit = StopLimitDA.GetStopLimit(changedPosition.Symbol);
if (null == stopLimit)
{
stopLimit = new StopLimit();
@@ -1097,7 +1097,7 @@ namespace TradeBlotter.ViewModels
stopLimit.Shares = changedPosition.Shares;
}
stopLimit.StopPrice = changedPosition.TrailingStopLimit;
PortfolioDA.InsertUpdateStopLimit(stopLimit);
StopLimitDA.InsertUpdateStopLimit(stopLimit);
}
selectedPosition.PurchaseDate = changedPosition.PurchaseDate;
selectedPosition.PurchasePrice = changedPosition.PurchasePrice;
@@ -1554,7 +1554,7 @@ namespace TradeBlotter.ViewModels
initialStopLimit.StopPrice = selectedPosition.InitialStopLimit;
initialStopLimit.StopType = StopLimitConstants.STOP_QUOTE;
initialStopLimit.EffectiveDate = selectedPosition.PurchaseDate;
initialStopLimit.Active = 1;
// initialStopLimit.Active = 1;
marketDataModelStopLimits.Add(initialStopLimit);
foreach (MarketData.Generator.Model.StopLimit stopLimit in stopLimits)
@@ -1565,7 +1565,7 @@ namespace TradeBlotter.ViewModels
marketDataModelStopLimit.StopPrice = stopLimit.NewStop;
marketDataModelStopLimit.StopType = StopLimitConstants.STOP_QUOTE;
marketDataModelStopLimit.EffectiveDate = stopLimit.AnalysisDate;
marketDataModelStopLimit.Active = 1;
// marketDataModelStopLimit.Active = 1;
marketDataModelStopLimits.Add(marketDataModelStopLimit);
}

View File

@@ -28,7 +28,7 @@ namespace TradeBlotter.ViewModels
base.DisplayName="TradeEntry";
this.trade=trade;
this.tradeRepository=tradeRepository;
if(PortfolioDA.HasStopLimit(trade.Symbol)) stopLimit=PortfolioDA.GetStopLimit(trade.Symbol);
if(StopLimitDA.HasStopLimit(trade.Symbol)) stopLimit=StopLimitDA.GetStopLimit(trade.Symbol);
PropertyChanged+=OnTradeEntryViewModelPropertyChanged;
UpdateProperties();
}
@@ -249,10 +249,10 @@ namespace TradeBlotter.ViewModels
{
stopLimit=new StopLimit();
stopLimit.Symbol=trade.Symbol;
stopLimit.Shares=trade.Shares;
stopLimit.StopType=StopLimitConstants.STOP_QUOTE;
}
stopLimit.StopPrice=Utility.ParseCurrency(value);
stopLimit.Active=1;
}
base.OnPropertyChanged("StopLimit");
}
@@ -347,21 +347,41 @@ namespace TradeBlotter.ViewModels
base.OnPropertyChanged("TradeId");
base.OnPropertyChanged("DisplayName");
statusText = "Save completed.";
}
else
} else
{
tradeRepository.UpdateTrade(trade);
statusText="Update completed.";
statusText = "Update completed.";
}
UpdateStopLimit();
base.OnPropertyChanged("Status");
}
/// <summary>
/// There is a general problem with StopLimits at this level because the StopLimits table is keyed on Symbol
/// What this means is that we cannot hold two positions for the same security with different stop limits.
/// It also means that when we close one of two positions where one or both of those positions has a stop limit
/// Then we are not quite sure which stop limit to update.
/// The solution would be to key the StopLimit table on the trade.Id as thid would allow us to have a per position stop limit
/// In the interim we do our best here to associate the trade with a given stop limit by matching it to the number of shares.
/// </summary>
private void UpdateStopLimit()
{
// if(null==stopLimit && PortfolioDA.HasStopLimit(trade.Symbol))PortfolioDA.DeleteStopLimit(trade.Symbol);
if(null==stopLimit)PortfolioDA.DeleteStopLimit(trade.Symbol);
else if(null!=stopLimit)PortfolioDA.InsertUpdateStopLimit(stopLimit);
if(trade.IsClosed)
{
if(null!=stopLimit && stopLimit.Shares.Equals(trade.Shares))
{
StopLimitDA.DeleteStopLimit(trade.Symbol);
}
}
else
{
if(null!=stopLimit)
{
StopLimitDA.InsertUpdateStopLimit(stopLimit);
}
}
}
public bool CanSave
{
get