Fix status IsFinished/IsOpen/IsForMetrics + use redis for markets on gmx.tsx instead of inmemory cache
This commit is contained in:
@@ -564,7 +564,7 @@ public static class TradingBox
|
||||
foreach (var position in positions.Values)
|
||||
{
|
||||
// Only count positions that were opened or closed within the last 24 hours
|
||||
if (position.IsFinished() &&
|
||||
if (position.IsValidForMetrics() &&
|
||||
(position.Open.Date >= cutoff ||
|
||||
(position.StopLoss.Status == TradeStatus.Filled && position.StopLoss.Date >= cutoff) ||
|
||||
(position.TakeProfit1.Status == TradeStatus.Filled && position.TakeProfit1.Date >= cutoff) ||
|
||||
@@ -595,7 +595,7 @@ public static class TradingBox
|
||||
if (timeFilter == "Total")
|
||||
{
|
||||
return positions
|
||||
.Where(p => p.IsFinished() && p.ProfitAndLoss != null)
|
||||
.Where(p => p.IsValidForMetrics() && p.ProfitAndLoss != null)
|
||||
.Sum(p => p.ProfitAndLoss.Realized);
|
||||
}
|
||||
|
||||
@@ -623,7 +623,7 @@ public static class TradingBox
|
||||
|
||||
// Include positions that were closed within the time range
|
||||
return positions
|
||||
.Where(p => p.IsFinished() && p.ProfitAndLoss != null &&
|
||||
.Where(p => p.IsValidForMetrics() && p.ProfitAndLoss != null &&
|
||||
(p.Date >= cutoffDate ||
|
||||
(p.StopLoss.Status == TradeStatus.Filled && p.StopLoss.Date >= cutoffDate) ||
|
||||
(p.TakeProfit1.Status == TradeStatus.Filled && p.TakeProfit1.Date >= cutoffDate) ||
|
||||
@@ -673,8 +673,8 @@ public static class TradingBox
|
||||
|
||||
// Filter positions in the time range
|
||||
var filteredPositions = timeFilter == "Total"
|
||||
? positions.Where(p => p.IsFinished() && p.ProfitAndLoss != null)
|
||||
: positions.Where(p => p.IsFinished() && p.ProfitAndLoss != null &&
|
||||
? positions.Where(p => p.IsValidForMetrics() && p.ProfitAndLoss != null)
|
||||
: positions.Where(p => p.IsValidForMetrics() && p.ProfitAndLoss != null &&
|
||||
(p.Date >= cutoffDate ||
|
||||
(p.StopLoss.Status == TradeStatus.Filled && p.StopLoss.Date >= cutoffDate) ||
|
||||
(p.TakeProfit1.Status == TradeStatus.Filled && p.TakeProfit1.Date >= cutoffDate) ||
|
||||
@@ -729,8 +729,8 @@ public static class TradingBox
|
||||
|
||||
// Filter positions in the time range
|
||||
var filteredPositions = timeFilter == "Total"
|
||||
? positions.Where(p => p.IsFinished())
|
||||
: positions.Where(p => p.IsFinished() &&
|
||||
? positions.Where(p => p.IsValidForMetrics())
|
||||
: positions.Where(p => p.IsValidForMetrics() &&
|
||||
(p.Date >= cutoffDate ||
|
||||
(p.StopLoss.Status == TradeStatus.Filled && p.StopLoss.Date >= cutoffDate) ||
|
||||
(p.TakeProfit1.Status == TradeStatus.Filled && p.TakeProfit1.Date >= cutoffDate) ||
|
||||
|
||||
@@ -137,20 +137,26 @@ public static class TradingHelpers
|
||||
// Check which closing trade was executed (StopLoss, TakeProfit1, or TakeProfit2)
|
||||
if (position.StopLoss?.Status == TradeStatus.Filled)
|
||||
{
|
||||
var stopLossPositionSizeUsd = (position.StopLoss.Price * position.StopLoss.Quantity) * position.StopLoss.Leverage;
|
||||
var uiFeeClose = stopLossPositionSizeUsd * Constants.GMX.Config.UiFeeRate; // Fee paid on closing via StopLoss
|
||||
var stopLossPositionSizeUsd =
|
||||
(position.StopLoss.Price * position.StopLoss.Quantity) * position.StopLoss.Leverage;
|
||||
var uiFeeClose =
|
||||
stopLossPositionSizeUsd * Constants.GMX.Config.UiFeeRate; // Fee paid on closing via StopLoss
|
||||
uiFees += uiFeeClose;
|
||||
}
|
||||
else if (position.TakeProfit1?.Status == TradeStatus.Filled)
|
||||
{
|
||||
var takeProfit1PositionSizeUsd = (position.TakeProfit1.Price * position.TakeProfit1.Quantity) * position.TakeProfit1.Leverage;
|
||||
var uiFeeClose = takeProfit1PositionSizeUsd * Constants.GMX.Config.UiFeeRate; // Fee paid on closing via TakeProfit1
|
||||
var takeProfit1PositionSizeUsd = (position.TakeProfit1.Price * position.TakeProfit1.Quantity) *
|
||||
position.TakeProfit1.Leverage;
|
||||
var uiFeeClose =
|
||||
takeProfit1PositionSizeUsd * Constants.GMX.Config.UiFeeRate; // Fee paid on closing via TakeProfit1
|
||||
uiFees += uiFeeClose;
|
||||
}
|
||||
else if (position.TakeProfit2?.Status == TradeStatus.Filled)
|
||||
{
|
||||
var takeProfit2PositionSizeUsd = (position.TakeProfit2.Price * position.TakeProfit2.Quantity) * position.TakeProfit2.Leverage;
|
||||
var uiFeeClose = takeProfit2PositionSizeUsd * Constants.GMX.Config.UiFeeRate; // Fee paid on closing via TakeProfit2
|
||||
var takeProfit2PositionSizeUsd = (position.TakeProfit2.Price * position.TakeProfit2.Quantity) *
|
||||
position.TakeProfit2.Leverage;
|
||||
var uiFeeClose =
|
||||
takeProfit2PositionSizeUsd * Constants.GMX.Config.UiFeeRate; // Fee paid on closing via TakeProfit2
|
||||
uiFees += uiFeeClose;
|
||||
}
|
||||
|
||||
@@ -190,7 +196,7 @@ public static class TradingHelpers
|
||||
return Constants.GMX.Config.GasFeePerTransaction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Calculates the total volume for a position based on its status and filled trades
|
||||
/// </summary>
|
||||
/// <param name="position">The position to calculate volume for</param>
|
||||
@@ -201,7 +207,7 @@ public static class TradingHelpers
|
||||
var totalVolume = position.Open.Price * position.Open.Quantity * position.Open.Leverage;
|
||||
|
||||
// For closed positions, add volume from filled closing trades
|
||||
if (position.IsFinished())
|
||||
if (position.IsValidForMetrics())
|
||||
{
|
||||
// Add Stop Loss volume if filled
|
||||
if (position.StopLoss?.Status == TradeStatus.Filled)
|
||||
@@ -212,13 +218,15 @@ public static class TradingHelpers
|
||||
// Add Take Profit 1 volume if filled
|
||||
if (position.TakeProfit1?.Status == TradeStatus.Filled)
|
||||
{
|
||||
totalVolume += position.TakeProfit1.Price * position.TakeProfit1.Quantity * position.TakeProfit1.Leverage;
|
||||
totalVolume += position.TakeProfit1.Price * position.TakeProfit1.Quantity *
|
||||
position.TakeProfit1.Leverage;
|
||||
}
|
||||
|
||||
// Add Take Profit 2 volume if filled
|
||||
if (position.TakeProfit2?.Status == TradeStatus.Filled)
|
||||
{
|
||||
totalVolume += position.TakeProfit2.Price * position.TakeProfit2.Quantity * position.TakeProfit2.Leverage;
|
||||
totalVolume += position.TakeProfit2.Price * position.TakeProfit2.Quantity *
|
||||
position.TakeProfit2.Leverage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,16 +77,46 @@ namespace Managing.Domain.Trades
|
||||
[Required]
|
||||
public Guid InitiatorIdentifier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Return true if position is finished even if the position was canceled or rejected
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsFinished()
|
||||
{
|
||||
return Status switch
|
||||
{
|
||||
PositionStatus.Finished => true,
|
||||
PositionStatus.Canceled => true,
|
||||
PositionStatus.Rejected => true,
|
||||
PositionStatus.Flipped => true,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
public bool IsInProfit()
|
||||
{
|
||||
if (ProfitAndLoss?.Net == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ProfitAndLoss.Net > 0;
|
||||
}
|
||||
|
||||
public bool IsOpen()
|
||||
{
|
||||
return Status switch
|
||||
{
|
||||
PositionStatus.Filled => true,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return true if position is valid for metrics calculation (PnL, WinRate, etc.)
|
||||
/// Only positions with status Filled, Finished or Flipped are considered valid
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsValidForMetrics()
|
||||
{
|
||||
return Status switch
|
||||
@@ -94,7 +124,6 @@ namespace Managing.Domain.Trades
|
||||
PositionStatus.Filled => true,
|
||||
PositionStatus.Finished => true,
|
||||
PositionStatus.Flipped => true,
|
||||
PositionStatus.Updating => true,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user