Add interfaces, add edit position , close position to MG model.

This commit is contained in:
2025-02-24 21:26:30 -05:00
parent f633cc43bb
commit c16c1f4988
6 changed files with 190 additions and 7 deletions

View File

@@ -0,0 +1,13 @@
using System;
namespace MarketData.Generator.Interface
{
public interface IPosition : IPurePosition
{
double TrailingStopLimit {get; set;}
double InitialStopLimit {get; set;}
double PositionRiskPercentDecimal {get; set;}
}
}

View File

@@ -0,0 +1,19 @@
using System;
namespace MarketData.Generator.Interface
{
public interface IPurePosition
{
String Symbol {get; set;}
DateTime PurchaseDate {get; set;}
DateTime SellDate {get; set;}
double CurrentPrice {get; set;}
double PurchasePrice {get; set;}
double Shares {get; set;}
}
}

View File

@@ -74,7 +74,6 @@ namespace MarketData.Generator.MGSHMomentum
public double Return1D{get;set;}
public double GainLoss{get{return MarketValue-Exposure;}}
public double GainLossPcnt{get{return (MarketValue-Exposure)/Exposure;}}
// public String ZacksRank{get;set;}
public double CumReturn252{get;set;}
public double IDIndicator{get;set;}
public double Score{get;set;}

View File

@@ -341,6 +341,90 @@ namespace MarketData.Generator.Momentum
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;
MGSessionParams sessionParams=null;
PathSessionFileName=pathSessionFile;
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) // if it is not in the active positions then the position is already closed and we are modifying either the sell date or the sell price
{
position=AllPositions.Where(x => x.Symbol.Equals(symbol) && x.PurchaseDate.Equals(purchaseDate)).FirstOrDefault();
if(null==position)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Cannot locate position for symbol '{0}' purchased on {1}.",symbol,purchaseDate.ToShortDateString()));
return false;
}
position.SellDate = sellDate;
CashBalance -= position.MarketValue;
position.CurrentPrice = sellPrice;
CashBalance += position.MarketValue;
SaveSession();
return true;
}
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;
MGSessionParams sessionParams=null;
PathSessionFileName=pathSessionFile;
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 *****************************************************************
// ******************************************************************************************************************************************************
@@ -702,5 +786,26 @@ namespace MarketData.Generator.Momentum
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));
MGSessionParams sessionParams=new MGSessionParams();
MGSessionManager sessionManager=new MGSessionManager();
sessionParams.LastUpdated=Today();
sessionParams.TradeDate=TradeDate;
sessionParams.StartDate=StartDate;
sessionParams.AnalysisDate=AnalysisDate;
sessionParams.Configuration=Configuration;
sessionParams.ActivePositions=ActivePositions;
sessionParams.AllPositions=AllPositions;
sessionParams.Cycle=Cycle;
sessionParams.CashBalance=CashBalance;
sessionParams.NonTradeableCash=NonTradeableCash;
sessionManager.SaveSession(sessionParams,backupFileName);
return true;
}
}
}

View File

@@ -1,21 +1,18 @@
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.Momentum
{
public class Position
public class Position : IPurePosition
{
public Position()
{
CurrentPrice=double.NaN;
}
public Position(Position position)
{
Symbol = position.Symbol;
@@ -37,27 +34,73 @@ namespace MarketData.Generator.Momentum
Beta = position.Beta;
SharpeRatio = position.SharpeRatio;
}
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.Volume = position.Volume;
clonedPosition.Return1D = position.Return1D;
clonedPosition.ZacksRank = position.ZacksRank;
clonedPosition.CumReturn252 = position.CumReturn252;
clonedPosition.IDIndicator = position.IDIndicator;
clonedPosition.Score = position.Score;
clonedPosition.MaxDrawdown = position.MaxDrawdown;
clonedPosition.MaxUpside = position.MaxUpside;
clonedPosition.Velocity = position.Velocity;
clonedPosition.PE = position.PE;
clonedPosition.Beta = position.Beta;
clonedPosition.SharpeRatio = position.SharpeRatio;
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;}}
public double MarketValue{get{return Shares*CurrentPrice;}}
public long Volume{get;set;}
public double Return1D{get;set;}
public double GainLoss{get{return MarketValue-Exposure;}}
public double GainLossPcnt{get{return (MarketValue-Exposure)/Exposure;}}
public String ZacksRank{get;set;}
public double CumReturn252{get;set;}
public double IDIndicator{get;set;}
public double Score{get;set;}
public double MaxDrawdown{get;set;}
public double MaxUpside{get;set;}
public double Velocity{get;set;}
public double PE{get;set;}
public double Beta{get;set;}
public double SharpeRatio { get; set; }
public virtual NVPCollection ToNVPCollection()
@@ -83,6 +126,7 @@ namespace MarketData.Generator.Momentum
nvpCollection.Add(new NVP("SharpeRatio", SharpeRatio.ToString()));
return nvpCollection;
}
public static Position FromNVPCollection(NVPCollection nvpCollection)
{
Position position=new Position();
@@ -109,10 +153,12 @@ namespace MarketData.Generator.Momentum
else position.Score=double.NaN;
return position;
}
public static void DisplayHeader()
{
MDTrace.WriteLine(LogLevel.DEBUG, "Symbol,Purchase Date,Shares,Purchase Price,Exposure,Volume,Return1D,Sell Date,Sell Price,Market Value,Gain Loss,Gain Loss(%),CumReturn252,IDIndicator,Score,MaxDrawdown,MaxUpside,Velocity,PE,Beta,SharpeRatio");
}
public void Display()
{
if (Utility.IsEpoch(SellDate) && double.IsNaN(CurrentPrice))

View File

@@ -141,6 +141,7 @@
<Compile Include="Generator\Indicators\BandBreakIndicator.cs" />
<Compile Include="Generator\Indicators\MVPIndicator.cs" />
<Compile Include="Generator\Interface\IPosition.cs" />
<Compile Include="Generator\Interface\IPurePosition.cs" />
<Compile Include="Generator\MGSHMomentum\CandidateSelector.cs" />
<Compile Include="Generator\MGSHMomentum\CandidateViolation.cs" />
<Compile Include="Generator\MGSHMomentum\HedgeManager.cs" />