141 lines
4.7 KiB
Python
141 lines
4.7 KiB
Python
#!/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() |