#!/usr/bin/env python3 """ Fixed Bybit ETH futures trading test with proper minimum order size handling """ import os import sys import time import logging import json # 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 core.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 get_instrument_info(bybit: BybitInterface, symbol: str) -> dict: """Get instrument information including minimum order size""" try: instruments = bybit.get_instruments("linear") for instrument in instruments: if instrument.get('symbol') == symbol: return instrument return {} except Exception as e: logger.error(f"Error getting instrument info: {e}") return {} def test_eth_futures_trading(): """Test ETH futures trading with proper minimum order size""" print("šŸš€ Starting Fixed Bybit ETH Futures Live Trading Test...") print("=" * 60) print("BYBIT ETH FUTURES LIVE TRADING TEST (FIXED)") print("=" * 60) print("āš ļø This uses LIVE environment with real money!") print("āš ļø Will check minimum order size first") 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 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 instrument information to check minimum order size print(f"\nšŸ“‹ Getting instrument information for {symbol}...") try: instrument_info = get_instrument_info(bybit, symbol) if not instrument_info: print(f"āŒ Failed to get instrument info for {symbol}") return False print("āœ… Instrument information retrieved:") print(f" Symbol: {instrument_info.get('symbol')}") print(f" Status: {instrument_info.get('status')}") print(f" Base Coin: {instrument_info.get('baseCoin')}") print(f" Quote Coin: {instrument_info.get('quoteCoin')}") # Extract minimum order size lot_size_filter = instrument_info.get('lotSizeFilter', {}) min_order_qty = float(lot_size_filter.get('minOrderQty', 0.01)) max_order_qty = float(lot_size_filter.get('maxOrderQty', 10000)) qty_step = float(lot_size_filter.get('qtyStep', 0.01)) print(f" Minimum Order Qty: {min_order_qty}") print(f" Maximum Order Qty: {max_order_qty}") print(f" Quantity Step: {qty_step}") # Use minimum order size for testing test_quantity = min_order_qty print(f" Using test quantity: {test_quantity} ETH") except Exception as e: print(f"āŒ Instrument info error: {e}") return False # Test 3: Get account balance print(f"\nšŸ’° Checking account balance...") try: usdt_balance = bybit.get_balance('USDT') print(f"USDT Balance: ${usdt_balance:.2f}") # Calculate required balance (with some buffer) current_price_data = bybit.get_ticker(symbol) if not current_price_data: print("āŒ Failed to get current ETH price") return False current_price = current_price_data['last_price'] required_balance = current_price * test_quantity * 1.1 # 10% buffer print(f"Current ETH price: ${current_price:.2f}") print(f"Required balance: ${required_balance:.2f}") if usdt_balance < required_balance: print(f"āŒ Insufficient USDT balance for testing (need at least ${required_balance:.2f})") return False print("āœ… Sufficient balance for testing") except Exception as e: print(f"āŒ Balance check 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)") print(f" Minimum order size confirmed: {min_order_qty}") 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 5 seconds for position to be reflected...") time.sleep(5) 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']}") # Don't return False here, as the position might still exist print("āš ļø You may need to manually close the position") else: 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}") print("āš ļø You may need to manually close the position") # Test 9: Final position check print(f"\nšŸ“Š Final position check...") time.sleep(3) 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}") print("šŸ’” You may want to manually close this position") 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}") balance_change = final_balance - usdt_balance if balance_change > 0: print(f"šŸ’° Profit: +${balance_change:.2f}") elif balance_change < 0: print(f"šŸ“‰ Loss: ${balance_change:.2f}") else: print(f"šŸ”„ No change: ${balance_change:.2f}") except Exception as e: print(f"āŒ Final balance check error: {e}") return True def main(): """Main function""" print("šŸš€ Starting Fixed 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("šŸ“ Minimum order size handling works") print("=" * 60) else: print("\nšŸ’„ Trading test failed!") print("šŸ” Check the error messages above for details") return success if __name__ == "__main__": success = main() sys.exit(0 if success else 1)