Add average time
This commit is contained in:
@@ -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}");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user