Add average time

This commit is contained in:
2025-06-01 14:59:55 +07:00
parent faafedbdd9
commit 8f8bdf8d69
3 changed files with 91 additions and 3 deletions

View File

@@ -799,6 +799,26 @@ public class TradingBot : Bot, ITradingBot
{
if (Positions.Any(p => p.Identifier == position.Identifier))
{
// Update the close date for the trade that actually closed the position
var currentCandle = Config.IsForBacktest
? OptimizedCandles.LastOrDefault()
: ExchangeService.GetCandle(Account, Config.Ticker, DateTime.UtcNow);
if (currentCandle != null && position.ProfitAndLoss != null)
{
// Determine which trade closed the position based on realized P&L
if (position.ProfitAndLoss.Realized > 0)
{
// Profitable close = Take Profit
position.TakeProfit1.SetDate(currentCandle.Date);
}
else
{
// Loss or breakeven close = Stop Loss
position.StopLoss.SetDate(currentCandle.Date);
}
}
await SetPositionStatus(position.SignalIdentifier, PositionStatus.Finished);
Logger.LogInformation(
$"Position {position.SignalIdentifier} type correctly close. Pnl on position : {position.ProfitAndLoss?.Realized}");

View File

@@ -23,7 +23,7 @@ namespace Managing.Domain.Trades
public decimal Fee { get; set; }
[Required]
public DateTime Date { get; }
public DateTime Date { get; private set; }
[Required]
public TradeDirection Direction { get; }
[Required]
@@ -46,6 +46,11 @@ namespace Managing.Domain.Trades
Status = status;
}
public void SetDate(DateTime date)
{
Date = date;
}
public void SetExchangeOrderId(string exchangeOrderId)
{
ExchangeOrderId = exchangeOrderId;

View File

@@ -24,6 +24,63 @@ const BacktestRowDetails: React.FC<IBacktestRowDetailsProps> = ({
config
} = backtest;
// Helper function to calculate position open time in hours
const calculateOpenTimeInHours = (position: any) => {
const openDate = new Date(position.open.date);
let closeDate: Date | null = null;
// Determine close date based on realized P&L (matching backend logic)
if (position.profitAndLoss?.realized != null) {
if (position.profitAndLoss.realized > 0) {
// Profitable close = Take Profit
closeDate = new Date(position.takeProfit1.date);
} else {
// Loss or breakeven close = Stop Loss
closeDate = new Date(position.stopLoss.date);
}
}
if (closeDate) {
const diffInMs = closeDate.getTime() - openDate.getTime();
return diffInMs / (1000 * 60 * 60); // Convert to hours
}
return 0;
};
// Calculate average open time for winning positions
const getAverageOpenTimeWinning = () => {
const winningPositions = positions.filter((p) => {
const realized = p.profitAndLoss?.realized ?? 0;
return realized > 0;
});
if (winningPositions.length === 0) return "0.00";
const totalHours = winningPositions.reduce((sum, position) => {
return sum + calculateOpenTimeInHours(position);
}, 0);
const averageHours = totalHours / winningPositions.length;
return averageHours.toFixed(2);
};
// Calculate average open time for losing positions
const getAverageOpenTimeLosing = () => {
const losingPositions = positions.filter((p) => {
const realized = p.profitAndLoss?.realized ?? 0;
return realized <= 0;
});
if (losingPositions.length === 0) return "0.00";
const totalHours = losingPositions.reduce((sum, position) => {
return sum + calculateOpenTimeInHours(position);
}, 0);
const averageHours = totalHours / losingPositions.length;
return averageHours.toFixed(2);
};
return (
<>
<div className="grid grid-flow-row">
@@ -81,8 +138,14 @@ const BacktestRowDetails: React.FC<IBacktestRowDetailsProps> = ({
"SL: " + backtest.optimizedMoneyManagement?.stopLoss.toFixed(2) + "% TP: " + backtest.optimizedMoneyManagement?.takeProfit.toFixed(2) + "%"
}
></CardText>
<CardText
title="Avg Open Time (Winning)"
content={getAverageOpenTimeWinning() + " hours"}
></CardText>
<CardText
title="Avg Open Time (Losing)"
content={getAverageOpenTimeLosing() + " hours"}
></CardText>
</div>
<div>
<figure>