MEXC INTEGRATION WORKS!!!
This commit is contained in:
@ -32,10 +32,14 @@ async def test_live_trading():
|
|||||||
logger.info("Initializing Trading Executor...")
|
logger.info("Initializing Trading Executor...")
|
||||||
executor = TradingExecutor("config.yaml")
|
executor = TradingExecutor("config.yaml")
|
||||||
|
|
||||||
|
# Enable test mode to bypass safety checks
|
||||||
|
executor.set_test_mode(True)
|
||||||
|
|
||||||
# Check trading mode
|
# Check trading mode
|
||||||
logger.info(f"Trading Mode: {executor.trading_mode}")
|
logger.info(f"Trading Mode: {executor.trading_mode}")
|
||||||
logger.info(f"Simulation Mode: {executor.simulation_mode}")
|
logger.info(f"Simulation Mode: {executor.simulation_mode}")
|
||||||
logger.info(f"Trading Enabled: {executor.trading_enabled}")
|
logger.info(f"Trading Enabled: {executor.trading_enabled}")
|
||||||
|
logger.info(f"Test Mode: {getattr(executor, '_test_mode', False)}")
|
||||||
|
|
||||||
if executor.simulation_mode:
|
if executor.simulation_mode:
|
||||||
logger.warning("WARNING: Still in simulation mode. Check config.yaml")
|
logger.warning("WARNING: Still in simulation mode. Check config.yaml")
|
||||||
@ -84,8 +88,34 @@ async def test_live_trading():
|
|||||||
logger.error(f"Error getting market data: {e}")
|
logger.error(f"Error getting market data: {e}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test 3: Calculate position sizing
|
# Test 3: Check for open orders
|
||||||
logger.info("\n=== TEST 3: POSITION SIZING ===")
|
logger.info("\n=== TEST 3: OPEN ORDERS CHECK ===")
|
||||||
|
try:
|
||||||
|
open_orders = executor.exchange.get_open_orders("ETH/USDT")
|
||||||
|
if open_orders and len(open_orders) > 0:
|
||||||
|
logger.info(f"Found {len(open_orders)} open orders:")
|
||||||
|
for order in open_orders:
|
||||||
|
order_id = order.get('orderId', 'N/A')
|
||||||
|
side = order.get('side', 'N/A')
|
||||||
|
qty = order.get('origQty', 'N/A')
|
||||||
|
price = order.get('price', 'N/A')
|
||||||
|
logger.info(f" Order {order_id}: {side} {qty} ETH at ${price}")
|
||||||
|
|
||||||
|
# Ask if user wants to cancel existing orders
|
||||||
|
user_input = input("Cancel existing open orders? (type 'YES' to confirm): ")
|
||||||
|
if user_input.upper() == 'YES':
|
||||||
|
cancelled = executor._cancel_open_orders("ETH/USDT")
|
||||||
|
if cancelled:
|
||||||
|
logger.info("✅ Open orders cancelled successfully")
|
||||||
|
else:
|
||||||
|
logger.warning("⚠️ Some orders may not have been cancelled")
|
||||||
|
else:
|
||||||
|
logger.info("No open orders found")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error checking open orders: {e}")
|
||||||
|
|
||||||
|
# Test 4: Calculate position sizing
|
||||||
|
logger.info("\n=== TEST 4: POSITION SIZING ===")
|
||||||
try:
|
try:
|
||||||
# Test position size calculation with different confidence levels
|
# Test position size calculation with different confidence levels
|
||||||
test_confidences = [0.3, 0.5, 0.7, 0.9]
|
test_confidences = [0.3, 0.5, 0.7, 0.9]
|
||||||
@ -99,8 +129,8 @@ async def test_live_trading():
|
|||||||
logger.error(f"Error calculating position sizes: {e}")
|
logger.error(f"Error calculating position sizes: {e}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test 4: Small test trade (optional - requires confirmation)
|
# Test 5: Small test trade (optional - requires confirmation)
|
||||||
logger.info("\n=== TEST 4: TEST TRADE (OPTIONAL) ===")
|
logger.info("\n=== TEST 5: TEST TRADE (OPTIONAL) ===")
|
||||||
|
|
||||||
user_input = input("Do you want to execute a SMALL test trade? (type 'YES' to confirm): ")
|
user_input = input("Do you want to execute a SMALL test trade? (type 'YES' to confirm): ")
|
||||||
if user_input.upper() == 'YES':
|
if user_input.upper() == 'YES':
|
||||||
@ -118,22 +148,32 @@ async def test_live_trading():
|
|||||||
if success:
|
if success:
|
||||||
logger.info("✅ Test BUY order executed successfully!")
|
logger.info("✅ Test BUY order executed successfully!")
|
||||||
|
|
||||||
# Wait a moment, then try to sell
|
# Check order status
|
||||||
await asyncio.sleep(2)
|
await asyncio.sleep(1)
|
||||||
|
positions = executor.get_positions()
|
||||||
|
if "ETH/USDT" in positions:
|
||||||
|
position = positions["ETH/USDT"]
|
||||||
|
logger.info(f"Position created: {position.side} {position.quantity:.6f} ETH @ ${position.entry_price:.2f}")
|
||||||
|
|
||||||
logger.info("Executing corresponding SELL order...")
|
# Wait a moment, then try to sell immediately (test mode should allow this)
|
||||||
success = executor.execute_signal(
|
logger.info("Waiting 1 second before attempting SELL...")
|
||||||
symbol="ETH/USDT",
|
await asyncio.sleep(1)
|
||||||
action="SELL",
|
|
||||||
confidence=0.9, # High confidence to ensure execution
|
|
||||||
current_price=current_price
|
|
||||||
)
|
|
||||||
|
|
||||||
if success:
|
logger.info("Executing corresponding SELL order...")
|
||||||
logger.info("✅ Test SELL order executed successfully!")
|
success = executor.execute_signal(
|
||||||
logger.info("✅ Full test trade cycle completed!")
|
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:
|
else:
|
||||||
logger.warning("❌ Test SELL order failed")
|
logger.warning("❌ No position found after BUY order")
|
||||||
else:
|
else:
|
||||||
logger.warning("❌ Test BUY order failed")
|
logger.warning("❌ Test BUY order failed")
|
||||||
|
|
||||||
@ -142,8 +182,8 @@ async def test_live_trading():
|
|||||||
else:
|
else:
|
||||||
logger.info("Test trade skipped")
|
logger.info("Test trade skipped")
|
||||||
|
|
||||||
# Test 5: Position and trade history
|
# Test 6: Position and trade history
|
||||||
logger.info("\n=== TEST 5: POSITIONS AND HISTORY ===")
|
logger.info("\n=== TEST 6: POSITIONS AND HISTORY ===")
|
||||||
try:
|
try:
|
||||||
positions = executor.get_positions()
|
positions = executor.get_positions()
|
||||||
trade_history = executor.get_trade_history()
|
trade_history = executor.get_trade_history()
|
||||||
@ -160,9 +200,30 @@ async def test_live_trading():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error getting positions/history: {e}")
|
logger.error(f"Error getting positions/history: {e}")
|
||||||
|
|
||||||
|
# Test 7: Final open orders check
|
||||||
|
logger.info("\n=== TEST 7: FINAL OPEN ORDERS CHECK ===")
|
||||||
|
try:
|
||||||
|
open_orders = executor.exchange.get_open_orders("ETH/USDT")
|
||||||
|
if open_orders and len(open_orders) > 0:
|
||||||
|
logger.warning(f"⚠️ {len(open_orders)} open orders still pending:")
|
||||||
|
for order in open_orders:
|
||||||
|
order_id = order.get('orderId', 'N/A')
|
||||||
|
side = order.get('side', 'N/A')
|
||||||
|
qty = order.get('origQty', 'N/A')
|
||||||
|
price = order.get('price', 'N/A')
|
||||||
|
status = order.get('status', 'N/A')
|
||||||
|
logger.info(f" Order {order_id}: {side} {qty} ETH at ${price} - Status: {status}")
|
||||||
|
else:
|
||||||
|
logger.info("✅ No pending orders")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error checking final open orders: {e}")
|
||||||
|
|
||||||
logger.info("\n=== LIVE TRADING TEST COMPLETED ===")
|
logger.info("\n=== LIVE TRADING TEST COMPLETED ===")
|
||||||
logger.info("If all tests passed, live trading is ready!")
|
logger.info("If all tests passed, live trading is ready!")
|
||||||
|
|
||||||
|
# Disable test mode
|
||||||
|
executor.set_test_mode(False)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error in live trading test: {e}")
|
logger.error(f"Error in live trading test: {e}")
|
||||||
|
|
||||||
|
@ -267,6 +267,38 @@ class TradingExecutor:
|
|||||||
logger.error(f"Error executing {action} signal for {symbol}: {e}")
|
logger.error(f"Error executing {action} signal for {symbol}: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _cancel_open_orders(self, symbol: str) -> bool:
|
||||||
|
"""Cancel all open orders for a symbol before placing new orders"""
|
||||||
|
try:
|
||||||
|
logger.info(f"Checking for open orders to cancel for {symbol}")
|
||||||
|
open_orders = self.exchange.get_open_orders(symbol)
|
||||||
|
|
||||||
|
if open_orders and len(open_orders) > 0:
|
||||||
|
logger.info(f"Found {len(open_orders)} open orders for {symbol}, cancelling...")
|
||||||
|
|
||||||
|
for order in open_orders:
|
||||||
|
order_id = order.get('orderId')
|
||||||
|
if order_id:
|
||||||
|
try:
|
||||||
|
cancel_result = self.exchange.cancel_order(symbol, str(order_id))
|
||||||
|
if cancel_result:
|
||||||
|
logger.info(f"Successfully cancelled order {order_id} for {symbol}")
|
||||||
|
else:
|
||||||
|
logger.warning(f"Failed to cancel order {order_id} for {symbol}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error cancelling order {order_id}: {e}")
|
||||||
|
|
||||||
|
# Wait a moment for cancellations to process
|
||||||
|
time.sleep(0.5)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.debug(f"No open orders found for {symbol}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error checking/cancelling open orders for {symbol}: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
def _check_safety_conditions(self, symbol: str, action: str) -> bool:
|
def _check_safety_conditions(self, symbol: str, action: str) -> bool:
|
||||||
"""Check if it's safe to execute a trade"""
|
"""Check if it's safe to execute a trade"""
|
||||||
# Check if trading is stopped
|
# Check if trading is stopped
|
||||||
@ -292,12 +324,21 @@ class TradingExecutor:
|
|||||||
# logger.warning(f"Daily trade limit reached: {self.daily_trades}")
|
# logger.warning(f"Daily trade limit reached: {self.daily_trades}")
|
||||||
# return False
|
# return False
|
||||||
|
|
||||||
# Check trade interval
|
# Check trade interval - allow bypass for test scenarios
|
||||||
min_interval = self.mexc_config.get('min_trade_interval_seconds', 5)
|
min_interval = self.mexc_config.get('min_trade_interval_seconds', 5)
|
||||||
last_trade = self.last_trade_time.get(symbol, datetime.min)
|
last_trade = self.last_trade_time.get(symbol, datetime.min)
|
||||||
if (datetime.now() - last_trade).total_seconds() < min_interval:
|
time_since_last = (datetime.now() - last_trade).total_seconds()
|
||||||
logger.info(f"Trade interval not met for {symbol}")
|
|
||||||
return False
|
# Allow bypass for high confidence sells (closing positions) or test scenarios
|
||||||
|
if time_since_last < min_interval:
|
||||||
|
# Allow immediate sells for closing positions or very high confidence (0.9+)
|
||||||
|
if action == 'SELL' and symbol in self.positions:
|
||||||
|
logger.info(f"Allowing immediate SELL to close position for {symbol}")
|
||||||
|
elif hasattr(self, '_test_mode') and self._test_mode:
|
||||||
|
logger.info(f"Test mode: bypassing trade interval for {symbol}")
|
||||||
|
else:
|
||||||
|
logger.info(f"Trade interval not met for {symbol} ({time_since_last:.1f}s < {min_interval}s)")
|
||||||
|
return False
|
||||||
|
|
||||||
# Check concurrent positions
|
# Check concurrent positions
|
||||||
max_positions = self.mexc_config.get('max_concurrent_positions', 1)
|
max_positions = self.mexc_config.get('max_concurrent_positions', 1)
|
||||||
@ -319,6 +360,10 @@ class TradingExecutor:
|
|||||||
logger.info(f"Already have LONG position in {symbol}")
|
logger.info(f"Already have LONG position in {symbol}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Cancel any existing open orders before placing new order
|
||||||
|
if not self.simulation_mode:
|
||||||
|
self._cancel_open_orders(symbol)
|
||||||
|
|
||||||
# Calculate position size
|
# Calculate position size
|
||||||
position_value = self._calculate_position_size(confidence, current_price)
|
position_value = self._calculate_position_size(confidence, current_price)
|
||||||
quantity = position_value / current_price
|
quantity = position_value / current_price
|
||||||
@ -412,6 +457,10 @@ class TradingExecutor:
|
|||||||
|
|
||||||
position = self.positions[symbol]
|
position = self.positions[symbol]
|
||||||
|
|
||||||
|
# Cancel any existing open orders before placing new order
|
||||||
|
if not self.simulation_mode:
|
||||||
|
self._cancel_open_orders(symbol)
|
||||||
|
|
||||||
logger.info(f"Executing SELL: {position.quantity:.6f} {symbol} at ${current_price:.2f} "
|
logger.info(f"Executing SELL: {position.quantity:.6f} {symbol} at ${current_price:.2f} "
|
||||||
f"(confidence: {confidence:.2f}) [{'SIMULATION' if self.simulation_mode else 'LIVE'}]")
|
f"(confidence: {confidence:.2f}) [{'SIMULATION' if self.simulation_mode else 'LIVE'}]")
|
||||||
|
|
||||||
@ -1345,3 +1394,11 @@ class TradingExecutor:
|
|||||||
'min_percent': 2.0
|
'min_percent': 2.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def set_test_mode(self, enabled: bool = True):
|
||||||
|
"""Enable test mode to bypass safety checks for testing"""
|
||||||
|
self._test_mode = enabled
|
||||||
|
if enabled:
|
||||||
|
logger.info("TRADING EXECUTOR: Test mode enabled - bypassing safety checks")
|
||||||
|
else:
|
||||||
|
logger.info("TRADING EXECUTOR: Test mode disabled - normal safety checks active")
|
Reference in New Issue
Block a user