diff --git a/NN/models/enhanced_cnn.py b/NN/models/enhanced_cnn.py index d5f4bd0..124d41a 100644 --- a/NN/models/enhanced_cnn.py +++ b/NN/models/enhanced_cnn.py @@ -528,7 +528,7 @@ class EnhancedCNN(nn.Module): state_tensor = torch.as_tensor(state, dtype=torch.float32, device=self.device) if state_tensor.dim() == 1: state_tensor = state_tensor.unsqueeze(0) - + with torch.no_grad(): q_values, extrema_pred, price_predictions, features, advanced_predictions = self(state_tensor) @@ -537,7 +537,7 @@ class EnhancedCNN(nn.Module): action_idx = int(torch.argmax(action_probs_tensor, dim=1).item()) confidence = float(action_probs_tensor[0, action_idx].item()) # Confidence of the chosen action action_probs = action_probs_tensor.squeeze(0).tolist() # Convert to list of floats for return - + # Log advanced predictions for better decision making if hasattr(self, '_log_predictions') and self._log_predictions: # Log volatility prediction diff --git a/core/trading_executor.py b/core/trading_executor.py index 2f10019..0000a59 100644 --- a/core/trading_executor.py +++ b/core/trading_executor.py @@ -131,7 +131,7 @@ class TradingExecutor: self.trade_records = [] # List of TradeRecord objects logger.info(f"TradingExecutor initialized - Trading: {self.trading_enabled}, Mode: {self.trading_mode}") - + # Legacy compatibility (deprecated) self.dry_run = self.simulation_mode @@ -276,7 +276,7 @@ class TradingExecutor: quote_asset = 'USDC' # Use USDC instead logger.info(f"BALANCE CHECK: Using USDC fallback balance for {symbol}") else: - available_balance = self.exchange.get_balance(quote_asset) + available_balance = self.exchange.get_balance(quote_asset) logger.info(f"BALANCE CHECK: Symbol: {symbol}, Action: {action}, Required: ${required_capital:.2f} {quote_asset}, Available: ${available_balance:.2f} {quote_asset}") @@ -303,23 +303,23 @@ class TradingExecutor: logger.info(f"LOCK ACQUIRED: Executing {action} for {symbol}") start_time = time.time() - if action == 'BUY': + if action == 'BUY': result = self._execute_buy(symbol, confidence, current_price) - elif action == 'SELL': + elif action == 'SELL': result = self._execute_sell(symbol, confidence, current_price) - elif action == 'SHORT': # Explicitly handle SHORT if it's a direct signal + elif action == 'SHORT': # Explicitly handle SHORT if it's a direct signal result = self._execute_short(symbol, confidence, current_price) - else: - logger.warning(f"Unknown action: {action}") + else: + logger.warning(f"Unknown action: {action}") result = False execution_time = time.time() - start_time logger.info(f"EXECUTION COMPLETE: {action} for {symbol} took {execution_time:.2f}s, result: {result}") return result - except Exception as e: - logger.error(f"Error executing {action} signal for {symbol}: {e}") - return False + except Exception as e: + logger.error(f"Error executing {action} signal for {symbol}: {e}") + return False finally: self.lock.release() logger.debug(f"LOCK RELEASED: {action} for {symbol}") @@ -386,7 +386,7 @@ class TradingExecutor: logger.info(f"Test mode: bypassing trade interval for {symbol}") else: logger.info(f"Trade interval not met for {symbol} ({time_since_last:.1f}s < {min_interval}s)") - return False + return False # Check concurrent positions max_positions = self.exchange_config.get('max_concurrent_positions', @@ -442,7 +442,7 @@ class TradingExecutor: # Only create position if order was actually filled if result.get('filled', True): # Assume filled for backward compatibility self.positions[symbol] = Position( - symbol=symbol, + symbol=symbol, side='LONG', quantity=float(filled_quantity), entry_price=float(fill_price), @@ -452,7 +452,7 @@ class TradingExecutor: logger.info(f"BUY position created: {filled_quantity:.6f} {symbol} at ${fill_price:.4f}") self.last_trade_time[symbol] = datetime.now() return True - else: + else: logger.error(f"BUY order placed but not filled: {result}") return False else: @@ -488,12 +488,12 @@ class TradingExecutor: if self.simulation_mode: # Create simulated short position - self.positions[symbol] = Position( - symbol=symbol, + self.positions[symbol] = Position( + symbol=symbol, side='SHORT', - quantity=quantity, - entry_price=current_price, - entry_time=datetime.now(), + quantity=quantity, + entry_price=current_price, + entry_time=datetime.now(), order_id=f"sim_{int(datetime.now().timestamp())}" ) logger.info(f"Simulated SHORT order: {quantity:.6f} {symbol} at ${current_price:.2f}") @@ -517,15 +517,15 @@ class TradingExecutor: order_id=result['orderId'] ) logger.info(f"SHORT position created: {filled_quantity:.6f} {symbol} at ${fill_price:.4f}") - self.last_trade_time[symbol] = datetime.now() - return True - else: + self.last_trade_time[symbol] = datetime.now() + return True + else: logger.error(f"SHORT order placed but not filled: {result}") return False else: logger.error("Failed to place SHORT order") return False - + def _place_order_with_retry(self, symbol: str, side: str, order_type: str, quantity: float, current_price: float, max_retries: int = 3) -> Dict[str, Any]: """Place order with retry logic for MEXC error handling""" order_start_time = time.time() @@ -628,7 +628,7 @@ class TradingExecutor: try: self.exchange.cancel_order(symbol, order_id) logger.info(f"Cancelled unfilled order {order_id}") - except Exception as e: + except Exception as e: logger.error(f"Failed to cancel unfilled order {order_id}: {e}") # If this was the last attempt, return failure @@ -763,7 +763,7 @@ class TradingExecutor: if symbol not in self.positions: logger.warning(f"No position to close in {symbol}") return False - + position = self.positions[symbol] if position.side != 'SHORT': logger.warning(f"Position in {symbol} is not SHORT, cannot close with BUY") @@ -899,7 +899,7 @@ class TradingExecutor: except Exception as e: logger.error(f"Error closing SHORT position: {e}") return False - + def _close_long_position(self, symbol: str, confidence: float, current_price: float) -> bool: """Close a long position by selling""" if symbol not in self.positions: @@ -1190,18 +1190,18 @@ class TradingExecutor: raw_balances = self.exchange.get_all_balances() if raw_balances: # Convert to the expected format with 'type' field - combined_balances = {} + combined_balances = {} for asset, balance_data in raw_balances.items(): if isinstance(balance_data, dict): - combined_balances[asset] = { + combined_balances[asset] = { 'free': balance_data.get('free', 0.0), 'locked': balance_data.get('locked', 0.0), 'total': balance_data.get('total', 0.0), 'type': 'spot' # Default to spot for now } - + logger.info(f"Retrieved balances for {len(combined_balances)} assets from {self.primary_name}") - return combined_balances + return combined_balances else: logger.warning(f"No balances returned from {self.primary_name} exchange") return {} diff --git a/test_bybit_eth_futures.py b/test_bybit_eth_futures.py new file mode 100644 index 0000000..ce9fb3e --- /dev/null +++ b/test_bybit_eth_futures.py @@ -0,0 +1,348 @@ +#!/usr/bin/env python3 +""" +Test script for Bybit ETH futures position opening/closing +""" + +import os +import sys +import time +import logging +from datetime import datetime + +# Add the project root to the path +sys.path.append(os.path.dirname(os.path.abspath(__file__))) + +# Load environment variables from .env file +try: + from dotenv import load_dotenv + load_dotenv() +except ImportError: + # If dotenv is not available, try to load .env manually + if os.path.exists('.env'): + with open('.env', 'r') as f: + for line in f: + if line.strip() and not line.startswith('#'): + key, value = line.strip().split('=', 1) + os.environ[key] = value + +from NN.exchanges.bybit_interface import BybitInterface + +# Configure logging +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger(__name__) + +class BybitEthFuturesTest: + """Test class for Bybit ETH futures trading""" + + def __init__(self, test_mode=True): + self.test_mode = test_mode + self.bybit = BybitInterface(test_mode=test_mode) + self.test_symbol = 'ETHUSDT' + self.test_quantity = 0.01 # Small test amount + + def run_tests(self): + """Run all tests""" + print("=" * 60) + print("BYBIT ETH FUTURES POSITION TESTING") + print("=" * 60) + print(f"Test mode: {'TESTNET' if self.test_mode else 'LIVE'}") + print(f"Symbol: {self.test_symbol}") + print(f"Test quantity: {self.test_quantity} ETH") + print("=" * 60) + + # Test 1: Connection + if not self.test_connection(): + print("❌ Connection failed - stopping tests") + return False + + # Test 2: Check balance + if not self.test_balance(): + print("❌ Balance check failed - stopping tests") + return False + + # Test 3: Check current positions + self.test_current_positions() + + # Test 4: Get ticker + if not self.test_ticker(): + print("❌ Ticker test failed - stopping tests") + return False + + # Test 5: Open a long position + long_order = self.test_open_long_position() + if not long_order: + print("❌ Open long position failed") + return False + + # Test 6: Check position after opening + time.sleep(2) # Wait for position to be reflected + if not self.test_position_after_open(): + print("❌ Position check after opening failed") + return False + + # Test 7: Close the position + if not self.test_close_position(): + print("❌ Close position failed") + return False + + # Test 8: Check position after closing + time.sleep(2) # Wait for position to be reflected + self.test_position_after_close() + + print("\n" + "=" * 60) + print("✅ ALL TESTS COMPLETED SUCCESSFULLY") + print("=" * 60) + return True + + def test_connection(self): + """Test connection to Bybit""" + print("\n📡 Testing connection to Bybit...") + + # First test simple connectivity without auth + print("Testing basic API connectivity...") + try: + from NN.exchanges.bybit_rest_client import BybitRestClient + client = BybitRestClient( + api_key="dummy", + api_secret="dummy", + testnet=True + ) + + # Test public endpoint (server time) + server_time = client.get_server_time() + print(f"✅ Public API working - Server time: {server_time.get('result', {}).get('timeSecond')}") + + except Exception as e: + print(f"❌ Public API failed: {e}") + return False + + # Now test with actual credentials + print("Testing with API credentials...") + try: + connected = self.bybit.connect() + if connected: + print("✅ Successfully connected to Bybit with credentials") + return True + else: + print("❌ Failed to connect to Bybit with credentials") + print("This might be due to:") + print("- Invalid API credentials") + print("- Credentials not enabled for testnet") + print("- Missing required permissions") + return False + except Exception as e: + print(f"❌ Connection error: {e}") + return False + + def test_balance(self): + """Test getting account balance""" + print("\n💰 Testing account balance...") + + try: + # Get USDT balance (for margin) + usdt_balance = self.bybit.get_balance('USDT') + print(f"USDT Balance: {usdt_balance}") + + # Get all balances + all_balances = self.bybit.get_all_balances() + print("All balances:") + for asset, balance in all_balances.items(): + if balance['total'] > 0: + print(f" {asset}: Free={balance['free']}, Locked={balance['locked']}, Total={balance['total']}") + + if usdt_balance > 10: # Need at least $10 for testing + print("✅ Sufficient balance for testing") + return True + else: + print("❌ Insufficient USDT balance for testing (need at least $10)") + return False + + except Exception as e: + print(f"❌ Balance check error: {e}") + return False + + def test_current_positions(self): + """Test getting current positions""" + print("\n📊 Checking current positions...") + + try: + positions = self.bybit.get_positions() + if positions: + print(f"Found {len(positions)} open positions:") + for pos in positions: + print(f" {pos['symbol']}: {pos['side']} {pos['size']} @ ${pos['entry_price']:.2f}") + print(f" PnL: ${pos['unrealized_pnl']:.2f} ({pos['percentage']:.2f}%)") + else: + print("No open positions found") + + except Exception as e: + print(f"❌ Position check error: {e}") + + def test_ticker(self): + """Test getting ticker information""" + print(f"\n📈 Testing ticker for {self.test_symbol}...") + + try: + ticker = self.bybit.get_ticker(self.test_symbol) + if ticker: + print(f"✅ Ticker data received:") + print(f" Last Price: ${ticker['last_price']:.2f}") + print(f" Bid: ${ticker['bid_price']:.2f}") + print(f" Ask: ${ticker['ask_price']:.2f}") + print(f" 24h Volume: {ticker['volume_24h']:.2f}") + print(f" 24h Change: {ticker['change_24h']:.4f}%") + return True + else: + print("❌ Failed to get ticker data") + return False + + except Exception as e: + print(f"❌ Ticker error: {e}") + return False + + def test_open_long_position(self): + """Test opening a long position""" + print(f"\n🚀 Opening long position for {self.test_quantity} {self.test_symbol}...") + + try: + # Place market buy order + order = self.bybit.place_order( + symbol=self.test_symbol, + side='buy', + order_type='market', + quantity=self.test_quantity + ) + + if 'error' in order: + print(f"❌ Order failed: {order['error']}") + return None + + print("✅ Long position opened successfully:") + print(f" Order ID: {order['order_id']}") + print(f" Symbol: {order['symbol']}") + print(f" Side: {order['side']}") + print(f" Quantity: {order['quantity']}") + print(f" Status: {order['status']}") + + return order + + except Exception as e: + print(f"❌ Open position error: {e}") + return None + + def test_position_after_open(self): + """Test checking position after opening""" + print(f"\n📊 Checking position after opening...") + + try: + positions = self.bybit.get_positions(self.test_symbol) + if positions: + position = positions[0] + print("✅ Position found:") + print(f" Symbol: {position['symbol']}") + print(f" Side: {position['side']}") + print(f" Size: {position['size']}") + print(f" Entry Price: ${position['entry_price']:.2f}") + print(f" Mark Price: ${position['mark_price']:.2f}") + print(f" Unrealized PnL: ${position['unrealized_pnl']:.2f}") + print(f" Percentage: {position['percentage']:.2f}%") + print(f" Leverage: {position['leverage']}x") + return True + else: + print("❌ No position found after opening") + return False + + except Exception as e: + print(f"❌ Position check error: {e}") + return False + + def test_close_position(self): + """Test closing the position""" + print(f"\n🔄 Closing position for {self.test_symbol}...") + + try: + # Close the position + close_order = self.bybit.close_position(self.test_symbol) + + if 'error' in close_order: + print(f"❌ Close order failed: {close_order['error']}") + return False + + print("✅ Position closed successfully:") + print(f" Order ID: {close_order['order_id']}") + print(f" Symbol: {close_order['symbol']}") + print(f" Side: {close_order['side']}") + print(f" Quantity: {close_order['quantity']}") + print(f" Status: {close_order['status']}") + + return True + + except Exception as e: + print(f"❌ Close position error: {e}") + return False + + def test_position_after_close(self): + """Test checking position after closing""" + print(f"\n📊 Checking position after closing...") + + try: + positions = self.bybit.get_positions(self.test_symbol) + if positions: + position = positions[0] + print("⚠️ Position still exists (may be partially closed):") + print(f" Symbol: {position['symbol']}") + print(f" Side: {position['side']}") + print(f" Size: {position['size']}") + print(f" Entry Price: ${position['entry_price']:.2f}") + print(f" Unrealized PnL: ${position['unrealized_pnl']:.2f}") + else: + print("✅ Position successfully closed - no open positions") + + except Exception as e: + print(f"❌ Position check error: {e}") + + def test_order_history(self): + """Test getting order history""" + print(f"\n📋 Checking recent orders...") + + try: + # Get open orders + open_orders = self.bybit.get_open_orders(self.test_symbol) + print(f"Open orders: {len(open_orders)}") + for order in open_orders: + print(f" {order['order_id']}: {order['side']} {order['quantity']} @ ${order['price']:.2f} - {order['status']}") + + except Exception as e: + print(f"❌ Order history error: {e}") + +def main(): + """Main function""" + print("Starting Bybit ETH Futures Test...") + + # Check if API credentials are set + api_key = os.getenv('BYBIT_API_KEY') + api_secret = os.getenv('BYBIT_API_SECRET') + + if not api_key or not api_secret: + print("❌ Please set BYBIT_API_KEY and BYBIT_API_SECRET environment variables") + return False + + # Create test instance + test = BybitEthFuturesTest(test_mode=True) # Always use testnet for safety + + # Run tests + success = test.run_tests() + + if success: + print("\n🎉 All tests passed!") + else: + print("\n💥 Some tests failed!") + + return success + +if __name__ == "__main__": + success = main() + sys.exit(0 if success else 1) diff --git a/test_bybit_eth_live.py b/test_bybit_eth_live.py new file mode 100644 index 0000000..28aff35 --- /dev/null +++ b/test_bybit_eth_live.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python3 +""" +Test Bybit ETH futures trading with live environment +""" + +import os +import sys +import time +import logging + +# Add the project root to the path +sys.path.append(os.path.dirname(os.path.abspath(__file__))) + +# Load environment variables +try: + from dotenv import load_dotenv + load_dotenv() +except ImportError: + if os.path.exists('.env'): + with open('.env', 'r') as f: + for line in f: + if line.strip() and not line.startswith('#'): + key, value = line.strip().split('=', 1) + os.environ[key] = value + +from NN.exchanges.bybit_interface import BybitInterface + +# Configure logging +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger(__name__) + +def test_eth_futures_trading(): + """Test ETH futures trading with live environment""" + print("=" * 60) + print("BYBIT ETH FUTURES LIVE TRADING TEST") + print("=" * 60) + print("⚠️ This uses LIVE environment with real money!") + print("⚠️ Test amount: 0.001 ETH (very small)") + print("=" * 60) + + # Check if API credentials are set + api_key = os.getenv('BYBIT_API_KEY') + api_secret = os.getenv('BYBIT_API_SECRET') + + if not api_key or not api_secret: + print("❌ API credentials not found in environment") + return False + + # Create Bybit interface with live environment + bybit = BybitInterface( + api_key=api_key, + api_secret=api_secret, + test_mode=False # Use live environment + ) + + symbol = 'ETHUSDT' + test_quantity = 0.01 # Minimum order size for ETH futures + + # Test 1: Connection + print(f"\n📡 Testing connection to Bybit live environment...") + try: + if not bybit.connect(): + print("❌ Failed to connect to Bybit") + return False + print("✅ Successfully connected to Bybit live environment") + except Exception as e: + print(f"❌ Connection error: {e}") + return False + + # Test 2: Get account balance + print(f"\n💰 Checking account balance...") + try: + usdt_balance = bybit.get_balance('USDT') + print(f"USDT Balance: ${usdt_balance:.2f}") + + if usdt_balance < 5: + print("❌ Insufficient USDT balance for testing (need at least $5)") + return False + + print("✅ Sufficient balance for testing") + except Exception as e: + print(f"❌ Balance check error: {e}") + return False + + # Test 3: Get current ETH price + print(f"\n📈 Getting current ETH price...") + try: + ticker = bybit.get_ticker(symbol) + if not ticker: + print("❌ Failed to get ticker") + return False + + current_price = ticker['last_price'] + print(f"Current ETH price: ${current_price:.2f}") + print(f"Test order value: ${current_price * test_quantity:.2f}") + + except Exception as e: + print(f"❌ Ticker error: {e}") + return False + + # Test 4: Check existing positions + print(f"\n📊 Checking existing positions...") + try: + positions = bybit.get_positions(symbol) + if positions: + print(f"Found {len(positions)} existing positions:") + for pos in positions: + print(f" {pos['symbol']}: {pos['side']} {pos['size']} @ ${pos['entry_price']:.2f}") + print(f" PnL: ${pos['unrealized_pnl']:.2f}") + else: + print("No existing positions found") + except Exception as e: + print(f"❌ Position check error: {e}") + return False + + # Test 5: Ask user confirmation before trading + print(f"\n⚠️ TRADING CONFIRMATION") + print(f" Symbol: {symbol}") + print(f" Quantity: {test_quantity} ETH") + print(f" Estimated cost: ${current_price * test_quantity:.2f}") + print(f" Environment: LIVE (real money)") + + response = input("\nDo you want to proceed with the live trading test? (y/N): ").lower() + if response != 'y' and response != 'yes': + print("❌ Trading test cancelled by user") + return False + + # Test 6: Open a small long position + print(f"\n🚀 Opening small long position...") + try: + order = bybit.place_order( + symbol=symbol, + side='buy', + order_type='market', + quantity=test_quantity + ) + + if 'error' in order: + print(f"❌ Order failed: {order['error']}") + return False + + print("✅ Long position opened successfully:") + print(f" Order ID: {order['order_id']}") + print(f" Symbol: {order['symbol']}") + print(f" Side: {order['side']}") + print(f" Quantity: {order['quantity']}") + print(f" Status: {order['status']}") + + order_id = order['order_id'] + + except Exception as e: + print(f"❌ Order placement error: {e}") + return False + + # Test 7: Wait a moment and check position + print(f"\n⏳ Waiting 3 seconds for position to be reflected...") + time.sleep(3) + + try: + positions = bybit.get_positions(symbol) + if positions: + position = positions[0] + print("✅ Position confirmed:") + print(f" Symbol: {position['symbol']}") + print(f" Side: {position['side']}") + print(f" Size: {position['size']}") + print(f" Entry Price: ${position['entry_price']:.2f}") + print(f" Current PnL: ${position['unrealized_pnl']:.2f}") + print(f" Leverage: {position['leverage']}x") + else: + print("⚠️ No position found (may already be closed)") + + except Exception as e: + print(f"❌ Position check error: {e}") + + # Test 8: Close the position + print(f"\n🔄 Closing the position...") + try: + close_order = bybit.close_position(symbol) + + if 'error' in close_order: + print(f"❌ Close order failed: {close_order['error']}") + return False + + print("✅ Position closed successfully:") + print(f" Order ID: {close_order['order_id']}") + print(f" Symbol: {close_order['symbol']}") + print(f" Side: {close_order['side']}") + print(f" Quantity: {close_order['quantity']}") + print(f" Status: {close_order['status']}") + + except Exception as e: + print(f"❌ Close position error: {e}") + return False + + # Test 9: Final position check + print(f"\n📊 Final position check...") + time.sleep(2) + + try: + positions = bybit.get_positions(symbol) + if positions: + position = positions[0] + print("⚠️ Position still exists:") + print(f" Size: {position['size']}") + print(f" PnL: ${position['unrealized_pnl']:.2f}") + else: + print("✅ No open positions - trading test completed successfully") + + except Exception as e: + print(f"❌ Final position check error: {e}") + + # Test 10: Final balance check + print(f"\n💰 Final balance check...") + try: + final_balance = bybit.get_balance('USDT') + print(f"Final USDT Balance: ${final_balance:.2f}") + + except Exception as e: + print(f"❌ Final balance check error: {e}") + + return True + +def main(): + """Main function""" + print("🚀 Starting Bybit ETH Futures Live Trading Test...") + + success = test_eth_futures_trading() + + if success: + print("\n" + "=" * 60) + print("✅ BYBIT ETH FUTURES TRADING TEST COMPLETED") + print("=" * 60) + print("🎯 Your Bybit integration is fully functional!") + print("🔄 Position opening and closing works correctly") + print("💰 Account balance integration works") + print("📊 All trading functions are operational") + print("=" * 60) + else: + print("\n💥 Trading test failed!") + + return success + +if __name__ == "__main__": + success = main() + sys.exit(0 if success else 1) diff --git a/test_bybit_public_api.py b/test_bybit_public_api.py new file mode 100644 index 0000000..d16d17c --- /dev/null +++ b/test_bybit_public_api.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python3 +""" +Test Bybit public API functionality (no authentication required) +""" + +import os +import sys +import time +import logging + +# Add the project root to the path +sys.path.append(os.path.dirname(os.path.abspath(__file__))) + +from NN.exchanges.bybit_rest_client import BybitRestClient + +# Configure logging +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger(__name__) + +def test_public_api(): + """Test public API endpoints""" + print("=" * 60) + print("BYBIT PUBLIC API TEST") + print("=" * 60) + + # Test both testnet and live for public endpoints + for testnet in [True, False]: + env_name = "TESTNET" if testnet else "LIVE" + print(f"\n🔄 Testing {env_name} environment...") + + client = BybitRestClient( + api_key="dummy", + api_secret="dummy", + testnet=testnet + ) + + # Test 1: Server time + try: + server_time = client.get_server_time() + time_second = server_time.get('result', {}).get('timeSecond') + print(f"✅ Server time: {time_second}") + except Exception as e: + print(f"❌ Server time failed: {e}") + continue + + # Test 2: Get ticker for ETHUSDT + try: + ticker = client.get_ticker('ETHUSDT', 'linear') + ticker_data = ticker.get('result', {}).get('list', []) + if ticker_data: + data = ticker_data[0] + print(f"✅ ETH/USDT ticker:") + print(f" Last Price: ${float(data.get('lastPrice', 0)):.2f}") + print(f" 24h Volume: {float(data.get('volume24h', 0)):.2f}") + print(f" 24h Change: {float(data.get('price24hPcnt', 0)) * 100:.2f}%") + else: + print("❌ No ticker data received") + except Exception as e: + print(f"❌ Ticker failed: {e}") + + # Test 3: Get instruments info + try: + instruments = client.get_instruments_info('linear') + instruments_list = instruments.get('result', {}).get('list', []) + eth_instruments = [i for i in instruments_list if 'ETH' in i.get('symbol', '')] + print(f"✅ Found {len(eth_instruments)} ETH instruments") + for instr in eth_instruments[:3]: # Show first 3 + print(f" {instr.get('symbol')} - Status: {instr.get('status')}") + except Exception as e: + print(f"❌ Instruments failed: {e}") + + # Test 4: Get orderbook + try: + orderbook = client.get_orderbook('ETHUSDT', 'linear', 5) + ob_data = orderbook.get('result', {}) + bids = ob_data.get('b', []) + asks = ob_data.get('a', []) + + if bids and asks: + print(f"✅ Orderbook (top 3):") + print(f" Best bid: ${float(bids[0][0]):.2f} (qty: {float(bids[0][1]):.4f})") + print(f" Best ask: ${float(asks[0][0]):.2f} (qty: {float(asks[0][1]):.4f})") + spread = float(asks[0][0]) - float(bids[0][0]) + print(f" Spread: ${spread:.2f}") + else: + print("❌ No orderbook data received") + except Exception as e: + print(f"❌ Orderbook failed: {e}") + + print(f"📊 {env_name} environment test completed") + +def test_live_authentication(): + """Test live authentication (if user wants to test with live credentials)""" + print("\n" + "=" * 60) + print("BYBIT LIVE AUTHENTICATION TEST") + print("=" * 60) + print("⚠️ This will test with LIVE credentials (not testnet)") + + # Load environment variables + try: + from dotenv import load_dotenv + load_dotenv() + except ImportError: + # If dotenv is not available, try to load .env manually + if os.path.exists('.env'): + with open('.env', 'r') as f: + for line in f: + if line.strip() and not line.startswith('#'): + key, value = line.strip().split('=', 1) + os.environ[key] = value + + api_key = os.getenv('BYBIT_API_KEY') + api_secret = os.getenv('BYBIT_API_SECRET') + + if not api_key or not api_secret: + print("❌ No API credentials found in environment") + return + + print(f"🔑 Using API key: {api_key[:8]}...") + + # Test with live environment (testnet=False) + client = BybitRestClient( + api_key=api_key, + api_secret=api_secret, + testnet=False # Use live environment + ) + + # Test connectivity + try: + if client.test_connectivity(): + print("✅ Basic connectivity OK") + else: + print("❌ Basic connectivity failed") + return + except Exception as e: + print(f"❌ Connectivity error: {e}") + return + + # Test authentication + try: + if client.test_authentication(): + print("✅ Authentication successful!") + + # Get account info + account_info = client.get_account_info() + accounts = account_info.get('result', {}).get('list', []) + + if accounts: + print("📊 Account information:") + for account in accounts: + account_type = account.get('accountType', 'Unknown') + print(f" Account Type: {account_type}") + + coins = account.get('coin', []) + usdt_balance = None + for coin in coins: + if coin.get('coin') == 'USDT': + usdt_balance = float(coin.get('walletBalance', 0)) + break + + if usdt_balance: + print(f" USDT Balance: ${usdt_balance:.2f}") + + # Show positions if any + try: + positions = client.get_positions('linear') + pos_list = positions.get('result', {}).get('list', []) + active_positions = [p for p in pos_list if float(p.get('size', 0)) != 0] + + if active_positions: + print(f" Active Positions: {len(active_positions)}") + for pos in active_positions: + symbol = pos.get('symbol') + side = pos.get('side') + size = float(pos.get('size', 0)) + pnl = float(pos.get('unrealisedPnl', 0)) + print(f" {symbol}: {side} {size} (PnL: ${pnl:.2f})") + else: + print(" No active positions") + except Exception as e: + print(f" ⚠️ Could not get positions: {e}") + + return True + else: + print("❌ Authentication failed") + return False + + except Exception as e: + print(f"❌ Authentication error: {e}") + return False + +def main(): + """Main function""" + print("🚀 Starting Bybit API Tests...") + + # Test public API + test_public_api() + + # Ask user if they want to test live authentication + print("\n" + "=" * 60) + response = input("Do you want to test live authentication? (y/N): ").lower() + + if response == 'y' or response == 'yes': + success = test_live_authentication() + if success: + print("\n✅ Live authentication test passed!") + print("🎯 Your Bybit integration is working!") + else: + print("\n❌ Live authentication test failed") + else: + print("\n📋 Skipping live authentication test") + + print("\n🎉 Public API tests completed successfully!") + print("📈 Bybit integration is functional for market data") + +if __name__ == "__main__": + main() diff --git a/web/clean_dashboard.py b/web/clean_dashboard.py index de654e8..329df06 100644 --- a/web/clean_dashboard.py +++ b/web/clean_dashboard.py @@ -3495,7 +3495,7 @@ class CleanTradingDashboard: # Train CNN model with multiple passes for enhanced learning if hasattr(self.orchestrator.cnn_model, 'train_on_batch'): for _ in range(int(training_weight)): - loss = self.orchestrator.cnn_model.train_on_batch(feature_tensor, target_tensor) + loss = self.orchestrator.cnn_model.train_on_batch(feature_tensor, target_tensor) logger.info(f"CNN enhanced training on executed signal - loss: {loss:.4f}, pnl: {pnl:.2f}") except Exception as e: