test bybit opening/closing orders
This commit is contained in:
@ -131,7 +131,7 @@ class TradingExecutor:
|
||||
self.trade_records = [] # List of TradeRecord objects
|
||||
|
||||
logger.info(f"TradingExecutor initialized - Trading: {self.trading_enabled}, Mode: {self.trading_mode}")
|
||||
|
||||
|
||||
# Legacy compatibility (deprecated)
|
||||
self.dry_run = self.simulation_mode
|
||||
|
||||
@ -276,7 +276,7 @@ class TradingExecutor:
|
||||
quote_asset = 'USDC' # Use USDC instead
|
||||
logger.info(f"BALANCE CHECK: Using USDC fallback balance for {symbol}")
|
||||
else:
|
||||
available_balance = self.exchange.get_balance(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}")
|
||||
|
||||
@ -303,23 +303,23 @@ class TradingExecutor:
|
||||
logger.info(f"LOCK ACQUIRED: Executing {action} for {symbol}")
|
||||
start_time = time.time()
|
||||
|
||||
if action == 'BUY':
|
||||
if action == 'BUY':
|
||||
result = self._execute_buy(symbol, confidence, current_price)
|
||||
elif action == 'SELL':
|
||||
elif action == 'SELL':
|
||||
result = self._execute_sell(symbol, confidence, current_price)
|
||||
elif action == 'SHORT': # Explicitly handle SHORT if it's a direct signal
|
||||
elif action == 'SHORT': # Explicitly handle SHORT if it's a direct signal
|
||||
result = self._execute_short(symbol, confidence, current_price)
|
||||
else:
|
||||
logger.warning(f"Unknown action: {action}")
|
||||
else:
|
||||
logger.warning(f"Unknown action: {action}")
|
||||
result = False
|
||||
|
||||
execution_time = time.time() - start_time
|
||||
logger.info(f"EXECUTION COMPLETE: {action} for {symbol} took {execution_time:.2f}s, result: {result}")
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error executing {action} signal for {symbol}: {e}")
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.error(f"Error executing {action} signal for {symbol}: {e}")
|
||||
return False
|
||||
finally:
|
||||
self.lock.release()
|
||||
logger.debug(f"LOCK RELEASED: {action} for {symbol}")
|
||||
@ -386,7 +386,7 @@ class TradingExecutor:
|
||||
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
|
||||
return False
|
||||
|
||||
# Check concurrent positions
|
||||
max_positions = self.exchange_config.get('max_concurrent_positions',
|
||||
@ -442,7 +442,7 @@ class TradingExecutor:
|
||||
# Only create position if order was actually filled
|
||||
if result.get('filled', True): # Assume filled for backward compatibility
|
||||
self.positions[symbol] = Position(
|
||||
symbol=symbol,
|
||||
symbol=symbol,
|
||||
side='LONG',
|
||||
quantity=float(filled_quantity),
|
||||
entry_price=float(fill_price),
|
||||
@ -452,7 +452,7 @@ class TradingExecutor:
|
||||
logger.info(f"BUY position created: {filled_quantity:.6f} {symbol} at ${fill_price:.4f}")
|
||||
self.last_trade_time[symbol] = datetime.now()
|
||||
return True
|
||||
else:
|
||||
else:
|
||||
logger.error(f"BUY order placed but not filled: {result}")
|
||||
return False
|
||||
else:
|
||||
@ -488,12 +488,12 @@ class TradingExecutor:
|
||||
|
||||
if self.simulation_mode:
|
||||
# Create simulated short position
|
||||
self.positions[symbol] = Position(
|
||||
symbol=symbol,
|
||||
self.positions[symbol] = Position(
|
||||
symbol=symbol,
|
||||
side='SHORT',
|
||||
quantity=quantity,
|
||||
entry_price=current_price,
|
||||
entry_time=datetime.now(),
|
||||
quantity=quantity,
|
||||
entry_price=current_price,
|
||||
entry_time=datetime.now(),
|
||||
order_id=f"sim_{int(datetime.now().timestamp())}"
|
||||
)
|
||||
logger.info(f"Simulated SHORT order: {quantity:.6f} {symbol} at ${current_price:.2f}")
|
||||
@ -517,15 +517,15 @@ class TradingExecutor:
|
||||
order_id=result['orderId']
|
||||
)
|
||||
logger.info(f"SHORT position created: {filled_quantity:.6f} {symbol} at ${fill_price:.4f}")
|
||||
self.last_trade_time[symbol] = datetime.now()
|
||||
return True
|
||||
else:
|
||||
self.last_trade_time[symbol] = datetime.now()
|
||||
return True
|
||||
else:
|
||||
logger.error(f"SHORT order placed but not filled: {result}")
|
||||
return False
|
||||
else:
|
||||
logger.error("Failed to place SHORT order")
|
||||
return False
|
||||
|
||||
|
||||
def _place_order_with_retry(self, symbol: str, side: str, order_type: str, quantity: float, current_price: float, max_retries: int = 3) -> Dict[str, Any]:
|
||||
"""Place order with retry logic for MEXC error handling"""
|
||||
order_start_time = time.time()
|
||||
@ -628,7 +628,7 @@ class TradingExecutor:
|
||||
try:
|
||||
self.exchange.cancel_order(symbol, order_id)
|
||||
logger.info(f"Cancelled unfilled order {order_id}")
|
||||
except Exception as e:
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to cancel unfilled order {order_id}: {e}")
|
||||
|
||||
# If this was the last attempt, return failure
|
||||
@ -763,7 +763,7 @@ class TradingExecutor:
|
||||
if symbol not in self.positions:
|
||||
logger.warning(f"No position to close in {symbol}")
|
||||
return False
|
||||
|
||||
|
||||
position = self.positions[symbol]
|
||||
if position.side != 'SHORT':
|
||||
logger.warning(f"Position in {symbol} is not SHORT, cannot close with BUY")
|
||||
@ -899,7 +899,7 @@ class TradingExecutor:
|
||||
except Exception as e:
|
||||
logger.error(f"Error closing SHORT position: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def _close_long_position(self, symbol: str, confidence: float, current_price: float) -> bool:
|
||||
"""Close a long position by selling"""
|
||||
if symbol not in self.positions:
|
||||
@ -1190,18 +1190,18 @@ class TradingExecutor:
|
||||
raw_balances = self.exchange.get_all_balances()
|
||||
if raw_balances:
|
||||
# Convert to the expected format with 'type' field
|
||||
combined_balances = {}
|
||||
combined_balances = {}
|
||||
for asset, balance_data in raw_balances.items():
|
||||
if isinstance(balance_data, dict):
|
||||
combined_balances[asset] = {
|
||||
combined_balances[asset] = {
|
||||
'free': balance_data.get('free', 0.0),
|
||||
'locked': balance_data.get('locked', 0.0),
|
||||
'total': balance_data.get('total', 0.0),
|
||||
'type': 'spot' # Default to spot for now
|
||||
}
|
||||
|
||||
|
||||
logger.info(f"Retrieved balances for {len(combined_balances)} assets from {self.primary_name}")
|
||||
return combined_balances
|
||||
return combined_balances
|
||||
else:
|
||||
logger.warning(f"No balances returned from {self.primary_name} exchange")
|
||||
return {}
|
||||
|
Reference in New Issue
Block a user