Hedge Cash + Code Cleanup

This commit is contained in:
2025-02-13 15:02:19 -05:00
parent f28495bfb4
commit 22a8b743a2
3 changed files with 201 additions and 167 deletions

View File

@@ -95,6 +95,134 @@ namespace MarketData.Generator.MGSHMomentum
return false;
}
/// <summary>
/// Mainains and adjusts the stop limits for teh hedge position
/// </summary>
/// <param name="analysisDate"></param>
/// <param name="position"></param>
/// <param name="configuration"></param>
/// <returns></returns>
public StopLimit EvaluateStopPriceHedge(DateTime analysisDate, MGSHPosition position, MGSHConfiguration configuration)
{
DateGenerator dateGenerator=new DateGenerator();
Price currentPrice=GBPriceCache.GetInstance().GetPrice(position.Symbol,analysisDate);
double trailingStop=position.InitialStopLimit+Math.Floor((currentPrice.Low-position.PurchasePrice)/position.R)*position.R;
double trailingStopScaled=trailingStop;
double daysHeld=Math.Abs(dateGenerator.DaysBetweenActual(position.PurchaseDate,analysisDate));
if(Utility.IsEpoch(position.LastStopAdjustment)) // we've never adjusted the stop price
{
BollingerBandElementsByDate bollingerBandElementsByDate = GetBollingerBandElementsByDate(analysisDate);
if(null == bollingerBandElementsByDate)return null;
trailingStopScaled=GetHedgeStopLimitWithScalingAverageTrueRange(analysisDate,currentPrice,position,trailingStop, configuration.StopLimitScalingVolatilityDays, configuration.HedgeATRMultiplier);
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 null;
}
if(Numerics.Round(trailingStop) <= (Numerics.Round(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 null;
}
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 on {0} after {1} days for {2} from {3} to {4}. Purchase Price: {5} Current Price:{6} Spread:{7} Shares:{8}",
analysisDate.ToShortDateString(),
daysHeld,
position.Symbol,
Utility.FormatCurrency(position.TrailingStopLimit),
Utility.FormatCurrency(trailingStop),
Utility.FormatCurrency(position.PurchasePrice),
Utility.FormatCurrency(currentPrice.Close),
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),
Symbol=position.Symbol,
AnalysisDate=analysisDate,
PreviousStop=0.00==position.TrailingStopLimit?position.InitialStopLimit:position.TrailingStopLimit,
NewStop=trailingStop,
CurrentPriceLow=currentPrice.Low,
CurrentPriceClose=currentPrice.Close,
PriceTrendIndicatorSlope=0.00
};
position.TrailingStopLimit=trailingStop;
position.LastStopAdjustment=analysisDate;
return newStopLimit;
}
else // we have already made prior stop adjustments
{
int daysSinceLastStopAdjustment=Math.Abs(dateGenerator.DaysBetweenActual(position.LastStopAdjustment,analysisDate));
if(daysSinceLastStopAdjustment>=configuration.HedgeMinDaysBetweenStopAdjustments)
{
trailingStopScaled=GetHedgeStopLimitWithScalingAverageTrueRange(analysisDate,currentPrice,position,trailingStop,daysSinceLastStopAdjustment,configuration.HedgeATRMultiplier);
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 null;
}
if(Numerics.Round(position.TrailingStopLimit) < Numerics.Round(trailingStop)) // round the stop limits to fractionals don't look like differences
{
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 on {0} after {1} days for {2} from {3} to {4}. Purchase Price: {5} Current Price:{6} Spread:{7} Shares:{8}",
analysisDate.ToShortDateString(),
daysHeld,
position.Symbol,
Utility.FormatCurrency(position.TrailingStopLimit),
Utility.FormatCurrency(trailingStop),
Utility.FormatCurrency(position.PurchasePrice),
Utility.FormatCurrency(currentPrice.Close),
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),
Symbol=position.Symbol,
AnalysisDate=analysisDate,
PreviousStop=0.00==position.TrailingStopLimit?position.InitialStopLimit:position.TrailingStopLimit,
NewStop=trailingStop,
CurrentPriceLow=currentPrice.Low,
CurrentPriceClose=currentPrice.Close,
PriceTrendIndicatorSlope=0.00
};
position.TrailingStopLimit=trailingStop;
position.LastStopAdjustment=analysisDate;
return newStopLimit;
}
else
{
double currentTrailingStopLimit=Numerics.Round(position.TrailingStopLimit);
double suggestedTrailingStopLimit=Numerics.Round(trailingStop);
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Not Adjusting Stop Limit for {0} because the new trailing stop limit would be less than or equal to the current trailing stop limit. Current Trailing Stop Limit:{1}, Calculated Trailing Stop Limit:{2}.",
position.Symbol,
Utility.FormatCurrency(currentTrailingStopLimit),
Utility.FormatCurrency(suggestedTrailingStopLimit)));
return null;
}
}
else
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("The trailing stop for {0} was adjusted {1} days ago. HedgeMinDaysBetweenStopAdjustments is {2}",
position.Symbol,
daysSinceLastStopAdjustment,
configuration.HedgeMinDaysBetweenStopAdjustments));
return null;
}
}
}
private int GetCloseLessL(DateTime analysisDate,BollingerBandElementsByDate bollingerBandElementsByDate, int days)
{
int count=0;
@@ -195,176 +323,55 @@ namespace MarketData.Generator.MGSHMomentum
return (lowLessLP1 >= days) && (closeLessLP1 >= days);
}
private bool CloseGreaterSMAN(DateTime analysisDate, BollingerBandElementsByDate bollingerBandElementsByDate, int days)
{
DateGenerator dateGenerator = new DateGenerator();
List<DateTime> dates = dateGenerator.GenerateHistoricalDates(analysisDate, days + 1);
dates.RemoveAt(0);
foreach (DateTime date in dates)
private bool CloseGreaterSMAN(DateTime analysisDate, BollingerBandElementsByDate bollingerBandElementsByDate, int days)
{
BollingerBandElement bollingerBandElement = bollingerBandElementsByDate[date];
if (bollingerBandElement.Close > bollingerBandElement.SMAN) return true;
}
return false;
}
/// <summary>
/// This is used to trigger an adjustment to the stop price.
/// </summary>
/// <param name="analysisDate"></param>
/// <param name="position"></param>
/// <returns></returns>
public bool IsLowerBandBreakIndicator(DateTime analysisDate, MGSHPosition position)
{
BollingerBandElementsByDate bollingerBandElementsByDate = GetBollingerBandElementsByDate(analysisDate);
if (null == bollingerBandElementsByDate) return false;
BollingerBandElement bollingerBandElement = bollingerBandElementsByDate[analysisDate];
if (bollingerBandElement.High > bollingerBandElement.K)
{
Display(String.Format("+++ [1] Upper band break detected for {0} on {1} Purchase Date:{2} Purchase Price:{3} Price Close:{4} Price High:{5} Price High(hF):{6} KL1:{7}",
HedgeShortSymbol,
analysisDate.ToShortDateString(),
position.PurchaseDate.ToShortDateString(),
Utility.FormatCurrency(position.PurchasePrice),
Utility.FormatCurrency(bollingerBandElement.Close),
Utility.FormatCurrency(bollingerBandElement.High),
Utility.FormatCurrency(bollingerBandElement.High),
Utility.FormatCurrency(bollingerBandElement.K)
));
return true;
}
return false;
}
public StopLimit EvaluateStopPriceHedge(DateTime analysisDate, MGSHPosition position, int hedgeStopLimitScalingVolatilityDays, int hedgeMinDaysBetweenStopAdjustments)
{
DateGenerator dateGenerator=new DateGenerator();
Price currentPrice=GBPriceCache.GetInstance().GetPrice(position.Symbol,analysisDate);
double trailingStop=position.InitialStopLimit+Math.Floor((currentPrice.Low-position.PurchasePrice)/position.R)*position.R;
double trailingStopScaled=trailingStop;
double daysHeld=Math.Abs(dateGenerator.DaysBetweenActual(position.PurchaseDate,analysisDate));
if(Utility.IsEpoch(position.LastStopAdjustment)) // we've never adjusted the stop price
DateGenerator dateGenerator = new DateGenerator();
List<DateTime> dates = dateGenerator.GenerateHistoricalDates(analysisDate, days + 1);
dates.RemoveAt(0);
foreach (DateTime date in dates)
{
BollingerBandElementsByDate bollingerBandElementsByDate = GetBollingerBandElementsByDate(analysisDate);
if(null == bollingerBandElementsByDate)return null;
trailingStopScaled=GetHedgeStopLimitWithScalingAverageTrueRange(analysisDate,currentPrice,position,trailingStop, hedgeStopLimitScalingVolatilityDays);
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 null;
}
if(Numerics.Round(trailingStop).Equals(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)));
return null;
}
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 on {0} after {1} days for {2} from {3} to {4}. Purchase Price: {5} Current Price:{6} Spread:{7} Shares:{8}",
analysisDate.ToShortDateString(),
daysHeld,
position.Symbol,
Utility.FormatCurrency(position.TrailingStopLimit),
Utility.FormatCurrency(trailingStop),
Utility.FormatCurrency(position.PurchasePrice),
Utility.FormatCurrency(currentPrice.Close),
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),
Symbol=position.Symbol,
AnalysisDate=analysisDate,
PreviousStop=0.00==position.TrailingStopLimit?position.InitialStopLimit:position.TrailingStopLimit,
NewStop=trailingStop,
CurrentPriceLow=currentPrice.Low,
CurrentPriceClose=currentPrice.Close,
PriceTrendIndicatorSlope=0.00
};
position.TrailingStopLimit=trailingStop;
position.LastStopAdjustment=analysisDate;
return newStopLimit;
}
else // we have already made prior stop adjustments
{
int daysSinceLastStopAdjustment=Math.Abs(dateGenerator.DaysBetweenActual(position.LastStopAdjustment,analysisDate));
if(daysSinceLastStopAdjustment>=hedgeMinDaysBetweenStopAdjustments)
{
trailingStopScaled=GetHedgeStopLimitWithScalingAverageTrueRange(analysisDate,currentPrice,position,trailingStop,daysSinceLastStopAdjustment);
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 null;
}
if(Numerics.Round(position.TrailingStopLimit) < Numerics.Round(trailingStop)) // round the stop limits to fractionals don't look like differences
{
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 on {0} after {1} days for {2} from {3} to {4}. Purchase Price: {5} Current Price:{6} Spread:{7} Shares:{8}",
analysisDate.ToShortDateString(),
daysHeld,
position.Symbol,
Utility.FormatCurrency(position.TrailingStopLimit),
Utility.FormatCurrency(trailingStop),
Utility.FormatCurrency(position.PurchasePrice),
Utility.FormatCurrency(currentPrice.Close),
Utility.FormatPercent((currentPrice.Close-trailingStop)/trailingStop),
Utility.FormatNumber(position.Shares,2)));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("****************************************************************************************"));
StopLimit newStopLimit=new StopLimit
{
Symbol=position.Symbol,
AnalysisDate=analysisDate,
PreviousStop=0.00==position.TrailingStopLimit?position.InitialStopLimit:position.TrailingStopLimit,
NewStop=trailingStop,
CurrentPriceLow=currentPrice.Low,
CurrentPriceClose=currentPrice.Close,
PriceTrendIndicatorSlope=0.00
};
position.TrailingStopLimit=trailingStop;
position.LastStopAdjustment=analysisDate;
return newStopLimit;
}
else
{
double currentTrailingStopLimit=Numerics.Round(position.TrailingStopLimit);
double suggestedTrailingStopLimit=Numerics.Round(trailingStop);
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Not Adjusting Stop Limit for {0} because the new trailing stop limit would be less than or equal to the current trailing stop limit. Current Trailing Stop Limit:{1}, Calculated Trailing Stop Limit:{2}.",
position.Symbol,
Utility.FormatCurrency(currentTrailingStopLimit),
Utility.FormatCurrency(suggestedTrailingStopLimit)));
return null;
}
}
else
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("The trailing stop for {0} was adjusted {1} days ago. MinDaysBetweenStopAdjustments is {2}",
position.Symbol,
daysSinceLastStopAdjustment,
hedgeMinDaysBetweenStopAdjustments));
return null;
}
BollingerBandElement bollingerBandElement = bollingerBandElementsByDate[date];
if (bollingerBandElement.Close > bollingerBandElement.SMAN) return true;
}
return false;
}
private double GetHedgeStopLimitWithScalingAverageTrueRange(DateTime analysisDate,Price currentPrice,MGSHPosition position,double stopLimitNonScaled, int stopLimitScalingVolatilityDays)
/// <summary>
/// This is used to trigger an adjustment to the stop price.
/// </summary>
/// <param name="analysisDate"></param>
/// <param name="position"></param>
/// <returns></returns>
public bool IsLowerBandBreakIndicator(DateTime analysisDate, MGSHPosition position)
{
BollingerBandElementsByDate bollingerBandElementsByDate = GetBollingerBandElementsByDate(analysisDate);
if (null == bollingerBandElementsByDate) return false;
BollingerBandElement bollingerBandElement = bollingerBandElementsByDate[analysisDate];
if (bollingerBandElement.High > bollingerBandElement.K)
{
Display(String.Format("+++ [1] Upper band break detected for {0} on {1} Purchase Date:{2} Purchase Price:{3} Price Close:{4} Price High:{5} Price High(hF):{6} KL1:{7}",
HedgeShortSymbol,
analysisDate.ToShortDateString(),
position.PurchaseDate.ToShortDateString(),
Utility.FormatCurrency(position.PurchasePrice),
Utility.FormatCurrency(bollingerBandElement.Close),
Utility.FormatCurrency(bollingerBandElement.High),
Utility.FormatCurrency(bollingerBandElement.High),
Utility.FormatCurrency(bollingerBandElement.K)
));
return true;
}
return false;
}
private double GetHedgeStopLimitWithScalingAverageTrueRange(DateTime analysisDate,Price currentPrice,MGSHPosition position,double stopLimitNonScaled, int stopLimitScalingVolatilityDays, double hedgeATRMultiplier)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("GetHedgeStopLimitWithScalingAverageTrueRange: Symbol:{0}",position.Symbol));
double volatility=double.NaN;
volatility=VolatilityGenerator.CalculateVolatility(position.Symbol,analysisDate,stopLimitScalingVolatilityDays, 1.00);
volatility=VolatilityGenerator.CalculateVolatility(position.Symbol,analysisDate,stopLimitScalingVolatilityDays, hedgeATRMultiplier);
if(double.IsNaN(volatility))
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Unable to calculate AverageTrueRange for {0} on {1}. Using non-scaled stop limit.",position.Symbol,analysisDate.ToShortDateString()));

