Add Edit/Close positions for MG and CM models. Remove the Fix for purchase date sell date fall on weekend. Dead code elimination

This commit is contained in:
2025-02-25 15:40:13 -05:00
parent 2cf653c2c1
commit 835c5be11a
6 changed files with 289 additions and 329 deletions

View File

@@ -1,11 +1,7 @@
using MarketData.MarketDataModel;
using MarketData.Utils;
using MarketData.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace MarketData.Generator.CMMomentum
{
@@ -26,6 +22,25 @@ namespace MarketData.Generator.CMMomentum
}
return exposure;
}
public bool Remove(Position searchPosition)
{
List<int> keys = new List<int>(this.Keys);
for (int index = 0; index < keys.Count; index++)
{
Positions positions = this[keys[index]];
foreach (Position slotPosition in positions)
{
if (slotPosition == searchPosition)
{
positions.Remove(searchPosition);
return true;
}
}
}
return false;
}
public Positions GetPositions()
{
Positions positionsCollection=new Positions();
@@ -41,6 +56,7 @@ namespace MarketData.Generator.CMMomentum
}
return positionsCollection;
}
public List<String> GetSymbols()
{
Dictionary<String, String> symbols = new Dictionary<String, String>();
@@ -56,6 +72,7 @@ namespace MarketData.Generator.CMMomentum
}
return new List<String>(symbols.Keys);
}
public double GetMarketValue()
{
int count = Count;
@@ -68,6 +85,7 @@ namespace MarketData.Generator.CMMomentum
}
return marketValue;
}
public double GetGainLoss()
{
int count = Count;
@@ -82,6 +100,7 @@ namespace MarketData.Generator.CMMomentum
}
return marketValue - exposure;
}
public double GetGainLossPercent()
{
double exposure = GetExposure();
@@ -89,6 +108,7 @@ namespace MarketData.Generator.CMMomentum
if (0.00 == exposure) return exposure;
return (marketValue - exposure) / exposure;
}
public void Display()
{
for (int slotIndex = 0; slotIndex < Count; slotIndex++)
@@ -99,6 +119,7 @@ namespace MarketData.Generator.CMMomentum
positions.Display();
}
}
public void AddFromNVPCollection(NVPCollection nvpCollection)
{
SlotPosition slotPosition = SlotPosition.FromNVPCollection(nvpCollection);
@@ -108,6 +129,7 @@ namespace MarketData.Generator.CMMomentum
}
this[slotPosition.Slot].Add(slotPosition.ToPosition());
}
public List<NVPCollections> ToNVPCollections()
{
List<int> slots = new List<int>(Keys);

View File

@@ -38,7 +38,7 @@ namespace MarketData.Generator.CMMomentum
private String PathSessionFileName { get; set; }
// ******************************************************************************************************************************************************
//********************************************************** U P D A T E S E S S I O N P R I C E *****************************************************
//********************************************************** D I S P L A Y G A I N L O S S *********************************************************
// ******************************************************************************************************************************************************
public void DisplayGainLoss(String paramPathSessionFileName)
{
@@ -119,25 +119,25 @@ namespace MarketData.Generator.CMMomentum
MarketData.Generator.CMMomentum.Positions combinedPositions=sessionParams.GetCombinedPositions();
// Fix purchase date/sell date fall on weekend
foreach(MarketData.Generator.CMMomentum.Position position in combinedPositions)
{
if(dateGenerator.IsWeekend(position.PurchaseDate))
{
while(true)
{
position.PurchaseDate=dateGenerator.GetPrevBusinessDay(position.PurchaseDate);
if(!HolidayDA.IsMarketHoliday(position.PurchaseDate)) break;
}
}
if(dateGenerator.IsWeekend(position.SellDate))
{
while(true)
{
position.SellDate=dateGenerator.GetNextBusinessDay(position.SellDate);
if(!HolidayDA.IsMarketHoliday(position.SellDate)) break;
}
}
}
//foreach(MarketData.Generator.CMMomentum.Position position in combinedPositions)
//{
// if(dateGenerator.IsWeekend(position.PurchaseDate))
// {
// while(true)
// {
// position.PurchaseDate=dateGenerator.GetPrevBusinessDay(position.PurchaseDate);
// if(!HolidayDA.IsMarketHoliday(position.PurchaseDate)) break;
// }
// }
// if(dateGenerator.IsWeekend(position.SellDate))
// {
// while(true)
// {
// position.SellDate=dateGenerator.GetNextBusinessDay(position.SellDate);
// if(!HolidayDA.IsMarketHoliday(position.SellDate)) break;
// }
// }
//}
// ********************************************************
DateTime minDate=combinedPositions.Min(x => x.PurchaseDate);
DateTime maxDate=PricingDA.GetLatestDate();
@@ -206,48 +206,6 @@ namespace MarketData.Generator.CMMomentum
}
}
// ******************************************************************************************************************************************************
//********************************************************** U P D A T E S E S S I O N P R I C E *****************************************************
// ******************************************************************************************************************************************************
public void UpdateSessionPrice(String symbol, DateTime tradeDate, double price, String pathSessionFileName)
{
CMSessionParams sessionParams = null;
if (null == symbol || Utility.IsEpoch(tradeDate) || null == pathSessionFileName)
{
MDTrace.WriteLine(LogLevel.DEBUG, "UpdateSessionPrice. One or more parameters are invalid.");
return;
}
PathSessionFileName = pathSessionFileName;
if (null == (sessionParams = RestoreSession()))
{
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Error loading session file {0}", pathSessionFileName));
return;
}
List<int> keys = new List<int>(ActivePositions.Keys);
bool hasChanges = false;
foreach (int key in keys)
{
Positions positions = ActivePositions[key];
foreach (Position position in positions)
{
if (!position.Symbol.Equals(symbol) || !position.PurchaseDate.Date.Equals(tradeDate.Date)) continue;
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Changing purchase price for {0} on {1} from {2} to {3}",
position.Symbol,
Utility.DateTimeToStringMMHDDHYYYY(position.PurchaseDate),
Utility.FormatCurrency(position.PurchasePrice),
Utility.FormatCurrency(price)));
position.PurchasePrice = price;
if (!hasChanges) hasChanges = true;
}
}
if (hasChanges) SaveSession();
ActivePositions.Display();
DisplayBalanceFromPositions();
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("StartDate:{0}", Utility.DateTimeToStringMMHDDHYYYY(StartDate)));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("TradeDate:{0}", Utility.DateTimeToStringMMHDDHYYYY(TradeDate)));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("AnalysisDate:{0}", Utility.DateTimeToStringMMHDDHYYYY(AnalysisDate)));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Next Slot:{0}", Cycle));
}
// ******************************************************************************************************************************************************
//************************************************************** D I S P L A Y S E S S I O N *****************************************************
// ******************************************************************************************************************************************************
public void DisplaySession(String paramPathSessionFileName)
@@ -299,45 +257,86 @@ namespace MarketData.Generator.CMMomentum
else MDTrace.WriteLine(LogLevel.DEBUG,"There does not appear to be any trade data in this file.");
}
// ******************************************************************************************************************************************************
//******************************************************* L I Q U I D A T E A L L P O S I T I O N S ***********************************************
// ****************************************************************** C L O S E **********************************************************************
// ******************************************************************************************************************************************************
public void CMLiquidate(String pathSessionFile, DateTime? tradeDate)
public bool ClosePosition(String symbol,DateTime purchaseDate,DateTime sellDate,double sellPrice,String pathSessionFile)
{
if (null == pathSessionFile) return;
CMSessionParams sessionParams = null;
if(null==pathSessionFile) return false;
CMSessionParams sessionParams=null;
PathSessionFileName = pathSessionFile;
if (null == (sessionParams = RestoreSession()))
PathSessionFileName=pathSessionFile;
if(null==(sessionParams=RestoreSession()))
{
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Error loading session file {0}", pathSessionFile));
return;
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Error loading session file {0}",pathSessionFile));
return false;
}
MDTrace.WriteLine(LogLevel.DEBUG, "************** L I Q U I D A T E P O S I T I O N S *************");
if (null == ActivePositions || 0 == ActivePositions.Count)
if(!BackupSession()) return false;
Positions activePositions = ActivePositions.GetPositions();
Position 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
{
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("No active positions in file {0}", pathSessionFile));
return;
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 = sellPrice;
CashBalance += position.MarketValue;
SaveSession();
return true;
}
if (null == tradeDate) tradeDate = PricingDA.GetLatestDate(ActivePositions.GetSymbols());
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Trade date:{0}", Utility.DateTimeToStringMMHDDHYYYY(tradeDate.Value)));
if (null == (sessionParams = RestoreSession()))
{
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Error loading session file {0}", pathSessionFile));
return;
}
for (int slotIndex = 0; slotIndex < ActivePositions.Count; slotIndex++)
{
Positions slotPositions = ActivePositions[slotIndex];
SellPositions(slotPositions, tradeDate.Value);
MDTrace.WriteLine(LogLevel.DEBUG, "********************* S E L L *********************");
slotPositions.Display();
AllPositions.Add(slotPositions);
CashBalance += slotPositions.MarketValue;
ActivePositions[slotIndex].Clear();
}
GBPriceCache.GetInstance().Dispose();
position.SellDate = sellDate;
position.CurrentPrice = sellPrice;
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;
}
// ******************************************************************************************************************************************************
// *************************************************************************** E D I T ******************************************************************
// ******************************************************************************************************************************************************
public bool EditPosition(String symbol,DateTime purchaseDate,double purchasePrice,String pathSessionFile)
{
if(null==pathSessionFile) return false;
PathSessionFileName=pathSessionFile;
CMSessionParams sessionParams=null;
if(null==(sessionParams=RestoreSession()))
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Error loading session file {0}",pathSessionFile));
return false;
}
if(!BackupSession()) return false;
Positions activePositions = ActivePositions.GetPositions();
Position 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.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)));
CashBalance+=(position.PurchasePrice-purchasePrice)*position.Shares;
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;
}
// ******************************************************************************************************************************************************
// ****************************************************************** B A C K T E S T *****************************************************************
// ******************************************************************************************************************************************************
@@ -356,7 +355,6 @@ namespace MarketData.Generator.CMMomentum
TradeDate = paramStartDate;
AnalysisDate = paramAnalysisDate;
PathSessionFileName = paramPathSessionFileName;
SMSNotifications = new SMSNotifications();
CMSessionParams sessionParams = null;
Cycle = 0;
@@ -606,7 +604,7 @@ namespace MarketData.Generator.CMMomentum
// ***************************************************************************************************************************************************
// ***************************************************************** P O S I T I O N W E I G H T S ************************************************
// ***************************************************************************************************************************************************
// This is a post-stage to the above PositiionSizing. It works by examing the weights of the positions in the bucket and ensuring that no position weight is larger than UseMaxPositionBucketWeightMaxWeight.
// This is a post-stage to the above PositionSizing. It works by examing the weights of the positions in the bucket and ensuring that no position weight is larger than UseMaxPositionBucketWeightMaxWeight.
// If an overweight position is located then it's exposure is reduced to UseMaxPositionBucketWeightMaxWeight and the remaining positions divide the excess exposure evenly.
// This prevents any single position from eclipsing the other positions in the bucket.
private Positions AdjustPositionWeights(Positions positions)
@@ -712,6 +710,22 @@ namespace MarketData.Generator.CMMomentum
return DateTime.Now;
}
// ****************************************************************************************************************************************
// ************************************************************** C N N S E R V E R ***************************************************
// ****************************************************************************************************************************************
private void CheckCNNServerStatus()
{
if(Parameters.UseCNN) // ping the server here so that we don't have to do it for each request
{
CNNClient cnnClient=new CNNClient(Parameters.UseCNNHost);
if(!cnnClient.Ping())
{
String strMessage=String.Format("******* UseCNN=true but the server is not responding. {0} *******",Parameters.UseCNNHost);
Console.Beep(800,200);
throw new Exception(strMessage);
}
}
}
// ****************************************************************************************************************************************
// **************************************************************** S E S S I O N M A N A G E M E N T ***********************************
// ****************************************************************************************************************************************
public CMSessionParams RestoreSession()
@@ -725,6 +739,7 @@ namespace MarketData.Generator.CMMomentum
TradeDate = sessionParams.TradeDate;
if (TradeDate.Date < AnalysisDate.Date) TradeDate = AnalysisDate;
StartDate = sessionParams.StartDate;
AnalysisDate = sessionParams.AnalysisDate;
Parameters = sessionParams.CMParams;
ActivePositions = sessionParams.ActivePositions;
AllPositions = sessionParams.AllPositions;
@@ -739,6 +754,7 @@ namespace MarketData.Generator.CMMomentum
return null;
}
}
public void SaveSession()
{
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Saving session to '{0}'", PathSessionFileName));
@@ -756,18 +772,25 @@ namespace MarketData.Generator.CMMomentum
sessionParams.NonTradeableCash = NonTradeableCash;
sessionManager.SaveSession(sessionParams, PathSessionFileName);
}
private void CheckCNNServerStatus()
public bool BackupSession()
{
if(Parameters.UseCNN) // ping the server here so that we don't have to do it for each request
{
CNNClient cnnClient=new CNNClient(Parameters.UseCNNHost);
if(!cnnClient.Ping())
{
String strMessage=String.Format("******* UseCNN=true but the server is not responding. {0} *******",Parameters.UseCNNHost);
Console.Beep(800,200);
throw new Exception(strMessage);
}
}
String[] parts=PathSessionFileName.Split('.');
String backupFileName=parts[0]+"_"+Utility.DateTimeToStringYYYYMMDDMMSSTT(DateTime.Now)+".bak";
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Saving session to '{0}'",backupFileName));
CMSessionParams sessionParams = new CMSessionParams();
CMSessionManager sessionManager = new CMSessionManager();
sessionParams.LastUpdated = Today();
sessionParams.TradeDate = TradeDate;
sessionParams.StartDate = StartDate;
sessionParams.AnalysisDate = AnalysisDate;
sessionParams.CMParams = Parameters;
sessionParams.ActivePositions = ActivePositions;
sessionParams.AllPositions = AllPositions;
sessionParams.Cycle = Cycle;
sessionParams.CashBalance = CashBalance;
sessionParams.NonTradeableCash = NonTradeableCash;
return sessionManager.SaveSession(sessionParams, backupFileName);
}
}
}

