Browse Source

Refactor TradingEngine methods to be asynchronous, enabling better integration with async workflows. Updated methods for fetching market data, token info, and position handling to use await, improving responsiveness and performance in trading operations.

Carles Sentis 4 days ago
parent
commit
f7643106db
2 changed files with 15 additions and 13 deletions
  1. 14 12
      src/trading/trading_engine.py
  2. 1 1
      trading_bot.py

+ 14 - 12
src/trading/trading_engine.py

@@ -107,7 +107,7 @@ class TradingEngine:
         """Get recent fills/trades."""
         """Get recent fills/trades."""
         return self.client.get_recent_fills()
         return self.client.get_recent_fills()
     
     
-    def get_market_data(self, symbol: str) -> Optional[Dict[str, Any]]:
+    async def get_market_data(self, symbol: str) -> Optional[Dict[str, Any]]:
         """Get market data for a symbol."""
         """Get market data for a symbol."""
         return self.client.get_market_data(symbol)
         return self.client.get_market_data(symbol)
     
     
@@ -115,7 +115,7 @@ class TradingEngine:
     _markets_cache: Optional[List[Dict[str, Any]]] = None
     _markets_cache: Optional[List[Dict[str, Any]]] = None
     _markets_cache_timestamp: Optional[datetime] = None
     _markets_cache_timestamp: Optional[datetime] = None
 
 
-    def get_token_info(self, base_asset: str) -> Dict[str, Any]:
+    async def get_token_info(self, base_asset: str) -> Dict[str, Any]:
         """Fetch (and cache) market data to find precision for a given base_asset."""
         """Fetch (and cache) market data to find precision for a given base_asset."""
         # Cache markets for 1 hour to avoid frequent API calls
         # Cache markets for 1 hour to avoid frequent API calls
         if self._markets_cache is None or \
         if self._markets_cache is None or \
@@ -123,7 +123,7 @@ class TradingEngine:
             (datetime.now(timezone.utc) - self._markets_cache_timestamp).total_seconds() > 3600):
             (datetime.now(timezone.utc) - self._markets_cache_timestamp).total_seconds() > 3600):
             try:
             try:
                 logger.info("Fetching and caching markets for token info...")
                 logger.info("Fetching and caching markets for token info...")
-                markets_data = self.client.get_markets() # This returns a list of market dicts
+                markets_data = await self.client.get_markets() # This returns a list of market dicts
                 if markets_data:
                 if markets_data:
                     self._markets_cache = markets_data
                     self._markets_cache = markets_data
                     self._markets_cache_timestamp = datetime.now(timezone.utc)
                     self._markets_cache_timestamp = datetime.now(timezone.utc)
@@ -173,7 +173,7 @@ class TradingEngine:
             'quote_precision': default_precision['price']
             'quote_precision': default_precision['price']
         }
         }
     
     
-    def find_position(self, token: str) -> Optional[Dict[str, Any]]:
+    async def find_position(self, token: str) -> Optional[Dict[str, Any]]:
         """Find an open position for a token."""
         """Find an open position for a token."""
         symbol = f"{token}/USDC:USDC"
         symbol = f"{token}/USDC:USDC"
         
         
@@ -238,7 +238,8 @@ class TradingEngine:
                                 limit_price_arg: Optional[float] = None,
                                 limit_price_arg: Optional[float] = None,
                                 stop_loss_price: Optional[float] = None) -> Dict[str, Any]:
                                 stop_loss_price: Optional[float] = None) -> Dict[str, Any]:
         symbol = f"{token}/USDC:USDC"
         symbol = f"{token}/USDC:USDC"
-        formatter = get_formatter() # Get formatter
+        token_info = await self.get_token_info(token)
+        formatter = get_formatter(token_info)
         
         
         try:
         try:
             # Validate inputs
             # Validate inputs
@@ -246,7 +247,7 @@ class TradingEngine:
                 return {"success": False, "error": "Invalid USDC amount"}
                 return {"success": False, "error": "Invalid USDC amount"}
             
             
             # Get market data for price validation
             # Get market data for price validation