View File

@@ -747,17 +747,36 @@ namespace MarketData.Generator.MGSHMomentum
position.CurrentPrice = position.TrailingStopLimit;
position.Comment = "Closed due to trailing stop.";
HedgeCashBalance+=position.MarketValue;
if(HedgeCashBalance>Configuration.HedgeInitialCash)
// This tries to maintain a 10% margin in the hedge cash
double hedgeCashMarginPercentDecimal=.10;
double hedgeCashTreshholdAmount=Configuration.HedgeInitialCash*(1.00+hedgeCashMarginPercentDecimal);
if(HedgeCashBalance > hedgeCashTreshholdAmount)
{
CashBalance+=HedgeCashBalance-Configuration.HedgeInitialCash; // if we made gains on the hedge and the hedge cash would grow then put proceeds above the initial hedge cash in regualr cash
HedgeCashBalance=Configuration.HedgeInitialCash; // For example, let hedge proceeeds help the portfolio invest
DisplayBalance();
MDTrace.WriteLine(LogLevel.DEBUG,$"The hedge cash balance would be {Utility.FormatCurrency(HedgeCashBalance)}, setting HedgeCashBalance to {Utility.FormatCurrency(hedgeCashTreshholdAmount)} and adding {Utility.FormatCurrency((HedgeCashBalance-hedgeCashTreshholdAmount))} to CashBalance.");
CashBalance += (HedgeCashBalance-hedgeCashTreshholdAmount);
HedgeCashBalance = hedgeCashTreshholdAmount;
DisplayBalance();
}
if(HedgeCashBalance<0.00)
{
HedgeCashBalance=0.00;
}
//if(HedgeCashBalance>Configuration.HedgeInitialCash)
//{
// CashBalance+=HedgeCashBalance-Configuration.HedgeInitialCash; // if we made gains on the hedge and the hedge cash would grow then put proceeds above the initial hedge cash in regualr cash
// HedgeCashBalance=Configuration.HedgeInitialCash; // For example, let hedge proceeeds help the portfolio invest
//}
AllPositions.Add(position);
closedPositions.Add(position);
}
else if(hedgeManager.IsLowerBandBreakIndicator(analysisDate, position))
{
StopLimit stopLimit = hedgeManager.EvaluateStopPriceHedge(analysisDate, position,Configuration.StopLimitScalingVolatilityDays,Configuration.HedgeMinDaysBetweenStopAdjustments);
StopLimit stopLimit = hedgeManager.EvaluateStopPriceHedge(analysisDate, position,Configuration);
if(null != stopLimit)
{
StopLimits.Add(stopLimit);
@@ -1363,6 +1382,7 @@ namespace MarketData.Generator.MGSHMomentum
Cycle=sessionParams.Cycle;
CashBalance=sessionParams.CashBalance;
NonTradeableCash=sessionParams.NonTradeableCash;
HedgeCashBalance=sessionParams.HedgeCashBalance;
return sessionParams;
}
catch(Exception exception)
@@ -1389,6 +1409,7 @@ namespace MarketData.Generator.MGSHMomentum
sessionParams.PricingExceptions=PricingExceptions;
sessionParams.CashBalance=CashBalance;
sessionParams.NonTradeableCash=NonTradeableCash;
sessionParams.HedgeCashBalance=HedgeCashBalance;
sessionManager.SaveSession(sessionParams,PathSessionFileName);
}
@@ -1412,6 +1433,7 @@ namespace MarketData.Generator.MGSHMomentum
sessionParams.PricingExceptions=PricingExceptions;
sessionParams.CashBalance=CashBalance;
sessionParams.NonTradeableCash=NonTradeableCash;
sessionParams.HedgeCashBalance=HedgeCashBalance;
return sessionManager.SaveSession(sessionParams,backupFileName);
}
}

