|
@@ -42,6 +42,10 @@ class PerformanceCalculator:
|
|
|
def get_performance_stats(self) -> Dict[str, Any]:
|
|
|
"""Get performance stats."""
|
|
|
try:
|
|
|
+ # Get initial balance from metadata
|
|
|
+ initial_balance_str = self.db._get_metadata('initial_balance')
|
|
|
+ initial_balance = float(initial_balance_str) if initial_balance_str else 0.0
|
|
|
+
|
|
|
# Get all token stats
|
|
|
token_stats = self.db._fetch_query(
|
|
|
"SELECT * FROM token_stats",
|
|
@@ -128,15 +132,23 @@ class PerformanceCalculator:
|
|
|
sum_losing = abs(sum(token.get('sum_of_losing_pnl', 0) for token in token_stats))
|
|
|
profit_factor = (sum_winning / sum_losing) if sum_losing > 0 else float('inf') if sum_winning > 0 else 0
|
|
|
|
|
|
+ # Calculate average P&L stats
|
|
|
+ avg_win_pnl = sum_winning / total_wins if total_wins > 0 else 0
|
|
|
+ avg_loss_pnl = sum_losing / total_losses if total_losses > 0 else 0
|
|
|
+ avg_trade_pnl = total_pnl / total_trades if total_trades > 0 else 0.0
|
|
|
+
|
|
|
# Calculate expectancy
|
|
|
- avg_win = sum_winning / total_wins if total_wins > 0 else 0
|
|
|
- avg_loss = sum_losing / total_losses if total_losses > 0 else 0
|
|
|
- expectancy = (avg_win * (win_rate/100)) - (avg_loss * (1 - win_rate/100))
|
|
|
+ expectancy = (avg_win_pnl * (win_rate/100)) - (avg_loss_pnl * (1 - win_rate/100))
|
|
|
|
|
|
# Get max drawdown
|
|
|
max_drawdown, max_drawdown_pct, drawdown_start_date = self.get_live_max_drawdown()
|
|
|
|
|
|
+ # Best/Worst trades by ROE
|
|
|
+ best_roe_trade = self.db._fetchone_query("SELECT token, best_roe_percentage as percentage FROM token_stats WHERE best_roe_percentage IS NOT NULL ORDER BY best_roe_percentage DESC LIMIT 1")
|
|
|
+ worst_roe_trade = self.db._fetchone_query("SELECT token, worst_roe_percentage as percentage FROM token_stats WHERE worst_roe_percentage IS NOT NULL ORDER BY worst_roe_percentage ASC LIMIT 1")
|
|
|
+
|
|
|
return {
|
|
|
+ 'initial_balance': initial_balance,
|
|
|
'total_trades': total_trades,
|
|
|
'total_wins': total_wins,
|
|
|
'total_losses': total_losses,
|
|
@@ -146,6 +158,9 @@ class PerformanceCalculator:
|
|
|
'total_exit_volume': total_exit_volume,
|
|
|
'profit_factor': profit_factor,
|
|
|
'expectancy': expectancy,
|
|
|
+ 'avg_trade_pnl': avg_trade_pnl,
|
|
|
+ 'avg_win_pnl': avg_win_pnl,
|
|
|
+ 'avg_loss_pnl': avg_loss_pnl,
|
|
|
'largest_win': largest_win,
|
|
|
'largest_loss': largest_loss,
|
|
|
'largest_win_token': largest_win_token,
|
|
@@ -163,7 +178,9 @@ class PerformanceCalculator:
|
|
|
'max_drawdown': max_drawdown,
|
|
|
'max_drawdown_pct': max_drawdown_pct,
|
|
|
'drawdown_start_date': drawdown_start_date,
|
|
|
- 'open_positions': len(open_positions)
|
|
|
+ 'open_positions': len(open_positions),
|
|
|
+ 'best_roe_trade': best_roe_trade,
|
|
|
+ 'worst_roe_trade': worst_roe_trade
|
|
|
}
|
|
|
|
|
|
except Exception as e:
|