gogo2/test_mexc_order_sizes.py
2025-05-28 11:18:07 +03:00

205 lines
7.7 KiB
Python

"""
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()