-            market_data = self.get_market_data(symbol)
+            market_data = await self.get_market_data(symbol)
             if not market_data or not market_data.get('ticker'):
             if not market_data or not market_data.get('ticker'):
                 return {"success": False, "error": f"Could not fetch market data for {token}"}
                 return {"success": False, "error": f"Could not fetch market data for {token}"}
             
             
@@ -399,13 +400,14 @@ class TradingEngine:
                                  limit_price_arg: Optional[float] = None,
                                  limit_price_arg: Optional[float] = None,
                                  stop_loss_price: Optional[float] = None) -> Dict[str, Any]:
                                  stop_loss_price: Optional[float] = None) -> Dict[str, Any]:
         symbol = f"{token}/USDC:USDC"
         symbol = f"{token}/USDC:USDC"
-        formatter = get_formatter() # Get formatter
+        token_info = await self.get_token_info(token)
+        formatter = get_formatter(token_info)
         
         
         try:
         try:
             if usdc_amount <= 0:
             if usdc_amount <= 0:
                 return {"success": False, "error": "Invalid USDC amount"}
                 return {"success": False, "error": "Invalid USDC amount"}
             
             
-            market_data = self.get_market_data(symbol)
+            market_data = await self.get_market_data(symbol)
             if not market_data or not market_data.get('ticker'):
             if not market_data or not market_data.get('ticker'):
                 return {"success": False, "error": f"Could not fetch market data for {token}"}
                 return {"success": False, "error": f"Could not fetch market data for {token}"}
             
             
@@ -545,7 +547,7 @@ class TradingEngine:
     
     
     async def execute_exit_order(self, token: str) -> Dict[str, Any]:
     async def execute_exit_order(self, token: str) -> Dict[str, Any]:
         """Execute an exit order to close a position."""
         """Execute an exit order to close a position."""
-        position = self.find_position(token)
+        position = await self.find_position(token)
         if not position:
         if not position:
             return {"success": False, "error": f"No open position found for {token}"}
             return {"success": False, "error": f"No open position found for {token}"}
         
         
@@ -648,7 +650,7 @@ class TradingEngine:
     
     
     async def execute_stop_loss_order(self, token: str, stop_price: float) -> Dict[str, Any]:
     async def execute_stop_loss_order(self, token: str, stop_price: float) -> Dict[str, Any]:
         """Execute a stop loss order."""
         """Execute a stop loss order."""
-        position = self.find_position(token)
+        position = await self.find_position(token)
         if not position:
         if not position:
             return {"success": False, "error": f"No open position found for {token}"}
             return {"success": False, "error": f"No open position found for {token}"}
         
         
@@ -744,7 +746,7 @@ class TradingEngine:
     
     
     async def execute_take_profit_order(self, token: str, profit_price: float) -> Dict[str, Any]:
     async def execute_take_profit_order(self, token: str, profit_price: float) -> Dict[str, Any]:
         """Execute a take profit order."""
         """Execute a take profit order."""
-        position = self.find_position(token)
+        position = await self.find_position(token)
         if not position:
         if not position:
             return {"success": False, "error": f"No open position found for {token}"}
             return {"success": False, "error": f"No open position found for {token}"}
         
         
@@ -1073,7 +1075,7 @@ class TradingEngine:
         # Get current market price to determine order type
         # Get current market price to determine order type
         current_price = None
         current_price = None
         try:
         try:
-            market_data = self.get_market_data(symbol)
+            market_data = await self.get_market_data(symbol)
             if market_data and market_data.get('ticker'):
             if market_data and market_data.get('ticker'):
                 current_price = float(market_data['ticker'].get('last', 0))
                 current_price = float(market_data['ticker'].get('last', 0))
         except Exception as price_error:
         except Exception as price_error:

+ 1 - 1
trading_bot.py

@@ -14,7 +14,7 @@ from datetime import datetime
 from pathlib import Path
 from pathlib import Path
 
 
 # Bot version
 # Bot version
-BOT_VERSION = "2.4.222"
+BOT_VERSION = "2.4.223"
 
 
 # Add src directory to Python path
 # Add src directory to Python path
 sys.path.insert(0, str(Path(__file__).parent / "src"))
 sys.path.insert(0, str(Path(__file__).parent / "src"))