View File

@@ -12,7 +12,7 @@ namespace MarketData.Generator.MGSHMomentum
public int MaxPositions{get;set;}
public String NoTradeSymbols{get;set;}
public String NoTradeFinancialSymbols{get;set;}
public double InitialCash{get;set;}
public double InitialCash{get;set;} // There is no defaullt for this value. It is supplied to the model at launch time.
// Stop Limit Functionality
public bool UseStopLimits{get;set;}
@@ -28,9 +28,10 @@ namespace MarketData.Generator.MGSHMomentum
public String HedgeShortSymbol{get;set;}
public double HedgeRiskPercentDecimal{get;set;}
public int HedgeMinDaysBetweenStopAdjustments;
public double HedgeInitialCash{get;set;}
public double HedgeInitialCash{get;set;} // There is no default for this value. It is supplied to the model at launch time
public int HedgeCloseAboveSMANDays{get;set;}
public int HedgeBandBreakCheckDays{get;set;}
public double HedgeATRMultiplier{get;set;}
// Manage buying and selling
public bool KeepSlotPositions{get;set;} // if this setting is true then we never sell slot positions, allowing the trailing stop to eventually invoke a sell.
@@ -120,6 +121,7 @@ namespace MarketData.Generator.MGSHMomentum
HedgeMinDaysBetweenStopAdjustments=1; // We use a single day for hedge positions
HedgeCloseAboveSMANDays=10; // Part of open hedge indicator if Close is not above Bollinger SMAN for this many days then reject
HedgeBandBreakCheckDays=3; // Number of days that low and close must be <= LP1 in order to open hedge. If >= number of days then reject
HedgeATRMultiplier=1.00; // 1.00 produces best results for the hedging stops. The default ATR multiplier in the code Volatility Calculator is 3 which gives a good spread when adjusting stop prices.
// Manage buying and selling
KeepSlotPositions=true; // The default is true to retain legacy functionality
@@ -207,6 +209,7 @@ namespace MarketData.Generator.MGSHMomentum
nvpCollection.Add(new NVP("HedgeInitialCash",HedgeInitialCash.ToString()));
nvpCollection.Add(new NVP("HedgeCloseAboveSMANDays",HedgeCloseAboveSMANDays.ToString()));
nvpCollection.Add(new NVP("HedgeBandBreakCheckDays",HedgeBandBreakCheckDays.ToString()));
nvpCollection.Add(new NVP("HedgeATRMultiplier",HedgeATRMultiplier.ToString()));
nvpCollection.Add(new NVP("MaxPricingExceptions",MaxPricingExceptions.ToString()));
@@ -281,6 +284,7 @@ namespace MarketData.Generator.MGSHMomentum
mgConfiguration.HedgeInitialCash = nvpDictionary["HedgeInitialCash"].Get<int>();
mgConfiguration.HedgeCloseAboveSMANDays = nvpDictionary["HedgeCloseAboveSMANDays"].Get<int>();
mgConfiguration.HedgeBandBreakCheckDays = nvpDictionary["HedgeBandBreakCheckDays"].Get<int>();
mgConfiguration.HedgeATRMultiplier = nvpDictionary["HedgeATRMultiplier"].Get<double>();
}
else
{
@@ -350,6 +354,7 @@ namespace MarketData.Generator.MGSHMomentum
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("HedgeInitialCash,{0}", HedgeInitialCash));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("HedgeCloseAboveSMANDays,{0}", HedgeCloseAboveSMANDays));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("HedgeBandBreakCheckDays,{0}", HedgeBandBreakCheckDays));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("HedgeATRMultiplier,{0}", HedgeATRMultiplier));
}
}
}