""" Test MEXC Order Size Requirements This script tests different order sizes to identify minimum order requirements and understand why order placement is failing. """ import os import sys import logging import time # Add paths for imports sys.path.append(os.path.join(os.path.dirname(__file__), 'NN')) from NN.exchanges.mexc_interface import MEXCInterface # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger("mexc_order_test") def test_order_sizes(): """Test different order sizes to find minimum requirements""" print("="*60) print("MEXC ORDER SIZE REQUIREMENTS TEST") print("="*60) api_key = os.getenv('MEXC_API_KEY') api_secret = os.getenv('MEXC_SECRET_KEY') if not api_key or not api_secret: print("❌ Missing API credentials") return False mexc = MEXCInterface(api_key=api_key, api_secret=api_secret, test_mode=True) # Get current ETH price ticker = mexc.get_ticker('ETH/USDT') if not ticker: print("❌ Failed to get ETH price") return False current_price = ticker['last'] print(f"Current ETH price: ${current_price:.2f}") # Test different USD amounts test_amounts_usd = [0.1, 0.5, 1.0, 5.0, 10.0, 20.0] print(f"\nTesting different order sizes...") print(f"{'USD Amount':<12} {'ETH Quantity':<15} {'Min ETH?':<10} {'Min USD?':<10}") print("-" * 50) for usd_amount in test_amounts_usd: eth_quantity = usd_amount / current_price # Check if quantity meets common minimum requirements min_eth_ok = eth_quantity >= 0.001 # 0.001 ETH common minimum min_usd_ok = usd_amount >= 5.0 # $5 common minimum print(f"${usd_amount:<11.2f} {eth_quantity:<15.6f} {'✅' if min_eth_ok else '❌':<9} {'✅' if min_usd_ok else '❌':<9}") # Test actual order parameter validation print(f"\nTesting order parameter validation...") # Test small order (likely to fail) small_usd = 1.0 small_eth = small_usd / current_price print(f"\n1. Testing small order: ${small_usd} (${small_eth:.6f} ETH)") success = test_order_validation(mexc, 'ETHUSDT', 'BUY', 'MARKET', small_eth) # Test medium order (might work) medium_usd = 10.0 medium_eth = medium_usd / current_price print(f"\n2. Testing medium order: ${medium_usd} (${medium_eth:.6f} ETH)") success = test_order_validation(mexc, 'ETHUSDT', 'BUY', 'MARKET', medium_eth) # Test with rounded quantities print(f"\n3. Testing with rounded quantities...") # Test 0.001 ETH (common minimum) print(f" Testing 0.001 ETH (${0.001 * current_price:.2f})") success = test_order_validation(mexc, 'ETHUSDT', 'BUY', 'MARKET', 0.001) # Test 0.01 ETH print(f" Testing 0.01 ETH (${0.01 * current_price:.2f})") success = test_order_validation(mexc, 'ETHUSDT', 'BUY', 'MARKET', 0.01) return True def test_order_validation(mexc: MEXCInterface, symbol: str, side: str, order_type: str, quantity: float) -> bool: """Test order parameter validation without actually placing the order""" try: # Prepare order parameters params = { 'symbol': symbol, 'side': side, 'type': order_type, 'quantity': str(quantity), 'recvWindow': 5000, 'timestamp': int(time.time() * 1000) } # Generate signature signature = mexc._generate_signature(params) params['signature'] = signature print(f" Params: {params}") # Try to validate parameters by making the request but catching the specific error headers = {'X-MEXC-APIKEY': mexc.api_key} url = f"{mexc.base_url}/{mexc.api_version}/order" import requests # Make the request to see what specific error we get response = requests.post(url, params=params, headers=headers, timeout=30) if response.status_code == 200: print(" ✅ Order would be accepted (parameters valid)") return True else: response_data = response.json() if response.headers.get('content-type', '').startswith('application/json') else {'msg': response.text} error_code = response_data.get('code', 'Unknown') error_msg = response_data.get('msg', 'Unknown error') print(f" ❌ Error {error_code}: {error_msg}") # Analyze specific error codes if error_code == 400001: print(" → Invalid parameter format") elif error_code == 700002: print(" → Invalid signature") elif error_code == 70016: print(" → Order size too small") elif error_code == 70015: print(" → Insufficient balance") elif 'LOT_SIZE' in error_msg: print(" → Lot size violation (quantity precision/minimum)") elif 'MIN_NOTIONAL' in error_msg: print(" → Minimum notional value not met") return False except Exception as e: print(f" ❌ Exception: {e}") return False def get_symbol_info(): """Get symbol trading rules and limits""" print("\nGetting symbol trading rules...") try: api_key = os.getenv('MEXC_API_KEY') api_secret = os.getenv('MEXC_SECRET_KEY') mexc = MEXCInterface(api_key=api_key, api_secret=api_secret, test_mode=True) # Try to get exchange info import requests url = f"{mexc.base_url}/{mexc.api_version}/exchangeInfo" response = requests.get(url, timeout=30) if response.status_code == 200: exchange_info = response.json() # Find ETHUSDT symbol info for symbol_info in exchange_info.get('symbols', []): if symbol_info.get('symbol') == 'ETHUSDT': print(f"Found ETHUSDT trading rules:") print(f" Status: {symbol_info.get('status')}") print(f" Base asset: {symbol_info.get('baseAsset')}") print(f" Quote asset: {symbol_info.get('quoteAsset')}") # Check filters for filter_info in symbol_info.get('filters', []): filter_type = filter_info.get('filterType') if filter_type == 'LOT_SIZE': print(f" Lot Size Filter:") print(f" Min Qty: {filter_info.get('minQty')}") print(f" Max Qty: {filter_info.get('maxQty')}") print(f" Step Size: {filter_info.get('stepSize')}") elif filter_type == 'MIN_NOTIONAL': print(f" Min Notional Filter:") print(f" Min Notional: {filter_info.get('minNotional')}") elif filter_type == 'PRICE_FILTER': print(f" Price Filter:") print(f" Min Price: {filter_info.get('minPrice')}") print(f" Max Price: {filter_info.get('maxPrice')}") print(f" Tick Size: {filter_info.get('tickSize')}") break else: print("❌ ETHUSDT symbol not found in exchange info") else: print(f"❌ Failed to get exchange info: {response.status_code}") except Exception as e: print(f"❌ Error getting symbol info: {e}") if __name__ == "__main__": get_symbol_info() test_order_sizes()