205 lines
7.7 KiB
Python
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() |