View File

@@ -1,22 +1,19 @@
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 MarketData.Generator.Interface;
namespace MarketData.Generator.CMMomentum
{
public class Position
public class Position : IPurePosition
{
public Position()
{
CurrentPrice = double.NaN;
CNNPrediction=false;
}
public Position(Position position)
{
Symbol = position.Symbol;
@@ -34,32 +31,69 @@ namespace MarketData.Generator.CMMomentum
TargetBetaOverBeta = position.TargetBetaOverBeta;
CNNPrediction=position.CNNPrediction;
}
public static Position Clone(Position position)
{
Position clonedPosition = new Position();
clonedPosition.Symbol = position.Symbol;
clonedPosition.PurchaseDate = position.PurchaseDate;
clonedPosition.SellDate = position.SellDate;
clonedPosition.Shares = position.Shares;
clonedPosition.PurchasePrice = position.PurchasePrice;
clonedPosition.CurrentPrice = position.CurrentPrice;
clonedPosition.Beta = position.Beta;
clonedPosition.BetaMonths = position.BetaMonths;
clonedPosition.SharpeRatio = position.SharpeRatio;
clonedPosition.Weight = position.Weight;
clonedPosition.RiskAdjustedWeight = position.RiskAdjustedWeight;
clonedPosition.RiskAdjustedAllocation = position.RiskAdjustedAllocation;
clonedPosition.TargetBetaOverBeta = position.TargetBetaOverBeta;
clonedPosition.CNNPrediction = position.CNNPrediction;
return clonedPosition;
}
public String Symbol { get; set; }
public DateTime PurchaseDate { get; set; }
public DateTime SellDate { get; set; }
public double Shares { get; set; }
public double PurchasePrice { get; set; }
public double CurrentPrice { get; set; }
public double Exposure { get { return Shares * PurchasePrice; } } // Derived
public double MarketValue { get { return Shares * CurrentPrice; } } // Derived
public double GainLoss { get { return MarketValue - Exposure; } } // Derived
public double GainLossPcnt { get { return (MarketValue - Exposure) / Exposure; } }// Derived
public double Beta { get; set; }
public int BetaMonths { get; set; }
public double SharpeRatio { get; set; }
public double Weight { get; set; }
public double RiskAdjustedWeight { get; set; }
public double RiskAdjustedAllocation { get; set; }
public double TargetBetaOverBeta { get; set; }
public double Score{get;set;}
public bool CNNPrediction{get;set;}
public virtual NVPCollection ToNVPCollection()
{
NVPCollection nvpCollection = new NVPCollection();
nvpCollection.Add(new NVP("Symbol", Symbol.ToString()));
//nvpCollection.Add(new NVP("PurchaseDate", PurchaseDate.ToString()));
//nvpCollection.Add(new NVP("SellDate", SellDate.ToString()));
nvpCollection.Add(new NVP("PurchaseDate", PurchaseDate.Date.ToString()));
nvpCollection.Add(new NVP("SellDate", SellDate.Date.ToString()));
nvpCollection.Add(new NVP("Shares", Shares.ToString()));
@@ -75,13 +109,12 @@ namespace MarketData.Generator.CMMomentum
nvpCollection.Add(new NVP("CNNPrediction", CNNPrediction.ToString()));
return nvpCollection;
}
public static Position FromNVPCollection(NVPCollection nvpCollection)
{
Position position = new Position();
NVPDictionary nvpDictionary = nvpCollection.ToDictionary();
position.Symbol = nvpDictionary["Symbol"].Get<String>();
//position.PurchaseDate = nvpDictionary["PurchaseDate"].Get<DateTime>();
//position.SellDate = nvpDictionary["SellDate"].Get<DateTime>();
position.PurchaseDate = nvpDictionary["PurchaseDate"].Get<DateTime>().Date;
position.SellDate = nvpDictionary["SellDate"].Get<DateTime>().Date;
position.Shares = nvpDictionary["Shares"].Get<double>();
@@ -97,6 +130,7 @@ namespace MarketData.Generator.CMMomentum
if(nvpDictionary.ContainsKey("CNNPrediction"))position.CNNPrediction = nvpDictionary["CNNPrediction"].Get<bool>();
return position;
}
public void Display()
{
if (Utility.IsEpoch(SellDate) && double.IsNaN(CurrentPrice))
@@ -146,6 +180,7 @@ namespace MarketData.Generator.CMMomentum
));
}
}
public static void DisplayHeader()
{
MDTrace.WriteLine(LogLevel.DEBUG, "Symbol,Shares,Purchase Date,Purchase Price,Sell Date,Sell Price,Exposure,Beta,BetaMonths,SharpeRatio,RiskAdjustedWeight,RiskAdjustedAllocation,TargetBetaOverBeta,Score,CNNPrediction,Market Value,Gain Loss,Gain Loss(%)");
@@ -154,25 +189,30 @@ namespace MarketData.Generator.CMMomentum
// ****************************************************************************************************************************************************************
public class Positions : List<Position>
{
public Positions()
public Positions()
{
}
public Positions(Positions positions)
{
foreach (Position position in positions) Add(position);
}
public Positions(List<Position> positions)
{
foreach (Position position in positions) Add(position);
}
public Positions(Position position)
{
Add(position);
}
public void Add(Positions positions)
{
foreach (Position position in positions) Add(position);
}
public double Exposure
{
get
@@ -180,6 +220,7 @@ namespace MarketData.Generator.CMMomentum
return (from Position position in this select position.PurchasePrice * position.Shares).Sum();
}
}
public double MarketValue
{
get
@@ -197,6 +238,7 @@ namespace MarketData.Generator.CMMomentum
}
return nvpCollections;
}
public static Positions FromNVPCollections(NVPCollections nvpCollections)
{
Positions positions = new Positions();
@@ -206,6 +248,7 @@ namespace MarketData.Generator.CMMomentum
}
return positions;
}
public void DisplayTopFive()
{
Positions positions = new Positions(this.OrderByDescending(x => x.GainLossPcnt).Take(5).ToList());
@@ -216,6 +259,7 @@ namespace MarketData.Generator.CMMomentum
position.Display();
}
}
public void DisplayBottomFive()
{
Positions positions = new Positions(this.OrderBy(x => x.GainLossPcnt).Take(5).ToList());
@@ -226,6 +270,7 @@ namespace MarketData.Generator.CMMomentum
position.Display();
}
}
public void Display()
{
Position.DisplayHeader();

View File

@@ -125,25 +125,25 @@ namespace MarketData.Generator.CMTrend
MarketData.Generator.CMTrend.Positions combinedPositions=sessionParams.GetCombinedPositions();
// Fix purchase date/sell date fall on weekend
foreach(MarketData.Generator.CMTrend.Position position in combinedPositions)
{
if(dateGenerator.IsWeekend(position.PurchaseDate))
{
while(true)
{
position.PurchaseDate=dateGenerator.GetPrevBusinessDay(position.PurchaseDate);
if(!HolidayDA.IsMarketHoliday(position.PurchaseDate)) break;
}
}
if(dateGenerator.IsWeekend(position.SellDate))
{
while(true)
{
position.SellDate=dateGenerator.GetNextBusinessDay(position.SellDate);
if(!HolidayDA.IsMarketHoliday(position.SellDate)) break;
}
}
}
//foreach(MarketData.Generator.CMTrend.Position position in combinedPositions)
//{
// if(dateGenerator.IsWeekend(position.PurchaseDate))
// {
// while(true)
// {
// position.PurchaseDate=dateGenerator.GetPrevBusinessDay(position.PurchaseDate);
// if(!HolidayDA.IsMarketHoliday(position.PurchaseDate)) break;
// }
// }
// if(dateGenerator.IsWeekend(position.SellDate))
// {
// while(true)
// {
// position.SellDate=dateGenerator.GetNextBusinessDay(position.SellDate);
// if(!HolidayDA.IsMarketHoliday(position.SellDate)) break;
// }
// }
//}
// ********************************************************
DateTime minDate=combinedPositions.Min(x => x.PurchaseDate);
DateTime maxDate=PricingDA.GetLatestDate();

View File

@@ -34,50 +34,6 @@ namespace MarketData.Generator.MGSHMomentum
private DateTime StartDate{get;set;}
private DateTime AnalysisDate{get;set;}
private String PathSessionFileName{get;set;}
// ******************************************************************************************************************************************************
//********************************************************** U P D A T E S E S S I O N P R I C E *****************************************************
// ******************************************************************************************************************************************************
public void UpdateSessionPrice(String symbol,DateTime tradeDate,double price,String pathSessionFileName)
{
MGSHSessionParams sessionParams=null;
if(null==symbol||Utility.IsEpoch(tradeDate)||null==pathSessionFileName)
{
MDTrace.WriteLine(LogLevel.DEBUG,"UpdateSessionPrice. One or more parameters are invalid.");
return;
}
PathSessionFileName=pathSessionFileName;
if(null==(sessionParams=RestoreSession()))
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Error loading session file {0}",pathSessionFileName));
return;
}
List<int> keys=new List<int>(ActivePositions.Keys);
bool hasChanges=false;
foreach(int key in keys)
{
MGSHPositions positions=ActivePositions[key];
foreach(MGSHPosition position in positions)
{
if(!position.Symbol.Equals(symbol)||!position.PurchaseDate.Date.Equals(tradeDate.Date))continue;
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Changing purchase price for {0} on {1} from {2} to {3}",
position.Symbol,
Utility.DateTimeToStringMMHDDHYYYY(position.PurchaseDate),
Utility.FormatCurrency(position.PurchasePrice),
Utility.FormatCurrency(price)));
position.PurchasePrice=price;
if(!hasChanges)hasChanges=true;
}
}
if(hasChanges)SaveSession();
ActivePositions.Display();
DisplayBalanceFromPositions();
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("StartDate:{0}",Utility.DateTimeToStringMMHDDHYYYY(StartDate)));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("TradeDate:{0}",Utility.DateTimeToStringMMHDDHYYYY(TradeDate)));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("AnalysisDate:{0}",Utility.DateTimeToStringMMHDDHYYYY(AnalysisDate)));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Next Slot:{0}",Cycle));
}
// ******************************************************************************************************************************************************
//************************************************************** D I S P L A Y G A I N L O S S *****************************************************
// ******************************************************************************************************************************************************
@@ -119,9 +75,9 @@ namespace MarketData.Generator.MGSHMomentum
}
}
// ******************************************************************************************************************************************************
// *************************************************************************** E D I T ******************************************************************
// ******************************************************************************************************************************************************
// ******************************************************************************************************************************************************
// *************************************************************************** E D I T ******************************************************************
// ******************************************************************************************************************************************************
public bool EditPosition(String symbol,DateTime purchaseDate,double purchasePrice,double initialStop,double trailingStop,String sessionFile)
{
if (!MGSHSessionManager.IsValidSessionFile(sessionFile))
@@ -137,7 +93,6 @@ namespace MarketData.Generator.MGSHMomentum
AnalysisDate = sessionParams.AnalysisDate;
Cycle=sessionParams.Cycle;
sessionParams.LastUpdated = DateTime.Now;
//sessionParams.CMTParams.AnalysisDate=DateTime.Now;
StopLimits=sessionParams.StopLimits;
ActivePositions=sessionParams.ActivePositions;
AllPositions=sessionParams.AllPositions;
@@ -170,6 +125,9 @@ namespace MarketData.Generator.MGSHMomentum
return true;
}
// ******************************************************************************************************************************************************
// ************************************************************************ C L O S E ******************************************************************
// ******************************************************************************************************************************************************
public bool ClosePosition(String symbol,DateTime purchaseDate,DateTime sellDate,double price,String sessionFile)
{
if (!MGSHSessionManager.IsValidSessionFile(sessionFile))
@@ -186,7 +144,6 @@ namespace MarketData.Generator.MGSHMomentum
AnalysisDate = sessionParams.AnalysisDate;
Cycle=sessionParams.Cycle;
sessionParams.LastUpdated = DateTime.Now;
//sessionParams.CMTParams.AnalysisDate=DateTime.Now;
StopLimits=sessionParams.StopLimits;
ActivePositions=sessionParams.ActivePositions;
AllPositions=sessionParams.AllPositions;
@@ -198,7 +155,7 @@ namespace MarketData.Generator.MGSHMomentum
if(!BackupSession())return false;
MGSHPositions activePositions = ActivePositions.GetPositions();
MGSHPosition position=activePositions.Where(x => x.Symbol.Equals(symbol)&&x.PurchaseDate.Equals(purchaseDate)).FirstOrDefault();
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();
@@ -275,25 +232,25 @@ namespace MarketData.Generator.MGSHMomentum
MGSHPositions combinedPositions=sessionParams.GetCombinedPositions();
// Fix purchase date/sell date fall on weekend
foreach(MGSHPosition position in combinedPositions)
{
if(dateGenerator.IsWeekend(position.PurchaseDate))
{
while(true)
{
position.PurchaseDate=dateGenerator.GetPrevBusinessDay(position.PurchaseDate);
if(!HolidayDA.IsMarketHoliday(position.PurchaseDate)) break;
}
}
if(dateGenerator.IsWeekend(position.SellDate))
{
while(true)
{
position.SellDate=dateGenerator.GetNextBusinessDay(position.SellDate);
if(!HolidayDA.IsMarketHoliday(position.SellDate)) break;
}
}
}
//foreach(MGSHPosition position in combinedPositions)
//{
// if(dateGenerator.IsWeekend(position.PurchaseDate))
// {
// while(true)
// {
// position.PurchaseDate=dateGenerator.GetPrevBusinessDay(position.PurchaseDate);
// if(!HolidayDA.IsMarketHoliday(position.PurchaseDate)) break;
// }
// }
// if(dateGenerator.IsWeekend(position.SellDate))
// {
// while(true)
// {
// position.SellDate=dateGenerator.GetNextBusinessDay(position.SellDate);
// if(!HolidayDA.IsMarketHoliday(position.SellDate)) break;
// }
// }
//}
// ********************************************************
DateTime minDate=combinedPositions.Min(x => x.PurchaseDate);
DateTime maxDate=PricingDA.GetLatestDate();

View File

@@ -18,7 +18,6 @@ namespace MarketData.Generator.Momentum
private int MaxPositions{get{return Configuration.MaxPositions;}}
private List<String> NoTradeSymbols{get{return Utility.ToList(Configuration.NoTradeSymbols);}}
private ActivePositions ActivePositions{get;set;}
private SMSNotifications SMSNotifications{get;set;}
private Positions AllPositions{get;set;}
private int Cycle{get;set;}
private DateTime TradeDate{get;set;}
@@ -26,48 +25,6 @@ namespace MarketData.Generator.Momentum
private DateTime AnalysisDate{get;set;}
private String PathSessionFileName{get;set;}
// ******************************************************************************************************************************************************
//********************************************************** U P D A T E S E S S I O N P R I C E *****************************************************
// ******************************************************************************************************************************************************
public void UpdateSessionPrice(String symbol,DateTime tradeDate,double price,String pathSessionFileName)
{
MGSessionParams sessionParams=null;
if(null==symbol||Utility.IsEpoch(tradeDate)||null==pathSessionFileName)
{
MDTrace.WriteLine(LogLevel.DEBUG,"UpdateSessionPrice. One or more parameters are invalid.");
return;
}
PathSessionFileName=pathSessionFileName;
if(null==(sessionParams=RestoreSession()))
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Error loading session file {0}",pathSessionFileName));
return;
}
List<int> keys=new List<int>(ActivePositions.Keys);
bool hasChanges=false;
foreach(int key in keys)
{
Positions positions=ActivePositions[key];
foreach(Position position in positions)
{
if(!position.Symbol.Equals(symbol)||!position.PurchaseDate.Date.Equals(tradeDate.Date))continue;
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Changing purchase price for {0} on {1} from {2} to {3}",
position.Symbol,
Utility.DateTimeToStringMMHDDHYYYY(position.PurchaseDate),
Utility.FormatCurrency(position.PurchasePrice),
Utility.FormatCurrency(price)));
position.PurchasePrice=price;
if(!hasChanges)hasChanges=true;
}
}
if(hasChanges)SaveSession();
ActivePositions.Display();
DisplayBalanceFromPositions();
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("StartDate:{0}",Utility.DateTimeToStringMMHDDHYYYY(StartDate)));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("TradeDate:{0}",Utility.DateTimeToStringMMHDDHYYYY(TradeDate)));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("AnalysisDate:{0}",Utility.DateTimeToStringMMHDDHYYYY(AnalysisDate)));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Next Slot:{0}",Cycle));
}
// ******************************************************************************************************************************************************
//************************************************************** D I S P L A Y G A I N L O S S *****************************************************
// ******************************************************************************************************************************************************
public static void DisplayGainLoss(String paramPathSessionFileName)
@@ -93,6 +50,7 @@ namespace MarketData.Generator.Momentum
}
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Done, took {0}(ms)",profiler.End()));
}
public static ModelPerformanceSeries GetModelPerformance(String paramPathSessionFileName)
{
try
@@ -139,6 +97,7 @@ namespace MarketData.Generator.Momentum
return modelStatistics;
}
}
public static ModelPerformanceSeries GetModelPerformance(MGSessionParams sessionParams)
{
Profiler profiler=new Profiler();
@@ -150,25 +109,25 @@ namespace MarketData.Generator.Momentum
MarketData.Generator.Momentum.Positions combinedPositions=sessionParams.GetCombinedPositions();
// Fix purchase date/sell date fall on weekend
foreach(MarketData.Generator.Momentum.Position position in combinedPositions)
{
if(dateGenerator.IsWeekend(position.PurchaseDate))
{
while(true)
{
position.PurchaseDate=dateGenerator.GetPrevBusinessDay(position.PurchaseDate);
if(!HolidayDA.IsMarketHoliday(position.PurchaseDate)) break;
}
}
if(dateGenerator.IsWeekend(position.SellDate))
{
while(true)
{
position.SellDate=dateGenerator.GetNextBusinessDay(position.SellDate);
if(!HolidayDA.IsMarketHoliday(position.SellDate)) break;
}
}
}
//foreach(MarketData.Generator.Momentum.Position position in combinedPositions)
//{
// if(dateGenerator.IsWeekend(position.PurchaseDate))
// {
// while(true)
// {
// position.PurchaseDate=dateGenerator.GetPrevBusinessDay(position.PurchaseDate);
// if(!HolidayDA.IsMarketHoliday(position.PurchaseDate)) break;
// }
// }
// if(dateGenerator.IsWeekend(position.SellDate))
// {
// while(true)
// {
// position.SellDate=dateGenerator.GetNextBusinessDay(position.SellDate);
// if(!HolidayDA.IsMarketHoliday(position.SellDate)) break;
// }
// }
//}
// ********************************************************
DateTime minDate=combinedPositions.Min(x => x.PurchaseDate);
DateTime maxDate=PricingDA.GetLatestDate();
@@ -298,53 +257,8 @@ namespace MarketData.Generator.Momentum
SaveSession();
}
// ******************************************************************************************************************************************************
//******************************************************* S E L L P O S I T I O N ***********************************************
// ****************************************************************** C L O S E **********************************************************************
// ******************************************************************************************************************************************************
public void MGClosePosition(String pathSessionFile,String symbol,DateTime purchaseDate,double sellPrice,DateTime sellDate)
{
if(null==pathSessionFile) return;
MGSessionParams sessionParams=null;
PathSessionFileName=pathSessionFile;
if(null==(sessionParams=RestoreSession()))
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Error loading session file {0}",pathSessionFile));
return;
}
MDTrace.WriteLine(LogLevel.DEBUG,"************** S E L L P O S I T I O N *************");
if(null==ActivePositions||0==ActivePositions.Count)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("No active positions in file {0}",pathSessionFile));
return;
}
Positions activePositions=ActivePositions.GetPositions();
Position positionToSell=ActivePositions.FindPosition(symbol,purchaseDate);
if(null==positionToSell)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("No active position found for {0} purchased on {1}",symbol,Utility.DateTimeToStringMMHDDHYYYY(purchaseDate)));
return;
}
int positionToSellSlot=ActivePositions.FindSlotForPosition(positionToSell);
if(-1==positionToSellSlot)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Could not locate slot index for position {0} purchased on {1}",symbol,Utility.DateTimeToStringMMHDDHYYYY(purchaseDate)));
return;
}
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Found position {0} purchased on {1}",symbol,Utility.DateTimeToStringMMHDDHYYYY(purchaseDate)));
positionToSell.SellDate=sellDate.Date;
positionToSell.CurrentPrice=sellPrice;
AllPositions.Add(positionToSell);
CashBalance+=positionToSell.MarketValue;
ActivePositions[positionToSellSlot].Remove(positionToSell);
DisplayBalance();
GBPriceCache.GetInstance().Dispose();
SaveSession();
}
// ******************************************************************************************************************************************************
// ****************************************************************** C L O S E **********************************************************************
// ******************************************************************************************************************************************************
public bool ClosePosition(String symbol,DateTime purchaseDate,DateTime sellDate,double sellPrice,String pathSessionFile)
{
if(null==pathSessionFile) return false;
@@ -383,17 +297,14 @@ namespace MarketData.Generator.Momentum
SaveSession();
return true;
}
// ******************************************************************************************************************************************************
// *************************************************************************** E D I T ******************************************************************
// ******************************************************************************************************************************************************
// ******************************************************************************************************************************************************
// *************************************************************************** E D I T ******************************************************************
// ******************************************************************************************************************************************************
public bool EditPosition(String symbol,DateTime purchaseDate,double purchasePrice,String pathSessionFile)
{
if(null==pathSessionFile) return false;
MGSessionParams sessionParams=null;
PathSessionFileName=pathSessionFile;
MGSessionParams sessionParams=null;
if(null==(sessionParams=RestoreSession()))
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Error loading session file {0}",pathSessionFile));
@@ -443,7 +354,6 @@ namespace MarketData.Generator.Momentum
TradeDate=paramStartDate;
AnalysisDate=paramAnalysisDate;
PathSessionFileName=paramPathSessionFileName;
SMSNotifications=new SMSNotifications();
MGSessionParams sessionParams=null;
Cycle=0;
@@ -481,7 +391,6 @@ namespace MarketData.Generator.Momentum
{
positions.Clear();
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("********** Insufficient funds to make additional purchases.**************"));
// break;
}
positions.Display();
ActivePositions.Add(slotIndex,positions);
@@ -543,7 +452,8 @@ namespace MarketData.Generator.Momentum
backTestResult.CashBalance=CashBalance;
GBPriceCache.GetInstance().Dispose();
return backTestResult;
}
}
public List<String> SymbolsHeld(DateTime tradeDate)
{
List<String> symbolsHeld=ActivePositions.SymbolsHeld();
@@ -603,6 +513,7 @@ namespace MarketData.Generator.Momentum
else position.CurrentPrice=price.Close;
}
}
private void SellPosition(Position position,DateTime sellDate)
{
Price price=GBPriceCache.GetInstance().GetPrice(position.Symbol,sellDate);
@@ -680,6 +591,7 @@ namespace MarketData.Generator.Momentum
}
return positions;
}
private Positions BuyBenchmarkPositions(DateTime tradeDate, double cash)
{
Positions positions = new Positions();
@@ -714,6 +626,7 @@ namespace MarketData.Generator.Momentum
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("TOTAL EXPOSURE: {0}",Utility.FormatCurrency(ActivePositions.GetExposure())));
MDTrace.WriteLine(LogLevel.DEBUG,"*******************************************");
}
private void DisplayBalanceFromPositions()
{
MDTrace.WriteLine(LogLevel.DEBUG,"EXPOSURE,GAIN/LOSS,GAIN/LOSS(%),AVAILABLE CASH,TOTAL ACCOUNT");
@@ -724,6 +637,7 @@ namespace MarketData.Generator.Momentum
Utility.AddQuotes(Utility.FormatCurrency(CashBalance)),
Utility.AddQuotes(Utility.FormatCurrency(ActivePositions.GetMarketValue()+CashBalance))));
}
private void DisplayBalance(RealtimeGainLoss gainLoss)
{
MDTrace.WriteLine(LogLevel.DEBUG,"EXPOSURE,GAIN/LOSS,GAIN/LOSS(%),AVAILABLE CASH,TOTAL ACCOUNT");
@@ -804,8 +718,7 @@ namespace MarketData.Generator.Momentum
sessionParams.Cycle=Cycle;
sessionParams.CashBalance=CashBalance;
sessionParams.NonTradeableCash=NonTradeableCash;
sessionManager.SaveSession(sessionParams,backupFileName);
return true;
return sessionManager.SaveSession(sessionParams,backupFileName);
}
}
}