|
@@ -564,12 +564,28 @@ Will trigger when {token} price moves {alarm['direction']} {target_price_str}
|
|
|
|
|
|
await self._reply(update, "🔄 Starting order synchronization...")
|
|
|
|
|
|
- # Get exchange order sync from monitoring coordinator
|
|
|
+ # Get monitoring coordinator
|
|
|
monitoring_coordinator = getattr(self.trading_engine, 'monitoring_coordinator', None)
|
|
|
- if not monitoring_coordinator or not monitoring_coordinator.exchange_order_sync:
|
|
|
- await self._reply(update, "❌ Order synchronization not available. Please restart the bot.")
|
|
|
+ if not monitoring_coordinator:
|
|
|
+ await self._reply(update, "❌ Monitoring coordinator not available. Please restart the bot.")
|
|
|
return
|
|
|
|
|
|
+ # Check if exchange order sync is available, if not try to initialize it
|
|
|
+ if not monitoring_coordinator.exchange_order_sync:
|
|
|
+ await self._reply(update, "⚠️ Exchange order sync not initialized. Attempting to initialize...")
|
|
|
+
|
|
|
+ # Try to initialize the sync manually
|
|
|
+ try:
|
|
|
+ await self._initialize_exchange_order_sync(monitoring_coordinator)
|
|
|
+ if not monitoring_coordinator.exchange_order_sync:
|
|
|
+ await self._reply(update, "❌ Failed to initialize exchange order sync. Please restart the bot.")
|
|
|
+ return
|
|
|
+ await self._reply(update, "✅ Exchange order sync initialized successfully.")
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"Failed to initialize exchange order sync: {e}")
|
|
|
+ await self._reply(update, f"❌ Failed to initialize exchange order sync: {str(e)}")
|
|
|
+ return
|
|
|
+
|
|
|
# Run synchronization
|
|
|
sync_results = monitoring_coordinator.exchange_order_sync.sync_exchange_orders_to_database()
|
|
|
|
|
@@ -581,6 +597,29 @@ Will trigger when {token} price moves {alarm['direction']} {target_price_str}
|
|
|
logger.error(f"Error in sync command: {e}", exc_info=True)
|
|
|
await self._reply(update, "❌ Error during synchronization.")
|
|
|
|
|
|
+ async def _initialize_exchange_order_sync(self, monitoring_coordinator):
|
|
|
+ """Try to manually initialize exchange order sync."""
|
|
|
+ try:
|
|
|
+ from src.monitoring.exchange_order_sync import ExchangeOrderSync
|
|
|
+
|
|
|
+ # Get trading stats from trading engine
|
|
|
+ stats = self.trading_engine.get_stats()
|
|
|
+ if not stats:
|
|
|
+ raise Exception("Trading stats not available from trading engine")
|
|
|
+
|
|
|
+ # Get hyperliquid client
|
|
|
+ hl_client = self.trading_engine.client
|
|
|
+ if not hl_client:
|
|
|
+ raise Exception("Hyperliquid client not available")
|
|
|
+
|
|
|
+ # Initialize the exchange order sync
|
|
|
+ monitoring_coordinator.exchange_order_sync = ExchangeOrderSync(hl_client, stats)
|
|
|
+ logger.info("✅ Manually initialized exchange order sync")
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"Error manually initializing exchange order sync: {e}")
|
|
|
+ raise
|
|
|
+
|
|
|
async def _format_sync_results(self, sync_results: Dict[str, Any], force: bool) -> str:
|
|
|
"""Format synchronization results for display."""
|
|
|
|
|
@@ -627,6 +666,111 @@ Will trigger when {token} price moves {alarm['direction']} {target_price_str}
|
|
|
|
|
|
return "\n".join(message_parts)
|
|
|
|
|
|
+ async def sync_status_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
|
|
+ """Handle the /sync_status command to show synchronization diagnostics."""
|
|
|
+ try:
|
|
|
+ if not self._is_authorized(update):
|
|
|
+ await self._reply(update, "❌ Unauthorized access.")
|
|
|
+ return
|
|
|
+
|
|
|
+ # Check monitoring coordinator
|
|
|
+ monitoring_coordinator = getattr(self.trading_engine, 'monitoring_coordinator', None)
|
|
|
+
|
|
|
+ diagnostic_parts = ["🔍 <b>Synchronization Diagnostics</b>\n"]
|
|
|
+
|
|
|
+ # Check monitoring coordinator
|
|
|
+ if monitoring_coordinator:
|
|
|
+ diagnostic_parts.append("✅ <b>Monitoring Coordinator:</b> Available")
|
|
|
+ diagnostic_parts.append(f" • Running: {'Yes' if monitoring_coordinator.is_running else 'No'}")
|
|
|
+
|
|
|
+ # Check exchange order sync
|
|
|
+ if monitoring_coordinator.exchange_order_sync:
|
|
|
+ diagnostic_parts.append("✅ <b>Exchange Order Sync:</b> Available")
|
|
|
+
|
|
|
+ # Try to get sync stats
|
|
|
+ try:
|
|
|
+ sync_stats = self._get_sync_diagnostics(monitoring_coordinator)
|
|
|
+ diagnostic_parts.extend(sync_stats)
|
|
|
+ except Exception as e:
|
|
|
+ diagnostic_parts.append(f"⚠️ <b>Sync Stats Error:</b> {str(e)}")
|
|
|
+ else:
|
|
|
+ diagnostic_parts.append("❌ <b>Exchange Order Sync:</b> Not Available")
|
|
|
+
|
|
|
+ # Try to diagnose why
|
|
|
+ diagnostic_parts.append("\n🔍 <b>Troubleshooting:</b>")
|
|
|
+
|
|
|
+ # Check position tracker
|
|
|
+ if hasattr(monitoring_coordinator, 'position_tracker'):
|
|
|
+ diagnostic_parts.append("✅ Position Tracker: Available")
|
|
|
+ if hasattr(monitoring_coordinator.position_tracker, 'trading_stats'):
|
|
|
+ if monitoring_coordinator.position_tracker.trading_stats:
|
|
|
+ diagnostic_parts.append("✅ Position Tracker Trading Stats: Available")
|
|
|
+ else:
|
|
|
+ diagnostic_parts.append("❌ Position Tracker Trading Stats: None")
|
|
|
+ else:
|
|
|
+ diagnostic_parts.append("❌ Position Tracker Trading Stats: Not Found")
|
|
|
+ else:
|
|
|
+ diagnostic_parts.append("❌ Position Tracker: Not Available")
|
|
|
+
|
|
|
+ # Check trading engine stats
|
|
|
+ stats = self.trading_engine.get_stats()
|
|
|
+ if stats:
|
|
|
+ diagnostic_parts.append("✅ Trading Engine Stats: Available")
|
|
|
+ else:
|
|
|
+ diagnostic_parts.append("❌ Trading Engine Stats: Not Available")
|
|
|
+
|
|
|
+ # Check hyperliquid client
|
|
|
+ client = self.trading_engine.client
|
|
|
+ if client:
|
|
|
+ diagnostic_parts.append("✅ Hyperliquid Client: Available")
|
|
|
+ else:
|
|
|
+ diagnostic_parts.append("❌ Hyperliquid Client: Not Available")
|
|
|
+ else:
|
|
|
+ diagnostic_parts.append("❌ <b>Monitoring Coordinator:</b> Not Available")
|
|
|
+
|
|
|
+ diagnostic_parts.append("\n💡 <b>Solutions:</b>")
|
|
|
+ diagnostic_parts.append("• Try: /sync force")
|
|
|
+ diagnostic_parts.append("• If that fails, restart the bot")
|
|
|
+ diagnostic_parts.append("• Check logs for detailed error messages")
|
|
|
+
|
|
|
+ await self._reply(update, "\n".join(diagnostic_parts))
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"Error in sync_status command: {e}", exc_info=True)
|
|
|
+ await self._reply(update, f"❌ Error getting sync status: {str(e)}")
|
|
|
+
|
|
|
+ def _get_sync_diagnostics(self, monitoring_coordinator):
|
|
|
+ """Get detailed sync diagnostics."""
|
|
|
+ diagnostic_parts = []
|
|
|
+
|
|
|
+ try:
|
|
|
+ # Test if we can access the sync components
|
|
|
+ sync_manager = monitoring_coordinator.exchange_order_sync
|
|
|
+
|
|
|
+ if hasattr(sync_manager, 'hl_client'):
|
|
|
+ diagnostic_parts.append("✅ Hyperliquid Client: Connected")
|
|
|
+ else:
|
|
|
+ diagnostic_parts.append("❌ Hyperliquid Client: Missing")
|
|
|
+
|
|
|
+ if hasattr(sync_manager, 'trading_stats'):
|
|
|
+ diagnostic_parts.append("✅ Trading Stats: Connected")
|
|
|
+
|
|
|
+ # Try to get a count of database orders
|
|
|
+ try:
|
|
|
+ db_orders = []
|
|
|
+ db_orders.extend(sync_manager.trading_stats.get_orders_by_status('open', limit=10))
|
|
|
+ db_orders.extend(sync_manager.trading_stats.get_orders_by_status('submitted', limit=10))
|
|
|
+ diagnostic_parts.append(f"✅ Database Orders: {len(db_orders)} found")
|
|
|
+ except Exception as e:
|
|
|
+ diagnostic_parts.append(f"⚠️ Database Orders: Error ({str(e)})")
|
|
|
+ else:
|
|
|
+ diagnostic_parts.append("❌ Trading Stats: Missing")
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ diagnostic_parts.append(f"❌ Sync Components: Error ({str(e)})")
|
|
|
+
|
|
|
+ return diagnostic_parts
|
|
|
+
|
|
|
async def deposit_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
|
|
"""Handle the /deposit command to record a deposit."""
|
|
|
if not self._is_authorized(update):
|