mexc API failed, working on futures API as it what i we need anyway
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -154,7 +154,7 @@ trading:
|
|||||||
# MEXC Trading API Configuration
|
# MEXC Trading API Configuration
|
||||||
mexc_trading:
|
mexc_trading:
|
||||||
enabled: true
|
enabled: true
|
||||||
trading_mode: simulation # simulation, testnet, live
|
trading_mode: live # simulation, testnet, live
|
||||||
|
|
||||||
# FIXED: Meaningful position sizes for learning
|
# FIXED: Meaningful position sizes for learning
|
||||||
base_position_usd: 25.0 # $25 base position (was $1)
|
base_position_usd: 25.0 # $25 base position (was $1)
|
||||||
|
@ -27,7 +27,6 @@ try:
|
|||||||
from selenium.webdriver.support import expected_conditions as EC
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
from selenium.common.exceptions import TimeoutException, WebDriverException
|
from selenium.common.exceptions import TimeoutException, WebDriverException
|
||||||
from webdriver_manager.chrome import ChromeDriverManager
|
from webdriver_manager.chrome import ChromeDriverManager
|
||||||
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print("Please install selenium and webdriver-manager:")
|
print("Please install selenium and webdriver-manager:")
|
||||||
print("pip install selenium webdriver-manager")
|
print("pip install selenium webdriver-manager")
|
||||||
@ -68,16 +67,21 @@ class MEXCRequestInterceptor:
|
|||||||
self.cookies_file = f"mexc_cookies_{self.timestamp}.json"
|
self.cookies_file = f"mexc_cookies_{self.timestamp}.json"
|
||||||
|
|
||||||
def setup_chrome_with_logging(self) -> webdriver.Chrome:
|
def setup_chrome_with_logging(self) -> webdriver.Chrome:
|
||||||
"""Setup Chrome with performance logging enabled"""
|
"""Setup Brave browser with performance logging enabled"""
|
||||||
logger.info("Setting up ChromeDriver with request interception...")
|
logger.info("Setting up ChromeDriver with request interception for Brave browser...")
|
||||||
|
|
||||||
# Chrome options
|
# Chrome options (used for Brave as it's Chromium-based)
|
||||||
chrome_options = Options()
|
chrome_options = Options()
|
||||||
|
|
||||||
if self.headless:
|
if self.headless:
|
||||||
chrome_options.add_argument("--headless")
|
chrome_options.add_argument("--headless")
|
||||||
logger.info("Running in headless mode")
|
logger.info("Running in headless mode")
|
||||||
|
|
||||||
|
# Set the binary location for Brave
|
||||||
|
# brave_binary_path = "C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe"
|
||||||
|
# chrome_options.binary_location = brave_binary_path
|
||||||
|
# logger.info(f"Using Brave binary at: {brave_binary_path}")
|
||||||
|
|
||||||
# Essential options for automation
|
# Essential options for automation
|
||||||
chrome_options.add_argument("--no-sandbox")
|
chrome_options.add_argument("--no-sandbox")
|
||||||
chrome_options.add_argument("--disable-dev-shm-usage")
|
chrome_options.add_argument("--disable-dev-shm-usage")
|
||||||
@ -99,12 +103,14 @@ class MEXCRequestInterceptor:
|
|||||||
chrome_options.add_argument("--log-level=0")
|
chrome_options.add_argument("--log-level=0")
|
||||||
chrome_options.add_argument("--v=1")
|
chrome_options.add_argument("--v=1")
|
||||||
|
|
||||||
# Set capabilities for performance logging
|
# Set logging preferences for performance data
|
||||||
caps = DesiredCapabilities.CHROME
|
chrome_options.set_capability('goog:loggingPrefs', {
|
||||||
caps['goog:loggingPrefs'] = {
|
|
||||||
'performance': 'ALL',
|
'performance': 'ALL',
|
||||||
'browser': 'ALL'
|
'browser': 'ALL'
|
||||||
}
|
})
|
||||||
|
|
||||||
|
# # Add profile directory argument as provided by the user
|
||||||
|
# chrome_options.add_argument("--profile-directory=Profile 3")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Automatically download and install ChromeDriver
|
# Automatically download and install ChromeDriver
|
||||||
@ -114,8 +120,7 @@ class MEXCRequestInterceptor:
|
|||||||
# Create driver
|
# Create driver
|
||||||
driver = webdriver.Chrome(
|
driver = webdriver.Chrome(
|
||||||
service=service,
|
service=service,
|
||||||
options=chrome_options,
|
options=chrome_options
|
||||||
desired_capabilities=caps
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Hide automation indicators
|
# Hide automation indicators
|
||||||
|
@ -3,6 +3,9 @@ Trading Executor for MEXC API Integration
|
|||||||
|
|
||||||
This module handles the execution of trading signals through the MEXC exchange API.
|
This module handles the execution of trading signals through the MEXC exchange API.
|
||||||
It includes position management, risk controls, and safety features.
|
It includes position management, risk controls, and safety features.
|
||||||
|
|
||||||
|
https://github.com/mexcdevelop/mexc-api-postman/blob/main/MEXC%20V3.postman_collection.json
|
||||||
|
MEXC V3.postman_collection.json
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -89,7 +92,8 @@ class TradingExecutor:
|
|||||||
self.exchange = MEXCInterface(
|
self.exchange = MEXCInterface(
|
||||||
api_key=api_key,
|
api_key=api_key,
|
||||||
api_secret=api_secret,
|
api_secret=api_secret,
|
||||||
test_mode=exchange_test_mode
|
test_mode=exchange_test_mode,
|
||||||
|
trading_mode=trading_mode
|
||||||
)
|
)
|
||||||
|
|
||||||
# Trading state
|
# Trading state
|
||||||
@ -101,6 +105,8 @@ class TradingExecutor:
|
|||||||
self.trading_enabled = self.mexc_config.get('enabled', False)
|
self.trading_enabled = self.mexc_config.get('enabled', False)
|
||||||
self.trading_mode = trading_mode
|
self.trading_mode = trading_mode
|
||||||
|
|
||||||
|
logger.debug(f"TRADING EXECUTOR: Initial trading_enabled state from config: {self.trading_enabled}")
|
||||||
|
|
||||||
# Legacy compatibility (deprecated)
|
# Legacy compatibility (deprecated)
|
||||||
self.dry_run = self.simulation_mode
|
self.dry_run = self.simulation_mode
|
||||||
|
|
||||||
@ -109,7 +115,12 @@ class TradingExecutor:
|
|||||||
|
|
||||||
# Connect to exchange
|
# Connect to exchange
|
||||||
if self.trading_enabled:
|
if self.trading_enabled:
|
||||||
self._connect_exchange()
|
logger.info("TRADING EXECUTOR: Attempting to connect to exchange...")
|
||||||
|
if not self._connect_exchange():
|
||||||
|
logger.error("TRADING EXECUTOR: Failed initial exchange connection. Trading will be disabled.")
|
||||||
|
self.trading_enabled = False
|
||||||
|
else:
|
||||||
|
logger.info("TRADING EXECUTOR: Trading is explicitly disabled in config.")
|
||||||
|
|
||||||
logger.info(f"Trading Executor initialized - Mode: {self.trading_mode}, Enabled: {self.trading_enabled}")
|
logger.info(f"Trading Executor initialized - Mode: {self.trading_mode}, Enabled: {self.trading_enabled}")
|
||||||
|
|
||||||
@ -143,17 +154,20 @@ class TradingExecutor:
|
|||||||
def _connect_exchange(self) -> bool:
|
def _connect_exchange(self) -> bool:
|
||||||
"""Connect to the MEXC exchange"""
|
"""Connect to the MEXC exchange"""
|
||||||
try:
|
try:
|
||||||
|
logger.debug("TRADING EXECUTOR: Calling self.exchange.connect()...")
|
||||||
connected = self.exchange.connect()
|
connected = self.exchange.connect()
|
||||||
|
logger.debug(f"TRADING EXECUTOR: self.exchange.connect() returned: {connected}")
|
||||||
if connected:
|
if connected:
|
||||||
logger.info("Successfully connected to MEXC exchange")
|
logger.info("Successfully connected to MEXC exchange")
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
logger.error("Failed to connect to MEXC exchange")
|
logger.error("Failed to connect to MEXC exchange: Connection returned False.")
|
||||||
if not self.dry_run:
|
if not self.dry_run:
|
||||||
|
logger.info("TRADING EXECUTOR: Setting trading_enabled to False due to connection failure.")
|
||||||
self.trading_enabled = False
|
self.trading_enabled = False
|
||||||
return False
|
return False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error connecting to MEXC exchange: {e}")
|
logger.error(f"Error connecting to MEXC exchange: {e}. Setting trading_enabled to False.")
|
||||||
self.trading_enabled = False
|
self.trading_enabled = False
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -170,8 +184,9 @@ class TradingExecutor:
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if trade executed successfully
|
bool: True if trade executed successfully
|
||||||
"""
|
"""
|
||||||
|
logger.debug(f"TRADING EXECUTOR: execute_signal called. trading_enabled: {self.trading_enabled}")
|
||||||
if not self.trading_enabled:
|
if not self.trading_enabled:
|
||||||
logger.info(f"Trading disabled - Signal: {action} {symbol} (confidence: {confidence:.2f})")
|
logger.info(f"Trading disabled - Signal: {action} {symbol} (confidence: {confidence:.2f}) - Reason: Trading executor is not enabled.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if action == 'HOLD':
|
if action == 'HOLD':
|
||||||
@ -181,23 +196,51 @@ class TradingExecutor:
|
|||||||
if not self._check_safety_conditions(symbol, action):
|
if not self._check_safety_conditions(symbol, action):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Get current price if not provided
|
# Get current price if not provided
|
||||||
if current_price is None:
|
if current_price is None:
|
||||||
ticker = self.exchange.get_ticker(symbol)
|
ticker = self.exchange.get_ticker(symbol)
|
||||||
if not ticker:
|
if not ticker or 'last' not in ticker:
|
||||||
logger.error(f"Failed to get current price for {symbol}")
|
logger.error(f"Failed to get current price for {symbol} or ticker is malformed.")
|
||||||
return False
|
return False
|
||||||
current_price = ticker['last']
|
current_price = ticker['last']
|
||||||
|
|
||||||
# Assert that current_price is not None for type checking
|
# Assert that current_price is not None for type checking
|
||||||
assert current_price is not None, "current_price should not be None at this point"
|
assert current_price is not None, "current_price should not be None at this point"
|
||||||
|
|
||||||
|
# --- Balance check before executing trade ---
|
||||||
|
# Only perform balance check for BUY actions or SHORT (initial sell) actions
|
||||||
|
if action == 'BUY' or (action == 'SELL' and symbol not in self.positions) or (action == 'SHORT'):
|
||||||
|
# Determine the quote asset (e.g., USDT, USDC) from the symbol
|
||||||
|
if '/' in symbol:
|
||||||
|
quote_asset = symbol.split('/')[1].upper() # Assuming symbol is like ETH/USDT
|
||||||
|
else:
|
||||||
|
# Fallback for symbols like ETHUSDT (assuming last 4 chars are quote)
|
||||||
|
quote_asset = symbol[-4:].upper()
|
||||||
|
|
||||||
|
# Calculate required capital for the trade
|
||||||
|
# If we are selling (to open a short position), we need collateral based on the position size
|
||||||
|
# For simplicity, assume required capital is the full position value in USD
|
||||||
|
required_capital = self._calculate_position_size(confidence, current_price)
|
||||||
|
|
||||||
|
# Get available balance for the quote asset
|
||||||
|
available_balance = self.exchange.get_balance(quote_asset)
|
||||||
|
|
||||||
|
logger.info(f"BALANCE CHECK: Symbol: {symbol}, Action: {action}, Required: ${required_capital:.2f} {quote_asset}, Available: ${available_balance:.2f} {quote_asset}")
|
||||||
|
|
||||||
|
if available_balance < required_capital:
|
||||||
|
logger.warning(f"Trade blocked for {symbol} {action}: Insufficient {quote_asset} balance. "
|
||||||
|
f"Required: ${required_capital:.2f}, Available: ${available_balance:.2f}")
|
||||||
|
return False
|
||||||
|
# --- End Balance check ---
|
||||||
|
|
||||||
with self.lock:
|
with self.lock:
|
||||||
try:
|
try:
|
||||||
if action == 'BUY':
|
if action == 'BUY':
|
||||||
return self._execute_buy(symbol, confidence, current_price)
|
return self._execute_buy(symbol, confidence, current_price)
|
||||||
elif action == 'SELL':
|
elif action == 'SELL':
|
||||||
return self._execute_sell(symbol, confidence, current_price)
|
return self._execute_sell(symbol, confidence, current_price)
|
||||||
|
elif action == 'SHORT': # Explicitly handle SHORT if it's a direct signal
|
||||||
|
return self._execute_short(symbol, confidence, current_price)
|
||||||
else:
|
else:
|
||||||
logger.warning(f"Unknown action: {action}")
|
logger.warning(f"Unknown action: {action}")
|
||||||
return False
|
return False
|
||||||
|
29
mexc_cookies_20250703_003625.json
Normal file
29
mexc_cookies_20250703_003625.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"bm_sv": "D92603BBC020E9C2CD11B2EBC8F22050~YAAQJKVf1NW5K7CXAQAAwtMVzRzHARcY60jrPVzy9G79fN3SY4z988SWHHxQlbPpyZHOj76c20AjCnS0QwveqzB08zcRoauoIe/sP3svlaIso9PIdWay0KIIVUe1XsiTJRfTm/DmS+QdrOuJb09rbfWLcEJF4/0QK7VY0UTzPTI2V3CMtxnmYjd1+tjfYsvt1R6O+Mw9mYjb7SjhRmiP/exY2UgZdLTJiqd+iWkc5Wejy5m6g5duOfRGtiA9mfs=~1",
|
||||||
|
"bm_sz": "98D80FE4B23FE6352AE5194DA699FDDB~YAAQJKVf1GK4K7CXAQAAeQ0UzRw+aXiY5/Ujp+sZm0a4j+XAJFn6fKT4oph8YqIKF6uHSgXkFY3mBt8WWY98Y2w1QzOEFRkje8HTUYQgJsV59y5DIOTZKC6wutPD/bKdVi9ZKtk4CWbHIIRuCrnU1Nw2jqj5E0hsorhKGh8GeVsAeoao8FWovgdYD6u8Qpbr9aL5YZgVEIqJx6WmWLmcIg+wA8UFj8751Fl0B3/AGxY2pACUPjonPKNuX/UDYA5e98plOYUnYLyQMEGIapSrWKo1VXhKBDPLNedJ/Q2gOCGEGlj/u1Fs407QxxXwCvRSegL91y6modtL5JGoFucV1pYc4pgTwEAEdJfcLCEBaButTbaHI9T3SneqgCoGeatMMaqz0GHbvMD7fBQofARBqzN1L6aGlmmAISMzI3wx/SnsfXBl~3228228~3294529",
|
||||||
|
"_abck": "0288E759712AF333A6EE15F66BC2A662~-1~YAAQJKVf1GC4K7CXAQAAeQ0UzQ77TfyX5SOWTgdW3DVqNFrTLz2fhLo2OC4I6ZHnW9qB0vwTjFDfOB65BwLSeFZoyVypVCGTtY/uL6f4zX0AxEGAU8tLg/jeO0acO4JpGrjYZSW1F56vEd9JbPU2HQPNERorgCDLQMSubMeLCfpqMp3VCW4w0Ssnk6Y4pBSs4mh0PH95v56XXDvat9k20/JPoK3Ip5kK2oKh5Vpk5rtNTVea66P0NBjVUw/EddRUuDDJpc8T4DtTLDXnD5SNDxEq8WDkrYd5kP4dNe0PtKcSOPYs2QLUbvAzfBuMvnhoSBaCjsqD15EZ3eDAoioli/LzsWSxaxetYfm0pA/s5HBXMdOEDi4V0E9b79N28rXcC8IJEHXtfdZdhJjwh1FW14lqF9iuOwER81wDEnIVtgwTwpd3ffrc35aNjb+kGiQ8W0FArFhUI/ZY2NDvPVngRjNrmRm0CsCm+6mdxxVNsGNMPKYG29mcGDi2P9HGDk45iOm0vzoaYUl1PlOh4VGq/V3QGbPYpkBsBtQUjrf/SQJe5IAbjCICTYlgxTo+/FAEjec+QdUsagTgV8YNycQfTK64A2bs1L1n+RO5tapLThU6NkxnUbqHOm6168RnT8ZRoAUpkJ5m3QpqSsuslnPRUPyxUr73v514jTBIUGsq4pUeRpXXd9FAh8Xkn4VZ9Bh3q4jP7eZ9Sv58mgnEVltNBFkeG3zsuIp5Hu69MSBU+8FD4gVlncbBinrTLNWRB8F00Gyvc03unrAznsTEyLiDq9guQf9tQNcGjxfggfnGq/Z1Gy/A7WMjiYw7pwGRVzAYnRgtcZoww9gQ/FdGkbp2Xl+oVZpaqFsHVvafWyOFr4pqQsmd353ddgKLjsEnpy/jcdUsIR/Ph3pYv++XlypXehXj0/GHL+WsosujJrYk4TuEsPKUcyHNr+r844mYUIhCYsI6XVKrq3fimdfdhmlkW8J1kZSTmFwP8QcwGlTK/mZDTJPyf8K5ugXcqOU8oIQzt5B2zfRwRYKHdhb8IUw=~-1~-1~-1",
|
||||||
|
"RT": "\"z=1&dm=www.mexc.com&si=f5d53b58-7845-4db4-99f1-444e43d35199&ss=mcmh857q&sl=3&tt=90n&bcn=%2F%2F684dd311.akstat.io%2F&ld=1c9o\"",
|
||||||
|
"mexc_fingerprint_visitorId": "tv1xchuZQbx9N0aBztUG",
|
||||||
|
"_ga_L6XJCQTK75": "GS2.1.s1751492192$o1$g1$t1751492248$j4$l0$h0",
|
||||||
|
"uc_token": "WEB66f893ede865e5d927efdea4a82e655ad5190239c247997d744ef9cd075f6f1e",
|
||||||
|
"u_id": "WEB66f893ede865e5d927efdea4a82e655ad5190239c247997d744ef9cd075f6f1e",
|
||||||
|
"_fbp": "fb.1.1751492193579.314807866777158389",
|
||||||
|
"mxc_exchange_layout": "BA",
|
||||||
|
"sensorsdata2015jssdkcross": "%7B%22distinct_id%22%3A%2221a8728990b84f4fa3ae64c8004b4aaa%22%2C%22first_id%22%3A%22197cd11dc751be-0dd66c04c69e96-26011f51-3686400-197cd11dc76189d%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_landing_page%22%3A%22https%3A%2F%2Fwww.mexc.com%2Fen-GB%2Flogin%3Fprevious%3D%252Ffutures%252FETH_USDT%253Ftype%253Dlinear_swap%22%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMTk3Y2QxMWRjNzUxYmUtMGRkNjZjMDRjNjllOTYtMjYwMTFmNTEtMzY4NjQwMC0xOTdjZDExZGM3NjE4OWQiLCIkaWRlbnRpdHlfbG9naW5faWQiOiIyMWE4NzI4OTkwYjg0ZjRmYTNhZTY0YzgwMDRiNGFhYSJ9%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%24identity_login_id%22%2C%22value%22%3A%2221a8728990b84f4fa3ae64c8004b4aaa%22%7D%2C%22%24device_id%22%3A%22197cd11dc751be-0dd66c04c69e96-26011f51-3686400-197cd11dc76189d%22%7D",
|
||||||
|
"mxc_theme_main": "dark",
|
||||||
|
"mexc_fingerprint_requestId": "1751492199306.WMvKJd",
|
||||||
|
"_ym_visorc": "b",
|
||||||
|
"mexc_clearance_modal_show_date": "2025-07-03-undefined",
|
||||||
|
"ak_bmsc": "35C21AA65F819E0BF9BEBDD10DCF7B70~000000000000000000000000000000~YAAQJKVf1BK2K7CXAQAAPAISzRwQdUOUs1H3HPAdl4COMFQAl+aEPzppLbdgrwA7wXbP/LZpxsYCFflUHDppYKUjzXyTZ9tIojSF3/6CW3OCiPhQo/qhf6XPbC4oQHpCNWaC9GJWEs/CGesQdfeBbhkXdfh+JpgmgCF788+x8IveDE9+9qaL/3QZRy+E7zlKjjvmMxBpahRy+ktY9/KMrCY2etyvtm91KUclr4k8HjkhtNJOlthWgUyiANXJtfbNUMgt+Hqgqa7QzSUfAEpxIXQ1CuROoY9LbU292LRN5TbtBy/uNv6qORT38rKsnpi7TGmyFSB9pj3YsoSzIuAUxYXSh4hXRgAoUQm3Yh5WdLp4ONeyZC1LIb8VCY5xXRy/VbfaHH1w7FodY1HpfHGKSiGHSNwqoiUmMPx13Rgjsgki4mE7bwFmG2H5WAilRIOZA5OkndEqGrOuiNTON7l6+g6mH0MzZ+/+3AjnfF2sXxFuV9itcs9x",
|
||||||
|
"mxc_theme_upcolor": "upgreen",
|
||||||
|
"_vid_t": "mQUFl49q1yLZhrL4tvOtFF38e+hGW5QoMS+eXKVD9Q4vQau6icnyipsdyGLW/FBukiO2ItK7EtzPIPMFrE5SbIeLSm1NKc/j+ZmobhX063QAlskf1x1J",
|
||||||
|
"_ym_isad": "2",
|
||||||
|
"_ym_d": "1751492196",
|
||||||
|
"_ym_uid": "1751492196843266888",
|
||||||
|
"bm_mi": "02862693F007017AEFD6639269A60D08~YAAQJKVf1Am2K7CXAQAAIf4RzRzNGqZ7Q3BC0kAAp/0sCOhHxxvEWTb7mBl8p7LUz0W6RZbw5Etz03Tvqu3H6+sb+yu1o0duU+bDflt7WLVSOfG5cA3im8Jeo6wZhqmxTu6gGXuBgxhrHw/RGCgcknxuZQiRM9cbM6LlZIAYiugFm2xzmO/1QcpjDhs4S8d880rv6TkMedlkYGwdgccAmvbaRVSmX9d5Yukm+hY+5GWuyKMeOjpatAhcgjShjpSDwYSpyQE7vVZLBp7TECIjI9uoWzR8A87YHScKYEuE08tb8YtGdG3O6g70NzasSX0JF3XTCjrVZA==~1",
|
||||||
|
"_ga": "GA1.1.626437359.1751492192",
|
||||||
|
"NEXT_LOCALE": "en-GB",
|
||||||
|
"x-mxc-fingerprint": "tv1xchuZQbx9N0aBztUG",
|
||||||
|
"CLIENT_LANG": "en-GB",
|
||||||
|
"sajssdk_2015_cross_new_user": "1"
|
||||||
|
}
|
16883
mexc_requests_20250703_003625.json
Normal file
16883
mexc_requests_20250703_003625.json
Normal file
File diff suppressed because it is too large
Load Diff
64
tests/test_mexc_account_private.py
Normal file
64
tests/test_mexc_account_private.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Configure logging
|
||||||
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Add project root to path
|
||||||
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
||||||
|
|
||||||
|
from NN.exchanges.mexc_interface import MEXCInterface
|
||||||
|
from core.config import get_config
|
||||||
|
|
||||||
|
def test_mexc_private_api():
|
||||||
|
"""Test MEXC private API endpoints"""
|
||||||
|
# Load configuration
|
||||||
|
config = get_config('config.yaml')
|
||||||
|
mexc_config = config.get('mexc_trading', {})
|
||||||
|
|
||||||
|
# Get API credentials
|
||||||
|
api_key = os.getenv('MEXC_API_KEY', mexc_config.get('api_key', ''))
|
||||||
|
api_secret = os.getenv('MEXC_SECRET_KEY', mexc_config.get('api_secret', ''))
|
||||||
|
|
||||||
|
if not api_key or not api_secret:
|
||||||
|
logger.error("API key or secret not found. Please set MEXC_API_KEY and MEXC_SECRET_KEY environment variables.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Initialize MEXC interface in test mode
|
||||||
|
mexc = MEXCInterface(api_key=api_key, api_secret=api_secret, test_mode=True, trading_mode='simulation')
|
||||||
|
|
||||||
|
# Test connection
|
||||||
|
if not mexc.connect():
|
||||||
|
logger.error("Failed to connect to MEXC API")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Test getting account information
|
||||||
|
logger.info("Testing account information retrieval...")
|
||||||
|
account_info = mexc.get_account_info()
|
||||||
|
if account_info:
|
||||||
|
logger.info(f"Account info retrieved: {account_info}")
|
||||||
|
else:
|
||||||
|
logger.error("Failed to retrieve account info")
|
||||||
|
|
||||||
|
# Test getting balance for a specific asset
|
||||||
|
asset = "USDT"
|
||||||
|
logger.info(f"Testing balance retrieval for {asset}...")
|
||||||
|
balance = mexc.get_balance(asset)
|
||||||
|
logger.info(f"Balance for {asset}: {balance}")
|
||||||
|
|
||||||
|
# Test placing a simulated order (in test mode)
|
||||||
|
symbol = "ETH/USDT"
|
||||||
|
side = "buy"
|
||||||
|
order_type = "market"
|
||||||
|
quantity = 0.01 # Small quantity for testing
|
||||||
|
logger.info(f"Testing order placement for {symbol} ({side}, {order_type}, qty: {quantity})...")
|
||||||
|
order_result = mexc.place_order(symbol=symbol, side=side, order_type=order_type, quantity=quantity)
|
||||||
|
if order_result:
|
||||||
|
logger.info(f"Order placed successfully: {order_result}")
|
||||||
|
else:
|
||||||
|
logger.error("Failed to place order")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_mexc_private_api()
|
@ -1,13 +1,31 @@
|
|||||||
from NN.exchanges.mexc_interface import MEXCInterface
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
from NN.exchanges.mexc_interface import MEXCInterface
|
||||||
|
|
||||||
# Set up logging to see debug info
|
# Set up logging to see debug info
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
# Load API credentials from environment variables or a configuration file
|
||||||
|
# For testing, prioritize environment variables for CI/CD or sensitive data
|
||||||
|
# Fallback to a placeholder or configuration reading if env vars are not set
|
||||||
|
api_key = os.getenv('MEXC_API_KEY', '')
|
||||||
|
api_secret = os.getenv('MEXC_SECRET_KEY', '')
|
||||||
|
|
||||||
|
# If using a config file, you might do something like:
|
||||||
|
# from core.config import get_config
|
||||||
|
# config = get_config('config.yaml')
|
||||||
|
# mexc_config = config.get('mexc_trading', {})
|
||||||
|
# api_key = mexc_config.get('api_key', api_key)
|
||||||
|
# api_secret = mexc_config.get('api_secret', api_secret)
|
||||||
|
|
||||||
|
if not api_key or not api_secret:
|
||||||
|
logging.error("API keys are not set. Please set MEXC_API_KEY and MEXC_SECRET_KEY environment variables or configure config.yaml")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
# Create interface with API credentials
|
# Create interface with API credentials
|
||||||
mexc = MEXCInterface(
|
mexc = MEXCInterface(
|
||||||
api_key='mx0aBYs33eIilxBWC5',
|
api_key=api_key,
|
||||||
api_secret='45d0b3c26f2644f19bfb98b07741b2f5',
|
api_secret=api_secret,
|
||||||
trading_mode='simulation'
|
trading_mode='simulation'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user