Add ClosePosition log and fix bug in the initial stop limit adjustment where it was possible to adjust a stop limit downwards.

This commit is contained in:
2025-02-11 19:19:05 -05:00
parent 61ab01db83
commit 8090a5e093

View File

@@ -170,6 +170,61 @@ namespace MarketData.Generator.MGSHMomentum
return true;
}
public bool ClosePosition(String symbol,DateTime purchaseDate,DateTime sellDate,double price,String sessionFile)
{
if (!MGSHSessionManager.IsValidSessionFile(sessionFile))
{
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Invalid session file '{0}'.", sessionFile));
return false;
}
PathSessionFileName = sessionFile;
MGSHSessionParams sessionParams=MGSHSessionManager.RestoreSession(PathSessionFileName);
Configuration = sessionParams.Configuration;
TradeDate = sessionParams.TradeDate;
StartDate = sessionParams.StartDate;
AnalysisDate = sessionParams.AnalysisDate;
Cycle=sessionParams.Cycle;
sessionParams.LastUpdated = DateTime.Now;
//sessionParams.CMTParams.AnalysisDate=DateTime.Now;
StopLimits=sessionParams.StopLimits;
ActivePositions=sessionParams.ActivePositions;
AllPositions=sessionParams.AllPositions;
HedgePositions=sessionParams.HedgePositions;
CashBalance=sessionParams.CashBalance;
NonTradeableCash=sessionParams.NonTradeableCash;
HedgeCashBalance=sessionParams.HedgeCashBalance;
PricingExceptions=sessionParams.PricingExceptions;
if(!BackupSession())return false;
MGSHPositions activePositions = ActivePositions.GetPositions();
MGSHPosition position=activePositions.Where(x => x.Symbol.Equals(symbol)&&x.PurchaseDate.Equals(purchaseDate)).FirstOrDefault();
if(null==position) // if it is not in the active positions then the position is already closed and we are modifying either the sell date or the sell price
{
position=AllPositions.Where(x => x.Symbol.Equals(symbol)&&x.PurchaseDate.Equals(purchaseDate)).FirstOrDefault();
if(null==position)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Cannot locate position for symbol '{0}' purchased on {1}.",symbol,purchaseDate.ToShortDateString()));
return false;
}
position.SellDate=sellDate;
CashBalance-=position.MarketValue;
position.CurrentPrice=price;
CashBalance+=position.MarketValue;
SaveSession();
return true;
}
position.SellDate=sellDate;
position.CurrentPrice=price;
position.Comment="Manual close.";
CashBalance+=position.MarketValue;
ActivePositions.Remove(position);
AllPositions.Add(position);
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Position for symbol '{0}' purchased on {1} is now closed.",symbol,purchaseDate.ToShortDateString()));
SaveSession();
return true;
}
// ******************************************************************************************************************************************************
// **************************************************************** S T A T I S T I C S ******************************************************************
// ******************************************************************************************************************************************************
@@ -800,15 +855,15 @@ namespace MarketData.Generator.MGSHMomentum
}
// This is an older position for which we never set an initial stop. We will not adjust these
if(double.IsNaN(position.R) || double.IsNaN(position.TrailingStopLimit) || double.IsNaN(position.InitialStopLimit))
if (double.IsNaN(position.R) || double.IsNaN(position.TrailingStopLimit) || double.IsNaN(position.InitialStopLimit))
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[UpdateStopLimitsForActivePositions] Position {0} on {1} is legacy will not adjust stop limit.",position.Symbol,analysisDate.ToShortDateString()));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("[UpdateStopLimitsForActivePositions] Position {0} on {1} is legacy will not adjust stop limit.", position.Symbol, analysisDate.ToShortDateString()));
continue;
}
position.CurrentPrice = price.Close;
RemovePricingException(position.Symbol);
if(price.Low < position.TrailingStopLimit && !position.PurchaseDate.Equals(analysisDate))
if (price.Low < position.TrailingStopLimit && !position.PurchaseDate.Equals(analysisDate))
{
position.SellDate = analysisDate;
position.CurrentPrice = position.TrailingStopLimit;
@@ -868,16 +923,19 @@ namespace MarketData.Generator.MGSHMomentum
{
trailingStopScaled=GetStopLimitWithScalingAverageTrueRange(analysisDate,currentPrice,position,trailingStop);
trailingStop=Math.Max(trailingStop,trailingStopScaled);
if(trailingStop>=currentPrice.Low || trailingStop>=currentPrice.Close)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("The calculated trailing stop for {0} of {1} would be higher than the Low/Close of {2}.",position.Symbol,Utility.FormatCurrency(trailingStop),Utility.FormatCurrency(currentPrice.Low)));
return changed;
}
if(Numerics.Round(trailingStop).Equals(Numerics.Round(position.TrailingStopLimit)))
if(Numerics.Round(trailingStop)<=(Numerics.Round(position.TrailingStopLimit)))
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("The calculated trailing stop for {0} of {1} would be the same as the existing stop limit of {2}.",position.Symbol,Utility.FormatCurrency(trailingStop),Utility.FormatCurrency(position.TrailingStopLimit)));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("The calculated trailing stop for {0} of {1} would be less than or equal to the existing stop limit of {2}.",position.Symbol,Utility.FormatCurrency(trailingStop),Utility.FormatCurrency(position.TrailingStopLimit)));
return changed;
}
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("****************************** A D J U S T S T O P L I M I T ************************"));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Adjusting StopLimit after {0} days for {1} from {2} to {3}. Purchase Price: {4} Current Price:{5} Spread:{6} Shares:{7}",
daysHeld,
@@ -888,6 +946,7 @@ namespace MarketData.Generator.MGSHMomentum
Utility.FormatPercent((currentPrice.Close-trailingStop)/trailingStop),
Utility.FormatNumber(position.Shares,2)));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("*****************************************************************************************"));
StopLimit newStopLimit=new StopLimit
{
StopLimitId=position.Symbol + Utility.DateTimeToStringYYYYMMDDMMSSTT(position.PurchaseDate),