Changes for MGSHBacktest model.
Code cleanup.
This commit is contained in:
@@ -1,17 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.DataAccess;
|
||||
using MarketData.Utils;
|
||||
using System.Linq;
|
||||
using MarketData.Helper;
|
||||
using MarketData.Numerical;
|
||||
using System.Reflection;
|
||||
using MarketData.Generator.Interface;
|
||||
|
||||
namespace MarketData.Generator.CMTrend
|
||||
{
|
||||
public class Position
|
||||
public class Position : IPosition
|
||||
{
|
||||
public Position()
|
||||
{
|
||||
|
||||
@@ -8,10 +8,7 @@ using MarketData.Utils;
|
||||
using System.Linq;
|
||||
using MarketData.Helper;
|
||||
using MarketData.Numerical;
|
||||
using System.Threading;
|
||||
using MarketData.Integration;
|
||||
using MarketData.Cache;
|
||||
using System.IO;
|
||||
using MarketData.Generator.Indicators;
|
||||
using MarketData.Generator.Model;
|
||||
using StopLimit=MarketData.Generator.Model.StopLimit;
|
||||
|
||||
@@ -283,6 +283,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
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,
|
||||
|
||||
@@ -22,12 +22,13 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
private MGSHConfiguration Configuration{get;set;}
|
||||
private int HoldingPeriod{get{return Configuration.HoldingPeriod;}}
|
||||
private int MaxPositions{get{return Configuration.MaxPositions;}}
|
||||
private List<String> NoTradeSymbols{get{return Utility.ToList(Configuration.NoTradeSymbols);}}
|
||||
private int MaxPricingExceptions{get{return Configuration.MaxPricingExceptions;}}
|
||||
//private List<String> NoTradeSymbols{get{return Utility.ToList(Configuration.NoTradeSymbols);}}
|
||||
private MGSHActivePositions ActivePositions{get;set;}
|
||||
// private SMSNotifications SMSNotifications{get;set;}
|
||||
private StopLimits StopLimits{get;set;}
|
||||
private MGSHPositions AllPositions{get;set;}
|
||||
private MGSHPositions HedgePositions{get;set;}
|
||||
private MGSHPricingExceptions PricingExceptions{get;set;}
|
||||
private int Cycle{get;set;}
|
||||
private DateTime TradeDate{get;set;}
|
||||
private DateTime StartDate{get;set;}
|
||||
@@ -118,6 +119,61 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
}
|
||||
}
|
||||
|
||||
// ******************************************************************************************************************************************************
|
||||
// *************************************************************************** E D I T ******************************************************************
|
||||
// ******************************************************************************************************************************************************
|
||||
public bool EditPosition(String symbol,DateTime purchaseDate,double purchasePrice,double initialStop,double trailingStop,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)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Cannot locate position for symbol '{0}' purchased on {1}.", symbol, purchaseDate.ToShortDateString()));
|
||||
return false;
|
||||
}
|
||||
if (!position.PurchaseDate.Equals(purchaseDate)) position.PurchaseDate = purchaseDate;
|
||||
if (!position.TrailingStopLimit.Equals(trailingStop)) position.TrailingStopLimit = trailingStop;
|
||||
if (!position.InitialStopLimit.Equals(initialStop)) position.InitialStopLimit = initialStop;
|
||||
if (!position.PurchasePrice.Equals(purchasePrice))
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Adjusting Cash for Position for symbol '{0}' purchased on {1}. Original Price: {2} New Price: {3} Change in Cash: {4}", symbol, purchaseDate.ToShortDateString(), Utility.FormatCurrency(position.PurchasePrice), Utility.FormatCurrency(purchasePrice), Utility.FormatCurrency((position.PurchasePrice - purchasePrice) * position.Shares)));
|
||||
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Adjusting R for Position for symbol '{0}' purchased on {1}. Original R: {2} New R: {3} ", symbol, purchaseDate.ToShortDateString(), Utility.FormatNumber(position.R, 2), Utility.FormatNumber(position.PositionRiskPercentDecimal * purchasePrice)));
|
||||
CashBalance += (position.PurchasePrice - purchasePrice) * position.Shares;
|
||||
position.Comment = (null == position.Comment ? "" : position.Comment + ".") + String.Format("Price changed on {0} from {1} to {2}", DateTime.Now.ToShortDateString(), Utility.FormatCurrency(position.PurchasePrice), Utility.FormatCurrency(purchasePrice));
|
||||
position.PurchasePrice = purchasePrice;
|
||||
}
|
||||
SaveSession();
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Position for symbol '{0}' purchased on {1} has been modified and saved.",symbol,purchaseDate.ToShortDateString()));
|
||||
return true;
|
||||
}
|
||||
|
||||
// ******************************************************************************************************************************************************
|
||||
// **************************************************************** S T A T I S T I C S ******************************************************************
|
||||
// ******************************************************************************************************************************************************
|
||||
|
||||
// Calcualtes the expectation for the model ( Percent of Winning Trades * Average Gain)/(Percent Losing Trades * Average Loss)
|
||||
// The expectation should be above zero
|
||||
// Using the AllPositions collection ignored open positions and active hedge positions
|
||||
@@ -308,6 +364,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
ActivePositions=new MGSHActivePositions();
|
||||
AllPositions=new MGSHPositions();
|
||||
HedgePositions=new MGSHPositions();
|
||||
PricingExceptions=new MGSHPricingExceptions();
|
||||
StartDate=paramStartDate;
|
||||
TradeDate=paramStartDate;
|
||||
AnalysisDate=paramAnalysisDate;
|
||||
@@ -450,14 +507,16 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
if(CashBalance-positions.Exposure<=0.00)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("********** Insufficient funds to make additional purchases.**************"));
|
||||
return;
|
||||
}
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,"********************** B U Y ********************");
|
||||
if(!ActivePositions.ContainsKey(slotIndex))ActivePositions.Add(slotIndex, positions);
|
||||
else ActivePositions[slotIndex].AddRange(positions);
|
||||
CashBalance-=positions.Exposure;
|
||||
SetInitialStopLimitsForNewPositions(TradeDate, positions);
|
||||
ActivePositions[slotIndex].Display();
|
||||
else
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,"********************** B U Y ********************");
|
||||
if(!ActivePositions.ContainsKey(slotIndex))ActivePositions.Add(slotIndex, positions);
|
||||
else ActivePositions[slotIndex].AddRange(positions);
|
||||
CashBalance-=positions.Exposure;
|
||||
SetInitialStopLimitsForNewPositions(TradeDate, positions);
|
||||
ActivePositions[slotIndex].Display();
|
||||
}
|
||||
UpdateStopLimitsForActivePositions(TradeDate);
|
||||
DisplayBalance();
|
||||
}
|
||||
@@ -582,7 +641,8 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
shortPosition.PurchasePrice = shortPositionPrice.Close;
|
||||
shortPosition.CurrentPrice = shortPositionPrice.Close;
|
||||
shortPosition.InitialStopLimit = shortPosition.PurchasePrice - ( shortPosition.PurchasePrice * Configuration.HedgeRiskPercentDecimal);
|
||||
shortPosition.R = shortPosition.PurchasePrice - shortPosition.InitialStopLimit;
|
||||
shortPosition.PositionRiskPercentDecimal = Configuration.HedgeRiskPercentDecimal; // The risk percent
|
||||
shortPosition.R = shortPosition.PositionRiskPercentDecimal * shortPosition.PurchasePrice; // PositionRiskPercentDecimal*PurchasePrice
|
||||
shortPosition.TrailingStopLimit = shortPosition.InitialStopLimit;
|
||||
shortPosition.LastStopAdjustment = Utility.Epoch;
|
||||
shortPosition.Shares = (int)Math.Floor(cashAllocation / shortPositionPrice.Close);
|
||||
@@ -685,7 +745,8 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
foreach(MGSHPosition position in positions)
|
||||
{
|
||||
position.InitialStopLimit = position.PurchasePrice - (position.PurchasePrice * Configuration.StopLimitRiskPercentDecimal);
|
||||
position.R = position.PurchasePrice - position.InitialStopLimit;
|
||||
position.PositionRiskPercentDecimal = Configuration.StopLimitRiskPercentDecimal; // = position.PurchasePrice - position.InitialStopLimit;
|
||||
position.R = position.PositionRiskPercentDecimal * position.PurchasePrice; // PositionRiskPercentDecimal*PurchasePrice
|
||||
position.TrailingStopLimit = position.InitialStopLimit;
|
||||
position.LastStopAdjustment = Utility.Epoch;
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Initial stop limit for {0} on {1} with PurchsePrice:{2} is {3}, Shares:{4} Risk:{5}%",
|
||||
@@ -718,10 +779,23 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
foreach(MGSHPosition position in positions)
|
||||
{
|
||||
Price price=GBPriceCache.GetInstance().GetPrice(position.Symbol,analysisDate);
|
||||
// Incorporate Pricing Exceptions
|
||||
|
||||
if(null==price)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[UpdateStopLimitsForActivePositions] No price for {0} on {1}. Cannot evaluate stop limit.",position.Symbol,analysisDate.ToShortDateString()));
|
||||
int exceptionCount=AddPricingException(position.Symbol);
|
||||
if(exceptionCount>MaxPricingExceptions)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[UpdateStopLimitsForActivePositions] Selling {0} on {1} because price exceptions exceeds maximum of {2}",position.Symbol,analysisDate.ToShortDateString(),MaxPricingExceptions));
|
||||
price=GBPriceCache.GetInstance().GetPriceOrLatestAvailable(position.Symbol,analysisDate);
|
||||
position.SellDate=analysisDate;
|
||||
position.CurrentPrice=price.Close;
|
||||
position.Comment="Close due to pricing exceptions.";
|
||||
CashBalance+=position.MarketValue;
|
||||
AllPositions.Add(position);
|
||||
closedPositions.Add(position);
|
||||
}
|
||||
else MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[UpdateStopLimitsForActivePositions] Cannot determine price for {0} on {1}",position.Symbol,analysisDate.ToShortDateString()));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -733,6 +807,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
}
|
||||
|
||||
position.CurrentPrice = price.Close;
|
||||
RemovePricingException(position.Symbol);
|
||||
if(price.Low < position.TrailingStopLimit && !position.PurchaseDate.Equals(analysisDate))
|
||||
{
|
||||
position.SellDate = analysisDate;
|
||||
@@ -741,10 +816,10 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
CashBalance += position.MarketValue;
|
||||
AllPositions.Add(position);
|
||||
closedPositions.Add(position);
|
||||
}
|
||||
else if(price.Low > position.PurchasePrice) // If the Low price is above our purchase price then re-evaluate the stop
|
||||
}
|
||||
else if (price.Low > position.PurchasePrice) // If the Low price is above our purchase price then re-evaluate the stop
|
||||
{
|
||||
EvaluateStopPrice(analysisDate,price,position);
|
||||
EvaluateStopPrice(analysisDate, price, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -777,9 +852,9 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
// only adjust stops if we are trending up
|
||||
Prices prices=GBPriceCache.GetInstance().GetPrices(position.Symbol,analysisDate,Configuration.StopLimitPriceTrendDays);
|
||||
PriceTrendIndicatorResult priceTrendIndicatorResult=PriceTrendIndicator.IsUptrend(prices,Configuration.StopLimitPriceTrendDays);
|
||||
if(!priceTrendIndicatorResult.IsUpTrend)
|
||||
if (!priceTrendIndicatorResult.IsUpTrend)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("{0} does not have upward price trend (higher highs and higher lows for {1} consecutive days), will not adjust stop price",position.Symbol,Configuration.StopLimitPriceTrendDays));
|
||||
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("{0} does not have upward price trend (higher highs and higher lows for {1} consecutive days), will not adjust stop price", position.Symbol, Configuration.StopLimitPriceTrendDays));
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -793,7 +868,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
{
|
||||
trailingStopScaled=GetStopLimitWithScalingAverageTrueRange(analysisDate,currentPrice,position,trailingStop);
|
||||
trailingStop=Math.Max(trailingStop,trailingStopScaled);
|
||||
if(trailingStop>=currentPrice.Low||trailingStop>=currentPrice.Close)
|
||||
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;
|
||||
@@ -804,10 +879,18 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
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,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("Adjusting StopLimit after {0} days for {1} from {2} to {3}. Purchase Price: {4} Current Price:{5} Spread:{6} Shares:{7}",
|
||||
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,
|
||||
@@ -846,6 +929,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
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,
|
||||
@@ -891,15 +975,46 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
return stopLimit;
|
||||
}
|
||||
|
||||
// **********************************************************************************************************************************************************
|
||||
// ***************************************************** S T O P L I M I T C O L L E C T I O N M A I N T E N A N C E ***********************************
|
||||
// **********************************************************************************************************************************************************
|
||||
// **************************************************************************************************************************************
|
||||
// ************************************************** S T O P L I M I T C O L L E C T I O N M A I N T E N A N C E ******************
|
||||
// **************************************************************************************************************************************
|
||||
private void AddStopLimit(StopLimit stopLimit)
|
||||
{
|
||||
if(null == StopLimits)StopLimits = new StopLimits();
|
||||
StopLimits.Add(stopLimit);
|
||||
}
|
||||
|
||||
// ************************************************************************************************************************************************
|
||||
// ********************************************* P R I C I N G E X C E P T I O N C O L L E C T I O N M A I N T E N A N C E ******************
|
||||
// ************************************************************************************************************************************************
|
||||
|
||||
private int AddPricingException(String symbol)
|
||||
{
|
||||
MGSHPricingException pricingException = PricingExceptions.Where(x => x.Symbol.Equals(symbol)).FirstOrDefault();
|
||||
if (null == pricingException)
|
||||
{
|
||||
pricingException = new MGSHPricingException(symbol, 1);
|
||||
PricingExceptions.Add(pricingException);
|
||||
PricingExceptions.Add(pricingException);
|
||||
}
|
||||
else pricingException.ExceptionCount++;
|
||||
return pricingException.ExceptionCount;
|
||||
}
|
||||
|
||||
private void RemovePricingException(String symbol)
|
||||
{
|
||||
MGSHPricingException pricingException = PricingExceptions.Where(x => x.Symbol.Equals(symbol)).FirstOrDefault();
|
||||
if (null == pricingException) return;
|
||||
PricingExceptions.Remove(pricingException);
|
||||
}
|
||||
|
||||
private bool HasPricingException(String symbol)
|
||||
{
|
||||
MGSHPricingException pricingException = PricingExceptions.Where(x => x.Symbol.Equals(symbol)).FirstOrDefault();
|
||||
if (null == pricingException) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ******************************************************************************************************************************************************
|
||||
// ******************************************************************************************************************************************************
|
||||
// ******************************************************************************************************************************************************
|
||||
@@ -1185,6 +1300,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
AllPositions=sessionParams.AllPositions;
|
||||
HedgePositions=sessionParams.HedgePositions;
|
||||
StopLimits=sessionParams.StopLimits;
|
||||
PricingExceptions = sessionParams.PricingExceptions;
|
||||
Cycle=sessionParams.Cycle;
|
||||
CashBalance=sessionParams.CashBalance;
|
||||
NonTradeableCash=sessionParams.NonTradeableCash;
|
||||
@@ -1211,9 +1327,33 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
sessionParams.HedgePositions=HedgePositions;
|
||||
sessionParams.Cycle=Cycle;
|
||||
sessionParams.StopLimits=StopLimits;
|
||||
sessionParams.PricingExceptions=PricingExceptions;
|
||||
sessionParams.CashBalance=CashBalance;
|
||||
sessionParams.NonTradeableCash=NonTradeableCash;
|
||||
sessionManager.SaveSession(sessionParams,PathSessionFileName);
|
||||
}
|
||||
|
||||
public bool BackupSession()
|
||||
{
|
||||
String[] parts=PathSessionFileName.Split('.');
|
||||
String backupFileName=parts[0]+"_"+Utility.DateTimeToStringYYYYMMDDMMSSTT(DateTime.Now)+".bak";
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Saving session to '{0}'",backupFileName));
|
||||
MGSHSessionParams sessionParams=new MGSHSessionParams();
|
||||
MGSHSessionManager sessionManager=new MGSHSessionManager();
|
||||
sessionParams.LastUpdated=Today();
|
||||
sessionParams.TradeDate=TradeDate;
|
||||
sessionParams.StartDate=StartDate;
|
||||
sessionParams.AnalysisDate=AnalysisDate;
|
||||
sessionParams.Configuration=Configuration;
|
||||
sessionParams.ActivePositions=ActivePositions;
|
||||
sessionParams.AllPositions=AllPositions;
|
||||
sessionParams.HedgePositions=HedgePositions;
|
||||
sessionParams.Cycle=Cycle;
|
||||
sessionParams.StopLimits=StopLimits;
|
||||
sessionParams.PricingExceptions=PricingExceptions;
|
||||
sessionParams.CashBalance=CashBalance;
|
||||
sessionParams.NonTradeableCash=NonTradeableCash;
|
||||
return sessionManager.SaveSession(sessionParams,backupFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
// 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.
|
||||
|
||||
// Pricing Exceptions
|
||||
public int MaxPricingExceptions{get;set;} // This is the pricing exception limit. If we have this many of exceptions then we will sell the security at the last known good price.
|
||||
|
||||
// Fundamental screenings
|
||||
public double MarketCapLowerLimit{get;set;}
|
||||
|
||||
@@ -121,6 +124,8 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
// Manage buying and selling
|
||||
KeepSlotPositions=true; // The default is true to retain legacy functionality
|
||||
|
||||
MaxPricingExceptions=3; // The maximum number of pricing exceptions. If exceeded then the security will be sold at the last known good price
|
||||
|
||||
// Other settings
|
||||
UseEBITDAScreen=true; // true is the default
|
||||
UseRevenuePerShareScreen=true; // true is the default
|
||||
@@ -203,6 +208,8 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
nvpCollection.Add(new NVP("HedgeCloseAboveSMANDays",HedgeCloseAboveSMANDays.ToString()));
|
||||
nvpCollection.Add(new NVP("HedgeBandBreakCheckDays",HedgeBandBreakCheckDays.ToString()));
|
||||
|
||||
nvpCollection.Add(new NVP("MaxPricingExceptions",MaxPricingExceptions.ToString()));
|
||||
|
||||
return nvpCollection;
|
||||
}
|
||||
public static MGSHConfiguration FromNVPCollection(NVPCollection nvpCollection)
|
||||
@@ -240,6 +247,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
mgConfiguration.UseFallbackCandidate=nvpDictionary["UseFallbackCandidate"].Get<Boolean>();
|
||||
mgConfiguration.FallbackCandidate=nvpDictionary["FallbackCandidate"].Get<String>();
|
||||
mgConfiguration.FallbackCandidateBestOf=nvpDictionary["FallbackCandidateBestOf"].Get<String>();
|
||||
mgConfiguration.MaxPricingExceptions=nvpDictionary["MaxPricingExceptions"].Get<int>();
|
||||
|
||||
if(nvpDictionary.ContainsKey("QualityIndicatorType")) mgConfiguration.QualityIndicatorType=nvpDictionary["QualityIndicatorType"].Get<String>();
|
||||
else mgConfiguration.QualityIndicatorType=MGSHQualityIndicator.ToString(MGSHQualityIndicator.QualityType.IDIndicator);
|
||||
@@ -283,6 +291,8 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
public void DisplayConfiguration()
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Verbose,{0}",Verbose));
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MaxPricingExceptions,{0}",MaxPricingExceptions));
|
||||
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("KeepSlotPositions,{0}",KeepSlotPositions));
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Holding Period,{0}",HoldingPeriod));
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MaxPositions,{0}",MaxPositions));
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
using System.Collections.Generic;
|
||||
using MarketData.Utils;
|
||||
using System.Linq;
|
||||
using MarketData.Generator.Interface;
|
||||
|
||||
namespace MarketData.Generator.MGSHMomentum
|
||||
{
|
||||
public class MGSHPosition
|
||||
public class MGSHPosition : IPosition
|
||||
{
|
||||
public MGSHPosition()
|
||||
{
|
||||
@@ -33,9 +34,40 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
InitialStopLimit = position.InitialStopLimit;
|
||||
TrailingStopLimit = position.TrailingStopLimit;
|
||||
LastStopAdjustment = position.LastStopAdjustment;
|
||||
PositionRiskPercentDecimal = position.PositionRiskPercentDecimal;
|
||||
R = position.R;
|
||||
if(null!=position.Comment)Comment=string.Copy(position.Comment);
|
||||
}
|
||||
|
||||
public static MGSHPosition Clone(MGSHPosition positionToClone)
|
||||
{
|
||||
MGSHPosition position = new MGSHPosition();
|
||||
position.Symbol = positionToClone.Symbol;
|
||||
position.PurchaseDate = positionToClone.PurchaseDate;
|
||||
position.SellDate=positionToClone.SellDate;
|
||||
position.Shares=positionToClone.Shares;
|
||||
position.PurchasePrice=positionToClone.PurchasePrice;
|
||||
position.CurrentPrice=positionToClone.CurrentPrice;
|
||||
position.Volume=positionToClone.Volume;
|
||||
position.Return1D=positionToClone.Return1D;
|
||||
position.ZacksRank=positionToClone.ZacksRank;
|
||||
position.CumReturn252=positionToClone.CumReturn252;
|
||||
position.IDIndicator=positionToClone.IDIndicator;
|
||||
position.Score=positionToClone.Score;
|
||||
position.MaxDrawdown=positionToClone.MaxDrawdown;
|
||||
position.MaxUpside=positionToClone.MaxUpside;
|
||||
position.Velocity=positionToClone.Velocity;
|
||||
position.PE=positionToClone.PE;
|
||||
position.Beta=positionToClone.Beta;
|
||||
position.InitialStopLimit=positionToClone.InitialStopLimit;
|
||||
position.TrailingStopLimit=positionToClone.TrailingStopLimit;
|
||||
position.LastStopAdjustment=positionToClone.LastStopAdjustment;
|
||||
position.PositionRiskPercentDecimal=positionToClone.PositionRiskPercentDecimal;
|
||||
position.R=positionToClone.R;
|
||||
position.Comment=positionToClone.Comment;
|
||||
return position;
|
||||
}
|
||||
|
||||
public String Symbol{get;set;}
|
||||
public DateTime PurchaseDate{get;set;}
|
||||
public DateTime SellDate{get;set;}
|
||||
@@ -60,7 +92,8 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
public double InitialStopLimit {get; set; }
|
||||
public double TrailingStopLimit {get; set; }
|
||||
public DateTime LastStopAdjustment {get; set; }
|
||||
public double R {get; set; }
|
||||
public double PositionRiskPercentDecimal {get; set; }
|
||||
public double R { get; set; }
|
||||
public String Comment {get; set; }
|
||||
|
||||
public virtual NVPCollection ToNVPCollection()
|
||||
@@ -86,6 +119,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
nvpCollection.Add(new NVP("InitialStopLimit", InitialStopLimit.ToString()));
|
||||
nvpCollection.Add(new NVP("TrailingStopLimit", TrailingStopLimit.ToString()));
|
||||
nvpCollection.Add(new NVP("LastStopAdjustment", LastStopAdjustment.ToString()));
|
||||
nvpCollection.Add(new NVP("PositionRiskPercentDecimal", PositionRiskPercentDecimal.ToString()));
|
||||
nvpCollection.Add(new NVP("R", R.ToString()));
|
||||
nvpCollection.Add(new NVP("Comment", Comment?.ToString()));
|
||||
return nvpCollection;
|
||||
@@ -121,6 +155,8 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
else position.LastStopAdjustment=Utility.Epoch;
|
||||
if(nvpDictionary.ContainsKey("Comment")) position.Comment=nvpDictionary["Comment"].Get<String>();
|
||||
else position.Comment=null;
|
||||
if(nvpDictionary.ContainsKey("PositionRiskPercentDecimal")) position.PositionRiskPercentDecimal=nvpDictionary["PositionRiskPercentDecimal"].Get<double>();
|
||||
else position.PositionRiskPercentDecimal=double.NaN;
|
||||
if(nvpDictionary.ContainsKey("R")) position.R=nvpDictionary["R"].Get<double>();
|
||||
else position.R=double.NaN;
|
||||
return position;
|
||||
|
||||
@@ -64,6 +64,11 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
streamWriter.WriteLine((new NVP("TotalHedgePositions",nvpHedgePositionsStringList.Count.ToString())).ToString());
|
||||
foreach(String str in nvpHedgePositionsStringList)streamWriter.WriteLine(str);
|
||||
|
||||
NVPCollections pricingExceptionsCollections=sessionParams.PricingExceptions.ToNVPCollections();
|
||||
List<String> nvpPricingExceptionsCollectionsStringList=pricingExceptionsCollections.ToList();
|
||||
streamWriter.WriteLine((new NVP("TotalPricingExceptions",nvpPricingExceptionsCollectionsStringList.Count.ToString())).ToString());
|
||||
foreach(String str in nvpPricingExceptionsCollectionsStringList)streamWriter.WriteLine(str);
|
||||
|
||||
streamWriter.Flush();
|
||||
outStream.Flush();
|
||||
streamWriter.Close();
|
||||
@@ -126,6 +131,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
|
||||
if(2.00==version)
|
||||
{
|
||||
// stop limits
|
||||
int totalStopLimits=(new NVP(streamReader.ReadLine())).Get<int>();
|
||||
sessionParams.StopLimits=new StopLimits();
|
||||
for(int stopLimitIndex=0;stopLimitIndex<totalStopLimits;stopLimitIndex++)
|
||||
@@ -134,6 +140,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
sessionParams.StopLimits.AddFromNVPCollection(nvpCollection);
|
||||
}
|
||||
|
||||
// hedges
|
||||
int totalHedgePositions = (new NVP(streamReader.ReadLine())).Get<int>();
|
||||
NVPCollections nvpHedgeCollections=new NVPCollections();
|
||||
for(int hedgePositionIndex=0;hedgePositionIndex<totalHedgePositions;hedgePositionIndex++)
|
||||
@@ -142,7 +149,18 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
nvpHedgeCollections.Add(nvpCollection);
|
||||
}
|
||||
sessionParams.HedgePositions=MGSHPositions.FromNVPCollections(nvpHedgeCollections);
|
||||
}
|
||||
|
||||
// pricing exceptions
|
||||
int totalPricingExceptions = (new NVP(streamReader.ReadLine())).Get<int>();
|
||||
NVPCollections nvpPricingExceptionsCollections=new NVPCollections();
|
||||
for(int pricingExceptionIndex=0;pricingExceptionIndex<totalPricingExceptions;pricingExceptionIndex++)
|
||||
{
|
||||
NVPCollection nvpCollection=new NVPCollection(streamReader.ReadLine());
|
||||
nvpPricingExceptionsCollections.Add(nvpCollection);
|
||||
}
|
||||
sessionParams.PricingExceptions=MGSHPricingExceptions.FromNVPCollections(nvpPricingExceptionsCollections);
|
||||
|
||||
} // version
|
||||
|
||||
inStream.Close();
|
||||
inStream.Dispose();
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
public double NonTradeableCash { get; set; }
|
||||
public StopLimits StopLimits { get; set;}
|
||||
public MGSHPositions HedgePositions { get; set; }
|
||||
public MGSHPricingExceptions PricingExceptions{ get; set; }
|
||||
public int Cycle { get; set; }
|
||||
|
||||
// This gets AllPositions+Positions+HedgePositions
|
||||
|
||||
@@ -5,6 +5,10 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// This StopLimit class is used by models and the UI
|
||||
/// </summary>
|
||||
|
||||
namespace MarketData.Generator.Model
|
||||
{
|
||||
public class StopLimits:List<StopLimit>
|
||||
@@ -53,6 +57,7 @@ namespace MarketData.Generator.Model
|
||||
this.CurrentPriceLow=stopLimit.CurrentPriceLow;
|
||||
this.CurrentPriceClose=stopLimit.CurrentPriceClose;
|
||||
this.PriceTrendIndicatorSlope=stopLimit.PriceTrendIndicatorSlope;
|
||||
this.StopLimitId=stopLimit.StopLimitId;
|
||||
}
|
||||
public StopLimit(String symbol,DateTime analysisDate,double previousStop,double newStop,double currentPriceLow,double currentPriceClose,double priceTrendIndicatorSlope)
|
||||
{
|
||||
@@ -71,15 +76,17 @@ namespace MarketData.Generator.Model
|
||||
public double CurrentPriceLow{get;set;}
|
||||
public double CurrentPriceClose{get;set;}
|
||||
public double PriceTrendIndicatorSlope{get;set;}
|
||||
public String StopLimitId {get;set;}
|
||||
public static String Header()
|
||||
{
|
||||
StringBuilder sb=new StringBuilder();
|
||||
sb.Append("Symbol,AnalysisDate,PreviousStop,NewStop,CurrentPriceLow,CurrentPriceClose,PriceTrendIndicatorSlope");
|
||||
sb.Append("Id,Symbol,AnalysisDate,PreviousStop,NewStop,CurrentPriceLow,CurrentPriceClose,PriceTrendIndicatorSlope");
|
||||
return sb.ToString();
|
||||
}
|
||||
public override String ToString()
|
||||
{
|
||||
StringBuilder sb=new StringBuilder();
|
||||
sb.Append(null==StopLimitId?"":StopLimitId).Append(",");
|
||||
sb.Append(Symbol).Append(",");
|
||||
sb.Append(AnalysisDate.ToShortDateString()).Append(",");
|
||||
sb.Append(Utility.FormatCurrency(PreviousStop)).Append(",");
|
||||
@@ -99,6 +106,7 @@ namespace MarketData.Generator.Model
|
||||
nvpCollection.Add(new NVP("CurrentPriceLow",CurrentPriceLow.ToString()));
|
||||
nvpCollection.Add(new NVP("CurrentPriceClose",CurrentPriceClose.ToString()));
|
||||
nvpCollection.Add(new NVP("PriceTrendIndicatorSlope",PriceTrendIndicatorSlope.ToString()));
|
||||
nvpCollection.Add(new NVP("StopLimitId",StopLimitId==null?"":StopLimitId));
|
||||
return nvpCollection;
|
||||
}
|
||||
public static StopLimit FromNVPCollection(NVPCollection nvpCollection)
|
||||
@@ -113,6 +121,7 @@ namespace MarketData.Generator.Model
|
||||
stopLimit.CurrentPriceLow=nvpDictionary["CurrentPriceLow"].Get<double>();
|
||||
stopLimit.CurrentPriceClose=nvpDictionary["CurrentPriceClose"].Get<double>();
|
||||
stopLimit.PriceTrendIndicatorSlope=nvpDictionary["PriceTrendIndicatorSlope"].Get<double>();
|
||||
if(nvpDictionary.ContainsKey("StopLimitId"))stopLimit.StopLimitId=nvpDictionary["StopLimitId"].Get<String>();
|
||||
return stopLimit;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user