123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- import logging
- from telegram import Update
- from telegram.ext import ContextTypes
- from .base import InfoCommandsBase
- from src.utils.token_display_formatter import get_formatter
- logger = logging.getLogger(__name__)
- class DailyCommands(InfoCommandsBase):
- """Handles all daily performance-related commands."""
- async def daily_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
- """Handle the /daily command to show daily performance stats."""
- if not self._is_authorized(update):
- return
- try:
- stats = self.trading_engine.get_stats()
- if not stats:
- await self._reply(update, "❌ Could not load trading statistics")
- return
- daily_stats_list = stats.get_daily_stats(10) # Last 10 days
- formatter = get_formatter()
- if not daily_stats_list:
- await self._reply(update, "📅 <b>Daily Performance</b>\n📭 No daily performance data available yet.\n💡 Daily stats are calculated from completed trades. Start trading to see them!")
- return
- daily_text_parts = [f"📅 <b>Daily Performance (Last 10 Days)</b>"]
- total_pnl_all_days = 0
- total_trades_all_days = 0
- total_roe_all_days = 0
- trading_days_count = 0
- period_lines = []
- for day_stats_item in daily_stats_list:
- if day_stats_item.get('has_trades'):
- pnl_emoji = "🟢" if day_stats_item.get('pnl', 0) >= 0 else "🔴"
- pnl_str = formatter.format_price_with_symbol(day_stats_item.get('pnl', 0))
- roe = day_stats_item.get('roe', 0.0) # Get ROE from stats
- roe_str = f"ROE: {roe:+.1f}%" if roe != 0 else ""
- day_str = day_stats_item.get('date_formatted', 'Unknown')
- period_lines.append(f"📅 <b>{day_str}</b>: {pnl_emoji} {pnl_str} ({day_stats_item.get('pnl_pct', 0):+.1f}%) {roe_str} | Trades: {day_stats_item.get('trades', 0)}")
- total_pnl_all_days += day_stats_item.get('pnl', 0)
- total_trades_all_days += day_stats_item.get('trades', 0)
- total_roe_all_days += roe
- trading_days_count += 1
- else:
- day_str = day_stats_item.get('date_formatted', 'Unknown')
- period_lines.append(f"📅 <b>{day_str}</b>: 📭 No trading activity")
- if period_lines:
- daily_text_parts.append("\n".join(period_lines))
- if trading_days_count > 0:
- avg_daily_pnl = total_pnl_all_days / trading_days_count
- avg_daily_roe = total_roe_all_days / trading_days_count
- avg_pnl_emoji = "🟢" if avg_daily_pnl >= 0 else "🔴"
- total_pnl_all_days_str = formatter.format_price_with_symbol(total_pnl_all_days)
- avg_daily_pnl_str = formatter.format_price_with_symbol(avg_daily_pnl)
- daily_text_parts.append(f"\n\n📈 <b>Period Summary:</b>")
- daily_text_parts.append(f" Total P&L: {avg_pnl_emoji} {total_pnl_all_days_str} | Avg Daily: {avg_daily_pnl_str}")
- daily_text_parts.append(f" Total ROE: {total_roe_all_days:+.1f}% | Avg Daily ROE: {avg_daily_roe:+.1f}%")
- daily_text_parts.append(f" Trading Days: {trading_days_count}/10 | Total Trades: {total_trades_all_days}")
- else:
- if not period_lines:
- daily_text_parts = [daily_text_parts[0]]
- daily_text_parts.append("\n\n📉 No trading activity in the last 10 days.")
- await self._reply(update, "\n".join(daily_text_parts).strip())
- except Exception as e:
- error_message = f"❌ Error processing daily command: {str(e)}"
- await self._reply(update, error_message)
- logger.error(f"Error in daily command: {e}")
|