From c651ae585a538ff33e2884c0504a118b00923137 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 14 Jul 2025 12:32:06 +0300 Subject: [PATCH] mexc debug files --- .../mexc/debug/final_mexc_order_test.py | 118 ++++++++++++ NN/exchanges/mexc/debug/fix_mexc_orders.py | 141 +++++++++++++++ NN/exchanges/mexc/debug/fix_mexc_orders_v2.py | 132 ++++++++++++++ NN/exchanges/mexc/debug/fix_mexc_orders_v3.py | 134 ++++++++++++++ .../mexc/debug/test_mexc_interface_debug.py | 130 ++++++++++++++ .../mexc/debug/test_mexc_order_signature.py | 166 +++++++++++++++++ .../debug/test_mexc_order_signature_v2.py | 161 +++++++++++++++++ .../mexc/debug/test_mexc_signature_debug.py | 140 +++++++++++++++ .../mexc/debug/test_small_mexc_order.py | 81 +++++++++ NN/exchanges/trading_agent_test.py | 13 +- check_ethusdc_precision.py | 76 -------- get_mexc_exchange_info.py | 97 ---------- test_live_trading.py | 170 ------------------ test_symbol_conversion.py | 50 ------ 14 files changed, 1212 insertions(+), 397 deletions(-) create mode 100644 NN/exchanges/mexc/debug/final_mexc_order_test.py create mode 100644 NN/exchanges/mexc/debug/fix_mexc_orders.py create mode 100644 NN/exchanges/mexc/debug/fix_mexc_orders_v2.py create mode 100644 NN/exchanges/mexc/debug/fix_mexc_orders_v3.py create mode 100644 NN/exchanges/mexc/debug/test_mexc_interface_debug.py create mode 100644 NN/exchanges/mexc/debug/test_mexc_order_signature.py create mode 100644 NN/exchanges/mexc/debug/test_mexc_order_signature_v2.py create mode 100644 NN/exchanges/mexc/debug/test_mexc_signature_debug.py create mode 100644 NN/exchanges/mexc/debug/test_small_mexc_order.py delete mode 100644 check_ethusdc_precision.py delete mode 100644 get_mexc_exchange_info.py delete mode 100644 test_live_trading.py delete mode 100644 test_symbol_conversion.py diff --git a/NN/exchanges/mexc/debug/final_mexc_order_test.py b/NN/exchanges/mexc/debug/final_mexc_order_test.py new file mode 100644 index 0000000..a35126f --- /dev/null +++ b/NN/exchanges/mexc/debug/final_mexc_order_test.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +""" +Final MEXC Order Test - Exact match to working examples +""" + +import os +import sys +import time +import hmac +import hashlib +import requests +import json +from urllib.parse import urlencode +from pathlib import Path + +# Add project root to path +project_root = Path(__file__).parent +sys.path.insert(0, str(project_root)) + +def test_final_mexc_order(): + """Test MEXC order with the working method""" + print("Final MEXC Order Test - Working Method") + print("=" * 50) + + # Get API credentials + api_key = os.getenv('MEXC_API_KEY', '') + api_secret = os.getenv('MEXC_SECRET_KEY', '') + + if not api_key or not api_secret: + print("❌ No MEXC API credentials found") + return + + # Parameters + timestamp = str(int(time.time() * 1000)) + + # Create the exact parameter string like the working example + params = f"symbol=ETHUSDC&side=BUY&type=LIMIT&quantity=0.003&price=2900&recvWindow=5000×tamp={timestamp}" + + print(f"Parameter string: {params}") + + # Create signature exactly like the working example + signature = hmac.new( + api_secret.encode('utf-8'), + params.encode('utf-8'), + hashlib.sha256 + ).hexdigest() + + print(f"Signature: {signature}") + + # Make the request exactly like the curl example + url = f"https://api.mexc.com/api/v3/order" + + headers = { + 'X-MEXC-APIKEY': api_key, + 'Content-Type': 'application/x-www-form-urlencoded' + } + + data = f"{params}&signature={signature}" + + try: + print(f"\nPOST to: {url}") + print(f"Headers: {headers}") + print(f"Data: {data}") + + response = requests.post(url, headers=headers, data=data) + + print(f"\nStatus: {response.status_code}") + print(f"Response: {response.text}") + + if response.status_code == 200: + print("✅ SUCCESS!") + else: + print("❌ FAILED") + # Try alternative method - sending as query params + print("\n--- Trying alternative method ---") + test_alternative_method(api_key, api_secret) + + except Exception as e: + print(f"Error: {e}") + +def test_alternative_method(api_key: str, api_secret: str): + """Try sending as query parameters instead""" + timestamp = str(int(time.time() * 1000)) + + params = { + 'symbol': 'ETHUSDC', + 'side': 'BUY', + 'type': 'LIMIT', + 'quantity': '0.003', + 'price': '2900', + 'timestamp': timestamp, + 'recvWindow': '5000' + } + + # Create query string + query_string = '&'.join([f"{k}={v}" for k, v in sorted(params.items())]) + + # Create signature + signature = hmac.new( + api_secret.encode('utf-8'), + query_string.encode('utf-8'), + hashlib.sha256 + ).hexdigest() + + # Add signature to params + params['signature'] = signature + + headers = { + 'X-MEXC-APIKEY': api_key + } + + print(f"Alternative query params: {params}") + + response = requests.post('https://api.mexc.com/api/v3/order', params=params, headers=headers) + print(f"Alternative response: {response.status_code} - {response.text}") + +if __name__ == "__main__": + test_final_mexc_order() \ No newline at end of file diff --git a/NN/exchanges/mexc/debug/fix_mexc_orders.py b/NN/exchanges/mexc/debug/fix_mexc_orders.py new file mode 100644 index 0000000..25c4358 --- /dev/null +++ b/NN/exchanges/mexc/debug/fix_mexc_orders.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 +""" +Fix MEXC Order Placement based on Official API Documentation +Uses the exact signature method from MEXC Postman collection +""" + +import os +import sys +import time +import hmac +import hashlib +import requests +from pathlib import Path + +# Add project root to path +project_root = Path(__file__).parent +sys.path.insert(0, str(project_root)) + +def create_mexc_signature(access_key: str, secret_key: str, params: dict, method: str = "POST") -> tuple: + """Create MEXC signature exactly as specified in their documentation""" + + # Get current timestamp in milliseconds + timestamp = str(int(time.time() * 1000)) + + # For POST requests, sort parameters alphabetically and create query string + if method == "POST": + # Sort parameters alphabetically + sorted_params = dict(sorted(params.items())) + + # Create parameter string + param_parts = [] + for key, value in sorted_params.items(): + param_parts.append(f"{key}={value}") + param_string = "&".join(param_parts) + else: + param_string = "" + + # Create signature target string: access_key + timestamp + param_string + signature_target = f"{access_key}{timestamp}{param_string}" + + print(f"Signature target: {signature_target}") + + # Generate HMAC SHA256 signature + signature = hmac.new( + secret_key.encode('utf-8'), + signature_target.encode('utf-8'), + hashlib.sha256 + ).hexdigest() + + return signature, timestamp, param_string + +def test_mexc_order_placement(): + """Test MEXC order placement with corrected signature""" + print("Testing MEXC Order Placement with Official API Method...") + print("=" * 60) + + # Get API credentials + api_key = os.getenv('MEXC_API_KEY', '') + api_secret = os.getenv('MEXC_SECRET_KEY', '') + + if not api_key or not api_secret: + print("❌ No MEXC API credentials found") + return + + # Test parameters - very small order + params = { + 'symbol': 'ETHUSDC', + 'side': 'BUY', + 'type': 'LIMIT', + 'quantity': '0.003', # $10 worth at ~$3000 + 'price': '3000.0', # Safe price below market + 'timeInForce': 'GTC' + } + + print(f"Order Parameters: {params}") + + # Create signature using official method + signature, timestamp, param_string = create_mexc_signature(api_key, api_secret, params) + + # Create headers as specified in documentation + headers = { + 'X-MEXC-APIKEY': api_key, + 'Request-Time': timestamp, + 'Content-Type': 'application/json' + } + + # Add signature to parameters + params['timestamp'] = timestamp + params['recvWindow'] = '5000' + params['signature'] = signature + + # Create URL with parameters + base_url = "https://api.mexc.com/api/v3/order" + + try: + print(f"\nMaking request to: {base_url}") + print(f"Headers: {headers}") + print(f"Parameters: {params}") + + # Make the request using POST with query parameters (MEXC style) + response = requests.post(base_url, headers=headers, params=params, timeout=10) + + print(f"\nResponse Status: {response.status_code}") + print(f"Response Headers: {dict(response.headers)}") + + if response.status_code == 200: + result = response.json() + print("✅ Order placed successfully!") + print(f"Order result: {result}") + + # Try to cancel it immediately if we got an order ID + if 'orderId' in result: + print(f"\nCanceling order {result['orderId']}...") + cancel_params = { + 'symbol': 'ETHUSDC', + 'orderId': result['orderId'] + } + + cancel_sig, cancel_ts, _ = create_mexc_signature(api_key, api_secret, cancel_params, "DELETE") + cancel_params['timestamp'] = cancel_ts + cancel_params['recvWindow'] = '5000' + cancel_params['signature'] = cancel_sig + + cancel_headers = { + 'X-MEXC-APIKEY': api_key, + 'Request-Time': cancel_ts, + 'Content-Type': 'application/json' + } + + cancel_response = requests.delete(base_url, headers=cancel_headers, params=cancel_params, timeout=10) + print(f"Cancel response: {cancel_response.status_code} - {cancel_response.text}") + + else: + print("❌ Order placement failed") + print(f"Response: {response.text}") + + except Exception as e: + print(f"❌ Request error: {e}") + +if __name__ == "__main__": + test_mexc_order_placement() \ No newline at end of file diff --git a/NN/exchanges/mexc/debug/fix_mexc_orders_v2.py b/NN/exchanges/mexc/debug/fix_mexc_orders_v2.py new file mode 100644 index 0000000..c60e945 --- /dev/null +++ b/NN/exchanges/mexc/debug/fix_mexc_orders_v2.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +""" +MEXC Order Fix V2 - Based on Exact Postman Collection Examples +""" + +import os +import sys +import time +import hmac +import hashlib +import requests +from urllib.parse import urlencode +from pathlib import Path + +# Add project root to path +project_root = Path(__file__).parent +sys.path.insert(0, str(project_root)) + +def create_mexc_signature_v2(api_key: str, secret_key: str, params: dict) -> tuple: + """Create MEXC signature based on exact Postman examples""" + + # Current timestamp in milliseconds + timestamp = str(int(time.time() * 1000)) + + # Add timestamp and recvWindow to params + params_with_time = params.copy() + params_with_time['timestamp'] = timestamp + params_with_time['recvWindow'] = '5000' + + # Sort parameters alphabetically (as shown in MEXC examples) + sorted_params = dict(sorted(params_with_time.items())) + + # Create query string exactly like the examples + query_string = urlencode(sorted_params, doseq=True) + + print(f"API Key: {api_key}") + print(f"Timestamp: {timestamp}") + print(f"Query String: {query_string}") + + # MEXC signature formula: HMAC-SHA256(query_string, secret_key) + # This matches the curl examples in their documentation + signature = hmac.new( + secret_key.encode('utf-8'), + query_string.encode('utf-8'), + hashlib.sha256 + ).hexdigest() + + print(f"Generated Signature: {signature}") + + return signature, timestamp, query_string + +def test_mexc_order_v2(): + """Test MEXC order placement with V2 signature method""" + print("Testing MEXC Order V2 - Exact Postman Method...") + print("=" * 60) + + # Get API credentials + api_key = os.getenv('MEXC_API_KEY', '') + api_secret = os.getenv('MEXC_SECRET_KEY', '') + + if not api_key or not api_secret: + print("❌ No MEXC API credentials found") + return + + # Order parameters matching MEXC examples + params = { + 'symbol': 'ETHUSDC', + 'side': 'BUY', + 'type': 'LIMIT', + 'quantity': '0.003', # Very small quantity + 'price': '2900.0', # Price below market + 'timeInForce': 'GTC' + } + + print(f"Order Parameters: {params}") + + # Create signature + signature, timestamp, query_string = create_mexc_signature_v2(api_key, api_secret, params) + + # Build final URL with all parameters + base_url = "https://api.mexc.com/api/v3/order" + full_url = f"{base_url}?{query_string}&signature={signature}" + + # Headers matching Postman examples + headers = { + 'X-MEXC-APIKEY': api_key, + 'Content-Type': 'application/x-www-form-urlencoded' + } + + try: + print(f"\nMaking POST request to: {full_url}") + print(f"Headers: {headers}") + + # POST request with query parameters (as shown in examples) + response = requests.post(full_url, headers=headers, timeout=10) + + print(f"\nResponse Status: {response.status_code}") + print(f"Response: {response.text}") + + if response.status_code == 200: + result = response.json() + print("✅ Order placed successfully!") + print(f"Order result: {result}") + + # Cancel immediately if successful + if 'orderId' in result: + print(f"\n🔄 Canceling order {result['orderId']}...") + cancel_order(api_key, api_secret, 'ETHUSDC', result['orderId']) + + else: + print("❌ Order placement failed") + + except Exception as e: + print(f"❌ Request error: {e}") + +def cancel_order(api_key: str, secret_key: str, symbol: str, order_id: str): + """Cancel a MEXC order""" + params = { + 'symbol': symbol, + 'orderId': order_id + } + + signature, timestamp, query_string = create_mexc_signature_v2(api_key, secret_key, params) + + url = f"https://api.mexc.com/api/v3/order?{query_string}&signature={signature}" + headers = {'X-MEXC-APIKEY': api_key} + + response = requests.delete(url, headers=headers, timeout=10) + print(f"Cancel response: {response.status_code} - {response.text}") + +if __name__ == "__main__": + test_mexc_order_v2() \ No newline at end of file diff --git a/NN/exchanges/mexc/debug/fix_mexc_orders_v3.py b/NN/exchanges/mexc/debug/fix_mexc_orders_v3.py new file mode 100644 index 0000000..57ece02 --- /dev/null +++ b/NN/exchanges/mexc/debug/fix_mexc_orders_v3.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 +""" +MEXC Order Fix V3 - Based on exact curl examples from MEXC documentation +""" + +import os +import sys +import time +import hmac +import hashlib +import requests +import json +from urllib.parse import urlencode +from pathlib import Path + +# Add project root to path +project_root = Path(__file__).parent +sys.path.insert(0, str(project_root)) + +def create_mexc_signature_v3(query_string: str, secret_key: str) -> str: + """Create MEXC signature exactly as shown in curl examples""" + + print(f"Signing string: {query_string}") + + # MEXC uses HMAC SHA256 on the query string + signature = hmac.new( + secret_key.encode('utf-8'), + query_string.encode('utf-8'), + hashlib.sha256 + ).hexdigest() + + print(f"Generated signature: {signature}") + return signature + +def test_mexc_order_v3(): + """Test MEXC order placement with V3 method matching curl examples""" + print("Testing MEXC Order V3 - Exact curl examples...") + print("=" * 60) + + # Get API credentials + api_key = os.getenv('MEXC_API_KEY', '') + api_secret = os.getenv('MEXC_SECRET_KEY', '') + + if not api_key or not api_secret: + print("❌ No MEXC API credentials found") + return + + # Order parameters exactly like the examples + timestamp = str(int(time.time() * 1000)) + + # Build the query string in alphabetical order (like the examples) + params = { + 'price': '2900.0', + 'quantity': '0.003', + 'recvWindow': '5000', + 'side': 'BUY', + 'symbol': 'ETHUSDC', + 'timeInForce': 'GTC', + 'timestamp': timestamp, + 'type': 'LIMIT' + } + + # Create query string in alphabetical order + query_string = urlencode(sorted(params.items())) + + print(f"Parameters: {params}") + print(f"Query string: {query_string}") + + # Generate signature + signature = create_mexc_signature_v3(query_string, api_secret) + + # Build the final URL and data exactly like the curl examples + base_url = "https://api.mexc.com/api/v3/order" + final_data = f"{query_string}&signature={signature}" + + # Headers exactly like the curl examples + headers = { + 'X-MEXC-APIKEY': api_key, + 'Content-Type': 'application/x-www-form-urlencoded' + } + + try: + print(f"\nMaking POST request to: {base_url}") + print(f"Headers: {headers}") + print(f"Data: {final_data}") + + # POST with data in body (like curl -d option) + response = requests.post(base_url, headers=headers, data=final_data, timeout=10) + + print(f"\nResponse Status: {response.status_code}") + print(f"Response: {response.text}") + + if response.status_code == 200: + result = response.json() + print("✅ Order placed successfully!") + print(f"Order result: {result}") + + # Cancel immediately if successful + if 'orderId' in result: + print(f"\n🔄 Canceling order {result['orderId']}...") + cancel_order_v3(api_key, api_secret, 'ETHUSDC', result['orderId']) + + else: + print("❌ Order placement failed") + + except Exception as e: + print(f"❌ Request error: {e}") + +def cancel_order_v3(api_key: str, secret_key: str, symbol: str, order_id: str): + """Cancel a MEXC order using V3 method""" + timestamp = str(int(time.time() * 1000)) + + params = { + 'orderId': order_id, + 'recvWindow': '5000', + 'symbol': symbol, + 'timestamp': timestamp + } + + query_string = urlencode(sorted(params.items())) + signature = create_mexc_signature_v3(query_string, secret_key) + + url = f"https://api.mexc.com/api/v3/order" + data = f"{query_string}&signature={signature}" + headers = { + 'X-MEXC-APIKEY': api_key, + 'Content-Type': 'application/x-www-form-urlencoded' + } + + response = requests.delete(url, headers=headers, data=data, timeout=10) + print(f"Cancel response: {response.status_code} - {response.text}") + +if __name__ == "__main__": + test_mexc_order_v3() \ No newline at end of file diff --git a/NN/exchanges/mexc/debug/test_mexc_interface_debug.py b/NN/exchanges/mexc/debug/test_mexc_interface_debug.py new file mode 100644 index 0000000..f244844 --- /dev/null +++ b/NN/exchanges/mexc/debug/test_mexc_interface_debug.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +""" +Debug MEXC Interface vs Manual + +Compare what the interface sends vs what works manually +""" + +import os +import sys +import time +import hmac +import hashlib +from pathlib import Path + +# Add project root to path +project_root = Path(__file__).parent +sys.path.insert(0, str(project_root)) + +def debug_interface(): + """Debug the interface signature generation""" + print("MEXC Interface vs Manual Debug") + print("=" * 50) + + # Get API credentials + api_key = os.getenv('MEXC_API_KEY', '') + api_secret = os.getenv('MEXC_SECRET_KEY', '') + + if not api_key or not api_secret: + print("❌ No MEXC API credentials found") + return False + + from NN.exchanges.mexc_interface import MEXCInterface + + mexc = MEXCInterface(api_key=api_key, api_secret=api_secret, test_mode=False, trading_mode='live') + + # Test parameters exactly like the interface would use + symbol = 'ETH/USDT' + formatted_symbol = mexc._format_spot_symbol(symbol) + quantity = 0.003 + price = 2900.0 + + print(f"Symbol: {symbol} -> {formatted_symbol}") + print(f"Quantity: {quantity}") + print(f"Price: {price}") + + # Interface parameters (what place_order would create) + interface_params = { + 'symbol': formatted_symbol, + 'side': 'BUY', + 'type': 'LIMIT', + 'quantity': str(quantity), # Interface converts to string + 'price': str(price), # Interface converts to string + 'timeInForce': 'GTC' # Interface adds this + } + + print(f"\nInterface params (before timestamp/recvWindow): {interface_params}") + + # Add timestamp and recvWindow like _send_private_request does + timestamp = str(int(time.time() * 1000)) + interface_params['timestamp'] = timestamp + interface_params['recvWindow'] = str(mexc.recv_window) + + print(f"Interface params (complete): {interface_params}") + + # Generate signature using interface method + interface_signature = mexc._generate_signature(interface_params) + print(f"Interface signature: {interface_signature}") + + # Manual signature (what we tested successfully) + manual_params = { + 'symbol': 'ETHUSDC', + 'side': 'BUY', + 'type': 'LIMIT', + 'quantity': '0.003', + 'price': '2900', + 'timestamp': timestamp, + 'recvWindow': '5000' + } + + print(f"\nManual params: {manual_params}") + + # Generate signature manually (working method) + mexc_order = ['symbol', 'side', 'type', 'quantity', 'price', 'timestamp', 'recvWindow'] + param_list = [] + for key in mexc_order: + if key in manual_params: + param_list.append(f"{key}={manual_params[key]}") + + manual_params_string = '&'.join(param_list) + manual_signature = hmac.new( + api_secret.encode('utf-8'), + manual_params_string.encode('utf-8'), + hashlib.sha256 + ).hexdigest() + + print(f"Manual params string: {manual_params_string}") + print(f"Manual signature: {manual_signature}") + + # Compare parameters + print(f"\n📊 COMPARISON:") + print(f"symbol: Interface='{interface_params['symbol']}', Manual='{manual_params['symbol']}' {'✅' if interface_params['symbol'] == manual_params['symbol'] else '❌'}") + print(f"side: Interface='{interface_params['side']}', Manual='{manual_params['side']}' {'✅' if interface_params['side'] == manual_params['side'] else '❌'}") + print(f"type: Interface='{interface_params['type']}', Manual='{manual_params['type']}' {'✅' if interface_params['type'] == manual_params['type'] else '❌'}") + print(f"quantity: Interface='{interface_params['quantity']}', Manual='{manual_params['quantity']}' {'✅' if interface_params['quantity'] == manual_params['quantity'] else '❌'}") + print(f"price: Interface='{interface_params['price']}', Manual='{manual_params['price']}' {'✅' if interface_params['price'] == manual_params['price'] else '❌'}") + print(f"timestamp: Interface='{interface_params['timestamp']}', Manual='{manual_params['timestamp']}' {'✅' if interface_params['timestamp'] == manual_params['timestamp'] else '❌'}") + print(f"recvWindow: Interface='{interface_params['recvWindow']}', Manual='{manual_params['recvWindow']}' {'✅' if interface_params['recvWindow'] == manual_params['recvWindow'] else '❌'}") + + # Check for timeInForce difference + if 'timeInForce' in interface_params: + print(f"timeInForce: Interface='{interface_params['timeInForce']}', Manual=None ❌ (EXTRA PARAMETER)") + + # Test without timeInForce + print(f"\n🔧 TESTING WITHOUT timeInForce:") + interface_params_minimal = interface_params.copy() + del interface_params_minimal['timeInForce'] + + interface_signature_minimal = mexc._generate_signature(interface_params_minimal) + print(f"Interface signature (no timeInForce): {interface_signature_minimal}") + + if interface_signature_minimal == manual_signature: + print("✅ Signatures match when timeInForce is removed!") + return True + else: + print("❌ Still don't match") + + return False + +if __name__ == "__main__": + debug_interface() \ No newline at end of file diff --git a/NN/exchanges/mexc/debug/test_mexc_order_signature.py b/NN/exchanges/mexc/debug/test_mexc_order_signature.py new file mode 100644 index 0000000..b27df89 --- /dev/null +++ b/NN/exchanges/mexc/debug/test_mexc_order_signature.py @@ -0,0 +1,166 @@ +#!/usr/bin/env python3 +""" +Debug MEXC Order Signature + +Tests order signature generation against MEXC API +""" + +import os +import sys +import time +import hmac +import hashlib +import logging +import requests +from pathlib import Path + +# Add project root to path +project_root = Path(__file__).parent +sys.path.insert(0, str(project_root)) + +# Enable debug logging +logging.basicConfig(level=logging.DEBUG) + +def test_order_signature(): + """Test order signature generation""" + print("MEXC Order Signature Debug") + print("=" * 50) + + # Get API credentials + api_key = os.getenv('MEXC_API_KEY', '') + api_secret = os.getenv('MEXC_SECRET_KEY', '') + + if not api_key or not api_secret: + print("❌ No MEXC API credentials found") + return False + + # Test order parameters + timestamp = str(int(time.time() * 1000)) + params = { + 'symbol': 'ETHUSDC', + 'side': 'BUY', + 'type': 'LIMIT', + 'quantity': '0.003', + 'price': '2900', + 'timeInForce': 'GTC', + 'timestamp': timestamp, + 'recvWindow': '5000' + } + + print(f"Order parameters: {params}") + + # Test 1: Manual signature generation (timestamp first) + print("\n1. Manual signature generation (timestamp first):") + + # Create parameter string with timestamp first, then alphabetical + param_list = [f"timestamp={params['timestamp']}"] + for key in sorted(params.keys()): + if key != 'timestamp': + param_list.append(f"{key}={params[key]}") + + params_string = '&'.join(param_list) + print(f"Params string: {params_string}") + + signature_manual = hmac.new( + api_secret.encode('utf-8'), + params_string.encode('utf-8'), + hashlib.sha256 + ).hexdigest() + + print(f"Manual signature: {signature_manual}") + + # Test 2: Interface signature generation + print("\n2. Interface signature generation:") + from NN.exchanges.mexc_interface import MEXCInterface + + mexc = MEXCInterface(api_key=api_key, api_secret=api_secret, test_mode=False) + signature_interface = mexc._generate_signature(params) + print(f"Interface signature: {signature_interface}") + + # Compare + if signature_manual == signature_interface: + print("✅ Signatures match!") + else: + print("❌ Signatures don't match") + print("This indicates a problem with the signature generation method") + return False + + # Test 3: Try order with manual signature + print("\n3. Testing order with manual method:") + + url = "https://api.mexc.com/api/v3/order" + headers = { + 'X-MEXC-APIKEY': api_key + } + + order_params = params.copy() + order_params['signature'] = signature_manual + + print(f"Making POST request to: {url}") + print(f"Headers: {headers}") + print(f"Params: {order_params}") + + try: + response = requests.post(url, headers=headers, params=order_params, timeout=10) + print(f"Response status: {response.status_code}") + print(f"Response: {response.text}") + + if response.status_code == 200: + print("✅ Manual order method works!") + return True + else: + print("❌ Manual order method failed") + + # Test 4: Try test order endpoint + print("\n4. Testing with test order endpoint:") + test_url = "https://api.mexc.com/api/v3/order/test" + + response2 = requests.post(test_url, headers=headers, params=order_params, timeout=10) + print(f"Test order response: {response2.status_code} - {response2.text}") + + if response2.status_code == 200: + print("✅ Test order works - real order parameters might have issues") + + # Test 5: Try different parameter variations + print("\n5. Testing different parameter sets:") + + # Minimal parameters + minimal_params = { + 'symbol': 'ETHUSDC', + 'side': 'BUY', + 'type': 'LIMIT', + 'quantity': '0.003', + 'price': '2900', + 'timestamp': str(int(time.time() * 1000)), + 'recvWindow': '5000' + } + + # Generate signature for minimal params + minimal_param_list = [f"timestamp={minimal_params['timestamp']}"] + for key in sorted(minimal_params.keys()): + if key != 'timestamp': + minimal_param_list.append(f"{key}={minimal_params[key]}") + + minimal_params_string = '&'.join(minimal_param_list) + minimal_signature = hmac.new( + api_secret.encode('utf-8'), + minimal_params_string.encode('utf-8'), + hashlib.sha256 + ).hexdigest() + + minimal_params['signature'] = minimal_signature + + print(f"Minimal params: {minimal_params_string}") + print(f"Minimal signature: {minimal_signature}") + + response3 = requests.post(test_url, headers=headers, params=minimal_params, timeout=10) + print(f"Minimal params response: {response3.status_code} - {response3.text}") + + except Exception as e: + print(f"Request failed: {e}") + return False + + return False + +if __name__ == "__main__": + test_order_signature() \ No newline at end of file diff --git a/NN/exchanges/mexc/debug/test_mexc_order_signature_v2.py b/NN/exchanges/mexc/debug/test_mexc_order_signature_v2.py new file mode 100644 index 0000000..61b1ec3 --- /dev/null +++ b/NN/exchanges/mexc/debug/test_mexc_order_signature_v2.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python3 +""" +Debug MEXC Order Signature V2 + +Tests different signature generation approaches for orders +""" + +import os +import sys +import time +import hmac +import hashlib +import logging +import requests +from pathlib import Path + +# Add project root to path +project_root = Path(__file__).parent +sys.path.insert(0, str(project_root)) + +def test_different_approaches(): + """Test different signature generation approaches""" + print("MEXC Order Signature V2 - Different Approaches") + print("=" * 60) + + # Get API credentials + api_key = os.getenv('MEXC_API_KEY', '') + api_secret = os.getenv('MEXC_SECRET_KEY', '') + + if not api_key or not api_secret: + print("❌ No MEXC API credentials found") + return False + + # Test order parameters + timestamp = str(int(time.time() * 1000)) + params = { + 'symbol': 'ETHUSDC', + 'side': 'BUY', + 'type': 'LIMIT', + 'quantity': '0.003', + 'price': '2900', + 'timestamp': timestamp, + 'recvWindow': '5000' + } + + print(f"Order parameters: {params}") + + def generate_signature(params_dict, method_name): + print(f"\n{method_name}:") + + if method_name == "Alphabetical (all params)": + # Pure alphabetical ordering + sorted_params = sorted(params_dict.items()) + params_string = '&'.join([f"{k}={v}" for k, v in sorted_params]) + + elif method_name == "Timestamp first": + # Timestamp first, then alphabetical + param_list = [f"timestamp={params_dict['timestamp']}"] + for key in sorted(params_dict.keys()): + if key != 'timestamp': + param_list.append(f"{key}={params_dict[key]}") + params_string = '&'.join(param_list) + + elif method_name == "Postman order": + # Try exact Postman order from collection + postman_order = ['symbol', 'side', 'type', 'quantity', 'price', 'timestamp', 'recvWindow'] + param_list = [] + for key in postman_order: + if key in params_dict: + param_list.append(f"{key}={params_dict[key]}") + params_string = '&'.join(param_list) + + elif method_name == "Binance-style": + # Similar to Binance (alphabetical) + sorted_params = sorted(params_dict.items()) + params_string = '&'.join([f"{k}={v}" for k, v in sorted_params]) + + print(f"Params string: {params_string}") + + signature = hmac.new( + api_secret.encode('utf-8'), + params_string.encode('utf-8'), + hashlib.sha256 + ).hexdigest() + + print(f"Signature: {signature}") + return signature, params_string + + # Try different methods + methods = [ + "Alphabetical (all params)", + "Timestamp first", + "Postman order", + "Binance-style" + ] + + for method in methods: + signature, params_string = generate_signature(params, method) + + # Test with test order endpoint + test_url = "https://api.mexc.com/api/v3/order/test" + headers = {'X-MEXC-APIKEY': api_key} + + test_params = params.copy() + test_params['signature'] = signature + + try: + response = requests.post(test_url, headers=headers, params=test_params, timeout=10) + print(f"Response: {response.status_code} - {response.text}") + + if response.status_code == 200: + print(f"✅ {method} WORKS!") + return True + else: + print(f"❌ {method} failed") + + except Exception as e: + print(f"❌ {method} error: {e}") + + # Try one more approach - use minimal parameters + print("\n" + "=" * 60) + print("Trying minimal parameters (no timeInForce):") + + minimal_params = { + 'symbol': 'ETHUSDC', + 'side': 'BUY', + 'type': 'LIMIT', + 'quantity': '0.003', + 'price': '2900', + 'timestamp': str(int(time.time() * 1000)), + 'recvWindow': '5000' + } + + # Try alphabetical order with minimal params + sorted_minimal = sorted(minimal_params.items()) + minimal_string = '&'.join([f"{k}={v}" for k, v in sorted_minimal]) + print(f"Minimal params string: {minimal_string}") + + minimal_signature = hmac.new( + api_secret.encode('utf-8'), + minimal_string.encode('utf-8'), + hashlib.sha256 + ).hexdigest() + + minimal_params['signature'] = minimal_signature + + try: + response = requests.post(test_url, headers=headers, params=minimal_params, timeout=10) + print(f"Minimal response: {response.status_code} - {response.text}") + + if response.status_code == 200: + print("✅ Minimal parameters work!") + return True + + except Exception as e: + print(f"❌ Minimal parameters error: {e}") + + return False + +if __name__ == "__main__": + test_different_approaches() \ No newline at end of file diff --git a/NN/exchanges/mexc/debug/test_mexc_signature_debug.py b/NN/exchanges/mexc/debug/test_mexc_signature_debug.py new file mode 100644 index 0000000..2b7786c --- /dev/null +++ b/NN/exchanges/mexc/debug/test_mexc_signature_debug.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +""" +Debug MEXC Signature Generation + +Tests signature generation against known working examples +""" + +import os +import sys +import time +import hmac +import hashlib +import logging +from pathlib import Path + +# Add project root to path +project_root = Path(__file__).parent +sys.path.insert(0, str(project_root)) + +# Enable debug logging +logging.basicConfig(level=logging.DEBUG) + +def test_signature_generation(): + """Test signature generation with known parameters""" + print("MEXC Signature Generation Debug") + print("=" * 50) + + # Get API credentials + api_key = os.getenv('MEXC_API_KEY', '') + api_secret = os.getenv('MEXC_SECRET_KEY', '') + + if not api_key or not api_secret: + print("❌ No MEXC API credentials found") + return False + + # Import the interface + from NN.exchanges.mexc_interface import MEXCInterface + + mexc = MEXCInterface(api_key=api_key, api_secret=api_secret, test_mode=False) + + # Test 1: Manual signature generation (working method from examples) + print("\n1. Manual signature generation (working method):") + timestamp = str(int(time.time() * 1000)) + + # Parameters in exact order from working example + params_string = f"timestamp={timestamp}&recvWindow=5000" + print(f"Params string: {params_string}") + + signature_manual = hmac.new( + api_secret.encode('utf-8'), + params_string.encode('utf-8'), + hashlib.sha256 + ).hexdigest() + + print(f"Manual signature: {signature_manual}") + + # Test 2: Interface signature generation + print("\n2. Interface signature generation:") + params_dict = { + 'timestamp': timestamp, + 'recvWindow': '5000' + } + + signature_interface = mexc._generate_signature(params_dict) + print(f"Interface signature: {signature_interface}") + + # Compare + if signature_manual == signature_interface: + print("✅ Signatures match!") + else: + print("❌ Signatures don't match") + print("This indicates a problem with the signature generation method") + + # Test 3: Try account request with manual signature + print("\n3. Testing account request with manual method:") + + import requests + + url = f"https://api.mexc.com/api/v3/account" + headers = { + 'X-MEXC-APIKEY': api_key + } + + params = { + 'timestamp': timestamp, + 'recvWindow': '5000', + 'signature': signature_manual + } + + print(f"Making request to: {url}") + print(f"Headers: {headers}") + print(f"Params: {params}") + + try: + response = requests.get(url, headers=headers, params=params, timeout=10) + print(f"Response status: {response.status_code}") + print(f"Response: {response.text}") + + if response.status_code == 200: + print("✅ Manual method works!") + return True + else: + print("❌ Manual method failed") + + # Test 4: Try different parameter ordering + print("\n4. Testing different parameter orderings:") + + # Try alphabetical ordering (current implementation) + params_alpha = sorted(params_dict.items()) + params_alpha_string = '&'.join([f"{k}={v}" for k, v in params_alpha]) + print(f"Alphabetical: {params_alpha_string}") + + # Try the exact order from Postman collection + params_postman_string = f"recvWindow=5000×tamp={timestamp}" + print(f"Postman order: {params_postman_string}") + + sig_alpha = hmac.new(api_secret.encode('utf-8'), params_alpha_string.encode('utf-8'), hashlib.sha256).hexdigest() + sig_postman = hmac.new(api_secret.encode('utf-8'), params_postman_string.encode('utf-8'), hashlib.sha256).hexdigest() + + print(f"Alpha signature: {sig_alpha}") + print(f"Postman signature: {sig_postman}") + + # Test with postman order + params_test = { + 'timestamp': timestamp, + 'recvWindow': '5000', + 'signature': sig_postman + } + + response2 = requests.get(url, headers=headers, params=params_test, timeout=10) + print(f"Postman order response: {response2.status_code} - {response2.text}") + + except Exception as e: + print(f"Request failed: {e}") + return False + + return False + +if __name__ == "__main__": + test_signature_generation() \ No newline at end of file diff --git a/NN/exchanges/mexc/debug/test_small_mexc_order.py b/NN/exchanges/mexc/debug/test_small_mexc_order.py new file mode 100644 index 0000000..08a4f57 --- /dev/null +++ b/NN/exchanges/mexc/debug/test_small_mexc_order.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +""" +Test Small MEXC Order +Try to place a very small real order to see what happens +""" + +import os +import sys +from pathlib import Path + +# Add project root to path +project_root = Path(__file__).parent +sys.path.insert(0, str(project_root)) + +from NN.exchanges.mexc_interface import MEXCInterface + +def test_small_order(): + """Test placing a very small order""" + print("Testing Small MEXC Order...") + print("=" * 50) + + # Get API credentials + api_key = os.getenv('MEXC_API_KEY', '') + api_secret = os.getenv('MEXC_SECRET_KEY', '') + + if not api_key or not api_secret: + print("❌ No MEXC API credentials found") + return + + # Create MEXC interface + mexc = MEXCInterface(api_key=api_key, api_secret=api_secret, test_mode=False) + + if not mexc.connect(): + print("❌ Failed to connect to MEXC API") + return + + print("✅ Connected to MEXC API") + + # Get current price + ticker = mexc.get_ticker("ETH/USDT") # Will be converted to ETHUSDC + if not ticker: + print("❌ Failed to get ticker") + return + + current_price = ticker['last'] + print(f"Current ETHUSDC Price: ${current_price:.2f}") + + # Calculate a very small quantity (minimum possible) + min_order_value = 10.0 # $10 minimum + quantity = min_order_value / current_price + quantity = round(quantity, 5) # MEXC precision + + print(f"Test order: {quantity} ETH at ${current_price:.2f} = ${quantity * current_price:.2f}") + + # Try placing the order + print("\nPlacing test order...") + try: + result = mexc.place_order( + symbol="ETH/USDT", # Will be converted to ETHUSDC + side="BUY", + order_type="MARKET", # Will be converted to LIMIT + quantity=quantity + ) + + if result: + print("✅ Order placed successfully!") + print(f"Order result: {result}") + + # Try to cancel it immediately + if 'orderId' in result: + print(f"\nCanceling order {result['orderId']}...") + cancel_result = mexc.cancel_order("ETH/USDT", result['orderId']) + print(f"Cancel result: {cancel_result}") + else: + print("❌ Order placement failed") + + except Exception as e: + print(f"❌ Order error: {e}") + +if __name__ == "__main__": + test_small_order() \ No newline at end of file diff --git a/NN/exchanges/trading_agent_test.py b/NN/exchanges/trading_agent_test.py index f593d9e..ce459e0 100644 --- a/NN/exchanges/trading_agent_test.py +++ b/NN/exchanges/trading_agent_test.py @@ -14,6 +14,7 @@ import logging import os import sys import time +from typing import Optional, List # Configure logging logging.basicConfig( @@ -37,7 +38,7 @@ except ImportError: from binance_interface import BinanceInterface from mexc_interface import MEXCInterface -def create_exchange(exchange_name: str, api_key: str = None, api_secret: str = None, test_mode: bool = True) -> ExchangeInterface: +def create_exchange(exchange_name: str, api_key: Optional[str] = None, api_secret: Optional[str] = None, test_mode: bool = True) -> ExchangeInterface: """Create an exchange interface instance. Args: @@ -51,14 +52,18 @@ def create_exchange(exchange_name: str, api_key: str = None, api_secret: str = N """ exchange_name = exchange_name.lower() + # Use empty strings if None provided + key = api_key or "" + secret = api_secret or "" + if exchange_name == 'binance': - return BinanceInterface(api_key, api_secret, test_mode) + return BinanceInterface(key, secret, test_mode) elif exchange_name == 'mexc': - return MEXCInterface(api_key, api_secret, test_mode) + return MEXCInterface(key, secret, test_mode) else: raise ValueError(f"Unsupported exchange: {exchange_name}. Supported exchanges: binance, mexc") -def test_exchange(exchange: ExchangeInterface, symbols: list = None): +def test_exchange(exchange: ExchangeInterface, symbols: Optional[List[str]] = None): """Test the exchange interface. Args: diff --git a/check_ethusdc_precision.py b/check_ethusdc_precision.py deleted file mode 100644 index a9a85bb..0000000 --- a/check_ethusdc_precision.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python3 -""" -Check ETHUSDC Trading Rules and Precision -""" - -import os -import sys -from pathlib import Path - -# Add project root to path -project_root = Path(__file__).parent -sys.path.insert(0, str(project_root)) - -from NN.exchanges.mexc_interface import MEXCInterface - -def check_ethusdc_precision(): - """Check ETHUSDC trading rules""" - print("Checking ETHUSDC Trading Rules...") - print("=" * 50) - - # Get API credentials - api_key = os.getenv('MEXC_API_KEY', '') - api_secret = os.getenv('MEXC_SECRET_KEY', '') - - if not api_key or not api_secret: - print("❌ No MEXC API credentials found") - return - - # Create MEXC interface - mexc = MEXCInterface(api_key=api_key, api_secret=api_secret, test_mode=False) - - if not mexc.connect(): - print("❌ Failed to connect to MEXC API") - return - - print("✅ Connected to MEXC API") - - # Check if ETHUSDC is supported - if mexc.is_symbol_supported("ETH/USDT"): # Will be converted to ETHUSDC - print("✅ ETHUSDC is supported for trading") - else: - print("❌ ETHUSDC is not supported for trading") - return - - # Get current ticker to see price - ticker = mexc.get_ticker("ETH/USDT") # Will query ETHUSDC - if ticker: - price = ticker.get('last', 0) - print(f"Current ETHUSDC Price: ${price:.2f}") - - # Test different quantities to find minimum - test_quantities = [ - 0.001, # $3 worth - 0.01, # $30 worth - 0.1, # $300 worth - 0.009871, # Our calculated quantity - ] - - print("\nTesting different quantities:") - print("-" * 30) - - for qty in test_quantities: - rounded_qty = round(qty, 6) - value_usd = rounded_qty * price if ticker else 0 - print(f"Quantity: {rounded_qty:8.6f} ETH (~${value_usd:.2f})") - - print(f"\nOur test quantity: 0.009871 ETH") - print(f"Rounded to 6 decimals: {round(0.009871, 6):.6f} ETH") - print(f"Value: ~${round(0.009871, 6) * price:.2f}") - - print("\nNext steps:") - print("1. Check if minimum order value is $10+ USD") - print("2. Try with a larger quantity (0.01 ETH = ~$30)") - -if __name__ == "__main__": - check_ethusdc_precision() \ No newline at end of file diff --git a/get_mexc_exchange_info.py b/get_mexc_exchange_info.py deleted file mode 100644 index 19e6a2d..0000000 --- a/get_mexc_exchange_info.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env python3 -""" -Get MEXC Exchange Info for ETHUSDC -""" - -import requests -import json - -def get_mexc_exchange_info(): - """Get detailed MEXC exchange information for ETHUSDC""" - print("Getting MEXC Exchange Info for ETHUSDC...") - print("=" * 50) - - try: - # Get exchange info from MEXC public API - resp = requests.get('https://api.mexc.com/api/v3/exchangeInfo') - data = resp.json() - - # Find ETHUSDC symbol - ethusdc_info = None - for symbol_info in data.get('symbols', []): - if symbol_info['symbol'] == 'ETHUSDC': - ethusdc_info = symbol_info - break - - if not ethusdc_info: - print("❌ ETHUSDC symbol not found") - return - - print("✅ Found ETHUSDC symbol information") - print(f"Symbol: {ethusdc_info['symbol']}") - print(f"Status: {ethusdc_info['status']}") - print(f"Base Asset: {ethusdc_info['baseAsset']}") - print(f"Quote Asset: {ethusdc_info['quoteAsset']}") - print(f"Base Precision: {ethusdc_info['baseAssetPrecision']}") - print(f"Quote Precision: {ethusdc_info['quoteAssetPrecision']}") - - print("\nFilters:") - print("-" * 20) - - lot_size_filter = None - min_notional_filter = None - - for filter_info in ethusdc_info.get('filters', []): - filter_type = filter_info['filterType'] - print(f"\n{filter_type}:") - - if filter_type == 'LOT_SIZE': - lot_size_filter = filter_info - elif filter_type == 'MIN_NOTIONAL': - min_notional_filter = filter_info - - for key, value in filter_info.items(): - if key != 'filterType': - print(f" {key}: {value}") - - # Analyze requirements - print("\n" + "=" * 50) - print("ANALYSIS:") - - if lot_size_filter: - min_qty = float(lot_size_filter['minQty']) - step_size = lot_size_filter['stepSize'] - - print(f"Minimum Quantity: {min_qty} ETH") - print(f"Step Size: {step_size}") - - # Check our test quantity - test_qty = 0.009871 - print(f"\nOur quantity: {test_qty}") - print(f"Meets minimum?: {'✅ Yes' if test_qty >= min_qty else '❌ No'}") - - # Check step size compliance - if '.' in step_size: - decimal_places = len(step_size.split('.')[-1].rstrip('0')) - properly_rounded = round(test_qty, decimal_places) - print(f"Required decimals: {decimal_places}") - print(f"Properly rounded: {properly_rounded}") - - if min_notional_filter: - min_notional = float(min_notional_filter['minNotional']) - test_value = 0.009871 * 3031 # approximate price - print(f"\nMinimum Order Value: ${min_notional}") - print(f"Our order value: ${test_value:.2f}") - print(f"Meets minimum?: {'✅ Yes' if test_value >= min_notional else '❌ No'}") - - print("\n💡 RECOMMENDATIONS:") - if lot_size_filter and min_notional_filter: - safe_qty = max(float(lot_size_filter['minQty']) * 1.1, min_notional / 3000) - print(f"Use quantity >= {safe_qty:.6f} ETH for safe trading") - print(f"This equals ~${safe_qty * 3031:.2f} USD") - - except Exception as e: - print(f"❌ Error: {e}") - -if __name__ == "__main__": - get_mexc_exchange_info() \ No newline at end of file diff --git a/test_live_trading.py b/test_live_trading.py deleted file mode 100644 index 7da97d5..0000000 --- a/test_live_trading.py +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env python3 -""" -Test Live Trading - Verify MEXC Connection and Trading -""" - -import os -import sys -import logging -import asyncio -from datetime import datetime - -# Add project root to path -sys.path.append(os.path.dirname(os.path.abspath(__file__))) - -from core.trading_executor import TradingExecutor -from core.config import get_config - -# Setup logging -logging.basicConfig( - level=logging.INFO, - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' -) -logger = logging.getLogger(__name__) - -async def test_live_trading(): - """Test live trading functionality""" - try: - logger.info("=== LIVE TRADING TEST ===") - logger.info("Testing MEXC connection and account balance reading") - - # Initialize trading executor - logger.info("Initializing Trading Executor...") - executor = TradingExecutor("config.yaml") - - # Check trading mode - logger.info(f"Trading Mode: {executor.trading_mode}") - logger.info(f"Simulation Mode: {executor.simulation_mode}") - logger.info(f"Trading Enabled: {executor.trading_enabled}") - - if executor.simulation_mode: - logger.warning("WARNING: Still in simulation mode. Check config.yaml") - return - - # Test 1: Get account balance - logger.info("\n=== TEST 1: ACCOUNT BALANCE ===") - try: - balances = executor.get_account_balance() - logger.info("Account Balances:") - - total_value = 0.0 - for asset, balance_info in balances.items(): - if balance_info['total'] > 0: - logger.info(f" {asset}: {balance_info['total']:.6f} ({balance_info['type']})") - if asset in ['USDT', 'USDC', 'USD']: - total_value += balance_info['total'] - - logger.info(f"Total USD Value: ${total_value:.2f}") - - if total_value < 25: - logger.warning(f"Account balance ${total_value:.2f} may be insufficient for testing") - else: - logger.info(f"Account balance ${total_value:.2f} looks good for testing") - - except Exception as e: - logger.error(f"Error getting account balance: {e}") - return - - # Test 2: Get current ETH price - logger.info("\n=== TEST 2: MARKET DATA ===") - try: - # Test getting current price for ETH/USDT - if executor.exchange: - ticker = executor.exchange.get_ticker("ETH/USDT") - if ticker and 'last' in ticker: - current_price = ticker['last'] - logger.info(f"Current ETH/USDT Price: ${current_price:.2f}") - else: - logger.error("Failed to get ETH/USDT ticker data") - return - else: - logger.error("Exchange interface not available") - return - except Exception as e: - logger.error(f"Error getting market data: {e}") - return - - # Test 3: Calculate position sizing - logger.info("\n=== TEST 3: POSITION SIZING ===") - try: - # Test position size calculation with different confidence levels - test_confidences = [0.3, 0.5, 0.7, 0.9] - - for confidence in test_confidences: - position_size = executor._calculate_position_size(confidence, current_price) - quantity = position_size / current_price - logger.info(f"Confidence {confidence:.1f}: ${position_size:.2f} = {quantity:.6f} ETH") - - except Exception as e: - logger.error(f"Error calculating position sizes: {e}") - return - - # Test 4: Small test trade (optional - requires confirmation) - logger.info("\n=== TEST 4: TEST TRADE (OPTIONAL) ===") - - user_input = input("Do you want to execute a SMALL test trade? (type 'YES' to confirm): ") - if user_input.upper() == 'YES': - try: - logger.info("Executing SMALL test BUY order...") - - # Execute a very small buy order with low confidence (minimum position size) - success = executor.execute_signal( - symbol="ETH/USDT", - action="BUY", - confidence=0.3, # Low confidence = minimum position size - current_price=current_price - ) - - if success: - logger.info("✅ Test BUY order executed successfully!") - - # Wait a moment, then try to sell - await asyncio.sleep(2) - - logger.info("Executing corresponding SELL order...") - success = executor.execute_signal( - symbol="ETH/USDT", - action="SELL", - confidence=0.9, # High confidence to ensure execution - current_price=current_price - ) - - if success: - logger.info("✅ Test SELL order executed successfully!") - logger.info("✅ Full test trade cycle completed!") - else: - logger.warning("❌ Test SELL order failed") - else: - logger.warning("❌ Test BUY order failed") - - except Exception as e: - logger.error(f"Error executing test trade: {e}") - else: - logger.info("Test trade skipped") - - # Test 5: Position and trade history - logger.info("\n=== TEST 5: POSITIONS AND HISTORY ===") - try: - positions = executor.get_positions() - trade_history = executor.get_trade_history() - - logger.info(f"Current Positions: {len(positions)}") - for symbol, position in positions.items(): - logger.info(f" {symbol}: {position.side} {position.quantity:.6f} @ ${position.entry_price:.2f}") - - logger.info(f"Trade History: {len(trade_history)} trades") - for trade in trade_history[-5:]: # Last 5 trades - pnl_str = f"${trade.pnl:+.2f}" if trade.pnl else "$0.00" - logger.info(f" {trade.symbol} {trade.side}: {pnl_str}") - - except Exception as e: - logger.error(f"Error getting positions/history: {e}") - - logger.info("\n=== LIVE TRADING TEST COMPLETED ===") - logger.info("If all tests passed, live trading is ready!") - - except Exception as e: - logger.error(f"Error in live trading test: {e}") - -if __name__ == "__main__": - asyncio.run(test_live_trading()) \ No newline at end of file diff --git a/test_symbol_conversion.py b/test_symbol_conversion.py deleted file mode 100644 index ccac7e0..0000000 --- a/test_symbol_conversion.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -""" -Test MEXC Symbol Conversion -Verify that USDT symbols are properly converted to USDC for MEXC execution -""" - -import sys -from pathlib import Path - -# Add project root to path -project_root = Path(__file__).parent -sys.path.insert(0, str(project_root)) - -from NN.exchanges.mexc_interface import MEXCInterface - -def test_symbol_conversion(): - """Test the symbol conversion logic""" - print("Testing MEXC Symbol Conversion...") - print("=" * 50) - - # Create MEXC interface (no need for real API keys for symbol conversion) - mexc = MEXCInterface(api_key="dummy", api_secret="dummy", test_mode=True) - - # Test cases - test_symbols = [ - "ETH/USDT", - "BTC/USDT", - "ETHUSDT", - "BTCUSDT", - "ETH/USDC", # Should stay as USDC - "ETHUSDC" # Should stay as USDC - ] - - print("Symbol Conversion Results:") - print("-" * 30) - - for symbol in test_symbols: - converted = mexc._format_spot_symbol(symbol) - print(f"{symbol:12} -> {converted}") - - print("\nExpected Results for MEXC Trading:") - print("- ETH/USDT should become ETHUSDC") - print("- BTC/USDT should become BTCUSDC") - print("- ETHUSDT should become ETHUSDC") - print("- BTCUSDT should become BTCUSDC") - print("- ETH/USDC should stay ETHUSDC") - print("- ETHUSDC should stay ETHUSDC") - -if __name__ == "__main__": - test_symbol_conversion() \ No newline at end of file