diff --git a/MarketDataLib/Generator/MGSHMomentum/HedgeManager.cs b/MarketDataLib/Generator/MGSHMomentum/HedgeManager.cs
index e58c56b..384a02b 100644
--- a/MarketDataLib/Generator/MGSHMomentum/HedgeManager.cs
+++ b/MarketDataLib/Generator/MGSHMomentum/HedgeManager.cs
@@ -95,6 +95,134 @@ namespace MarketData.Generator.MGSHMomentum
return false;
}
+ ///
+ /// Mainains and adjusts the stop limits for teh hedge position
+ ///
+ ///
+ ///
+ ///
+ ///
+ 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 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;
- }
-
-
- ///
- /// This is used to trigger an adjustment to the stop price.
- ///
- ///
- ///
- ///
- 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 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)
+
+ ///
+ /// This is used to trigger an adjustment to the stop price.
+ ///
+ ///
+ ///
+ ///
+ 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()));
diff --git a/MarketDataLib/Generator/MGSHMomentum/MGSHBacktest.cs b/MarketDataLib/Generator/MGSHMomentum/MGSHBacktest.cs
index dc56128..29c92f9 100644
--- a/MarketDataLib/Generator/MGSHMomentum/MGSHBacktest.cs
+++ b/MarketDataLib/Generator/MGSHMomentum/MGSHBacktest.cs
@@ -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);
}
}
diff --git a/MarketDataLib/Generator/MGSHMomentum/MGSHConfiguration.cs b/MarketDataLib/Generator/MGSHMomentum/MGSHConfiguration.cs
index 1d059ae..16d98d7 100644
--- a/MarketDataLib/Generator/MGSHMomentum/MGSHConfiguration.cs
+++ b/MarketDataLib/Generator/MGSHMomentum/MGSHConfiguration.cs
@@ -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();
mgConfiguration.HedgeCloseAboveSMANDays = nvpDictionary["HedgeCloseAboveSMANDays"].Get();
mgConfiguration.HedgeBandBreakCheckDays = nvpDictionary["HedgeBandBreakCheckDays"].Get();
+ mgConfiguration.HedgeATRMultiplier = nvpDictionary["HedgeATRMultiplier"].Get();
}
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));
}
}
}