Add netPnl in db for position

This commit is contained in:
2025-10-03 03:11:17 +07:00
parent 5bd4fd7b52
commit 58b07a1a13
9 changed files with 1674 additions and 5 deletions

View File

@@ -0,0 +1,147 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using Managing.Common;
using Managing.Domain.Trades;
namespace Managing.Api.Models.Responses
{
/// <summary>
/// View model for Position data, matching the Position domain model structure
/// </summary>
public class PositionViewModel
{
/// <summary>
/// Date when the position was created
/// </summary>
[Required]
public DateTime Date { get; set; }
/// <summary>
/// Account ID associated with this position
/// </summary>
[Required]
public int AccountId { get; set; }
/// <summary>
/// Original direction of the trade (Long/Short)
/// </summary>
[Required]
public Enums.TradeDirection OriginDirection { get; set; }
/// <summary>
/// Trading pair ticker
/// </summary>
[Required]
public Enums.Ticker Ticker { get; set; }
/// <summary>
/// Opening trade for this position
/// </summary>
[Required]
[JsonPropertyName("Open")]
public Trade Open { get; set; }
/// <summary>
/// Stop loss trade for this position
/// </summary>
[Required]
[JsonPropertyName("StopLoss")]
public Trade StopLoss { get; set; }
/// <summary>
/// First take profit trade for this position
/// </summary>
[Required]
[JsonPropertyName("TakeProfit1")]
public Trade TakeProfit1 { get; set; }
/// <summary>
/// Profit and loss information for this position
/// </summary>
[JsonPropertyName("ProfitAndLoss")]
public ProfitAndLoss ProfitAndLoss { get; set; }
/// <summary>
/// UI fees associated with this position
/// </summary>
public decimal UiFees { get; set; }
/// <summary>
/// Gas fees associated with this position
/// </summary>
public decimal GasFees { get; set; }
/// <summary>
/// Current status of the position
/// </summary>
[Required]
public Enums.PositionStatus Status { get; set; }
/// <summary>
/// Signal identifier that triggered this position
/// </summary>
public string SignalIdentifier { get; set; }
/// <summary>
/// Unique identifier for this position
/// </summary>
[Required]
public Guid Identifier { get; set; }
/// <summary>
/// Calculates the total fees for this position based on GMX V2 fee structure
/// </summary>
/// <returns>The total fees for the position</returns>
public decimal CalculateTotalFees()
{
return UiFees + GasFees;
}
/// <summary>
/// Gets the net PnL after deducting fees
/// </summary>
/// <returns>The net PnL after fees</returns>
public decimal GetNetPnL()
{
if (ProfitAndLoss?.Realized == null)
{
return 0;
}
return ProfitAndLoss.Realized;
}
/// <summary>
/// Updates the UI fees for this position
/// </summary>
/// <param name="uiFees">The UI fees to add</param>
public void AddUiFees(decimal uiFees)
{
UiFees += uiFees;
}
/// <summary>
/// Updates the gas fees for this position
/// </summary>
/// <param name="gasFees">The gas fees to add</param>
public void AddGasFees(decimal gasFees)
{
GasFees += gasFees;
}
/// <summary>
/// Checks if the position is finished
/// </summary>
/// <returns>True if the position is finished or flipped</returns>
public bool IsFinished()
{
return Status switch
{
Enums.PositionStatus.Finished => true,
Enums.PositionStatus.Flipped => true,
_ => false
};
}
}
}

View File

@@ -1,5 +1,4 @@
using Managing.Common;
using Managing.Domain.Trades;
namespace Managing.Api.Models.Responses
{
@@ -66,7 +65,7 @@ namespace Managing.Api.Models.Responses
/// <summary>
/// Dictionary of all positions executed by this strategy, keyed by position identifier
/// </summary>
public List<Position> Positions { get; set; } = new List<Position>();
public List<PositionViewModel> Positions { get; set; } = new List<PositionViewModel>();
public Guid Identifier { get; set; }